OSDN Git Service

initial commit.
[gokigen/BLEControl.git] / app / src / main / java / net / osdn / gokigen / blecontrol / lib / ble / connection / PowerOnCamera.java
1 package net.osdn.gokigen.blecontrol.lib.ble.connection;
2
3 import android.app.Activity;
4 import android.bluetooth.BluetoothAdapter;
5 import android.bluetooth.BluetoothDevice;
6 import android.bluetooth.BluetoothGatt;
7 import android.bluetooth.BluetoothGattCallback;
8 import android.bluetooth.BluetoothManager;
9 import android.content.Context;
10 import android.content.SharedPreferences;
11 import android.os.Build;
12 import android.preference.PreferenceManager;
13 import android.util.Log;
14 import android.widget.Toast;
15
16 import androidx.annotation.NonNull;
17 import androidx.annotation.Nullable;
18
19 import net.osdn.gokigen.blecontrol.lib.ble.R;
20
21 import java.util.ArrayList;
22 import java.util.List;
23 import java.util.Locale;
24
25 /**
26  *   BLE経由でカメラの電源を入れるクラス
27  *
28  */
29 public class PowerOnCamera implements ICameraPowerOn
30 {
31     private final String TAG = toString();
32     private final int BLE_SCAN_TIMEOUT_MILLIS = 5 * 1000; // 5秒間
33     private final int BLE_WAIT_DURATION  = 100;             // 100ms間隔
34     private final Activity context;
35     private List<CameraBleSetArrayItem> myCameraList;
36     private BluetoothDevice myBluetoothDevice = null;
37     private String myBtDevicePassCode = "";
38
39     /**
40      *
41      */
42     public PowerOnCamera(@NonNull Activity context)
43     {
44         Log.v(TAG, "PowerOnCamera()");
45         this.context = context;
46         setupCameraList();
47     }
48
49     public void wakeup(final PowerOnCameraCallback callback)
50     {
51         Log.v(TAG, "PowerOnCamera::wakeup()");
52
53         try
54         {
55             BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
56             if (!btAdapter.isEnabled()) {
57                 // Bluetoothの設定がOFFだった
58                 Log.v(TAG, "Bluetooth is currently off.");
59                 context.runOnUiThread(new Runnable()
60                 {
61                     @Override
62                     public void run()
63                     {
64                         // Toastで カメラ起動エラーがあったことを通知する
65                         Toast.makeText(context, context.getString(R.string.ble_setting_is_off), Toast.LENGTH_LONG).show();
66                     }
67                 });
68                 callback.wakeupExecuted(false);
69                 return;
70             }
71         }
72         catch (Exception e)
73         {
74             e.printStackTrace();
75             callback.wakeupExecuted(false);
76             return;
77         }
78
79         final BluetoothManager btMgr;
80         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
81         {
82             // BLE のサービスを取得
83             btMgr = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
84             if (btMgr == null)
85             {
86                 // Bluetooth LEのサポートがない場合は、何もしない
87                 Log.v(TAG, "PowerOnCamera::wakeup() NOT SUPPORT BLE...");
88
89                 // BLEの起動はしなかった...
90                 callback.wakeupExecuted(false);
91                 return;
92             }
93             final  List<CameraBleSetArrayItem> deviceList = myCameraList;
94
95             //  BLE_SCAN_TIMEOUT_MILLIS の間だけBLEのスキャンを実施する
96             Thread thread = new Thread(new Runnable()
97             {
98                 @Override
99                 public void run()
100                 {
101                     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
102                     {
103                         class bleScanCallback implements BluetoothAdapter.LeScanCallback
104                         {
105                             @Override
106                             public void onLeScan(final BluetoothDevice bluetoothDevice, int i, byte[] bytes)
107                             {
108                                 try
109                                 {
110                                     final String btDeviceName = bluetoothDevice.getName();
111                                     // Log.v(TAG, "onLeScan() " + btDeviceName);   // BluetoothDevice::getName() でログ出力してくれるので
112                                     for (CameraBleSetArrayItem device : deviceList)
113                                     {
114                                         final String btName = device.getBtName();
115                                         // Log.v(TAG, "onLeScan() [" + btName + "]");
116                                         if (btName.equals(btDeviceName))
117                                         {
118                                             // マイカメラ発見!
119                                             // 別スレッドで起動する
120                                             myBluetoothDevice = bluetoothDevice;
121                                             myBtDevicePassCode = device.getBtPassCode();
122                                             break;
123                                         }
124                                     }
125                                 }
126                                 catch (Exception e)
127                                 {
128                                     e.printStackTrace();
129                                 }
130                             }
131                             private void reset()
132                             {
133                                 try
134                                 {
135                                     myBluetoothDevice = null;
136                                     myBtDevicePassCode = "";
137                                 }
138                                 catch (Exception e)
139                                 {
140                                     e.printStackTrace();
141                                 }
142                             }
143                         }
144
145                         bleScanCallback scanCallback = new bleScanCallback();
146                         try
147                         {
148                             // スキャン開始
149                             scanCallback.reset();
150                             BluetoothAdapter adapter = btMgr.getAdapter();
151                             if (!adapter.startLeScan(scanCallback))
152                             {
153                                 // Bluetooth LEのスキャンが開始できなかった場合...
154                                 Log.v(TAG, "Bluetooth LE SCAN START fail...");
155                                 callback.wakeupExecuted(false);
156                                 return;
157                             }
158                             Log.v(TAG, "BT SCAN STARTED");
159                             int passed = 0;
160                             while (passed < BLE_SCAN_TIMEOUT_MILLIS)
161                             {
162                                 // BLEデバイスが見つかったときは抜ける...
163                                 if (myBluetoothDevice != null)
164                                 {
165                                     break;
166                                 }
167
168                                 // BLEのスキャンが終わるまで待つ
169                                 Thread.sleep(BLE_WAIT_DURATION);
170                                 passed = passed + BLE_WAIT_DURATION;
171                             }
172                             // スキャンを止める
173                             adapter.stopLeScan(scanCallback);
174                             Log.v(TAG, "BT SCAN STOPPED");
175
176                             // カメラの起動
177                             callback.wakeupExecuted(wakeupViaBle(adapter, myBluetoothDevice, myBtDevicePassCode));
178                         }
179                         catch (Exception e)
180                         {
181                             e.printStackTrace();
182                             Log.v(TAG, "Bluetooth LE SCAN EXCEPTION...");
183                             callback.wakeupExecuted(false);
184
185                             try
186                             {
187                                 final String btName = (myBluetoothDevice != null) ? myBluetoothDevice.getName() : "";
188                                 context.runOnUiThread(new Runnable()
189                                 {
190                                     @Override
191                                     public void run()
192                                     {
193                                         // Toastで カメラ起動エラーがあったことを通知する
194                                         Toast.makeText(context, context.getString(R.string.launch_fail_via_ble) + btName, Toast.LENGTH_LONG).show();
195                                     }
196                                 });
197                             }
198                             catch (Exception ee)
199                             {
200                                 ee.printStackTrace();
201                             }
202                         }
203                         Log.v(TAG, "Bluetooth LE SCAN STOPPED");
204                     }   // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
205                 }
206             });
207             thread.start();
208         }
209     }
210
211     private boolean wakeupViaBle(@Nullable BluetoothAdapter adapter, @Nullable BluetoothDevice myBluetoothDevice, String passCode)
212     {
213         if (adapter == null)
214         {
215             Log.v(TAG, " BluetoothAdapter is UNKNOWN(null).");
216             return (false);
217         }
218
219         if (myBluetoothDevice == null)
220         {
221             Log.v(TAG, " Bt Device is UNKNOWN(null).");
222             return (false);
223         }
224
225         Log.v(TAG, "WAKE UP CAMERA : " + myBluetoothDevice.getName() + " [" + myBluetoothDevice.getAddress() + "]");
226         try
227         {
228             Log.v(TAG, "PASSCODE : " + passCode);
229             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
230             {
231                 // デバイスに接続する
232                 myBluetoothDevice.connectGatt(context, false, new BleConnectionApi18());
233             }
234
235         }
236         catch (Exception e)
237         {
238             e.printStackTrace();
239         }
240         return (true);
241     }
242
243
244     /**
245      *
246      *
247      */
248     private void setupCameraList()
249     {
250         myCameraList = new ArrayList<>();
251
252         SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
253         for (int index = 1; index <= ICameraBleProperty.MAX_STORE_PROPERTIES; index++)
254         {
255             String idHeader = String.format(Locale.ENGLISH, "%03d", index);
256             String prefDate = preferences.getString(idHeader + ICameraBleProperty.DATE_KEY, "");
257             if (prefDate.length() <= 0)
258             {
259                 // 登録が途中までだったとき
260                 break;
261             }
262             String btName = preferences.getString(idHeader + ICameraBleProperty.NAME_KEY, "");
263             String btCode = preferences.getString(idHeader + ICameraBleProperty.CODE_KEY, "");
264             myCameraList.add(new CameraBleSetArrayItem(idHeader, btName, btCode, prefDate));
265         }
266         Log.v(TAG, "setupCameraList() : " + myCameraList.size());
267     }
268
269 }