【问题标题】:Location permission compilation error位置权限编译错误
【发布时间】:2017-08-02 23:32:44
【问题描述】:

我确定我在这里获得了许可:

private void checkPermissions() {
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
            != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_LOCATION_REQUEST_CODE);
    } else {
        getLocation();
    }
}

private void getLocation() {
    LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
    LocationListener locationListener = new UserLocationListener();
    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 10, this);
}

但我仍然收到 requestLocationUpdates() 调用的编译错误:

Call requires permission which may be rejected by user: code should explicitly check to see if permission is available (with `checkPermission`) or explicitly handle a potential `SecurityException`

当我像这样删除函数调用时,错误得到解决:

private void checkPermissions() {
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
            != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_LOCATION_REQUEST_CODE);
    } else {
        LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
        LocationListener locationListener = new UserLocationListener();
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 10, this);
    }
}

不过我还需要在 onRequestPermissionsResult 回调中调用 getLocation 函数,所以我想保留它。

清单:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- Needed only if your app targets Android 5.0 (API level 21) or higher. -->
<uses-feature android:name="android.hardware.location.gps" />

这通常是如何解决的?

【问题讨论】:

    标签: android android-permissions android-gps runtime-permissions


    【解决方案1】:

    像这样管理这些权限是一场噩梦。我建议你使用这个库来处理所有样板文件。 只需很少的 RXJava 知识就可以做到这一点 https://github.com/tbruyelle/RxPermissions

    compile 'com.tbruyelle.rxpermissions:rxpermissions:0.9.3@aar'
    

    然后:

    final String permission = Manifest.permission.ACCESS_FINE_LOCATION;
    rxPermissions
    .request(permission)
    .switchMap(new Func1<Boolean, Observable<Boolean>>() {
        @Override
        public Observable<Boolean> call(Boolean permissionGranted) {
            if (permissionGranted) {
                //todo: do stuff require permissions.
            } else {
                rxPermissions.shouldShowRequestPermissionRationale(activity, permission).switchMap(
                new Func1<Boolean, Observable<Boolean>>() {
                    @Override
                    public Observable<Boolean> call(Boolean canShowRationale) {
                        if (canShowRationale) {
                            /**
                             * when user deny permission,Show dialog explaining why permission is
                             * necessary. On Selecting Ask again, permission access will be
                             * re-requested.
                             */
    
                            //todo: 
                        } else {
                            /**
                             * When user deny permission and select Never Ask Again, Show dialog
                             * explaining why permission are necessary. In this case user need to
                             * go to settings and grant permission.
                             */
    
                            //todo: 
                        }
                    }
                });
              }
        }
    });
    

    【讨论】:

    • 太棒了。我很想看看,但我的老板讨厌任何第三方。
    • 嗯,好的。我刚刚修改了带有位置请求的示例
    • “我的老板讨厌任何第三方”。除非您在一个非常特殊的环境中工作,证明这种厌恶是合理的,否则您的老板需要意识到所有应用程序都使用第三方库,这是快速发布内容的唯一方法,并且需要更少的代码来维护自己。
    【解决方案2】:

    对于非反应式方法,这个库将非常有帮助,它使用简单的基于注释的 API 来处理运行时权限:

    https://github.com/hotchemi/PermissionsDispatcher

    @RuntimePermissions
    public class MainActivity extends AppCompatActivity {
    
        @NeedsPermission(Manifest.permission.CAMERA)
        void showCamera() {
            getSupportFragmentManager().beginTransaction()
                    .replace(R.id.sample_content_fragment, CameraPreviewFragment.newInstance())
                    .addToBackStack("camera")
                    .commitAllowingStateLoss();
        }
    
        @OnShowRationale(Manifest.permission.CAMERA)
        void showRationaleForCamera(final PermissionRequest request) {
            new AlertDialog.Builder(this)
                .setMessage(R.string.permission_camera_rationale)
                .setPositiveButton(R.string.button_allow, (dialog, button) -> request.proceed())
                .setNegativeButton(R.string.button_deny, (dialog, button) -> request.cancel())
                .show();
        }
    
        @OnPermissionDenied(Manifest.permission.CAMERA)
        void showDeniedForCamera() {
            Toast.makeText(this, R.string.permission_camera_denied, Toast.LENGTH_SHORT).show();
        }
    
        @OnNeverAskAgain(Manifest.permission.CAMERA)
        void showNeverAskForCamera() {
            Toast.makeText(this, R.string.permission_camera_neverask, Toast.LENGTH_SHORT).show();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2017-09-23
      • 2018-09-08
      • 2019-08-10
      • 2014-12-06
      • 2012-05-14
      • 1970-01-01
      • 2013-03-01
      • 2013-08-25
      • 2017-04-30
      相关资源
      最近更新 更多