web-dev-qa-db-ja.com

Android-Bluetooth検出でデバイスが見つかりません

私は現在、Bluetooth Android APIが提供できるサービスを開始するために、小さなアプリに取り組んでいます。

編集->回答:

この問題は特定のNexus 5デバイスが原因であるようです。 Bluetoothレシーバーがうまく機能しないようです。以下の解決策は他のデバイスでも機能するはずです

備考:

  1. ここでドキュメントを読みました: http://developer.Android.com/guide/topics/connectivity/bluetooth.html およびこのチュートリアルの次のソースコード http: //www.londatiga.net/it/programming/Android/how-to-programmatically-scan-or-discover-Android-bluetooth-device/ githubの/ lorensiuswlt/AndroBluetoothにあります

  2. 興味のあるほぼすべての機能を終了しました(アダプターの存在の確認、ブルースの有効化/無効化、ペアのデバイスのクエリ、アダプターの検出可能の設定など)。

問題:

Nexus 5の設定/ Bluetoothからデバイスが見つかった場合でも、.onDiscovery()メソッドを起動すると、実際にはデバイスが見つかりません

ここに私がそれを処理する方法があります:

public class MainActivity extends AppCompatActivity {
private BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

...

protected void onCreate(Bundle savedInstanceState) {
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(mReceiver, filter); 
}

フィルターは、できる限りうまく機能しています、つまり、ACTION_STATE_CHANGED(bluetooth有効化)と2つのACTION_DISCOVERY _ ***を試すことができます。

その後、次のメソッドが正常に呼び出されます。

public void onDiscovery(View view)
{
    mBluetoothAdapter.startDiscovery();
}

そして、私のBluetoothレシーバーがあります:

private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();

        if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
            final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);

            if (state == BluetoothAdapter.STATE_ON) {
                showToast("ACTION_STATE_CHANGED: STATE_ON");
            }
        }

        else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
            mDeviceList = new ArrayList<>();
            showToast("ACTION_DISCOVERY_STARTED");
            mProgressDlg.show();
        }

        else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action) && !bluetoothSwitchedOFF) {
            mProgressDlg.dismiss();
            showToast("ACTION_DISCOVERY_FINISHED");

            Intent newIntent = new Intent(MainActivity.this, DeviceListActivity.class);

            newIntent.putParcelableArrayListExtra("device.list", mDeviceList);

            startActivity(newIntent);
        }

        else if (BluetoothDevice.ACTION_FOUND.equals(action)) {// When discovery finds a device
            // Get the BluetoothDevice object from the Intent
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            mDeviceList.add(device);
            showToast("Device found = " + device.getName());
        }
    }
};

私はlogcatから出てくる問題はなく、テスト中に問題に気付きませんでした。唯一の問題は、多くの検出可能なデバイスが近辺で利用可能な場合、スキャンの最後にデバイスが検出されないことです

トピックをあふれさせないために、あまり多くのコードを入れないようにしました。さらに必要な場合は私に聞いてください。

読んでくれてありがとう、そして答えてくれてありがとう。

38
Amesys

Androidのどのバージョンでこれを実行していますか?それがAndroid 6.xである場合、ACCESS_COURSE_LOCATIONマニフェストに対する許可。例えば:

<uses-permission Android:name="Android.permission.ACCESS_COARSE_LOCATION"/> 

私は同様の問題を抱えていたので、修正されました。

UPDATE:これに Googleから直接のドキュメント を追加:

BluetoothおよびWi-Fiスキャンを介して近くの外部デバイスのハードウェア識別子にアクセスするには、アプリにACCESS_FINE_LOCATION または ACCESS_COARSE_LOCATIONパーミッション

71
nverbeek

パーティーに少し遅れましたが、これは他の人にとって便利かもしれません。

あなたは2つのことをする必要があります

  1. _<uses-permission Android:name="Android.permission.ACCESS_COARSE_LOCATION"/>_を追加

または_<uses-permission Android:name="Android.permission.ACCESS_FINE_LOCATION"/>_

androidManifest.xmlに

  1. Android 6.0デバイスの場合は、次のようなものを使用して、ランタイムでも許可をリクエストしていることを確認してください

    _int MY_PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION = 1; 
    ActivityCompat.requestPermissions(this,
            new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
            MY_PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION);
    _

    mBluetoothAdapter.startDiscovery();の直前

ステップ2を行わないと、Android> = 6.0でデバイスのハードウェア識別子情報を取得できなくなります

更新/編集:
Androidバージョンチェックおよび警告としての警告ダイアログを含む例

_if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {  // Only ask for these permissions on runtime when running Android 6.0 or higher
    switch (ContextCompat.checkSelfPermission(getBaseContext(), Manifest.permission.ACCESS_COARSE_LOCATION)) {
        case PackageManager.PERMISSION_DENIED:
            ((TextView) new AlertDialog.Builder(this)
                    .setTitle("Runtime Permissions up ahead")
                    .setMessage(Html.fromHtml("<p>To find nearby bluetooth devices please click \"Allow\" on the runtime permissions popup.</p>" +
                            "<p>For more info see <a href=\"http://developer.Android.com/about/versions/Marshmallow/Android-6.0-changes.html#behavior-hardware-id\">here</a>.</p>"))
                    .setNeutralButton("Okay", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            if (ContextCompat.checkSelfPermission(getBaseContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                                ActivityCompat.requestPermissions(DeviceListActivity.this,
                                        new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
                                        REQUEST_ACCESS_COARSE_LOCATION);
                            }
                        }
                    })
                    .show()
                    .findViewById(Android.R.id.message))
                    .setMovementMethod(LinkMovementMethod.getInstance());       // Make the link clickable. Needs to be called after show(), in order to generate hyperlinks
            break;
        case PackageManager.PERMISSION_GRANTED:
            break;
    }
}
_
60
Nils