【问题标题】:Android Preview M: activity recreates after permission grantAndroid Preview M:授予权限后重新创建活动
【发布时间】:2015-10-04 14:52:11
【问题描述】:

我使用 Preview M 并在上面测试我的应用程序,尤其是“将文件保存到外部存储”部分。 在下载/保存过程开始之前,我要求

  Manifest.permission.WRITE_EXTERNAL_STORAGE

开发者页面上描述的权限:https://developer.android.com/preview/features/runtime-permissions.html

对话框按预期出现:

"Allow <AppName> to access photos, media, and files on your device?" Deny / Allow

如果我点击“拒绝”按钮,则调用活动的 onRequestPermissionsResult 方法。

如果我按下“允许”按钮,则首先重新创建活动,然后调用 onRequestPermissionsResult 方法。我认为这是授予权限的结果。

但是第二种情况比较棘手,因为我想触发一个开始下载的回调,但是此时这个对象为空:

public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {

    getLogger().error("onRequestPermissionsResult ( " + requestCode + ", " + permissions + ", " + grantResults + " )");
    switch (requestCode) {


        //permission for saving files?
        case PermissionCode.WRITE_EXTERNAL_STORAGE: {


            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                //HERE IS THE NULL-OBJECT 
                if (controller != null) {

                    controller.triggerCallback();
                }
            }
            break;
        }
        default: {

            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }
}

所以我的问题是:

  1. 我可以避免这种消遣吗?
  2. 如果不是,我该如何重新设计我的代码来解决问题 - 我现在完全没有想法

编辑 1:

我尝试使用处理程序和 postDelayed 来解决问题 - 但我跳过了它。

编辑 2:

我初步解决了这个问题,并向用户展示了一个 Toast,请求再次按下下载按钮(在获得许可的情况下)。但是谷歌:你是认真的吗?

编辑 3:

最新的 SDK 6.0(第 23 版)没有任何乐趣 - 也许有人听到了我在山景城的哭泣 :-)

【问题讨论】:

  • 嘿,你最后是怎么解决的?我也在使用版本 23 进行编译,但我仍然面临在允许和拒绝权限时重新启动活动。永远不会调用 onRequestPermissionsResult 方法。我正在从片段中调用 requestPermissions() 。这有什么区别吗?
  • @Mayur More:你如何撤销/授予权限?在应用程序设置内撤销/授予时,恢复应用程序后我仍然有娱乐。但是在应用程序工作流程内部 - 如上所述 - 没有重新发生......
  • 截至 2016 年 1 月,我仍在观察这个游戏。
  • 当我拒绝许可时,我遇到了这个问题。允许权限工作正常。

标签: android android-activity permissions preview


【解决方案1】:

您可以随时在onCreate() 中重新创建活动后立即检查下载情况:

static final int MY_PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 0;
boolean initiateDownload = false;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if(savedInstanceState != null) {
        initiateDownload = savedInstanceState.getBoolean("toDownload");
    }
}

@Override
public void onResume() {
    super.onResume();
    final boolean hasPermission = checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
            == PackageManager.PERMISSION_GRANTED;
    if(initiateDownload && hasPermission) {
        // start download here...
    } else {
        requestPermissions(new String[]{WRITE_EXTERNAL_STORAGE},
                MainActivity.MY_PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE);
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if(requestCode == MY_PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE) {
        if(grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            initiateDownload = true;
        } else {
            // denied permission...
        }
    }
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putBoolean("toDownload", initiateDownload);
}

【讨论】:

    【解决方案2】:

    出于多种原因,Android 可能会破坏并重新创建您的 Activity。请求权限的用例也不例外。您可以使用您喜欢的方式来保存和恢复 UI 状态。如果你的状态是可包裹的,你可以像下面的例子那样做。为什么Request App PermissionsAndroid RuntimePermissions Sample 中没有提到这一点我不知道。

    查看更多内容 Saving and restoring transient UI stateSaving UI States

    public class ExampleActivity extends AppCompatActivity {
        private static final String CURRENT_DOWNLOAD_ITEM = "CURRENT_DOWNLOAD_ITEM";
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            if (savedInstanceState != null)
                currentDownloadItem = savedInstanceState.getParcelable(CURRENT_DOWNLOAD_ITEM);
        }
    
        @Override
        protected void onSaveInstanceState(Bundle outState) {
            outState.putParcelable(CURRENT_DOWNLOAD_ITEM, currentDownloadItem);
            super.onSaveInstanceState(outState);
        }
    
        public void downloadItem(Parcelable item) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
                    checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                currentDownloadItem = item;
                requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
            } else
                perfornDownload(item);
        }
    
        private Parcelable currentDownloadItem;
    
        @Override
        public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
            switch (requestCode) {
                case 1:
                    if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                        if (currentDownloadItem != null) {
                            perfornDownload(currentDownloadItem);
                            currentDownloadItem = null;
                        } else
                            Toast.makeText(this, "Please select download again now that we have permission to save it", Toast.LENGTH_LONG).show();
                    } else
                        Toast.makeText(this, "Download cancelled, as we don\'t have permission to save the downloaded files", Toast.LENGTH_LONG).show();
                    break;
            }
        }
    
        private void perfornDownload(Parcelable item) {
            // Here we are sure we have the permission
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-19
      • 1970-01-01
      相关资源
      最近更新 更多