权限检查申请小框架

Android应用程序为了用户的安全,引入相关的权限机制,如何在应用中有效检查权限,而不需要每个地方都重复性的进行检查、请求、回调的编码呢?

思路:应用中A activity进行权限检查,无权限启动一个专门的权限activity,申请权限,完成后,再启动原A activity.

1. 自定义基类 RequestPermissionsActivityBase

/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.jxh.activities;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Trace;
import android.support.v4.app.ActivityCompat;
import android.util.Log;

import java.util.ArrayList;
import java.util.Arrays;

/**
 * Activity that asks the user for all {@link #getPermissions} if any are missing.
 *
 * NOTE: As a result of b/22095159, this can behave oddly in the case where the final permission
 * you are requesting causes an application restart.
 */
public abstract class RequestPermissionsActivityBase extends Activity
        implements ActivityCompat.OnRequestPermissionsResultCallback {

    protected static final String TAG = "RequestPermissionsActivityBase";
    public static final String PREVIOUS_ACTIVITY_INTENT = "previous_intent";

    /** Whether the permissions activity was already started. */
    protected static final String EXTRA_STARTED_PERMISSIONS_ACTIVITY =
            "started_permissions_activity";

    protected static final String EXTRA_IS_CALLER_SELF = "is_caller_self";

    protected static final int PERMISSIONS_REQUEST_ALL_PERMISSIONS = 1;

    /**
     * @return list of permissions that are needed in order for {@link #PREVIOUS_ACTIVITY_INTENT}
     * to operate. You only need to return a single permission per permission group you care about.
     */
    protected abstract String[] getPermissions();

    protected Intent mPreviousActivityIntent;

    /** If true then start the target activity "for result" after permissions are granted. */
    protected boolean mIsCallerSelf;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mPreviousActivityIntent = (Intent) getIntent().getExtras().get(PREVIOUS_ACTIVITY_INTENT);
        mIsCallerSelf = getIntent().getBooleanExtra(EXTRA_IS_CALLER_SELF, false);

        // Only start a requestPermissions() flow when first starting this activity the first time.
        // The process is likely to be restarted during the permission flow (necessary to enable
        // permissions) so this is important to track.
        if (savedInstanceState == null) {
            requestPermissions();
        }
    }

    /**
     * If any permissions the app needs are missing, open an Activity
     * to prompt the user for these permissions. Moreover, finish the current activity.
     *
     * This is designed to be called inside {@link android.app.Activity#onCreate}
     */
    protected static boolean startPermissionActivity(Activity activity,
            String[] requiredPermissions, Class<?> newActivityClass) {
        return startPermissionActivity(activity, requiredPermissions, /* isCallerSelf */ false,
                newActivityClass);
    }

    protected static boolean startPermissionActivity(Activity activity,
                String[] requiredPermissions, boolean isCallerSelf, Class<?> newActivityClass) {
        if (!hasPermissions(activity, requiredPermissions)) {
            final Intent intent = new Intent(activity,  newActivityClass);
            activity.getIntent().putExtra(EXTRA_STARTED_PERMISSIONS_ACTIVITY, true);
            intent.putExtra(PREVIOUS_ACTIVITY_INTENT, activity.getIntent());
            intent.putExtra(EXTRA_IS_CALLER_SELF, isCallerSelf);
            activity.startActivity(intent);
            Log.d(TAG," startPermissionActivity() ... ,  finish activity: "+activity);
            activity.finish();
            return true;
        }

        return false;
    }

    protected boolean isAllGranted(String permissions[], int[] grantResult) {
        for (int i = 0; i < permissions.length; i++) {
            if (grantResult[i] != PackageManager.PERMISSION_GRANTED
                    && isPermissionRequired(permissions[i])) {
                return false;
            }
        }
        return true;
    }

    private boolean isPermissionRequired(String p) {
        return Arrays.asList(getPermissions()).contains(p);
    }

    private void requestPermissions() {
        Trace.beginSection("requestPermissions");
        try {
            // Construct a list of missing permissions
            final ArrayList<String> unsatisfiedPermissions = new ArrayList<>();
            for (String permission : getPermissions()) {
                if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
                    unsatisfiedPermissions.add(permission);
                }
            }
            if (unsatisfiedPermissions.size() == 0) {
                throw new RuntimeException("Request permission activity was called even"
                        + " though all permissions are satisfied.");
            }
            ActivityCompat.requestPermissions(
                    this,
                    unsatisfiedPermissions.toArray(new String[unsatisfiedPermissions.size()]),
                    PERMISSIONS_REQUEST_ALL_PERMISSIONS);
        } finally {
            Trace.endSection();
        }
    }

    protected static boolean hasPermissions(Context context, String[] permissions) {
        Trace.beginSection("hasPermission");
        try {
            for (String permission : permissions) {
                if (context.checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
                    return false;
                }
            }
            return true;
        } finally {
            Trace.endSection();
        }
    }
}

2. 自定义子类 RequestPermissionsActivity

/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.jxh.activities;

import android.Manifest.permission;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.widget.Toast;

import com.sprd.fileexplorer.R;

import java.util.ArrayList;
import java.util.List;

/**
 * Activity that requests permissions needed for activities exported from Our App by referencing Google Contacts App.
 */
public class RequestPermissionsActivity extends RequestPermissionsActivityBase {

    private static final String[] REQUIRED_PERMISSIONS = new String[] {
            permission.READ_EXTERNAL_STORAGE,
            permission.WRITE_EXTERNAL_STORAGE
    };

    public static boolean hasRequiredPermissions(Context context) {
        return hasPermissions(context, REQUIRED_PERMISSIONS);
    }

    @Override
    protected String[] getPermissions() {
        return REQUIRED_PERMISSIONS;
    }

    public static boolean startPermissionActivityIfNeeded(Activity activity) {
        return startPermissionActivity(activity,
                REQUIRED_PERMISSIONS,
                RequestPermissionsActivity.class);
    }

    @Override
    public void onRequestPermissionsResult(
            int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case PERMISSIONS_REQUEST_ALL_PERMISSIONS:
                if (permissions != null && permissions.length > 0
                        && isAllGranted(permissions, grantResults)) {
                    mPreviousActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
                    if (mIsCallerSelf) {
                        startActivityForResult(mPreviousActivityIntent, 0);
                    } else {
                        startActivity(mPreviousActivityIntent);
                    }
                    finish();
                    overridePendingTransition(0, 0);

                } else {
                    Toast.makeText(this, R.string.error_permissions, Toast.LENGTH_SHORT).show();
                    finish();
                }
                break;
            default:
                break;
        }
    }
}

3. 使用方法

应用Activity的onCreate()使用:

if(!RequestPermissionsActivity.hasRequiredPermissions(this)){

   RequestPermissionsActivity.startPermissionActivityIfNeeded(this);

   return;

}


猜你喜欢

转载自blog.csdn.net/snail201211/article/details/79752024