运行时请求权限,Android M+

7
首先,我知道这是一个重复的问题,但是我已经查看了其他类似问题的答案,并没有成功找到任何解决方案。
我开发了一个应用程序,在我的测试设备上完美运行,该设备是Samsung S4运行Android L(5.0.1),但是我希望此应用程序也能在更新的Android版本上运行。
我知道请求权限已经改变为在Android M+中必须在运行时请求,但当我尝试实现此操作时,对话框从未出现,因此未要求所需的权限。
我请求的权限是ACCESS_FINE_LOCATION。
以下是来自我的清单文件的相关代码:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

如果权限尚未被授予,我会在哪里请求权限:

if (ActivityCompat.checkSelfPermission(MapsActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {

    startGeofenceMonitoring();

} else {
    askForPermission(android.Manifest.permission.ACCESS_FINE_LOCATION,LOCATION);
}

askForPermission函数(略有修改自谷歌的例子):

private void askForPermission(String permission, Integer requestCode) {
    if (ContextCompat.checkSelfPermission(MapsActivity.this, permission) != PackageManager.PERMISSION_GRANTED) {

        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(MapsActivity.this, permission)) {

            //This is called if user has denied the permission before
            //In this case I am just asking the permission again
            ActivityCompat.requestPermissions(MapsActivity.this, new String[]{permission}, requestCode);

        } else {

            Log.d(TAG, "askForPermission: " + permission);

            ActivityCompat.requestPermissions(MapsActivity.this, new String[]{permission}, requestCode);
        }
    } else {
        Toast.makeText(this, "" + permission + " is already granted.", Toast.LENGTH_SHORT).show();
    }
}

而onRequestPermissionsResult函数:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    Log.d(TAG, "onRequestPermissionsResult: " + requestCode);

        switch (requestCode) {
            case 1:
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                    Log.d(TAG, "onRequestPermissionsResult: request");

                    Toast.makeText(this, "Permission granted", Toast.LENGTH_SHORT).show();

                    startGeofenceMonitoring();
                }
                break;
        }
}

正如我所说的那样,要求权限的对话框从未出现,但是我的控制台告诉我调用了ActivityCompat.requestPermissions(MapsActivity.this, new String[]{permission}, requestCode);,经过大量研究,我仍然不确定为什么它不起作用。我认为唯一可能的原因是此Activity是一个Fragment activity,显示谷歌地图。我确实尝试在另一个activity中请求权限,但发生完全相同的情况。
谢谢。
编辑
所以我刚刚在一个全新的项目中测试了我发布在这里的代码,它运行得很好并显示了对话框。我现在真的很困惑,不知道什么阻止了该对话框在我的当前项目中显示。

2
尝试完全卸载您的应用程序,然后重新安装它。也许在测试中,当被询问时您拒绝了权限两次,此后Android将停止显示对话框。 - CommonsWare
刚试了一下,不幸的是它没有解决问题。 - Haris
3个回答

3
final private int REQUEST_CODE_ASK_PERMISSIONS = 123;

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

private void requestPermission() {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ) {
        ActivityCompat
                .requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE_ASK_PERMISSIONS);
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    switch (requestCode) {
        case REQUEST_CODE_ASK_PERMISSIONS:
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Permission Granted
                Toast.makeText(MainActivity.this, "Permission Granted", Toast.LENGTH_SHORT)
                        .show();
            } else {
                // Permission Denied
                Toast.makeText(MainActivity.this, "Permission Denied", Toast.LENGTH_SHORT)
                        .show();
            }
            break;
        default:
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

这仍然给我带来了完全相同的问题。没有对话框。 - Haris
请检查您的设备是否支持运行时权限。(尝试使用另一个新设备) - Sameera Jayarathna
谢谢,但我已经解决了。我在这里发布了我的解决方案。 - Haris

0
以下代码对我有效。
public static final int MY_PERMISSION_REQUEST_READ_EXTERNAL_STORAGE=1;

 public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
    View view=inflater.inflate(R.layout.activity_tracks,container,false);

    getPermission();
        ...
          }

 public void getPermission(){
        if(ContextCompat.checkSelfPermission(getActivity(),Manifest.permission.READ_EXTERNAL_STORAGE)!=PackageManager.PERMISSION_GRANTED){
            if(ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),Manifest.permission.READ_EXTERNAL_STORAGE)){

            }else{
                ActivityCompat.requestPermissions(getActivity(),new String[] {Manifest.permission.READ_EXTERNAL_STORAGE},MY_PERMISSION_REQUEST_READ_EXTERNAL_STORAGE);
            }
        }else{
            getSongDetails();
        }
    }


 @Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode){
        case -1:
            //hello
            break;
        case MY_PERMISSION_REQUEST_READ_EXTERNAL_STORAGE:
            if(grantResults.length>0 && grantResults[0]==PackageManager.PERMISSION_GRANTED){
                getPermission();
            }else{
                Toast.makeText(getActivity(),"You've denied permission",Toast.LENGTH_LONG).show();
            }
            return;
        default:
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

}

0

我成功修复了它!

在我的应用程序中,我使用了不同的活动来控制选项卡和向用户显示的活动。这是要显示的第一个活动,我认为它是整个程序中唯一显示的活动,但只显示其他活动的内容。因此,当我请求MapsActivity的权限时,它没有显示,因为MapsActivity实际上并不存在。

我的解释可能有误,因此这是我的TabBarActivity代码:

    TabHost tabHost = getTabHost();
    TabHost.TabSpec spec;
    Intent intent;

    intent = new Intent().setClass(this, SecondActivity.class);
    spec = tabHost.newTabSpec("Second").setIndicator("Profile")
            .setContent(intent);
    tabHost.addTab(spec);

    intent = new Intent().setClass(this, MapsActivity.class);
    spec = tabHost.newTabSpec("First").setIndicator("Location")
            .setContent(intent);
    tabHost.addTab(spec);

    intent = new Intent().setClass(this, ThirdActivity.class);
    spec = tabHost.newTabSpec("Third").setIndicator("Settings")
            .setContent(intent);
    tabHost.addTab(spec);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接