20

次のコードは、Android 5.1.1(LMY48Mのビルド)を実行しているNexus 9ではうまく動作しますが、Android 6.0(Build MPA44l)を実行するNexus 9では動作しません。Bluetooth LE ScanFiltersがAndroid Mで動作しない

List<ScanFilter> filters = new ArrayList<ScanFilter>(); 
ScanSettings settings = (new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_POWER)).build(); 
ScanFilter.Builder builder = new ScanFilter.Builder(); 
builder.setManufacturerData((int) 0x0118, new byte[]{(byte) 0xbe, (byte) 0xac}, new byte[]{(byte) 0xff, (byte)0xff}); 
ScanFilter scanFilter = builder.build(); 
filters.add(scanFilter); 
mBluetoothLeScanner.startScan(filters, settings, new ScanCallback() { 
    ... 
}); 

Android 5.xでは、上記のコードは、スキャンフィルタに一致する製造元の広告が表示されたときにコールバックを生成します。 (下記のLogcatの出力例を参照してください).Nexus 9 with MPA44lでは、コールバックは受信されません。あなたはスキャンフィルタをコメントアウトした場合、コールバックは9

09-22 00:07:28.050 1748-1796/org.altbeacon.beaconreference D/BluetoothLeScanner﹕ onScanResult() - ScanResult{mDevice=00:07:80:03:89:8C, mScanRecord=ScanRecord [mAdvertiseFlags=6, mServiceUuids=null, mManufacturerSpecificData={280=[-66, -84, 47, 35, 68, 84, -49, 109, 74, 15, -83, -14, -12, -111, 27, -87, -1, -90, 0, 1, 0, 1, -66, 0]}, mServiceData={}, mTxPowerLevel=-2147483648, mDeviceName=null], mRssi=-64, mTimestampNanos=61272522487278} 

誰が見ていScanFiltersは、Android M上で動作ネクサス上で正常に受信されていますか?

+0

NETWORK_PROVIDERとGPS_PROVIDERの両方が必要ですか?または単にNETWORK_PROVIDER。詳細はこちらhttps://developer.android.com/guide/topics/connectivity/bluetooth-le.html –

答えて

16

問題はスキャンフィルタではなく、アプリケーションがバックグラウンドになっているときにのみスキャンフィルタが使用されていました。 AndroidのM、バックグラウンドでのBluetooth LEスキャンを開始するアプリは、次の2つの権限の1持っていない限り、ブロックされている:私はそれがで動作しませんでしたので、テストは、これらの権限のいずれかを要求しなかったでした

android.permission.ACCESS_COARSE_LOCATION 
android.permission.ACCESS_FINE_LOCATION 

アプリをAndroid Mのバックグラウンド(スキャンフィルタがアクティブだった唯一の時間)を追加します。最初のものを追加すると問題が解決しました。

私はLogcatに以下の行を見たので、これは問題に気づいた:

09-22 22:35:20.152 5158 5254 E BluetoothUtils: Permission denial: Need ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission to get scan results 

詳細はこちらをご覧ください:https://code.google.com/p/android-developer-preview/issues/detail?id=2964

+11

マニフェストにを追加しましたが、 「java.lang.SecurityException:スキャン結果を取得するためのACCESS_COARSE_LOCATIONまたはACCESS_FINE_LOCATION権限が必要です」というエラーメッセージが表示されます。どのようにこれを解決するための任意のアイデア? –

+5

Android 6からは、実行時にusrに許可要求を提示する必要があります。例についてはこちらを参照してください:http://developer.radiusnetworks.com/2015/09/29/is-your-beacon-app-ready-for-android-6.html – davidgyoung

+0

@davidgyoung許可を与えるとスキャンが停止しますビーコン。この問題を解決するためにお手伝いください。 –

27

私は、Bluetoothに接続するアプリで同様の問題がありました。 LE ScanFilterではなく、OPのように権限の問題でした。

根本的な原因は、SDK 23から、実行時にActivityrequestPermissions()メソッドを使用する権限をユーザーに求める必要があるということです。ここで

