Advertisement
Guest User

Untitled

a guest
May 14th, 2020
273
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.36 KB | None | 0 0
  1. package com.example.bluetoothapplication2
  2.  
  3. import android.Manifest
  4. import android.bluetooth.BluetoothAdapter
  5. import android.bluetooth.BluetoothClass
  6. import android.bluetooth.BluetoothDevice
  7. import android.bluetooth.BluetoothDevice.DEVICE_TYPE_LE
  8. import android.bluetooth.BluetoothDevice.DEVICE_TYPE_UNKNOWN
  9. import android.bluetooth.le.ScanCallback
  10. import android.bluetooth.le.ScanResult
  11. import android.content.BroadcastReceiver
  12. import android.content.Context
  13. import android.content.Intent
  14. import android.content.IntentFilter
  15. import android.content.pm.PackageManager
  16. import android.os.Build
  17. import androidx.appcompat.app.AppCompatActivity
  18. import android.os.Bundle
  19. import android.os.Handler
  20. import android.util.Log
  21. import android.view.View
  22. import android.widget.AdapterView
  23. import android.widget.ArrayAdapter
  24. import android.widget.ListView
  25. import android.widget.Toast
  26. import androidx.annotation.RequiresApi
  27. import androidx.core.app.ActivityCompat
  28. import androidx.core.content.ContextCompat
  29. import kotlinx.android.synthetic.main.activity_b_l_e_realated.*
  30. import kotlinx.android.synthetic.main.activity_b_l_e_realated.sw_ble
  31. import kotlinx.android.synthetic.main.activity_scan.*
  32. import org.jetbrains.anko.selector
  33. import kotlinx.android.synthetic.main.activity_scan.btn_startScan as btn_startScan1
  34.  
  35. class BLERealatedActivity : AppCompatActivity() {
  36.  
  37. private val TAG = this.javaClass.simpleName
  38.  
  39. val REQUEST_CODE_PERMISSION:Int = 0
  40. val BROADCAST_BT_STATE:Int = 1
  41. val REQUEST_CODE_ENABLE_BT:Int = 1
  42.  
  43. var mScanning: Boolean = false
  44.  
  45. //for delay function
  46. val handler = Handler()
  47.  
  48. //ListView: searching type
  49. val ble_type_list = listOf<String>("All Device", "Paired Device", "Unpaired Device", "Classic BT", "BLE")
  50. private var searched_device : ArrayList<String> = ArrayList()
  51. private var all_device : ArrayList<String> = ArrayList()
  52. private var paired_device : ArrayList<String> = ArrayList()
  53. private var unpaired_device : ArrayList<String> = ArrayList()
  54. private var classic_device : ArrayList<String> = ArrayList()
  55. private var ble_device : ArrayList<String> = ArrayList()
  56.  
  57. var bluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
  58. private var btScanReceiver = BTScanReceiver()
  59.  
  60. @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
  61. var mBLEScanner = bluetoothAdapter.getBluetoothLeScanner()
  62.  
  63. var getLocationPermission :Boolean = false
  64.  
  65.  
  66.  
  67.  
  68. override fun onCreate(savedInstanceState: Bundle?) {
  69. super.onCreate(savedInstanceState)
  70. setContentView(R.layout.activity_b_l_e_realated)
  71.  
  72. val ble_listView = findViewById<ListView>(R.id.lv_bleList)
  73. val allListadapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, all_device)
  74. val pairedListadapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, paired_device)
  75. val unpairedListadapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, unpaired_device)
  76. val bleListadapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, ble_device)
  77. val classicListadapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, classic_device)
  78. ble_listView.adapter = allListadapter
  79.  
  80. getLocationPermission =
  81. ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
  82.  
  83. //spinner: search type
  84. val array_adapter = ArrayAdapter(this, R.layout.support_simple_spinner_dropdown_item, ble_type_list)
  85. sp_search.adapter = array_adapter
  86. sp_search.onItemSelectedListener = object :AdapterView.OnItemSelectedListener{
  87. override fun onNothingSelected(parent: AdapterView<*>?) {
  88.  
  89. }
  90.  
  91. override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
  92. //show_device.clear()
  93.  
  94. when(ble_type_list[position]){
  95. "All Device" -> {
  96. //Toast.makeText(this@BLERealatedActivity, "0", Toast.LENGTH_SHORT).show()
  97. ble_listView.adapter = allListadapter
  98. }
  99. "Paired Device" -> {
  100. //Toast.makeText(this@BLERealatedActivity, "1", Toast.LENGTH_SHORT).show()
  101. ble_listView.adapter = pairedListadapter
  102. }
  103. "Unpaired Device" -> {
  104. //Toast.makeText(this@BLERealatedActivity, "2", Toast.LENGTH_SHORT).show()
  105. ble_listView.adapter = unpairedListadapter
  106. }
  107. "Classic BT" -> {
  108. //Toast.makeText(this@BLERealatedActivity, "3", Toast.LENGTH_SHORT).show()
  109. ble_listView.adapter = classicListadapter
  110. }
  111. "BLE" -> {
  112. //Toast.makeText(this@BLERealatedActivity, "4", Toast.LENGTH_SHORT).show()
  113. ble_listView.adapter = bleListadapter
  114. }
  115. }
  116. }
  117. }
  118.  
  119. fun updatedListView() {
  120. allListadapter.notifyDataSetChanged()
  121. pairedListadapter.notifyDataSetChanged()
  122. unpairedListadapter.notifyDataSetChanged()
  123. classicListadapter.notifyDataSetChanged()
  124. bleListadapter.notifyDataSetChanged()
  125. }
  126.  
  127. fun clearSearchedList(){
  128. searched_device.clear()
  129. all_device.clear()
  130. paired_device.clear()
  131. unpaired_device.clear()
  132. classic_device.clear()
  133. ble_device.clear()
  134. }
  135.  
  136. //updated list
  137. btn_updated.setOnClickListener {
  138. updatedListView()
  139. }
  140.  
  141. //Sop BLE Scan
  142. fun stopBLEScan(){
  143. mScanning = false
  144.  
  145. //Android 5.0 up
  146. if(android.os.Build.VERSION.SDK_INT >= 21){
  147. mBLEScanner.stopScan(mScanCallback)
  148. //Toast.makeText(this, "5.0! Scan stop", Toast.LENGTH_SHORT).show()
  149. Log.d(TAG, "5.0! Scan stop")
  150. }else{
  151. bluetoothAdapter.stopLeScan(leScanCallback)
  152. //Toast.makeText(this, "4.3! Scan stop", Toast.LENGTH_SHORT).show()
  153. Log.d(TAG, "4.3! Scan stop")
  154. }
  155.  
  156. //classic device discovery
  157. bluetoothAdapter.cancelDiscovery()
  158. updatedListView()
  159. }
  160.  
  161. //Start BLE Scan
  162. fun startBLEScan(){
  163. mScanning = true
  164. clearSearchedList()
  165. updatedListView()
  166.  
  167. handler.postDelayed({
  168. stopBLEScan()
  169. }, 12000)
  170.  
  171. //Android 5.0 up
  172. if(android.os.Build.VERSION.SDK_INT >= 21){
  173. if (mBLEScanner == null){
  174. mBLEScanner = bluetoothAdapter.getBluetoothLeScanner();
  175. }
  176. mBLEScanner.startScan(mScanCallback);
  177. //Toast.makeText(this, "5.0 up! Scan start", Toast.LENGTH_SHORT).show()
  178. Log.d(TAG, "5.0 up! Scan start")
  179. }else{
  180. bluetoothAdapter.startLeScan(leScanCallback);
  181. //Toast.makeText(this, "4.3! Scan start", Toast.LENGTH_SHORT).show()
  182. Log.d(TAG, "4.3! Scan start")
  183. }
  184.  
  185. //classic device discovery
  186. bluetoothAdapter.startDiscovery()
  187. //Toast.makeText(this, "Start BT discovering.", Toast.LENGTH_SHORT).show()
  188. }
  189.  
  190. //BLE switch
  191. sw_ble.setOnCheckedChangeListener { buttonView, isChecked ->
  192. if (isChecked) {
  193. if (!bluetoothAdapter.isEnabled) {
  194. val intent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
  195. startActivityForResult(intent, REQUEST_CODE_ENABLE_BT)
  196. }
  197. } else {
  198. if (bluetoothAdapter.isEnabled) {
  199. bluetoothAdapter.disable()
  200. if(mScanning){
  201. stopBLEScan()
  202. mScanning = false
  203. }
  204. }
  205. }
  206. }
  207.  
  208. btn_startScan.setOnClickListener {
  209. if(!bluetoothAdapter.isEnabled){
  210. Toast.makeText(this@BLERealatedActivity, "Please turn on BLE first", Toast.LENGTH_SHORT).show()
  211. }else{
  212. if (getLocationPermission != true){
  213. hasLocationPermission()
  214. } else {
  215. if(!mScanning){
  216. startBLEScan()
  217. }else{
  218. Toast.makeText(this, "Scanning....", Toast.LENGTH_SHORT).show()
  219. }
  220. }
  221. }
  222. }
  223. }
  224.  
  225. //Check location permission
  226. private fun hasLocationPermission(): Boolean{
  227. if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
  228. && ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
  229. ActivityCompat.requestPermissions(
  230. this,
  231. arrayOf(
  232. Manifest.permission.ACCESS_FINE_LOCATION,
  233. Manifest.permission.ACCESS_COARSE_LOCATION
  234. ), REQUEST_CODE_PERMISSION
  235. )
  236. return false
  237. }else{
  238. return true
  239. }
  240. }
  241.  
  242. override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
  243. super.onRequestPermissionsResult(requestCode, permissions, grantResults)
  244.  
  245. when (requestCode) {
  246. REQUEST_CODE_PERMISSION -> {
  247. if ((grantResults.isNotEmpty() && hasAllPermissionsGranted(grantResults))) {
  248. //startBLEScan()
  249. //Toast.makeText(this, "Start BLE scan", Toast.LENGTH_SHORT).show()
  250. getLocationPermission = true
  251. } else {
  252. Toast.makeText(this, "Need location permission to start scan bluetooth", Toast.LENGTH_SHORT).show()
  253. getLocationPermission = false
  254. }
  255. }
  256. }
  257. }
  258.  
  259. private fun hasAllPermissionsGranted(grantResults: IntArray): Boolean {
  260. for (grantResult in grantResults) {
  261. if (grantResult == PackageManager.PERMISSION_DENIED) {
  262. return false
  263. }
  264. }
  265. return true
  266. }
  267.  
  268. //Android 5.0
  269. private val mScanCallback = @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
  270. object : ScanCallback() {
  271.  
  272. override fun onScanResult(callbackType: Int, result: ScanResult?) {
  273. super.onScanResult(callbackType, result)
  274.  
  275. val bleDevice = result?.device
  276. if (bleDevice != null) {
  277. if(!ble_device.contains("Name: ${bleDevice.name}" + "\n" + "Address: ${bleDevice.address}" + "\n" + "Type: ${bleDevice.type}")){
  278. ble_device.add("Name: ${bleDevice.name}" + "\n" + "Address: ${bleDevice.address}" + "\n" + "Type: ${bleDevice.type}")
  279. Log.d(TAG,"Name: ${bleDevice.name}" + "\n" + "Address: ${bleDevice.address}" + "\n" + "Type: ${bleDevice.type}")
  280. }
  281. }
  282. }
  283.  
  284. override fun onBatchScanResults(results: List<ScanResult>) {
  285. for (sr in results) {
  286. Log.d(TAG, "BatchResults: ${sr.toString()}" )
  287. }
  288. }
  289.  
  290. override fun onScanFailed(errorCode: Int) {
  291. Log.d(TAG, "Error Code: $errorCode")
  292. }
  293. }
  294.  
  295.  
  296. //Android 4.3
  297. private var leScanCallback = BluetoothAdapter.LeScanCallback { device, rssi, scanRecord ->
  298. runOnUiThread {
  299. Log.d(TAG, "Find something ${device}")
  300. }
  301. }
  302.  
  303. //Broadcast receiver
  304. //classic device: discovery, BLE: Scan
  305. private fun registerDiscoveryReceiver() {
  306. val intentFilter = IntentFilter()
  307. intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED) //偵測藍芽狀態變化
  308. intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED) //Just for classic, not BLE
  309. intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED) //Just for classic, not BLE
  310. intentFilter.addAction(BluetoothDevice.ACTION_FOUND)
  311. registerReceiver(btScanReceiver, intentFilter)
  312. }
  313.  
  314. override fun onStart() {
  315. super.onStart()
  316. sw_ble.isChecked = bluetoothAdapter.isEnabled
  317. registerDiscoveryReceiver()
  318. }
  319.  
  320. override fun onStop() {
  321. super.onStop()
  322. unregisterReceiver(btScanReceiver)
  323. }
  324.  
  325. private inner class BTScanReceiver:BroadcastReceiver(){
  326. override fun onReceive(context: Context?, intent: Intent?) {
  327. val action = intent?.action
  328.  
  329. //classic device discovering
  330. if(BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
  331. Toast.makeText(context, "Receiver: Start classic discovering.", Toast.LENGTH_SHORT).show()
  332. Log.d(TAG, "Start BT discovering")
  333. }
  334.  
  335. if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
  336. Toast.makeText(context, "Receiver: Stop classic discovering.", Toast.LENGTH_SHORT).show()
  337. Log.d(TAG, "Stop discovering.")
  338. }
  339.  
  340. //Find classic device
  341. if (BluetoothDevice.ACTION_FOUND.equals(action)) {
  342. val classicDevice = intent.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE)
  343. //val deviceClass = intent.getParcelableExtra<BluetoothClass>(BluetoothDevice.EXTRA_CLASS)
  344.  
  345. if (classicDevice != null) {
  346. if(!classic_device.contains("Classic:" + classicDevice.name + "\n" + classicDevice.address + "\n" + classicDevice.type)){
  347. classic_device.add("Classic:" + classicDevice.name + "\n" + classicDevice.address + "\n" + classicDevice.type)
  348. }
  349. }
  350. }
  351.  
  352. val pairedDevices: Set<BluetoothDevice> = bluetoothAdapter.getBondedDevices()
  353. for (boundedDevice in pairedDevices) {
  354. if(!paired_device.contains(boundedDevice.name + "\n" + boundedDevice.address + "\n" + boundedDevice.type)){
  355. paired_device.add(boundedDevice.name + "\n" + boundedDevice.address + "\n" + boundedDevice.type)
  356. }
  357. }
  358.  
  359. //偵測藍芽狀態的改變
  360. if(BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)){
  361. val state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BROADCAST_BT_STATE)
  362. var str:String = "正在開啟藍芽"
  363.  
  364. when(state) {
  365. BluetoothAdapter.STATE_TURNING_ON -> str = "正在開啟藍芽"
  366. BluetoothAdapter.STATE_ON -> {
  367. str = "藍芽已開啟"
  368. sw_ble.isChecked = true
  369. }
  370. BluetoothAdapter.STATE_TURNING_OFF -> str = "正在關閉藍芽"
  371. BluetoothAdapter.STATE_OFF -> {
  372. str = "藍芽已關閉"
  373. sw_ble.isChecked = false
  374. }
  375. }
  376.  
  377. Toast.makeText(context, "${str}", Toast.LENGTH_SHORT).show()
  378. }
  379. }
  380. }
  381. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement