1. 程式人生 > >Android-動態申請許可權-及開啟許可權設定

Android-動態申請許可權-及開啟許可權設定

一:

package com.vitamio.dome;

/**
 * 許可權申請介面 再 Activity 中實現該介面
 * 在 要申請許可權的Activity 中實現此介面
 */
public interface PermissionInterface {
    /**
     * 可設定請求許可權請求碼
     * 設定許可權請求requestCode,只要不跟onRequestPermissionsResult方法中的其他請求碼衝突即可。
     * 可以自己建立一個 請求碼的管理類,將專案中所有的請求碼寫在這個類中,做統一管理
     */
    int getPermissionsRequestCode();

    /**
     * 設定需要請求的許可權
     */
    String[] getPermissions();

    /**
     * 請求許可權成功回撥
     */
    void requestPermissionsSuccess();

    /**
     * 請求許可權失敗回撥
     */
    void requestPermissionsFail();

}

二:許可權工具類,提取公共方法

package com.vitamio.dome;

import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;

import java.util.ArrayList;

/**
 * 動態許可權工具類
 */
public class PermissionUtil {
    /**
     * Main的許可權請求返回碼
     */
    public static int mainPermissionCode = 1000;
    /**
     * 判斷是否有某個許可權
     * @param context
     * @param permission
     * @return
     */
    public static boolean hasPermission(Context context, String permission){
        //Build.VERSION.SDK_INT :獲取當前手機的 android 版本
        //6.0以上才進行檢測
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if(context.checkSelfPermission(permission)  != PackageManager.PERMISSION_GRANTED){
                return false;
            }
        }
        return true;
    }

    /**
     * 彈出對話方塊請求許可權
     * @param activity
     * @param permissions
     * @param requestCode
     */
    public static void requestPermissions(Activity activity, String[] permissions, int requestCode){
        //Build.VERSION.SDK_INT :獲取當前手機的 android 版本
        //6.0以上才進行請求
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            activity.requestPermissions(permissions, requestCode);
        }
    }

    /**
     * 返回缺失的許可權
     * @param context
     * @param permissions
     * @return 返回缺少的許可權,null 意味著沒有缺少許可權
     */
    public static String[] getDeniedPermissions(Context context, String[] permissions){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            ArrayList<String> deniedPermissionList = new ArrayList<>();
            for(String permission : permissions){
                if(context.checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED){
                    deniedPermissionList.add(permission);
                }
            }
            int size = deniedPermissionList.size();
            if(size > 0){
                return deniedPermissionList.toArray(new String[deniedPermissionList.size()]);
            }
        }
        return null;
    }
}

三:許可權被拒絕後開啟許可權設定工具類

package com.vitamio.dome;

import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import android.util.Log;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;

/**
 * 開啟許可權設定介面
 */
public class PermissionPageUtils {
    private final String TAG = "PermissionPageManager";
    private Context mContext;
    //自己的專案包名
    private String packageName="com.vitamio.dome";

    public PermissionPageUtils(Context context) {
        this.mContext = context;
    }

    /**
     * 進入許可權設定介面
     */
    public void OpenPermissionPage() {
        String name = Build.MANUFACTURER;
        Log.e(TAG, "jumpPermissionPage --- name : " + name);
        switch (name) {
            case "HUAWEI":
                goHuaWeiMainager();
                break;
            case "vivo":
                goVivoMainager();
                break;
            case "OPPO":
                goOppoMainager();
                break;
            case "Coolpad":
                goCoolpadMainager();
                break;
            case "Meizu":
                goMeizuMainager();
                break;
            case "Xiaomi":
                goXiaoMiMainager();
                break;
            case "samsung":
                goSangXinMainager();
                break;
            case "Sony":
                goSonyMainager();
                break;
            case "LG":
                goLGMainager();
                break;
            default:
                goIntentSetting();
                break;
        }
    }

    private void goLGMainager(){
        try {
            Intent intent = new Intent(packageName);
            ComponentName comp = new ComponentName("com.android.settings", "com.android.settings.Settings$AccessLockSummaryActivity");
            intent.setComponent(comp);
            mContext.startActivity(intent);
        } catch (Exception e) {
            Toast.makeText(mContext, "跳轉失敗", Toast.LENGTH_LONG).show();
            e.printStackTrace();
            goIntentSetting();
        }
    }
    private void goSonyMainager(){
        try {
            Intent intent = new Intent(packageName);
            ComponentName comp = new ComponentName("com.sonymobile.cta", "com.sonymobile.cta.SomcCTAMainActivity");
            intent.setComponent(comp);
            mContext.startActivity(intent);
        } catch (Exception e) {
            Toast.makeText(mContext, "跳轉失敗", Toast.LENGTH_LONG).show();
            e.printStackTrace();
            goIntentSetting();
        }
    }

    private void goHuaWeiMainager() {
        try {
            Intent intent = new Intent(packageName);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            ComponentName comp = new ComponentName("com.huawei.systemmanager", "com.huawei.permissionmanager.ui.MainActivity");
            intent.setComponent(comp);
            mContext.startActivity(intent);
        } catch (Exception e) {
            Toast.makeText(mContext, "跳轉失敗", Toast.LENGTH_LONG).show();
            e.printStackTrace();
            goIntentSetting();
        }
    }

    private static String getMiuiVersion() {
        String propName = "ro.miui.ui.version.name";
        String line;
        BufferedReader input = null;
        try {
            Process p = Runtime.getRuntime().exec("getprop " + propName);
            input = new BufferedReader(
                    new InputStreamReader(p.getInputStream()), 1024);
            line = input.readLine();
            input.close();
        } catch (IOException ex) {
            ex.printStackTrace();
            return null;
        } finally {
            try {
                input.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return line;
    }

    private void goXiaoMiMainager() {
        String rom = getMiuiVersion();
        Log.e(TAG,"goMiaoMiMainager --- rom : "+rom);
        Intent intent=new Intent();
        if ("V6".equals(rom) || "V7".equals(rom)) {
            intent.setAction("miui.intent.action.APP_PERM_EDITOR");
            intent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.AppPermissionsEditorActivity");
            intent.putExtra("extra_pkgname", packageName);
        } else if ("V8".equals(rom) || "V9".equals(rom)) {
            intent.setAction("miui.intent.action.APP_PERM_EDITOR");
            intent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.PermissionsEditorActivity");
            intent.putExtra("extra_pkgname", packageName);
        } else {
            goIntentSetting();
        }
        mContext.startActivity(intent);
    }

    private void goMeizuMainager() {
        try {
            Intent intent = new Intent("com.meizu.safe.security.SHOW_APPSEC");
            intent.addCategory(Intent.CATEGORY_DEFAULT);
            intent.putExtra("packageName", packageName);
            mContext.startActivity(intent);
        } catch (ActivityNotFoundException localActivityNotFoundException) {
            localActivityNotFoundException.printStackTrace();
            goIntentSetting();
        }
    }

    private void goSangXinMainager() {
        //三星4.3可以直接跳轉
        goIntentSetting();
    }

    private void goIntentSetting() {
        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        Uri uri = Uri.fromParts("package", mContext.getPackageName(), null);
        intent.setData(uri);
        try {
            mContext.startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void goOppoMainager() {
        doStartApplicationWithPackageName("com.coloros.safecenter");
    }

    /**
     * doStartApplicationWithPackageName("com.yulong.android.security:remote")
     * 和Intent open = getPackageManager().getLaunchIntentForPackage("com.yulong.android.security:remote");
     * startActivity(open);
     * 本質上沒有什麼區別,通過Intent open...開啟比呼叫doStartApplicationWithPackageName方法更快,也是android本身提供的方法
     */
    private void goCoolpadMainager() {
        doStartApplicationWithPackageName("com.yulong.android.security:remote");
      /*  Intent openQQ = getPackageManager().getLaunchIntentForPackage("com.yulong.android.security:remote");
        startActivity(openQQ);*/
    }

    private void goVivoMainager() {
        doStartApplicationWithPackageName("com.bairenkeji.icaller");
     /*   Intent openQQ = getPackageManager().getLaunchIntentForPackage("com.vivo.securedaemonservice");
        startActivity(openQQ);*/
    }


    private void doStartApplicationWithPackageName(String packagename) {
        // 通過包名獲取此APP詳細資訊,包括Activities、services、versioncode、name等等
        PackageInfo packageinfo = null;
        try {
            packageinfo = mContext.getPackageManager().getPackageInfo(packagename, 0);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        if (packageinfo == null) {
            return;
        }
        // 建立一個類別為CATEGORY_LAUNCHER的該包名的Intent
        Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null);
        resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER);
        resolveIntent.setPackage(packageinfo.packageName);
        // 通過getPackageManager()的queryIntentActivities方法遍歷
        List<ResolveInfo> resolveinfoList = mContext.getPackageManager()
                .queryIntentActivities(resolveIntent, 0);
        Log.e("PermissionPageManager", "resolveinfoList" + resolveinfoList.size());
        for (int i = 0; i < resolveinfoList.size(); i++) {
            Log.e("PermissionPageManager", resolveinfoList.get(i).activityInfo.packageName + resolveinfoList.get(i).activityInfo.name);
        }
        ResolveInfo resolveinfo = resolveinfoList.iterator().next();
        if (resolveinfo != null) {
            // packageName引數2 = 引數 packname
            String packageName = resolveinfo.activityInfo.packageName;
            // 這個就是我們要找的該APP的LAUNCHER的Activity[組織形式:packageName引數2.mainActivityname]
            String className = resolveinfo.activityInfo.name;
            // LAUNCHER Intent
            Intent intent = new Intent(Intent.ACTION_MAIN);
            intent.addCategory(Intent.CATEGORY_LAUNCHER);
            // 設定ComponentName引數1:packageName引數2:MainActivity路徑
            ComponentName cn = new ComponentName(packageName, className);
            intent.setComponent(cn);
            try {
                mContext.startActivity(intent);
            } catch (Exception e) {
                goIntentSetting();
                e.printStackTrace();
            }
        }
    }
}

四:動態許可權幫助類,在Activity中呼叫該類進行動態許可權申請

package com.vitamio.dome;

import android.app.Activity;
import android.content.pm.PackageManager;
import android.support.annotation.NonNull;

/**
 * 動態許可權幫助類,在Activity中呼叫該類進行動態許可權申請
 */
public class PermissionHelper {
    private Activity mActivity;
    private PermissionInterface mPermissionInterface;

    public PermissionHelper(@NonNull Activity activity, @NonNull PermissionInterface permissionInterface) {
        mActivity = activity;
        mPermissionInterface = permissionInterface;
    }

    /**
     * 開始請求許可權。
     * 方法內部已經對Android M 或以上版本進行了判斷,外部使用不再需要重複判斷。
     * 如果裝置還不是M或以上版本,則也會回撥到requestPermissionsSuccess方法。
     */
    public void requestPermissions(){
        String[] deniedPermissions = PermissionUtil.getDeniedPermissions(mActivity, mPermissionInterface.getPermissions());
        if(deniedPermissions != null && deniedPermissions.length > 0){
            //彈出申請全新框
            PermissionUtil.requestPermissions(mActivity, deniedPermissions, mPermissionInterface.getPermissionsRequestCode());
        }else{
            mPermissionInterface.requestPermissionsSuccess();
        }
    }

    /**
     * 在Activity中的onRequestPermissionsResult中呼叫
     * @param requestCode
     * @param permissions
     * @param grantResults
     * @return true 代表對該requestCode感興趣,並已經處理掉了。false 對該requestCode不感興趣,不處理。
     */
    public boolean requestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults){
        if(requestCode == mPermissionInterface.getPermissionsRequestCode()){
            boolean isAllGranted = true;//是否全部許可權已授權
            for(int result : grantResults){
                if(result == PackageManager.PERMISSION_DENIED){
                    isAllGranted = false;
                    break;
                }
            }
            if(isAllGranted){
                //已全部授權
                mPermissionInterface.requestPermissionsSuccess();
            }else{
                //許可權有缺失
                mPermissionInterface.requestPermissionsFail();
            }
            return true;
        }
        return false;
    }
}

五:呼叫,開始動態申請許可權

package com.vitamio.dome;

import android.Manifest;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import io.vov.vitamio.MediaPlayer;
import io.vov.vitamio.Vitamio;
import io.vov.vitamio.utils.Log;
import io.vov.vitamio.widget.MediaController;
import io.vov.vitamio.widget.VideoView;

//實現 PermissionInterface  許可權請求介面
public class MainActivity extends AppCompatActivity implements PermissionInterface {
    //動態獲取許可權工具類
    private PermissionHelper permissionHelper = null;
    //開啟許可權設定工具類
    private PermissionPageUtils permissionPageUtils = null;
    //直播 rtmp 流視訊
    private VideoView vitamio_videoview;
    private String path;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Vitamio.isInitialized(getApplicationContext());
        permissionHelper = new PermissionHelper(this, this);
        permissionPageUtils = new PermissionPageUtils(this.getApplicationContext());
        setContentView(R.layout.activity_main);
        permissionHelper.requestPermissions();

    }

    //onRequestPermissionsResult

   //許可權申請回調
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        permissionHelper.requestPermissionsResult(requestCode, permissions, grantResults);
    }

    /**
     * 設定播放視訊
     */
    private void settingVoide() {
        vitamio_videoview = findViewById(R.id.vitamio_videoview);
        path = "rtmp://202.69.69.180:443/webcast/bshdlive-pc";
        //放入地址
        vitamio_videoview.setVideoPath(path);

        //設定控制欄
        vitamio_videoview.setMediaController(new MediaController(this));

        //獲取焦點
        vitamio_videoview.requestFocus();

        //準備播放監聽
        vitamio_videoview.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp) {
                mp.setPlaybackSpeed(1.0f);//設定播放速度
            }
        });

    }
    
    //設定申請許可權請求返回碼
    @Override
    public int getPermissionsRequestCode() {
        return PermissionUtil.mainPermissionCode;
    }

    //設定要申請的許可權 
    @Override
    public String[] getPermissions() {
        return new String[]{
                //讀取裝置外部儲存空間許可權
                Manifest.permission.READ_EXTERNAL_STORAGE
        };

    }

    //獲取許可權成功執行的方法
    @Override
    public void requestPermissionsSuccess() {
        settingVoide();
    }

    //獲取許可權失敗執行的方法
    @Override
    public void requestPermissionsFail() {
        //android.permission.READ_EXTERNAL_STORAGE
        String[] permissionAry = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE};
        //獲取被拒絕的許可權
        String[] juPermission = PermissionUtil.getDeniedPermissions(this, permissionAry);
        //開啟許可權設定
        permissionPageUtils.OpenPermissionPage();

    }
}