は私のために働いていたものです:接続しようとする前に、あなたの活動に

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> 
    1. ルートノード内で、AndroidManifest.xmlに次の2行の1を追加します。 Bluetoothには、ActivityrequestPermissions()メソッドを呼び出します。これにより、ユーザに許可を求めるシステムダイアログが開きます。アクセス許可ダイアログは別のスレッドで開きますので、結果を待ってからBluetooth接続を試みてください。

    2. 結果を処理するには、ActivityonRequestPermissionsResult()を上書きします。このメソッドは、ユーザーが許可を拒否した場合、アプリがブルートゥースアクティビティを実行できないことをユーザーに伝えるために、実際に何かを行うだけです。

    This blog postで何が起こっているかをユーザーに伝えるためにAlertDialogsを使用して、いくつかのサンプルコードがあります。それは良い出発点であるが、いくつかの欠点があります。

    それはrequestPermissions()への呼び出しをラップ
  • AlertDialogを終了するrequestPermissions()スレッドを待って処理しません
    • は、私には無関係なようですが。 requestPermissions()への裸の電話で十分です。
  • 6

    BLE

    <uses-permission android:name="android.permission.BLUETOOTH" /> 
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> 
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> 
    

    と一緒にコピー要求と補助金の場所許可

    @Override 
        public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { 
         switch (requestCode) { 
          case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS: { 
           Map<String, Integer> perms = new HashMap<String, Integer>(); 
           // Initial 
           perms.put(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED); 
    
    
           // Fill with results 
           for (int i = 0; i < permissions.length; i++) 
            perms.put(permissions[i], grantResults[i]); 
    
           // Check for ACCESS_FINE_LOCATION 
           if (perms.get(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED 
    
             ) { 
            // All Permissions Granted 
    
            // Permission Denied 
            Toast.makeText(ScanningActivity.this, "All Permission GRANTED !! Thank You :)", Toast.LENGTH_SHORT) 
              .show(); 
    
    
           } else { 
            // Permission Denied 
            Toast.makeText(ScanningActivity.this, "One or More Permissions are DENIED Exiting App :(", Toast.LENGTH_SHORT) 
              .show(); 
    
            finish(); 
           } 
          } 
          break; 
          default: 
           super.onRequestPermissionsResult(requestCode, permissions, grantResults); 
         } 
        } 
    
    
        @TargetApi(Build.VERSION_CODES.M) 
        private void fuckMarshMallow() { 
         List<String> permissionsNeeded = new ArrayList<String>(); 
    
         final List<String> permissionsList = new ArrayList<String>(); 
         if (!addPermission(permissionsList, Manifest.permission.ACCESS_FINE_LOCATION)) 
          permissionsNeeded.add("Show Location"); 
    
         if (permissionsList.size() > 0) { 
          if (permissionsNeeded.size() > 0) { 
    
           // Need Rationale 
           String message = "App need access to " + permissionsNeeded.get(0); 
    
           for (int i = 1; i < permissionsNeeded.size(); i++) 
            message = message + ", " + permissionsNeeded.get(i); 
    
           showMessageOKCancel(message, 
             new DialogInterface.OnClickListener() { 
    
              @Override 
              public void onClick(DialogInterface dialog, int which) { 
               requestPermissions(permissionsList.toArray(new String[permissionsList.size()]), 
                 REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS); 
              } 
             }); 
           return; 
          } 
          requestPermissions(permissionsList.toArray(new String[permissionsList.size()]), 
            REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS); 
          return; 
         } 
    
         Toast.makeText(ScanningActivity.this, "No new Permission Required- Launching App .You are Awesome!!", Toast.LENGTH_SHORT) 
           .show(); 
        } 
    
        private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) { 
         new AlertDialog.Builder(ScanningActivity.this) 
           .setMessage(message) 
           .setPositiveButton("OK", okListener) 
           .setNegativeButton("Cancel", null) 
           .create() 
           .show(); 
        } 
    
        @TargetApi(Build.VERSION_CODES.M) 
        private boolean addPermission(List<String> permissionsList, String permission) { 
    
         if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) { 
          permissionsList.add(permission); 
          // Check for Rationale Option 
          if (!shouldShowRequestPermissionRationale(permission)) 
           return false; 
         } 
         return true; 
        } 
    

    に、このメソッドを貼り付け、その後、許可

    のためのonCreateチェックに位置許可を追加します。
    if (Build.VERSION.SDK_INT >= 23) { 
          // Marshmallow+ Permission APIs 
          fuckMarshMallow(); 
         } 
    

    あなたの時間を節約したいと思っています。

    +1

    それは働いた!しかし、関数の名前:p –

    関連する問題