Commit 7c921c9c by Lee Jaebin

端末の再起動時、ble通信ができない問題対応

parent a26bcdfe
......@@ -9,8 +9,11 @@ import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.content.Context;
import android.os.Build;
import android.os.Handler;
import android.widget.Toast;
import java.nio.ByteBuffer;
......@@ -20,6 +23,10 @@ import java.util.UUID;
import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.launcher.android.R;
import jp.agentec.abook.abv.ui.common.activity.ABVActivity;
import jp.agentec.abook.abv.ui.common.activity.ABVAuthenticatedActivity;
import jp.agentec.abook.abv.ui.common.appinfo.AppDefType;
import jp.agentec.adf.util.StringUtil;
import static android.bluetooth.BluetoothDevice.TRANSPORT_LE;
import static org.chromium.base.ThreadUtils.runOnUiThread;
......@@ -28,8 +35,9 @@ public class BleManagerUtil {
private final String TAG = "BleManagerUtil";
private BluetoothManager bluetoothManager;
private Context context;
private BleManagerUtilListener listener;
private Context mContext;
private BleManagerUtilListener mListener;
private Handler mHandler;
// 定数(Bluetooth LE Gatt UUID)
// Private Service
......@@ -46,8 +54,7 @@ public class BleManagerUtil {
// メンバー変数
public BluetoothAdapter mBluetoothAdapter; // BluetoothAdapter : Bluetooth処理で必要
public String mDeviceAddress = ""; // デバイスアドレス
public String mDeviceName = ""; // ディバイス名
private String mDeviceAddress = ""; // デバイスアドレス
public BluetoothGatt mBluetoothGatt = null; // Gattサービスの検索、キャラスタリスティックの読み書き
// BluetoothGattコールバック
......@@ -59,41 +66,43 @@ public class BleManagerUtil {
// if( BluetoothGatt.GATT_SUCCESS != status ) {
// runOnUiThread( new Runnable() {
// public void run() {
// listener.onGetDeviceInfoFailed();
// mListener.onGetDeviceInfoFailed();
// }
// });
// return;
// }
final int fStatus = status;
Logger.d("onConnectionStateChange status = " + fStatus);
// ディバイスと接続されていない場合のメッセージコード:133, 62
// ディバイスと接続が切れた場合のメッセージコード:19
if (status == 133 || status == 62) { // 接続失敗
runOnUiThread( new Runnable() {
@Override
public void run() {
Logger.e("onConnectionStateChange status = " + fStatus);
listener.onConnectionError(fStatus);
mListener.onConnectionError(fStatus);
}
});
return;
}
if( status == BluetoothGatt.GATT_SUCCESS && BluetoothProfile.STATE_CONNECTED == newState ) {
// 接続完了
if (!mBluetoothGatt.discoverServices()) { // サービス検索
runOnUiThread( new Runnable() { // 接続失敗
public void run() {
listener.onGetDeviceInfoFailed(fStatus);
Logger.e("onConnectionStateChange2 status = " + fStatus);
}
});
}
runOnUiThread( new Runnable() {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
// 接続成功
listener.onConnectionState();
// 接続完了
if (!mBluetoothGatt.discoverServices()) { // サービス検索
runOnUiThread( new Runnable() { // 接続失敗
@Override
public void run() {
mListener.onGetDeviceInfoFailed(fStatus);
Logger.e("onConnectionStateChange2 status = " + fStatus);
}
});
}
}
} );
}, 600);
return;
}
......@@ -114,10 +123,16 @@ public class BleManagerUtil {
return;
}
Logger.d(TAG, "--gattSize : " + gatt.getServices().size());
if (gatt.getServices().size() == 0) {
mListener.onGetDeviceInfoFailed(-1);
return;
}
// 発見されたサービスのループ
for( BluetoothGattService service : gatt.getServices() ) {
for(BluetoothGattService service : gatt.getServices()) {
// サービスごとに個別の処理
if( ( null == service ) || ( null == service.getUuid() ) ) {
if((service == null) || (service.getUuid()== null)) {
continue;
}
......@@ -129,13 +144,15 @@ public class BleManagerUtil {
}
// プライベートサービス
if( UUID_SERVICE_PRIVATE.equals( service.getUuid() ) ) {
if(UUID_SERVICE_PRIVATE.equals(service.getUuid())) {
// 最初の読み取り
readCharacteristic(UUID_SERVICE_PRIVATE, UUID_CHARACTERISTIC_PRIVATE1);
runOnUiThread( new Runnable() {
@Override
public void run() {
// 渡すデータがある場合
// 操作可能
mListener.onConnectionState();
}
});
continue;
......@@ -153,10 +170,11 @@ public class BleManagerUtil {
final String strTemperature = byteToString(characteristic.getValue());
runOnUiThread( new Runnable() {
@Override
public void run() {
// 芯温計の温度を渡す。
// 端末と接続時に呼ばれるのでコメント処理
// listener.onGetDeviceInfo(strTemperature);
// mListener.onGetDeviceInfo(strTemperature);
}
});
......@@ -176,11 +194,11 @@ public class BleManagerUtil {
@Override
public void run() {
// 複数呼ばれるため、mBluetoothGattがnullの場合、以下の処理を行わない
if( null == mBluetoothGatt ) {
if(mBluetoothGatt == null) {
return;
}
// 芯温計の温度を渡す。
listener.onGetDeviceInfo(strTemperature);
mListener.onGetDeviceInfo(strTemperature);
}
});
return;
......@@ -189,8 +207,64 @@ public class BleManagerUtil {
};
public BleManagerUtil(Context context, BleManagerUtilListener listener) {
this.context = context;
this.listener = listener;
mContext = context;
mListener = listener;
mHandler = new Handler();
}
// スキャンコールバック
private final ScanCallback mScanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, final ScanResult result) {
super.onScanResult(callbackType, result);
runOnUiThread(new Runnable() {
@Override
public void run() {
BluetoothDevice device = result.getDevice();
Logger.d(TAG, "--scaning : " + device.getName() );
if (device.getAddress().equals(mDeviceAddress)) {
// 異常と見做し、stopScanでエラーを返す。
stopScan(device.getAddress());
}
}
});
}
// スキャンに失敗
@Override
public void onScanFailed(final int errorCode) {
super.onScanFailed(errorCode);
Logger.e(TAG, "scan failed errorCode : " + errorCode);
runOnUiThread( new Runnable() {
@Override
public void run() {
mListener.onConnectionError(errorCode);
}
});
}
};
/**
* スキャンを中止
*/
private void stopScan(String deviceAddress) {
Logger.d(TAG, "stop ble scan");
// 一定期間後にスキャン停止するためのHandlerのRunnableの削除
mHandler.removeCallbacksAndMessages(null);
if (StringUtil.isNullOrEmpty(deviceAddress)) {
// deviceAddressが見つからなかったと見做し、エラーで返す。
mListener.onConnectionError(-1);
return;
}
// スキャン停止
mBluetoothAdapter.getBluetoothLeScanner().stopScan(mScanCallback);
// ble接続
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(deviceAddress);
bleGattConnect(device);
}
/**
......@@ -207,30 +281,53 @@ public class BleManagerUtil {
}
// 接続
public void connect() {
if( mDeviceAddress.equals( "" ) ) { // DeviceAddressが空の場合は処理しない
public void connect(String deviceAddress) {
mDeviceAddress = deviceAddress;
if(StringUtil.isNullOrEmpty(mDeviceAddress)) { // DeviceAddressが空の場合は処理しない
return;
}
if( null != mBluetoothGatt ) { // mBluetoothGattがnullでないなら接続済みか、接続中。
if(mBluetoothGatt != null) { // mBluetoothGattがnullでないなら接続済みか、接続中。
return;
}
// mBluetoothGattのサービスと接続
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice( mDeviceAddress );
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(deviceAddress);
if (device.getName() == null) {
// deviceの名称がない場合、接続エラーになるため、再スキャンすることで検知したらgetRemoteDeviceメソッドに名称がセットされる
mBluetoothAdapter.getBluetoothLeScanner().startScan(mScanCallback);
// スキャン開始(一定時間後にスキャン停止する)
mHandler.postDelayed( new Runnable() {
@Override
public void run() {
// 20秒後に呼ばれた時はスキャンで端末を取得できなかったと見做す。
stopScan(null);
Logger.d(TAG, "scan in 20 sec");
}
}, 20000 );
} else {
bleGattConnect(device);
}
}
/**
* GATT BLE接続処理
* @param device
*/
private void bleGattConnect(BluetoothDevice device) {
// GATT BLEを利用する時Androidのバージョン「23」をチェックしてGATTと接続する。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mBluetoothGatt = device.connectGatt( context, false, mGattcallback, TRANSPORT_LE);
mBluetoothGatt = device.connectGatt(mContext, false, mGattcallback, TRANSPORT_LE);
} else {
mBluetoothGatt = device.connectGatt( context, false, mGattcallback );
mBluetoothGatt = device.connectGatt(mContext, false, mGattcallback );
}
}
// 切断
public void disconnect() {
if( null == mBluetoothGatt ) {
if(mBluetoothGatt == null) {
return;
}
......@@ -240,16 +337,17 @@ public class BleManagerUtil {
// ①「ユーザーの意思による切断」は、mBluetoothGattオブジェクトを解放する。再接続は、オブジェクト構築から。
// ②「接続可能範囲から外れた切断」は、内部処理でmBluetoothGatt.disconnect()処理が実施される。
// 切断時のコールバックでmBluetoothGatt.connect()を呼んでおくと、接続可能範囲に入ったら自動接続する。
// mBluetoothGatt.close();
mBluetoothGatt.disconnect();
mBluetoothGatt.close();
mBluetoothGatt = null;
runOnUiThread( new Runnable() {
@Override
public void run() {
// 切断トーストメッセージを表示する。
listener.onDisConnectionState();
mListener.onDisConnectionState();
}
} );
});
}
// キャラクタリスティックの読み込み
......@@ -291,10 +389,10 @@ public class BleManagerUtil {
// Bluetoothアダプタの取得処理
public void startDeviceInfo() {
// Bluetoothアダプタの取得
BluetoothManager bluetoothManager = (BluetoothManager) context.getSystemService( Context.BLUETOOTH_SERVICE );
BluetoothManager bluetoothManager = (BluetoothManager) mContext.getSystemService( Context.BLUETOOTH_SERVICE );
mBluetoothAdapter = bluetoothManager.getAdapter();
if( null == mBluetoothAdapter ) { // Android端末がBluetoothをサポートしていない
Toast.makeText( context, R.string.bluetooth_is_not_supported, Toast.LENGTH_SHORT ).show();
Toast.makeText(mContext, R.string.bluetooth_is_not_supported, Toast.LENGTH_SHORT ).show();
return;
}
}
......
......@@ -216,11 +216,7 @@ public class ABVCheckContentViewActivity extends ABVContentViewActivity {
unregisterReceiver(mReceiver);
// 接続されている機器と切断する。
if( null != bleManagerUtil.mBluetoothGatt ) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
bleManagerUtil.mBluetoothGatt.disconnect();
}
}
bleThermometerDisconnect();
super.onDestroy();
}
......@@ -378,9 +374,8 @@ public class ABVCheckContentViewActivity extends ABVContentViewActivity {
if (deviceAddress.length() > 0) { //登録されている中心温度計がある
showWaitingDialog(getString(R.string.set_pairing_central_thermometer), getString(R.string.ble_connecting));
bleManagerUtil.mDeviceAddress = deviceAddress;
// 接続
bleManagerUtil.connect();
bleManagerUtil.connect(deviceAddress);
} else { //登録されている中心温度計がない
errorAfterAbookCheckAip(getString(R.string.msg_no_device_info));
......@@ -531,4 +526,10 @@ public class ABVCheckContentViewActivity extends ABVContentViewActivity {
// mediaPlayerを初期化
mMediaPlayer = null;
}
@Override
protected void onStop() {
super.onStop();
Logger.d(TAG, "--onStop");
}
}
......@@ -73,7 +73,9 @@ public class PairingSettingActivity extends ABVUIActivity {
@Override
public void run() {
BluetoothDevice device = result.getDevice();
Logger.d("mLeScanCallback device.getName() = " + device.getName());
if (device.getName() != null) {
Logger.d("mScanCallback device.getName() = " + device.getName());
}
// 識別商品名に絞る
if(device.getName() != null && device.getName().startsWith("MF500")) {
if (!device.getAddress().equals(mSavedDeviceAddress)) { //登録されたデバイスの場合、スキャン情報から除外する。
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment