DeviceScanActivity.java 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. /*
  2. * Copyright (C) 2013 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.slam.bboxble;
  17. import android.Manifest;
  18. import android.app.Activity;
  19. import android.bluetooth.BluetoothAdapter;
  20. import android.bluetooth.BluetoothDevice;
  21. import android.bluetooth.BluetoothManager;
  22. import android.content.Context;
  23. import android.content.Intent;
  24. import android.content.pm.PackageManager;
  25. import android.os.Build;
  26. import android.os.Bundle;
  27. import android.support.annotation.NonNull;
  28. import android.support.v4.app.ActivityCompat;
  29. import android.support.v4.content.ContextCompat;
  30. import android.util.Log;
  31. import android.view.LayoutInflater;
  32. import android.view.Menu;
  33. import android.view.MenuItem;
  34. import android.view.View;
  35. import android.view.ViewGroup;
  36. import android.widget.AdapterView;
  37. import android.widget.BaseAdapter;
  38. import android.widget.Button;
  39. import android.widget.ListView;
  40. import android.widget.TextView;
  41. import android.widget.Toast;
  42. import com.slam.bboxblelib.DeviceEvent;
  43. import com.slam.bboxblelib.MainBluetooth;
  44. import com.slam.bboxblelib.impl.MainBluetoothImpl;
  45. import com.slam.bboxblelib.Responser;
  46. import java.util.ArrayList;
  47. import java.util.Set;
  48. /**
  49. * Activity for scanning and displaying available Bluetooth LE devices.
  50. */
  51. public class DeviceScanActivity extends Activity implements View.OnClickListener {
  52. private final String TAG = "DeviceScanActivity";
  53. private LeDeviceListAdapter mLeDeviceListAdapter;
  54. private LeDeviceListAdapter mPairLeDeviceListAdapter;
  55. private BluetoothAdapter mBluetoothAdapter;
  56. private boolean mScanning;
  57. private ListView mListView, mPairListView;
  58. private Button mButtonStopScan, mButtonStartScan;
  59. private TextView mTextViewResult;
  60. private boolean noNeedShowDialog = false;
  61. private static final int REQUEST_ENABLE_BT = 1;
  62. private static final int REQUEST_WRITE_STORAGE = 112;
  63. //蓝牙
  64. private MainBluetoothImpl mainBluetooth = new MainBluetoothImpl();
  65. @Override
  66. public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
  67. super.onRequestPermissionsResult(requestCode, permissions, grantResults);
  68. switch (requestCode) {
  69. case REQUEST_WRITE_STORAGE:
  70. FileUnit.getOTAFilePath();
  71. break;
  72. default:
  73. break;
  74. }
  75. }
  76. @Override
  77. public void onCreate(Bundle savedInstanceState) {
  78. super.onCreate(savedInstanceState);
  79. getActionBar().setTitle(R.string.title_devices);
  80. setContentView(R.layout.list_device_view);
  81. if (Build.VERSION.SDK_INT >= 23) {
  82. int permission1 = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION);
  83. int permission2 = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
  84. if (permission1 != PackageManager.PERMISSION_GRANTED || permission2 != PackageManager.PERMISSION_GRANTED) {
  85. if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_COARSE_LOCATION)) {
  86. ActivityCompat.requestPermissions(DeviceScanActivity.this,
  87. new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.WRITE_EXTERNAL_STORAGE},
  88. REQUEST_WRITE_STORAGE);
  89. } else {
  90. ActivityCompat.requestPermissions(DeviceScanActivity.this,
  91. new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.WRITE_EXTERNAL_STORAGE},
  92. REQUEST_WRITE_STORAGE);
  93. }
  94. }
  95. } else {
  96. FileUnit.getOTAFilePath();
  97. }
  98. mButtonStartScan = (Button) findViewById(R.id.button_startScan);
  99. mButtonStopScan = (Button) findViewById(R.id.button_stopScan);
  100. mButtonStartScan.setOnClickListener(this);
  101. mButtonStopScan.setOnClickListener(this);
  102. mButtonStopScan.setVisibility(View.GONE);
  103. mTextViewResult = (TextView) findViewById(R.id.textview_OTAResult);
  104. mListView = (ListView) findViewById(R.id.list_device);
  105. mPairListView = (ListView) findViewById(R.id.list_pair_device);
  106. mPairListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
  107. @Override
  108. public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
  109. final BluetoothDevice device = mPairLeDeviceListAdapter.getDevice(position);
  110. if (device == null) return;
  111. final Intent intent = new Intent(DeviceScanActivity.this, DeviceControlActivity.class);
  112. intent.putExtra(DeviceControlActivity.EXTRAS_DEVICE_NAME, device.getName());
  113. intent.putExtra(DeviceControlActivity.EXTRAS_DEVICE_ADDRESS, device.getAddress());
  114. mScanning = false;
  115. //蓝牙部分
  116. mainBluetooth.stopScanLeDevice();
  117. noNeedShowDialog = false;
  118. startActivityForResult(intent, 2);
  119. }
  120. });
  121. mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
  122. @Override
  123. public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
  124. final BluetoothDevice device = mLeDeviceListAdapter.getDevice(i);
  125. if (device == null) return;
  126. final Intent intent = new Intent(DeviceScanActivity.this, DeviceControlActivity.class);
  127. intent.putExtra(DeviceControlActivity.EXTRAS_DEVICE_NAME, device.getName());
  128. intent.putExtra(DeviceControlActivity.EXTRAS_DEVICE_ADDRESS, device.getAddress());
  129. mScanning = false;
  130. //蓝牙部分
  131. mainBluetooth.stopScanLeDevice();
  132. noNeedShowDialog = false;
  133. startActivityForResult(intent, 2);
  134. }
  135. });
  136. // Use this check to determine whether BLE is supported on the device. Then you can
  137. // selectively disable BLE-related features.
  138. if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
  139. Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
  140. finish();
  141. }
  142. // Initializes a Bluetooth adapter. For API level 18 and above, get a reference to
  143. // BluetoothAdapter through BluetoothManager.
  144. final BluetoothManager bluetoothManager =
  145. (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
  146. mBluetoothAdapter = bluetoothManager.getAdapter();
  147. //初始化蓝牙参数部分
  148. Responser responser = new Responser() {
  149. @Override
  150. public void onSuccess(DeviceEvent deviceEvent) {
  151. if (deviceEvent.getType().equals("pairedDevices")) {
  152. if (deviceEvent.getDevices().size() > 0) {
  153. for (BluetoothDevice device : deviceEvent.getDevices()) {
  154. Log.e(TAG, "**********DeviceEvent responser=" + device.getAddress() + device.getName());
  155. mPairLeDeviceListAdapter.addDevice(device);
  156. mPairLeDeviceListAdapter.notifyDataSetChanged();
  157. }
  158. mScanning = true;
  159. }
  160. } else if (deviceEvent.getType().equals("device")) {
  161. // Log.e(TAG, "**********DeviceEvent responser=" + deviceEvent.getDevice().getAddress());
  162. // Log.e(TAG, "**********DeviceEvent responser=" + deviceEvent.getRssi());
  163. if (deviceEvent.getDevice().getBondState() != BluetoothDevice.BOND_BONDED) {
  164. mLeDeviceListAdapter.addDevice(deviceEvent.getDevice());
  165. mLeDeviceListAdapter.notifyDataSetChanged();
  166. }
  167. ;
  168. } else if (deviceEvent.getType().equals("none")) {
  169. runOnUiThread(new Runnable() {
  170. @Override
  171. public void run() {
  172. mButtonStopScan.performClick();
  173. }
  174. });
  175. }
  176. }
  177. @Override
  178. public void onFailed(String prompt) {
  179. }
  180. // @Override
  181. // public void onSuccessDevices(Set<BluetoothDevice> devices) {
  182. // if (devices.size() > 0) {
  183. // for (BluetoothDevice device : devices) {
  184. // Log.e(TAG, "**********DeviceEvent responser=" +device.getAddress() + device.getName() );
  185. // mPairLeDeviceListAdapter.addDevice(device);
  186. // mPairLeDeviceListAdapter.notifyDataSetChanged();
  187. // }
  188. // mScanning = true;
  189. // }
  190. //
  191. // }
  192. //
  193. // @Override
  194. // public void onSuccess(String data) {
  195. // runOnUiThread(new Runnable() {
  196. // @Override
  197. // public void run() {
  198. // mButtonStopScan.performClick();
  199. // }
  200. // });
  201. // }
  202. };
  203. mainBluetooth.onCreate(this,responser);
  204. // Checks if Bluetooth is supported on the device.
  205. if (mBluetoothAdapter == null) {
  206. Toast.makeText(this, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show();
  207. finish();
  208. return;
  209. }
  210. }
  211. @Override
  212. protected void onStart() {
  213. super.onStart();
  214. }
  215. @Override
  216. public boolean onCreateOptionsMenu(Menu menu) {
  217. getMenuInflater().inflate(R.menu.main, menu);
  218. if (!mScanning) {
  219. menu.findItem(R.id.menu_stop).setVisible(false);
  220. menu.findItem(R.id.menu_scan).setVisible(true);
  221. menu.findItem(R.id.menu_refresh).setActionView(null);
  222. mButtonStopScan.setVisibility(View.GONE);
  223. mButtonStartScan.setVisibility(View.VISIBLE);
  224. } else {
  225. menu.findItem(R.id.menu_stop).setVisible(true);
  226. menu.findItem(R.id.menu_scan).setVisible(false);
  227. menu.findItem(R.id.menu_refresh).setActionView(
  228. R.layout.actionbar_indeterminate_progress);
  229. mButtonStopScan.setVisibility(View.VISIBLE);
  230. mButtonStartScan.setVisibility(View.GONE);
  231. }
  232. return true;
  233. }
  234. @Override
  235. public boolean onOptionsItemSelected(MenuItem item) {
  236. return true;
  237. }
  238. @Override
  239. protected void onResume() {
  240. super.onResume();
  241. // Ensures Bluetooth is enabled on the device. If Bluetooth is not currently enabled,
  242. // fire an intent to display a dialog asking the user to grant permission to enable it.
  243. Log.e(TAG, "onResume");
  244. if (!noNeedShowDialog) {
  245. if (!mBluetoothAdapter.isEnabled()) {
  246. Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
  247. startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
  248. }
  249. }
  250. mLeDeviceListAdapter = new LeDeviceListAdapter();
  251. mPairLeDeviceListAdapter = new LeDeviceListAdapter();
  252. mListView.setAdapter(mLeDeviceListAdapter);
  253. mPairListView.setAdapter(mPairLeDeviceListAdapter);
  254. }
  255. @Override
  256. protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  257. super.onActivityResult(requestCode, resultCode, data);
  258. // User chose not to enable Bluetooth.
  259. Log.e(TAG, "back check resultCode: " + resultCode);
  260. if (requestCode == REQUEST_ENABLE_BT && resultCode == Activity.RESULT_CANCELED) {
  261. finish();
  262. return;
  263. } else if (requestCode == REQUEST_ENABLE_BT && resultCode == Activity.RESULT_OK) {
  264. Toast.makeText(this, "Bluetooth Enable", Toast.LENGTH_SHORT).show();
  265. } else if (requestCode == 2) {
  266. if (resultCode == 4 || resultCode == 3) {
  267. noNeedShowDialog = true;
  268. String aaa = data.getExtras().getString("Result OTA");
  269. mTextViewResult.setText(aaa);
  270. } else if (resultCode == 5) {
  271. noNeedShowDialog = false;
  272. Toast.makeText(this, "OTA Done", Toast.LENGTH_SHORT).show();
  273. mTextViewResult.setText("");
  274. } else {
  275. noNeedShowDialog = false;
  276. mTextViewResult.setText("");
  277. }
  278. }
  279. }
  280. @Override
  281. protected void onPause() {
  282. super.onPause();
  283. if (mButtonStartScan.getVisibility() == View.GONE) {
  284. mButtonStopScan.performClick();
  285. }
  286. mLeDeviceListAdapter.clear();
  287. mPairLeDeviceListAdapter.clear();
  288. }
  289. @Override
  290. protected void onDestroy() {
  291. super.onDestroy();
  292. }
  293. @Override
  294. public void onClick(View view) {
  295. switch (view.getId()) {
  296. case R.id.button_startScan:
  297. mLeDeviceListAdapter.clear();
  298. mPairLeDeviceListAdapter.clear();
  299. mButtonStopScan.setVisibility(View.VISIBLE);
  300. mButtonStartScan.setVisibility(View.GONE);
  301. mainBluetooth.startScanLeDevice();
  302. invalidateOptionsMenu();
  303. break;
  304. case R.id.button_stopScan:
  305. mButtonStopScan.setVisibility(View.GONE);
  306. mButtonStartScan.setVisibility(View.VISIBLE);
  307. mainBluetooth.stopScanLeDevice();
  308. break;
  309. default:
  310. break;
  311. }
  312. }
  313. // Adapter for holding devices found through scanning.
  314. private class LeDeviceListAdapter extends BaseAdapter {
  315. private ArrayList<BluetoothDevice> mLeDevices;
  316. private LayoutInflater mInflator;
  317. public LeDeviceListAdapter() {
  318. super();
  319. mLeDevices = new ArrayList<BluetoothDevice>();
  320. mInflator = DeviceScanActivity.this.getLayoutInflater();
  321. }
  322. public void addDevice(BluetoothDevice device) {
  323. if (!mLeDevices.contains(device)) {
  324. mLeDevices.add(device);
  325. }
  326. }
  327. public BluetoothDevice getDevice(int position) {
  328. if (mLeDevices.size() > position) {
  329. return mLeDevices.get(position);
  330. } else {
  331. return null;
  332. }
  333. }
  334. public void clear() {
  335. mLeDevices.clear();
  336. }
  337. @Override
  338. public int getCount() {
  339. return mLeDevices.size();
  340. }
  341. @Override
  342. public Object getItem(int i) {
  343. return mLeDevices.get(i);
  344. }
  345. @Override
  346. public long getItemId(int i) {
  347. return i;
  348. }
  349. @Override
  350. public View getView(int i, View view, ViewGroup viewGroup) {
  351. ViewHolder viewHolder;
  352. // General ListView optimization code.
  353. if (view == null) {
  354. view = mInflator.inflate(R.layout.listitem_device, null);
  355. viewHolder = new ViewHolder();
  356. viewHolder.deviceAddress = (TextView) view.findViewById(R.id.device_address);
  357. viewHolder.deviceName = (TextView) view.findViewById(R.id.device_name);
  358. view.setTag(viewHolder);
  359. } else {
  360. viewHolder = (ViewHolder) view.getTag();
  361. }
  362. BluetoothDevice device = mLeDevices.get(i);
  363. final String deviceName = device.getName();
  364. if (deviceName != null && deviceName.length() > 0)
  365. viewHolder.deviceName.setText(deviceName);
  366. else
  367. viewHolder.deviceName.setText(R.string.unknown_device);
  368. viewHolder.deviceAddress.setText(device.getAddress());
  369. return view;
  370. }
  371. }
  372. @Override
  373. protected void onSaveInstanceState(Bundle outState) {
  374. super.onSaveInstanceState(outState);
  375. outState.putBoolean("HBG", noNeedShowDialog);
  376. }
  377. @Override
  378. protected void onRestoreInstanceState(Bundle savedInstanceState) {
  379. super.onRestoreInstanceState(savedInstanceState);
  380. noNeedShowDialog = savedInstanceState.getBoolean("HBG");
  381. }
  382. static class ViewHolder {
  383. TextView deviceName;
  384. TextView deviceAddress;
  385. }
  386. }