Android Preview M: activity recreates after permission grant

烂漫一生 提交于 2019-12-21 07:15:17

问题


I play around with the Preview M and test my app on it, especially the "saving a file to external storage" part. Before the download/save process starts, i request for

  Manifest.permission.WRITE_EXTERNAL_STORAGE

permission as described on the developer page: https://developer.android.com/preview/features/runtime-permissions.html

The dialog occurs as expected:

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

If i hit the "deny"-button, the onRequestPermissionsResult-method of the activity is called.

If i press the "allow"-button, the activity is first recreated and afterwards the onRequestPermissionsResult-method is called. I think it's a result of the granted permission.

But the second situation is tricky because i want to trigger a callback that starts the download, but this object is null at this point:

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

So my questions are:

  1. Can I avoid this recreation?
  2. If no, how can i redesign my code to solve the problem - i'm totally idealess at the moment

EDIT 1:

I tried to solve the problem with a handler and postDelayed - but i skipped it.

EDIT 2:

I preliminary solved it and show a Toast to user with the request to push the download button again (in case of granted permission). But Google: ARE YOU SERIOUS?

EDIT 3:

No recreation happens with the latest SDK 6.0 (Version 23) - maybe somebody heard my weeping in Mountain View :-)


回答1:


You can always check the download condition immediately after the activity recreates itself in 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 may destroy and recreate your activity for a number of reasons. The use case of requesting permissions is no exception. You can use your preferred way of saving and restoring UI state. If your state is parcelable you can do it like the example below. Why this is not mentioned in Request App Permissions or Android RuntimePermissions Sample I don't know.

See more in Saving and restoring transient UI state and Saving 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
    }
}


来源:https://stackoverflow.com/questions/31432534/android-preview-m-activity-recreates-after-permission-grant

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!