【问题标题】:ActivityCompat.requestPermissions does not show promptActivityCompat.requestPermissions 不显示提示
【发布时间】:2016-09-05 13:10:55
【问题描述】:

我正在尝试请求ACCESS_FINE_LOCATION 权限以获取用户的当前位置。

我的日志显示我的应用在查询ContextCompat.checkSelfPermission()时当前没有此权限,但在调用ActivityCompat.requestPermissions()时没有显示任何内容。

我的 Google 地图代码(实现 OnMapReadyCallbackActivityCompat.OnRequestPermissionsResultCallback())在 FragmentActivity 中。

我已经设法让requestPermissions() 功能在应用程序的其他活动中成功运行,它只是带有谷歌地图的那个。放在ActivityonCreate() 方法或onMapReady()(它需要去的地方)中时,它不起作用。

if(ContextCompat.checkSelfPermission(LocationActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        Log.d(TAG, "not granted");
        final String[] permissions = new String[] {android.Manifest.permission.ACCESS_FINE_LOCATION};
    if(ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.ACCESS_FINE_LOCATION)) {
            Log.d(TAG, "rationale");
            // Explain to the user why permission is required, then request again
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage("We need permissions")
                    .setCancelable(false)
                    .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int id) {
                            ActivityCompat.requestPermissions(LocationActivity.this, permissions, 1);
                    }
                });
        AlertDialog alert = builder.create();
        alert.show();

    } else {
        Log.d(TAG, "request" + android.Manifest.permission.ACCESS_FINE_LOCATION);
        // If permission has not been denied before, request the permission
        ActivityCompat.requestPermissions(LocationActivity.this, permissions, 1);
    }
} else {
    Log.d(TAG, "granted");
}

有什么想法吗?是否与我的 Activity 类 (FragmentActivity) 有关,或者可能是 Google 地图异步调用权限请求?

【问题讨论】:

  • 我很惊讶这个编译。 checkSelfPermission() 使用 LocationActivity.this。第二个requestPermissions() 使用PermissionsRequestActivity.this
  • 对不起,我不得不稍微更改我的代码以发布,第二个应该是 LocationActivity.this
  • 我一直在尝试在一个单独的 Activity 中创建所有 requestPermissions,但这使得回调变得困难,而且很hacky。
  • FWIW,this sample app 使用运行时权限没有问题。
  • 你不应该在清单中指定finelocation吗?或者android在去年发生了彻底的变化?

标签: java android google-maps android-fragments android-permissions


【解决方案1】:

在完全删除我的类后,它仍然无法正常工作,我意识到这个 Activity 正在使用 TabHost 实例化。

当我停止使用 TabHost 时,提示显示成功。我猜新的权限提示不支持 TabHosts - 这是一个错误吗?

App requests aren't showing up一样的问题

我最终创建了一个 PermissionsRequestActivity,它代表我的 TabHost 处理权限请求和响应,然后退出(通过 Intent extras Bundle 传递请求的权限信息)。
它将对请求的响应作为广播传回,由我的 TabHost 接收。

有点破解,但工作正常!

【讨论】:

  • 同上 - 使用 TabHost 也没有显示给我。有人知道怎么处理吗?
  • 我最终创建了一个 PermissionsRequestActivity,它代表我的 TabHost 处理权限请求和响应,然后退出(通过 Intent extras Bundle 传递请求的权限信息)。它将对请求的响应作为广播传回,由我的 TabHost 接收。有点破解,但工作正常!
  • 澄清一下,TabActivity 本身可以很好地处理权限请求,但是作为选项卡托管在其中的任何活动都不能。所以我能够通过将消息发布到主要活动然后返回片段来解决这个问题。
【解决方案2】:

检查您是否已经像之前的 Android M 一样在 Android 的清单文件中添加了请求的权限,只有这样您才能获得预期的行为。

将权限添加到您的清单,以便您可以通过 ActivityCompat.requestPermissions:

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

【讨论】:

  • 谢谢,我有这个;在应用程序的其他地方,权限请求已成功显示。我找到了原因,请参阅上面的答案。
【解决方案3】:

我将分享适合我的代码。在我想要查看提示的活动的 protected void onCreate(Bundle savedInstanceState) {} 方法中,我包含了以下代码:

    /* Check whether the app has the ACCESS_FINE_LOCATION permission and whether the app op that corresponds to
     * this permission is allowed. The return value is an int: The permission check result which is either
     * PERMISSION_GRANTED or PERMISSION_DENIED or PERMISSION_DENIED_APP_OP.
     * Source: https://developer.android.com/reference/android/support/v4/content/PermissionChecker.html
     * While testing, the return value is -1 when the "Your location" permission for the App is OFF, and 1 when it is ON.
     */
    int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
    // The "Your location" permission for the App is OFF.
    if (permissionCheck == -1){
        /* This message will appear: "Allow [Name of my App] to access this device's location?"
         * "[Name of my Activity]._instance" is the activity.
         */
        ActivityCompat.requestPermissions([Name of my Activity]._instance, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE_ACCESS_FINE_LOCATION);
    }else{
        // The "Your location" permission for the App is ON.
        if (permissionCheck == 0){
        }
    }

在受保护的 void onCreate(Bundle savedInstanceState) {} 方法之前,我创建了以下常量和方法:

public static final int REQUEST_CODE_ACCESS_FINE_LOCATION = 1; // For implementation of permission requests for Android 6.0 with API Level 23.

// Code from "Handle the permissions request response" at https://developer.android.com/training/permissions/requesting.html.
@Override
public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {
    switch (requestCode) {
        case REQUEST_CODE_ACCESS_FINE_LOCATION: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay! Do the
                // location-related task you need to do.                

            } else {

                // permission denied, boo! Disable the
                // functionality that depends on this permission.
            }
            return;
        }

        // other 'case' lines to check for other
        // permissions this app might request
    }
}

【讨论】:

    【解决方案4】:

    我在使用 TabHost 的项目中遇到了同样的问题。 基于@Robin 解决方案,我使用 EventBus 库将消息从子活动发送到 TabActity。

    事件总线:https://github.com/greenrobot/EventBus

    创建一个事件对象:

    public class MessageEvent {
        private String message;
        public MessageEvent(String message){
            this.message = message;
        }
    
        public String getMessage(){
            return this.message;
        }
    }
    

    在您的主要活动中:

    private EventBus eventBus = EventBus.getDefault();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        eventBus.register(this);
    }
    @Override
    protected void onDestroy() {
        eventBus.unregister(this);
        super.onDestroy();
    }
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(MessageEvent event) {
        if (event.getMessage().equals("contacts")){
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && checkSelfPermission(android.Manifest.permission.WRITE_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(MainPage.this,new String[]{android.Manifest.permission.WRITE_CONTACTS}, 100 );
            }
        }
    };
    

    为您要请求的权限设置不同的消息。 在您的孩子活动中,您可以发布足够的信息:

    EventBus.getDefault().post(new MessageEvent("contacts"));
    

    注意 onRequestPermissionsResult 回调和请求代码 ;)!它只适用于主要活动。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-05-30
      • 2017-07-03
      • 2011-04-06
      • 2020-03-22
      • 2019-07-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多