web-dev-qa-db-ja.com

BluetoothLeScanner.startScan with Android 6.0はデバイスを検出しません

非推奨のものBluetoothAdapter.startLeScanの代わりに、関数BluatoothLeScanner.startScanを使用しようとしています。昨日、Nexus 5をAndroid 6.0に更新し、その瞬間からアプリは動作しなくなりました。まず、必要な設定ACCESS_COARSE_LOCATIONを追加しました。ここで、 https://developer.Android.com/about/versions/Marshmallow/Android-6.0-changes.html#behavior-hardware-id その後、ここで説明するように許可を追加しました:- https://developer.Android.com/training/permissions/requesting.html 。しかし、最終的には動作していないようで、bleデバイスを送り返しません。

これは私のコードです:

manifest

<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
          package="com.stm.sensitronapp">
          <uses-sdk Android:maxSdkVersion="23"/>
          <uses-feature Android:name="Android.hardware.bluetooth_le" Android:required="true"/>

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

DeviceScanActivity

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
...

if (ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_COARSE_LOCATION)
            != PackageManager.PERMISSION_GRANTED){
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.ACCESS_COARSE_LOCATION)) {
        } else {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
                    MY_PERMISSIONS_REQUEST_ACCESS_COARSE);
        }
    }

// Device scan callback.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop) {
        if (ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_COARSE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
            mScanCallback = new ScanCallback() {
                @Override
                public void onScanResult(int callbackType, ScanResult result) {
                    super.onScanResult(callbackType, result);
                    mLeDeviceListAdapter.addDevice(result.getDevice());
                    mLeDeviceListAdapter.notifyDataSetChanged();
                }
            };
        }
    } 
}
final BluetoothManager bluetoothManager =
            (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();

if (mBluetoothAdapter.getState() == BluetoothAdapter.STATE_ON) {
        mSwipeRefreshLayout.setRefreshing(true);
        mLeDeviceListAdapter.clear();
        mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
        if(ContextCompat.checkSelfPermission(this,
                    Manifest.permission.ACCESS_COARSE_LOCATION ) == PackageManager.PERMISSION_GRANTED) {
                mBluetoothLeScanner.startScan(mScanCallback);
            }
        }

編集:この問題を解決するために、GPSのみをオンにしました。 this way でプログラムで簡単に実行できます。

21
Jacopo Tosi

許可が与えられたら、試してみてください:GPSをオンにします。

22
qinmiao

アプリは起動時に場所の許可を求めていますか?そうでない場合は、プロンプトが表示されるようにコードを別の場所で処理します。

また、これをチェックして、アプリが正常に動作しているかどうかをテストできます。

[設定]> [アプリ]> [YourApplication]> [権限]を開き、[場所]を有効にして、結果のスキャンを試みます。

マニフェストでACCESS_COARSE_LOCATIONを指定した場合にのみ、場所が権限の下にリストされます。

8
Kamal Kishore

上記のソリューションを使用しても機能しますが、副作用は、ロケーションサービスを必要としないものに対してオンにする必要があることです。 aroundくて満足できない回避策は、マニフェストでターゲットバージョンを指定することです

Android:targetSdkVersion = "21"

インストールされているバージョンが6.0.1でも、Nexus 7でスキャンできます。インストールされているバージョンよりも低いバージョンをターゲットにした場合の副作用はわかりませんが、少なくともスキャンは機能します。 GPSのないデバイス(そのようなデバイスが存在する場合)の唯一のソリューションである可能性があります。

このためにGoogleは十字架につけられるべきです。

4
Brian Reinhold

1つ-完全な答えではありませんが、新しいランタイムロケーション許可を有効にすると、同じ古いメソッドBTスキャンメソッドを引き続き使用できるということです。

            mBluetoothAdapter.startDiscovery();

.......

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

                if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                BluetoothDevice device = (BluetoothDevice) intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                mDeviceList.add(device);


            }
        }
    };
0
aiden_fry

それは古い質問ですが、誰かを助けるために答えます。
残念ながら、ACCESS_COARSE_LOCATIONとtargetSdkVersion 22の組み合わせは、一部のデバイスでは機能しません。
これは良い方法ではありませんが、ランタイム権限(ACCESS_COARSE_LOCATIONまたはACCESS_FINE_LOCATION)を使用せずに次の方法で解決しました。

  1. 'targetSdkVersion'を19に設定します(おそらくapi19〜api22が可能になると思います)
  2. マニフェストファイルに次のアクセス許可を追加します

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

テスト済みAndroid 4.4〜7.1.1

0
Andromer