2017-05-12 58 views
1

大家好,我正在开发基于beacon的android应用程序,它在Android 6.0以下工作正常,它只需要蓝牙许可。但Android 6.0及以上,它要求给蓝牙和位置许可。Android 6.0中无位置权限的信标扫描

为什么我们需要在Android 6.0中为扫描信标提供位置权限?

在此先感谢!

回答

1

我实际上正在开发类似的东西,令我感到惊讶,因为从逻辑上讲,您不需要通过蓝牙/低能量扫描信标的位置权限。这实际上适用于Android 6.0之前 - 但谷歌决定改变这一点。

From the notes

访问硬件标识符 为用户提供更高的数据保护,在这个版本开始,Android的删除程序访问设备的本地硬件标识符使用Wi-Fi和蓝牙API的应用程序。 WifiInfo.getMacAddress()和BluetoothAdapter.getAddress()方法现在返回恒定值02:00:00:00:00:00。

访问通过蓝牙和Wi-Fi扫描附近的外部装置的硬件识别码,您的应用程序现在必须有ACCESS_FINE_LOCATION或ACCESS_COARSE_LOCATION权限:

WifiManager.getScanResults()
BluetoothDevice.ACTION_FOUND
BluetoothLeScanner。 startScan()

注意:当运行Android 6.0(API级别23)的设备启动后台Wi-Fi或蓝牙扫描时,操作对外部设备可见,源自随机MAC地址

,这并不意味着你必须开启GPS,而是在画面中的位置模式Bluetooh/Battery Saving这里看看

enter image description here

+0

的任何解决方案呢? –

+0

@BossRustler不是现在。 –

0

检查我的代码,我做了很久以前,不,你只需要启用蓝牙。正如我在代码中看到的那样。请忽略postNotification方法,因为这不是必需的。

private void initBluetooth() { 
     // Check if device supports Bluetooth Low Energy. 
     if (!beaconManager.hasBluetooth()) { 
      //Toast.makeText(this, "Device does not have Bluetooth Low Energy", Toast.LENGTH_LONG).show(); 
      return; 
     } 

     // If Bluetooth is not enabled, let user enable it. 
     if (!beaconManager.isBluetoothEnabled()) { 
      Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); 
      startActivityForResult(enableBtIntent, Constant.REQUEST_ENABLE_BT); 
     } else { 
      Log.v(this.getClass(), "---> bluetooth already is enabled"); 
      startService(new Intent(this, EstimoteService.class)); 
     } 
    } 

// EstimoteService类

public class EstimoteService extends Service implements BeaconManager.RangingListener, BeaconManager.MonitoringListener { 
    private static final int NOTIFICATION_ID = 123; 
    private static final Region ALL_ESTIMOTE_BEACONS_REGION = new Region("regionId", null, null, null); 
    private Beacon beaconFound; 

    private NotificationManager notificationManager; 
    private BeaconManager beaconManager; 

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

     initResources(); 
    } 

    @Override 
    public IBinder onBind(Intent intent) { 
     return null; 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     notificationManager.cancel(NOTIFICATION_ID); 

     // Default values are 5s of scanning and 25s of waiting time to save CPU cycles. 
     // In order for this demo to be more responsive and immediate we lower down those values. 
     beaconManager.setBackgroundScanPeriod(TimeUnit.SECONDS.toMillis(1), 0); 
     beaconManager.connect(new BeaconManager.ServiceReadyCallback() { 
      @Override 
      public void onServiceReady() { 
       try { 
        beaconManager.startRanging(ALL_ESTIMOTE_BEACONS_REGION); 
       } catch (RemoteException e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 


     return START_NOT_STICKY; 
    } 

    private void initResources() { 
     notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 
     beaconManager = new BeaconManager(this); 
     beaconManager.setRangingListener(this); 
     beaconManager.setMonitoringListener(this); 
    } 

    @Override 
    public void onBeaconsDiscovered(Region region, List<Beacon> beacons) { 
     if (beaconFound == null) { 
      // Get the first available beaconFound 
      if (beacons.isEmpty()) 
       return; 

      beaconFound = beacons.get(0); 
      final Region beaconRegion = new Region("regionId", beaconFound.getProximityUUID(), beaconFound.getMajor(), beaconFound.getMinor()); 
      beaconManager.connect(new BeaconManager.ServiceReadyCallback() { 
       @Override 
       public void onServiceReady() { 
        try { 
         beaconManager.startMonitoring(beaconRegion); 
        } catch (RemoteException e) { 
         e.printStackTrace(); 
        } 
       } 
      }); 
     } 
    } 

    @Override 
    public void onEnteredRegion(Region region, List<Beacon> beacons) { 
     postNotification("Entered region"); 
     System.out.println("---> enter region"); 
    } 

    @Override 
    public void onExitedRegion(Region region) { 
     postNotification("Exited region"); 
     System.out.println("---> exit region"); 
    } 

    private void postNotification(String msg) { 
     NotificationCompat.Builder builder = new NotificationCompat.Builder(this); 
     builder.setSmallIcon(R.drawable.beacon_gray).setContentTitle("XXX").setContentText(msg); 
     notificationManager.notify(NOTIFICATION_ID, builder.build()); 
    } 
} 
+0

kggoh - 对于Android Marshmallow为什么我们需要6.0的位置权限? –