Android 2.0から備わっているというBluetooth用のAPIを使ってみようと思い、通信まで頑張ろうとしたが今日は探索までしかいかなかった。そしてListViewの使い方を俺がわかってない。
とりあえず探索までのながれ
- BluetoothAdapterを取得する
- BluetoothAdapterが利用可能ならデバイス探索、そうでなければ利用許可をユーザに求める
- 利用許可をユーザから貰えたら探索開始
- BroadcastReceiverで見つけたデバイスを受け取る
という感じ。Android SDKのサンプルにBluetoothチャットがあるのでそれ見ながら作成した。android.permission.BLUETOOTHとandroid.permission.BLUETOOTH_ADMINが必要なpermissionになっている
以下ソースコード
package test.bluetooth; import android.app.Activity; import android.app.AlertDialog; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.BroadcastReceiver; import android.os.Bundle; import android.view.View; import android.view.ViewGroup; import android.widget.ListView; import android.widget.TextView; import android.widget.BaseAdapter; import android.graphics.Color; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothAdapter; import java.util.List; import java.util.ArrayList; import java.util.Set; public class BluetoothActivity extends Activity { private static final int REQUEST_ENABLE_BLUETOOTH = 1; private BluetoothAdapter adapter; private BroadcastReceiver receiver; private ListView listView; private DeviceList deviceList; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); listView = new ListView(this); deviceList = new DeviceList(this); listView.setAdapter(deviceList); listView.setBackgroundColor(Color.WHITE); if(createAdapter()){ //デバイス探索用のBroadcastReceiverの準備 setReceiver(); //レシーバで受け取るメッセージの設定 IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); registerReceiver(receiver, filter); filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); registerReceiver(receiver, filter); bluetoothEnable(); } setContentView(listView); } //アダプタの作成。成功したらtrueを、失敗したらfalseを返す private boolean createAdapter(){ adapter = BluetoothAdapter.getDefaultAdapter(); if(adapter == null){ return false; } return true; } private void bluetoothEnable(){ if(adapter.isEnabled()){ //Bluetoothが利用可能な状態ならデバイスの探索開始 doDiscovery(); }else{ //Bluetoothの利用許可を求めるダイアログ表示。結果はonActibityResultで受け取る Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(intent, BluetoothActivity.REQUEST_ENABLE_BLUETOOTH); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data){ if(requestCode == BluetoothActivity.REQUEST_ENABLE_BLUETOOTH){ if(resultCode == Activity.RESULT_OK){ //Bluetoothの仕様許可が来たらデバイスの探索開始 doDiscovery(); }else{ error("Bluetoothを利用出来ません"); } } } //デバイスを探索を始める。結果はBroadcastReceiverで受け取る private void doDiscovery(){ if(adapter.isDiscovering()){ adapter.cancelDiscovery(); } adapter.startDiscovery(); } // private void setReceiver(){ receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); //デバイスを見つけたらアダプタに名前とアドレスを追加 if(BluetoothDevice.ACTION_FOUND.equals(action)) { BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if (device.getBondState() != BluetoothDevice.BOND_BONDED) { deviceList.addDeviceInfo(device.getName(), device.getAddress()); listView.invalidateViews(); } }else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) { //デバイスを見つけられなければメッセージを表示 if(deviceList.getCount() == 0){ deviceList.addDeviceInfo("Not Found Device", ""); } } } }; } //デバイスのリストを格納するアダプター private static class DeviceList extends BaseAdapter{ private Context context; private List<DeviceInfo> infoList; private DeviceList(Context context){ this.context = context; infoList = new ArrayList<DeviceInfo>(); } public void addDeviceInfo(String name, String address){ infoList.add(new DeviceInfo(name, address)); } @Override public int getCount(){ return infoList.size(); } @Override public Object getItem(int position){ return infoList.get(position); } @Override public long getItemId(int position){ return position; } @Override public View getView(int position, View convertView, ViewGroup parent){ //デバイスの名前を取得してTextViewで表示 DeviceInfo info = infoList.get(position); TextView deviceView = new TextView(context); deviceView.setText(info.getName()); deviceView.setTextSize(16f); return deviceView; } //デバイスの名前とアドレスを持つクラス private static class DeviceInfo{ private final String name; private final String address; private DeviceInfo(String name, String address){ this.name = name; this.address = address; } private String getName(){ return name; } private String getAddress(){ return address; } } } @Override protected void onDestroy() { super.onDestroy(); // デバイスの探索を止める if (adapter != null) { adapter.cancelDiscovery(); } // ブロードキャストのレシーバを外す this.unregisterReceiver(receiver); } //エラーメッセージをアラートで表示 private void error(String msg){ AlertDialog.Builder builder = new AlertDialog.Builder (this); builder.setTitle("エラー"); builder.setMessage(msg); builder.setCancelable(true); AlertDialog dialog = builder.create(); dialog.show(); } }