不后台监控时是否提示位置许可? [英] Prompting for location permission when NOT monitoring in background?

查看:111
本文介绍了不后台监控时是否提示位置许可?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Android信标库.自棉花糖以来,我看到了以下错误,这是预期的并有记录的.

I'm using the Android Beacon Library. Since Marshmallow, I am seeing the following error, as expected and documented.

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

Permission denial: Need ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission to get scan results

我将测距代码放在一个Fragment中,并且在Fragment出现在屏幕上时抛出RuntimeException,这是预期的,因为我没有提示输入权限.如果按下主屏幕按钮,则会调用Pause,并且我将解除beaconManager的绑定,并且不再像预期的那样再次引发异常.从上一个应用程序列表回到活动",每次扫描都会再次引发RuntimeException.

I have my ranging code in a Fragment, and the RuntimeException is thrown when the Fragment is on screen, as expected as I'm not prompting for permission. If I hit the home button, Pause is called, and I'm unbinding beaconManager, and the exception is no longer thrown, again, as expected. Coming back to Activity from previous app list, the RuntimeException is thrown again each scan.

即使我向AndroidManifest添加了权限,为什么在前台时也会引发异常?

Why is the exception thrown when in the foreground even though I have added the permission to the AndroidManifest?

根据文档 这里,如果您愿意,只需提示用户输入位置权限在后台执行扫描?

According to the documentation HERE, you only need to prompt the user for location permission if you are performing a scan in the background?

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

you'll get the following error in LogCat when you try to do a bluetooth scan in the background, and no beacons will be detected

这是否意味着背景扫描,或者我误解了文档,无论如何您都必须提示?如果要避免的话,我想避免在应用程序内出现多余的提示(可能会给紧张的用户带来烦恼)!

Does this mean ONLY a background scan, or am I misinterpreting the documentation, and you must prompt regardless? I want to avoid the extra (off-putting perhaps to nervous users) prompt for permission inside the app if avoidable!!

我的清单包含-

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

我从片段中截取的代码是-

My snipped code from the Fragment is -

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错误是

My actual Logcat error is

W/Binder:从活页夹存根实现中捕获了RuntimeException. java.lang.SecurityException:需要ACCESS_COARSE_LOCATION或ACCESS_FINE_LOCATION权限才能获取扫描结果

W/Binder﹕ Caught a RuntimeException from the binder stub implementation. java.lang.SecurityException: Need ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission to get scan results

推荐答案

要弄清要求是不同的,具体取决于您是否在build.gradle文件中设置了targetSdkVersion 23.

To clarify the requirement is different depending on whether you set targetSdkVersion 23 in your build.gradle file.

如果您定位的是SDK 23(棉花糖)或更高版本:

  • 您必须在清单中声明android.permission.ACCESS_COARSE_LOCATION或android.permission.ACCESS_FINE_LOCATION.
  • 您必须按照我的博客文章
  • You must declare android.permission.ACCESS_COARSE_LOCATION or android.permission.ACCESS_FINE_LOCATION in your manifest.
  • You must prompt a user for permission as described in my blog post here.
  • The user must accept this permission and not turn it off.
  • If any of the above requirements are not met, you won't be able to detect beacons in the foreground or the background.

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

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

此处此处了解详情.

这篇关于不后台监控时是否提示位置许可?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