在运行时请求权限,Android M+

Posted

技术标签:

【中文标题】在运行时请求权限,Android M+【英文标题】:Asking for permissions at run-time, Android M+ 【发布时间】:2017-07-25 07:48:56 【问题描述】:

首先,我知道这是一个重复的问题,但我已经研究过其他类似问题的答案,并且无法通过任何这些解决方案找到成功。

我开发了一个应用程序,它可以在我的测试设备上完美运行,该设备是运行 android L (5.0.1) 的三星 S4,但是我希望这个应用程序也可以在较新版本的 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 函数(根据 Google 的示例稍作修改):

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); 被调用,经过大量研究,我仍然不确定为什么它不起作用.我认为这可能是由于这个活动是一个显示谷歌地图地图的片段活动。我确实尝试在另一个活动中请求权限,但发生了完全相同的事情。

谢谢。

编辑

所以我刚刚在一个全新的项目中测试了我在此处发布的代码,它运行良好并显示了对话框。我现在真的很困惑是什么阻止了这个对话框在我当前的项目中显示。

【问题讨论】:

尝试完全卸载您的应用,然后重新安装。也许在测试中,当被问及两次拒绝权限时,Android 将停止显示对话框。 刚试过这个,很遗憾没有解决问题。 【参考方案1】:
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);
    

【讨论】:

这仍然给我同样的问题。没有对话框。 请检查您的设备是否支持运行时权限。 (换个新设备试试) 谢谢,但我能够修复它。我在这里发布了我的解决方案。【参考方案2】:

我设法解决了它!

在我的应用程序中,我使用了不同的活动来控制选项卡以及向用户显示的活动。这是要显示的第一个活动,我认为这是整个程序中唯一显示的活动,但仅显示其他活动的内容。因此,当我请求 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);

【讨论】:

【参考方案3】:

下面的代码对我有用。

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);
    


【讨论】:

以上是关于在运行时请求权限,Android M+的主要内容,如果未能解决你的问题,请参考以下文章

我们如何区分 Android M 的运行时权限中的从不询问和停止询问?

Android M(6.0) 权限爬坑之旅

请求运行时权限时检查 Android 版本

Android M新的运行时权限开发者需要知道的一切

何时在运行时请求 Android Marshmallow 6.0 的权限?

如何在 Android M 或更高版本中在运行时更改权限时防止重新创建 Activity