不在后台监控时提示位置许可?

时间:2015-10-15 13:25:53

标签: android android-6.0-marshmallow ibeacon-android altbeacon

我正在使用Android Beacon Library。从棉花糖开始,我看到了以下错误,正如预期和记录的那样。

  

权限拒绝:需要ACCESS_COARSE_LOCATION或ACCESS_FINE_LOCATION权限才能获得扫描结果

我在Fragment中有我的测距代码,当Fragment在屏幕上时会抛出RuntimeException,正如我没有提示允许的那样。如果我点击主页按钮,就会调用Pause,并且我正在取消绑定beaconManager,并且不再按预期抛出异常。从之前的应用列表返回Activity,每次扫描都会再次抛出RuntimeException。

为什么即使我已将权限添加到AndroidManifest中,也会在前台抛出异常?

根据文件 HERE,如果您在后台执行扫描,则只需提示用户获取位置权限?

  

当您尝试在后台进行蓝牙扫描时,您将在LogCat中收到以下错误,并且不会检测到信标

这是否意味着后台扫描,还是我误解了文档,您必须提示无论如何?如果可以避免的话,我想避免额外的(可能会让紧张的用户反感)提示在应用内部获得许可!!

我的清单包含 -

<uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION"/>

片段中我的剪切代码是 -

public class NearMeNowFragment extends Fragment implements BeaconConsumer {

//Beacon manager stuff
private BeaconManager beaconManager;

<SNIP>


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    beaconManager = BeaconManager.getInstanceForApplication(getActivity());
    beaconManager.getBeaconParsers().add(new BeaconParser().
            setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View rootView = inflater.inflate(R.layout.near_me_now, container, false);

    //Set up beacon stuff if Bluetooth available
    if (verifyBluetooth(false)) {
        beaconManager.bind(this);
    }

    <SNIP>

    return rootView;
}


/***************************
Beacon config methods
****************************
*/

@Override
public void onBeaconServiceConnect() {
    //update all scan periods
    beaconManager.setForegroundScanPeriod(1100l);
    beaconManager.setForegroundBetweenScanPeriod(8900l);
    beaconManager.setAndroidLScanningDisabled(true);
    try {
        beaconManager.updateScanPeriods();
    } catch (RemoteException e) {
        e.printStackTrace();
    }

    beaconManager.setRangeNotifier(new RangeNotifier() {
        @Override
        public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
            if (beacons.size() > 0) {
                <SNIP>
                //handling beacons here
                ...
            } else {
                Log.i(TAG, "ZERO BEACONS IN SCAN");
            }
        }
    });

    try {
        beaconManager.startRangingBeaconsInRegion(new Region(TAG, null, null, null));
    } catch (RemoteException e) {
        e.printStackTrace();
    }
}

@Override
public Context getApplicationContext() {
    return getActivity().getApplicationContext();
}

@Override
public void unbindService(ServiceConnection serviceConnection) {
    getActivity().unbindService(serviceConnection);
}

@Override
public boolean bindService(Intent intent, ServiceConnection serviceConnection, int mode) {
    return getActivity().bindService(intent, serviceConnection, mode);
}


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

    if(beaconManager.isBound(this)){
        beaconManager.unbind(this);
    }
}

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

    beaconManager.bind(this);
}

@Override
public void onDestroy() {
    super.onDestroy();
    if(beaconManager.isBound(this)){
        beaconManager.unbind(this);
    }
}

}

我的实际Logcat错误是

  

W / Binder:从绑定器存根实现中捕获了RuntimeException。       java.lang.SecurityException:需要ACCESS_COARSE_LOCATION或ACCESS_FINE_LOCATION权限才能获得扫描结果

2 个答案:

答案 0 :(得分:22)

根据您是否在build.gradle文件中设置targetSdkVersion 23来澄清需求不同

如果您定位SDK 23(Marshmallow)或更高版本:

  • 您必须在清单中声明android.permission.ACCESS_COARSE_LOCATION或android.permission.ACCESS_FINE_LOCATION。
  • 您必须按照我的博文Shuffling Algorithm
  • 中所述提示用户获得许可
  • 用户必须接受此权限,不能将其关闭。
  • 如果未满足上述任何要求,您将无法检测前景或背景中的信标。

如果您定位SDK 22或更低版本:

  • 您可以选择在清单中声明android.permission.ACCESS_COARSE_LOCATION或android.permission.ACCESS_FINE_LOCATION。
  • 用户可以通过转到设置来打开或关闭权限。
  • 如果未授予其中一个权限,您仍然可以检测前景中的信标,但不能检测后台中的信标。

有关详细信息,请参阅here.here

答案 1 :(得分:1)

当我在Marshmallow设备上测试时,我的应用程序遇到了同样的问题。为了避免提示用户提供权限,我只是将targetSdkVersion更改为22. compileSdkVersion可以保留为23.更改build.gradle后,您可能需要运行Tools&gt; Android&gt;使用Gradle文件同步项目。如果您使用Eclipse,则targetSdkVersion位于清单文件中。