物事の難しさは、物事への恐れよりもはるかに小さい
0. 序文
最近完成した BLE Bluetooth 通信に基づく簡単な APP をここに記録します。参考までに、それを必要とする人々の疑問を解決することを願っています。このアプリには、合計 2 つのインターフェイスがあります.最初のインターフェイスは、Bluetooth のオン/オフ、Bluetooth のスキャンとスキャン結果の表示を実現します.スキャンされた Bluetooth デバイスを選択して 2 番目のインターフェイスにジャンプし、選択した Bluetooth を再処理 デバイスが接続し、サービスを取得します。接続状態は 2 番目のインターフェイスに表示され、データを送受信できます.このコードは、Bluetooth データ伝送の最も基本的な機能を実現するだけであり、これに基づいて実際のニーズに応じてさらに開発を行うことができます!
1. 許可を得る
まず第一に、最初のステップは Bluetooth パーミッションとロケーション パーミッションを取得することですAndroi 6.0(API 23)
.パーミッションを静的に追加する必要があるだけでなく (AndroidMainfest.xml
で構成)、プログラムでパーミッションを動的に取得する必要もあります.以下は、必要なパーミッションの一部です.動的に取得されます。
所属団体 | パーミッション |
---|---|
カレンダー | READ_CALENDAR |
カレンダー | WRITE_CALENDAR |
カメラ | カメラ |
連絡窓口 | READ_CONTACTS |
連絡窓口 | 書き込み_連絡先 |
連絡窓口 | GET_CONTACTS |
位置 | ACCESS_FINE_LOCATION |
位置 | ACCESS_COARSE_LOCATION |
マイクロフォン | レコードオーディオ |
電話 | READ_PHONE_STATE |
電話 | 電話をかける |
電話 | READ_CALL_LOG |
電話 | WRITE_CALL_LOG |
電話 | ADD_VOICEMAIL |
電話 | USE_SIP |
電話 | PROCESS_OUTGOING_CALLS |
センサー | BODY_SENSORS |
ショートメッセージ | SMSを送信 |
ショートメッセージ | RECEIVE_SMS |
ショートメッセージ | READ_SMS |
ショートメッセージ | RECEICE_WAP_PUSH |
ショートメッセージ | RECEIVE_MMS |
ショートメッセージ | READ_EXTERNAL_STORAGE |
ショートメッセージ | WRITE_EXTERNAL_STORAGE |
注: アプリがAndroidManifest.xml
に、システムはユーザーからの操作なしで、そのアクセス許可をすぐに付与します。たとえば、アプリが以前にACCESS_FINE_LOCATION
パーミッションをACCESS_COARSE_LOCATION
、その後リクエストした (同じ地域グループに属している) 場合、システムはすぐにパーミッションを付与し、パーミッションの付与を求めるダイアログ ボックスは表示されなくなります。
ACCESS_FINE_LOCATION
この記事では、ACCESS_COARSE_LOCATION
危険なアクセス許可と通常のアクセス許可が使用されます. まず、ファイルにアクセス許可を静的に追加するBLUETOOTH
必要があります。BLUETOOTH_ADMIN
AndroidMainfest.xml
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
その中にはBLUETOOTH
、 Bluetooth の通常のアクセス許可があります. Bluetooth を操作する必要がある場合は、 Bluetooth の高度なアクセス許可が必要です.BLUETOOTH_ADMIN
これら 2 つのアクセス許可は共通のアクセス許可であり、静的に追加する必要があるだけであり、残りの 2 つのアクセス許可は危険なアクセス許可であり、動的に追加されます。
2.権限を動的に追加する
最初に、AndroidMainfest.xml
アクセス許可がファイルに静的に追加されているかどうかを確認します。追加されている場合は、引き続き動的に追加できますが、追加されていない場合は動的に追加できません。
最初に静的に追加 (テンプレート)
<uses-permission android:name="android.permission.上表的权限字符" />
次に、動的に追加します(テンプレート)
public void requestPower() {
//判断是否已经赋予权限
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.上表权限字符)
!= PackageManager.PERMISSION_GRANTED) {
//如果应用之前请求过此权限但用户拒绝了请求,此方法将返回 true。
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.上表权限字符)) {
//这里可以写个对话框之类的项向用户解释为什么要申请权限,并在对话框的确认键后续再次申请权限.它在用户选择"不再询问"的情况下返回false
} else {
//申请权限,字符串数组内是一个或多个要申请的权限,1是申请权限结果的返回参数,在onRequestPermissionsResult可以得知申请结果
ActivityCompat.requestPermissions(this,
new String[]{
Manifest.permission.上表权限字符,}, 1);
}
}
}
なお、判定文のため、実際には利用者が許可申請を却下して再度メソッドを呼び出した場合、許可申請のダイアログボックスは再度表示されません。
3. この記事で使用する動的アプリケーション許可方法
最初に静的に追加
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
次に、動的に追加します
public void requestPower() {
//判断是否已经赋予权限
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
//如果应用之前请求过此权限但用户拒绝了请求,此方法将返回 true。
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
//这里可以写个对话框之类的项向用户解释为什么要申请权限,并在对话框的确认键后续再次申请权限.它在用户选择"不再询问"的情况下返回false
} else {
//申请权限,字符串数组内是一个或多个要申请的权限,1是申请权限结果的返回参数,在onRequestPermissionsResult可以得知申请结果
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.ACCESS_FINE_LOCATION}, 1);
}
}
}
注: ここでは、動的アクセス許可を取得するメソッドがメソッドにカプセル化されており、アクセス許可を取得するonCreat
メソッド
4. 初期化インターフェース
最初のインターフェイスには、3 つのボタン (Bluetooth をオンにする、Bluetooth をオフにする、Bluetooth をスキャンする) とコントロールSpinner
(スキャンされた Bluetooth デバイスを表示するために使用される) があり、初期化して、対応するクリック イベントを設定します。コードを参照してください。
private final static String TAG = "hello";
private Button btn_Search, btn_On, btn_Off;
private Spinner mSpinner;
private BluetoothManager bluetoothManager;
private BluetoothAdapter bluetoothAdapter;
private BluetoothLeScanner bluetoothLeScanner;
//初始化界面
public void initView() {
bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
bluetoothAdapter = bluetoothManager.getAdapter();
bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
btn_Search = findViewById(R.id.btn_Search); //扫描蓝牙按钮
btn_On = findViewById(R.id.btn_On); //开启蓝牙按钮
btn_Off = findViewById(R.id.btn_Off); //关闭蓝牙按钮
mSpinner = findViewById(R.id.spinner); //显示蓝牙设备的Spinne控件
btn_Search.setOnClickListener(this);
btn_On.setOnClickListener(this);
btn_Off.setOnClickListener(this);
}
上記のコードは、最初のインターフェイスでコントロールの初期化を完了し、コードの一部であるクリック イベントを設定します。
private BluetoothManager bluetoothManager;
private BluetoothAdapter bluetoothAdapter;
private BluetoothLeScanner bluetoothLeScanner;
bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
bluetoothAdapter = bluetoothManager.getAdapter();
bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
以下で詳しく紹介するBluetoothの開閉とスキャンを完了することです。
5. BLE ブルートゥースをオンにします
さまざまな権限を追加した後、次のステップは BLE bluetooth を操作することです.まず、APP を開いたときに bluetooth を開く必要があります.最初に、コードを追加します:
private BluetoothManager bluetoothManager;
private BluetoothAdapter bluetoothAdapter;
bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
bluetoothAdapter = bluetoothManager.getAdapter();
最初にBluetoothManager
クラス (Bluetooth マネージャー) とBluetoothAdapter
クラス (Bluetooth アダプター) のオブジェクトを定義します. オブジェクトはメソッドbluetoothManager
を通じてgetSystemService(Context.BLUETOOTH_SERVICE)
取得され, オブジェクトはメソッドbluetoothAdapter
を通じて取得されますbluetoothManager.getAdapter()
. デバイスが Bluetooth をサポートしている場合は ではなく,bluetoothAdapter
それnull
以外の場合は ですnull
. 次に、Bluetooth をオンにしてコードをアップロードできます
public void turnOnBle() {
if (bluetoothAdapter != null) {
if (bluetoothAdapter.isEnabled() == false) {
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, 11);
} else {
Toast.makeText(this, "蓝牙已经打开了", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(this, "该设备不支持蓝牙", Toast.LENGTH_SHORT).show();
}
}
最初に動作を継続しbluetoothAdapter
ないことを判断します。それ以外の場合は、デバイスが Bluetooth をサポートしていないことを意味し、メソッドを使用してデバイスの現在の Bluetooth ステータスを判断します。yes が返された場合、現在の Bluetooth が戻り値がyes の場合は、デバイスの現在の Bluetooth がオフであることを意味し、メソッドを介してBluetooth をオンにし、最初にオブジェクトを作成します。最初のパラメーターはクラス オブジェクトで、2 番目のパラメーターは自分で定義することができ、コールバック関数で Bluetooth が正常にオンになったかどうかを判断できます。このコールバック メソッドのコードは記述されていません。興味がある場合は、自分で実装できます。null
bluetoothAdapter.isEnabled()
true
Toast
false
Intent
Intent
startActivityForResult(intent, 11)
intent
Intent
Code
6. Bluetooth をオフにする
Bluetooth デバイスの電源を入れた後、Bluetooth をオフにする操作を手動で完了することもできます。まずコードを見てください。
public void turnOffBle() {
if (bluetoothAdapter.isEnabled()) {
bluetoothAdapter.disable();
} else {
Toast.makeText(this, "蓝牙已经关闭了", Toast.LENGTH_SHORT).show();
}
}
まず、bluetoothAdapter.isEnabled()
Bluetooth の現在のステータスがメソッドによって取得され、Bluetooth がオンになっている場合にのみ、bluetoothAdapter.disable()
オフにする操作が実行され、このメソッドを使用して Bluetooth がオフになります。それ以外の場合、ユーザーは現在の Bluetoothはオフになっており、操作をオフにする必要はありません。
7. Bluetooth をスキャンする
コードの検索を開始
Bluetooth のオンとオフの操作が完了したら、次のステップは、周囲の Bluetooth デバイスを取得する操作、つまり Bluetooth のスキャンを実現することです。最初はBluetoothAdapter.startLeScan(BluetoothAdapter.LeScanCallback)
スキャンに使用したかったのですが、この方法のプロンプトは古く、使用は推奨されていません. その後、情報を参照した後、スキャンに使用することをお勧めしますBluetoothLeScanner.startScan(ScanCallback)
. . 最初にコードを見てみましょう:
private Handler mHanler = new Handler();
private BluetoothLeScanner bluetoothLeScanner;
bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
//开启蓝牙扫描
public void searchBle() {
if (bluetoothAdapter.isEnabled()) {
mHanler.postDelayed(myRunnable, 5000);
btn_Search.setText("停止搜索");
bluetoothLeScanner.startScan(scanCallback);
} else {
Toast.makeText(MainActivity.this, "请打开蓝牙", Toast.LENGTH_SHORT).show();
}
}
//延时停止搜索线程
Runnable myRunnable = new Runnable() {
@Override
public void run() {
bluetoothLeScanner.stopScan(scanCallback);
btn_Search.setText("搜索设备");
setBLESpinner();
}
};
BluetoothLeScanner
スキャンを開始する前に、クラスのオブジェクトを取得し、初期化関数でbluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner()
初期化してから、Bluetooth のスキャン操作を実行する必要があります。
Bluetooth スキャンを有効にするコードでは、まずbluetoothAdapter.isEnabled()
現在の Bluetooth の状態を判断します.yes が返された場合はfalse
、現在の Bluetooth がオンになっていないことを意味し、ユーザーに Bluetooth をオンにするように促し、true が返された場合は、 Bluetooth スキャンをオンにするmHanler.postDelayed(myRunnable, 5000)
. そのときの非同期スレッド、つまり 5 秒後にbluetoothLeScanner.stopScan(scanCallback)
Bluetooth をオフにするスキャンをパラメーターscanCallback
は Bluetooth スキャンのコールバック関数であり、スキャンされたデバイスをコールバック関数に記録します.以下で詳しく紹介します。
次に、bluetoothLeScanner.startScan(scanCallback)
Bluetooth スキャンをオンにし、Bluetooth スキャン ボタンのテキストを「検索停止」に設定しbtn_Search.setText("停止搜索")
、5 秒間スキャンし、時間が経過したらスキャンを停止し、Bluetooth スキャン ボタンのテキストを「デバイスの検索」に設定します。 , ここでボタンのテキストを変更します. 目的は, ユーザーがボタンをクリックしたときに, ボタン上のテキストに応じて異なる機能が選択されるようにすることです. 表示されたテキストが「検索デバイス」の場合は機能が実行されて検索されます.表示されたテキストが「検索停止」の場合、searchBle()
検索を停止する関数が実行されますdisSearchBle()
。
検索を停止するコード内のsetBLESpinner()
機能は、Spinner
コントロール内のコンテンツを更新すること、つまり、見つかったデバイスを表示することです。
検索停止とコールバック関数のコード
private List<BluetoothDevice> listdevices = new ArrayList<BluetoothDevice>(); //存放扫描到的设备
private List<String> listdevicename = new ArrayList<String>(); //存放扫描到的设备名字
//停止搜索
public void disSearchBle() {
if (bluetoothLeScanner != null) {
mHanler.removeCallbacks(myRunnable);
bluetoothLeScanner.stopScan(scanCallback);
btn_Search.setText("搜索设备");
setBLESpinner();
}
}
//扫描蓝牙设备的回调
public ScanCallback scanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, final ScanResult result) {
runOnUiThread(new Runnable() {
@Override
public void run() {
BluetoothDevice device = result.getDevice();
String str = device.getName();
if ((listdevicename.indexOf(str) == -1) && (device.getName() != null)) {
listdevices.add(device);
listdevicename.add(str);
Log.i(TAG, str);
}
}
});
}
@Override
public void onBatchScanResults(List<ScanResult> results) {
super.onBatchScanResults(results);
}
@Override
public void onScanFailed(int errorCode) {
super.onScanFailed(errorCode);
}
};
上記のコードはスキャン停止とBluetoothのスキャンを行うコールバック関数ですが、上記ではユーザーがデバイス検索のボタンをクリックすると5秒後に検索を停止するように設定していましたが、ここでは検索を停止する実装関数を追加しています。検索処理中 ユーザーは検索停止ボタン(検索デバイスと同じボタンですが、表示される文字が異なります)をクリックして検索デバイスを停止することができます.このボタンをクリックすると、5.以降に実行されたスレッドが前に設定した秒数が最初に実行され、その後mHanler.removeCallbacks(myRunnable)
実行がbluetoothLeScanner.stopScan(scanCallback)
停止します 検索、実行してbtn_Search.setText("搜索设备")
ボタンの表示テキストを「検索デバイス」に設定し、最後に実行してコントロールの内容をsetBLESpinner()
更新します。Bluetoothスキャンのコールバック関数では、デバイスがBluetoothデバイスを検索しているときに、デバイスが見つかるたびにメソッドが実行されます.このメソッドでは、最初にスキャンされたデバイスが取得され、デバイスの名前が取得され、次にデバイスの名前が取得されます.名前が For かどうか、保存されているかどうかを判断し、上記の 2 つの条件を満たさない場合はデバイスがコレクションに格納され、デバイスの名前がコレクションに格納されます。グローバル変数であり、スキャンされたデバイスを表示するメソッドで使用されます。Spinner
public void onScanResult(int callbackType, final ScanResult result)
null
listdevicename
listdevicename
setBLESpinner()
8. スキャンした Bluetooth デバイスを表示する
この記事では、スキャンされた Bluetooth デバイスがSpinner
コントロールに表示されます。上記では、2 つのコレクションに格納されている周囲の Bluetooth デバイスの名前とデバイスを取得しました。コードは次のとおりです。
private Spinner mSpinner;
private ArrayAdapter<String> ListAdapter;
mSpinner = findViewById(R.id.spinner); //显示蓝牙设备的Spinne控件
//将扫描到的设备添加到Spinner控件中
public void setBLESpinner() {
mSpinner.setOnItemSelectedListener(this);
ListAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, listdevicename);
ListAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mSpinner.setAdapter(ListAdapter);
}
まず、Spinner
コントロール内の各項目のモニターを選択します.項目の 1 つが選択されると、Bluetooth デバイスの名前とアドレスがIntent
2 番目のインターフェイスに渡され、接続、データ送信などが実現されます.これは以下で行われます.詳細な説明。次に、コントロールlistdevicename
に格納されている Bluetooth デバイスの名前をSpinner
表示用のコントロールに入れますが、直接配置することはできず、ArrayAdapter
正常に表示するには途中でクラスのオブジェクトを遷移させる必要があります。
9. 接続する Bluetooth デバイスを選択します
表示が完了したら、接続する必要がある Bluetooth デバイスを選択できます。まずコードを確認します。
public static String EXTRAS_DEVICE_NAME = "DEVICE_NAME";
public static String EXTRAS_DEVICE_ADDRESS = "DEVICE_ADDRESS";
//选择蓝牙设备
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String Item = parent.getSelectedItem().toString();
if (Item != "<BLE List>") {
for (BluetoothDevice device : listdevices) {
if (Item.equals(device.getName())) {
Intent intent = new Intent(this, BLECommunicationActivity.class);
intent.putExtra(EXTRAS_DEVICE_NAME, device.getName());
intent.putExtra(EXTRAS_DEVICE_ADDRESS, device.getAddress());
startActivity(intent);
}
}
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
上記では、mSpinner.setOnItemSelectedListener(this)
選択したリスニング イベントを設定します。Bluetooth デバイスを選択すると、上記のコードが実行されます。まず、選択した Bluetooth デバイスの名前を取得しますItem
。追加した文字列でない場合は“<BLE List>”
、開始します。スキャンされた bluetooth デバイスのセットは、名前に従って対応する bluetooth デバイスを見つけ、デバイスの名前とアドレスを 2 番目のインターフェイスに渡し、後続の操作のために 2 番目のインターフェイスにジャンプします。
10. ボタンクリックリスナーイベント
以下は、ボタン クリック リスナー イベントのコードです。
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_On: //打开蓝牙按钮
turnOnBle();
break;
case R.id.btn_Off: //关闭蓝牙按钮
turnOffBle();
break;
case R.id.btn_Search: //搜索蓝牙设备按钮
if (btn_Search.getText().equals("搜索设备")) {
listdevices.clear();
listdevicename.clear();
listdevicename.add("<BLE List>");
searchBle();
} else if (btn_Search.getText().equals("停止搜索")) {
disSearchBle();
}
break;
}
}
Bluetooth デバイスの検索ボタンをクリックすると、ボタンに表示されているテキストを判断し、異なるテキストに従って対応するメソッドを実行します。
listdevices.clear();
istdevicename.clear();
listdevicename.add("<BLE List>");
これら 2 行のコードの役割は、各デバイス検索の前に Bluetooth デバイスと名前の 2 つのコレクションをクリアし、新しくスキャンされたデバイスと名前を保存することです。Spinner
コントロールは最初の項目のコンテンツを自動的に選択するため、誤接続を防ぐために、このlistdevicename.add("<BLE List>")
ステートメントを使用して、各スキャン後に保存された Bluetooth デバイス名のコレクションの最初の項目が自分で定義した文字列であることを確認します。そのpublic void onItemSelected(AdapterView<?> parent, View view, int position, long id)
中で、選択した文字列が弊社独自の文字列かどうかを判断し、そうでなければジャンプして接続します。
これは、一部の機能のみを実現する最初のインターフェイスのコードです. 以下の機能は、Android BLE Bluetooth 設定 (2) の全プロセスで APP ソース コードを使用して説明されます. 必要に応じて、それを確認してください. ご不明な点がございましたら、メッセージまたはプライベートメッセージを残していただければ、確認次第返信いたします.上記の内容が間違っている場合は、お気軽に教えてください.ここで,あなたの研究の成功を祈っています.そして明るい未来〜
Android BLE Bluetooth (HC-08) のソースコードを無料で入手する方法