权限管理

未有解决方案问题:

vivo 权限兼容,当APP在运行时,提示授权进去修改权限后,并不会实时同步到系统中,导致看到已经授权,但是依然没有权限操作(x20a    Y75a  7.1.1系统)
https://blog.csdn.net/aabbwoshishei/article/details/78895510

华为手机  当提示授权,进入授权并且授权读写SDCARD后,会导致Application重新创建,会导致application丢失数据

(荣耀畅享6X  7.0系统)

https://blog.csdn.net/dirksmaller/article/details/76737545


问题一:

Andorid 6.0以下权限检测(测试红米2A 红米2  小米3)

音频

华为荣耀3C  型号H30-T00 ,系统4.4.2--EMUI3.0  以下校验不出来

 // 音频获取源
public static int audioSource = MediaRecorder.AudioSource.MIC;
// 设置音频采样率,44100是目前的标准,但是某些设备仍然支持22050,16000,11025
public static int sampleRateInHz = 44100;
// 设置音频的录制的声道CHANNEL_IN_STEREO为双声道,CHANNEL_CONFIGURATION_MONO为单声道
public static int channelConfig = AudioFormat.CHANNEL_IN_STEREO;
// 音频数据格式:PCM 16位每个样本。保证设备支持。PCM 8位每个样本。不一定能得到设备支持。
public static int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
// 缓冲区字节大小
public static int bufferSizeInBytes = 0;


//录音是否可用
public static boolean isAudioUseable() {
    boolean canUse;
    Boolean isGetVoiceRun = true;
    int count = 0;
    Object mLock = new Object();
    AudioRecord audioRecord = null;
    try {
        Log.d("PermissionUtil", "isAudioUseable 1");
        bufferSizeInBytes = 0;
        bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRateInHz,
                channelConfig, audioFormat);
        audioRecord = new AudioRecord(audioSource, sampleRateInHz,
                channelConfig, audioFormat, bufferSizeInBytes);
        //开始录制音频
        audioRecord.startRecording();
        Log.d("PermissionUtil", "isAudioUseable 2");
        /**
         * 根据开始录音判断是否有录音权限
         */
        if (audioRecord.getRecordingState() != AudioRecord.RECORDSTATE_RECORDING) {
            Log.d("PermissionUtil", "isAudioUseable 3");
            return false;
        }
        short[] buffer = new short[bufferSizeInBytes];
        while (isGetVoiceRun) {
            count++;
            if (count++ > 5) {
                isGetVoiceRun = false;
            }
            //r是实际读取的数据长度,一般而言r会小于buffersize
            int r = audioRecord.read(buffer, 0, bufferSizeInBytes);
            long v = 0;
            // 将 buffer 内容取出,进行平方和运算
            for (int i = 0; i < buffer.length; i++) {
                v += buffer[i] * buffer[i];
            }
            // 平方和除以数据总长度,得到音量大小。
            double mean = v / (double) r;
            double volume = 10 * Math.log10(mean);
            Log.d("PermissionUtil", "-------分贝值:" + volume + "----v" + v + "------r" + r);
            if (r <= 0) {
                //没有录音
                return false;
            }
            if (Build.MANUFACTURER.toLowerCase().contains("xiaomi") && Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN_MR2) {//只针对红米1S 4.3系统兼容
                if(v<=0){
                    return false;
                }
            }
            // 大概一秒十次
            synchronized (mLock) {
                try {
                    mLock.wait(5);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        audioRecord.stop();
        audioRecord.release();
        audioRecord = null;
        canUse = true;
    } catch (Exception e) {
        canUse = false;
        Log.d("PermissionUtil", "isAudioUseable e ");
        e.printStackTrace();
    } finally {
        if (audioRecord != null) {
            audioRecord.release();
            audioRecord = null;
        }
    }
    return canUse;
}

拍照

  //摄像头是否可用
    public static boolean isCameraUseable() {

        boolean canUse;

        Camera mCamera = null;

        try {
            mCamera = Camera.open();
            Camera.Parameters mParameters = mCamera.getParameters();
            mCamera.setParameters(mParameters);
            canUse = true;
        } catch (Exception e) {
            canUse = false;
        } finally {
            if (mCamera != null) {
                mCamera.release();
            }
        }
        return canUse;
    }

检测蓝牙是否可以用(有蓝牙开关的手机,vivo是检测不到当前权限是打开还是关闭的)

 //蓝牙是否可以静默打开  兼容vivo    如果蓝牙没打开,直接显式提示,如果打开了,就需要去判断一下是否可用,不可用就继续显式提示打开
    public static boolean isBluetoothUserAble(Context context) {
        boolean canUse;
        BluetoothAdapter mBluetoothAdapter;
        try {
            BluetoothManager mBluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
            mBluetoothAdapter = mBluetoothManager.getAdapter();
            if (!mBluetoothAdapter.isEnabled()) {
                //某些手机无法打开该权限,只能走显示打开,这种情况下,权限基本上没关系,只要用户选择打开了蓝牙,无所谓权限
                //会弹出系统对话框,提示用户是否允许蓝牙设备对其他设备的可见性
                Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
                intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 120);//可被发现的持续时间
                context.startActivity(intent);
                return false;
            }
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                if (mBluetoothAdapter.isEnabled() && null != mBluetoothAdapter.getBluetoothLeScanner()) {
                    return true;
                }else{
                    //某些手机无法打开该权限,只能走显示打开,这种情况下,权限基本上没关系,只要用户选择打开了蓝牙,无所谓权限
                    //会弹出系统对话框,提示用户是否允许蓝牙设备对其他设备的可见性
                    Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
                    intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 120);//可被发现的持续时间
                    context.startActivity(intent);
                }
            } else {
                return true;
            }
            canUse = false;
        } catch (Exception e) {
            canUse = false;
            e.printStackTrace();
        }
        return canUse;
    }

当没有权限时候,需要做处理

 //主要为了兼容vivo  设置了权限也是之前的权限不会动态更新  而且不是缺失定位,如果缺失定位还是要提示
                                if (isBluetoothUserAble(context) && !permissions.contains("android.permission.ACCESS_FINE_LOCATION") && !permissions.contains("android.permission.ACCESS_COARSE_LOCATION")) {
                                    if (null != listener) {
                                        listener.onGranted(type);
                                    }
                                    return;
                                } else {
                                    //某些手机无法打开该权限,只能走显示打开,这种情况下,权限基本上没关系,只要用户选择打开了蓝牙,无所谓权限
                                    //会弹出系统对话框,提示用户是否允许蓝牙设备对其他设备的可见性
                                    Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
                                    intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 120);//可被发现的持续时间
                                    context.startActivity(intent);
                                    if (null != listener) {
                                        listener.onDenied(type);
                                    }
                                    return;
                                }



问题二:

如果默认跳入

  Context context = target.getContext();
        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        Uri uri = Uri.fromParts("package", context.getPackageName(), null);
        intent.setData(uri);
        target.startActivityForResult(intent, mRequestCode);

你会发现华为手机荣耀3c是没办法设置权限,只能做兼容

    /**
     * 跳转: 「权限设置」界面
     * <p>
     * 根据各大厂商的不同定制而跳转至其权限设置
     * 目前已测试成功机型: 小米V7V8V9, 华为, 三星, 锤子, 魅族; 测试失败: OPPO
     *
     * @return 成功跳转权限设置, 返回 true; 没有适配该厂商或不能跳转, 则自动默认跳转设置界面, 并返回 false
     */
    public static boolean gotoPermissionSetting() {
        boolean success = true;
        Intent intent = new Intent();
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        String packageName = AppUtils.getPackageName();

        OSUtils.ROM romType = OSUtils.getRomType();
        switch (romType) {
            case EMUI: // 华为
                intent.putExtra("packageName", packageName);
                intent.setComponent(new ComponentName("com.huawei.systemmanager", "com.huawei.permissionmanager.ui.MainActivity"));
                break;
            case Flyme: // 魅族
                intent.setAction("com.meizu.safe.security.SHOW_APPSEC");
                intent.addCategory(Intent.CATEGORY_DEFAULT);
                intent.putExtra("packageName", packageName);
                break;
            case MIUI: // 小米
                String rom = getMiuiVersion();
                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 {
                    intent = getAppDetailsSettingsIntent(packageName);
                }
                break;
            case Sony: // 索尼
                intent.putExtra("packageName", packageName);
                intent.setComponent(new ComponentName("com.sonymobile.cta", "com.sonymobile.cta.SomcCTAMainActivity"));
                break;
            case ColorOS: // OPPO
                intent.putExtra("packageName", packageName);
                intent.setComponent(new ComponentName("com.coloros.safecenter", "com.coloros.safecenter.permission.PermissionManagerActivity"));
                break;
            case EUI: // 乐视
                intent.putExtra("packageName", packageName);
                intent.setComponent(new ComponentName("com.letv.android.letvsafe", "com.letv.android.letvsafe.PermissionAndApps"));
                break;
            case LG: // LG
                intent.setAction("android.intent.action.MAIN");
                intent.putExtra("packageName", packageName);
                ComponentName comp = new ComponentName("com.android.settings", "com.android.settings.Settings$AccessLockSummaryActivity");
                intent.setComponent(comp);
                break;
            case SamSung: // 三星
            case SmartisanOS: // 锤子
                gotoAppDetailSetting(packageName);
                break;
            default:
                intent.setAction(Settings.ACTION_SETTINGS);
                LogUtils.i("没有适配该机型, 跳转普通设置界面");
                success = false;
                break;
        }
        try {
            ContextUtils.startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
            // 跳转失败, 前往普通设置界面
            IntentUtils.gotoSetting();
            success = false;
            LogUtils.i("无法跳转权限界面, 开始跳转普通设置界面");
        }
        return success;
    }

上面跳转未测全,另外AndPermission跳转页未测全

    private Intent obtainSettingIntent(Context context) {
        if (MARK.contains("huawei")) {
            return huaweiApi(context);
        } else if (MARK.contains("xiaomi")) {
            return xiaomiApi(context);
        } else if (MARK.contains("oppo")) {
            return oppoApi(context);
        } else if (MARK.contains("vivo")) {
            return vivoApi(context);
        } else if (MARK.contains("samsung")) {
            return samsungApi(context);
        } else if (MARK.contains("meizu")) {
            return meizuApi(context);
        } else if (MARK.contains("smartisan")) {
            return smartisanApi(context);
        }
        return defaultApi(context);
    }

    /**
     * App details page.
     */
    private static Intent defaultApi(Context context) {
        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        intent.setData(Uri.fromParts("package", context.getPackageName(), null));
        return intent;
    }

    /**
     * Huawei cell phone Api23 the following method.
     */
    private static Intent huaweiApi(Context context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            return defaultApi(context);
        }
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.huawei.systemmanager", "com.huawei.permissionmanager.ui.MainActivity"));
        return intent;
    }

    /**
     * Xiaomi phone to achieve the method.
     */
    private static Intent xiaomiApi(Context context) {
        if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN_MR2){
            return defaultApi(context);
        }
        Intent intent = new Intent("miui.intent.action.APP_PERM_EDITOR");
        intent.putExtra("extra_pkgname", context.getPackageName());
        return intent;
    }

    /**
     * Vivo phone to achieve the method.
     */
    private static Intent vivoApi(Context context) {
        Intent intent = new Intent();
        intent.putExtra("packagename", context.getPackageName());
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
            intent.setComponent(new ComponentName("com.vivo.permissionmanager", "com.vivo.permissionmanager.activity.SoftPermissionDetailActivity"));
        } else {
            intent.setComponent(new ComponentName("com.iqoo.secure", "com.iqoo.secure.safeguard.SoftPermissionDetailActivity"));
        }
        return intent;
    }

    /**
     * Oppo phone to achieve the method.
     */
    private static Intent oppoApi(Context context) {
        return defaultApi(context);
    }

    /**
     * Meizu phone to achieve the method.
     */
    private static Intent meizuApi(Context context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
            return defaultApi(context);
        }
        Intent intent = new Intent("com.meizu.safe.security.SHOW_APPSEC");
        intent.putExtra("packageName", context.getPackageName());
        intent.setComponent(new ComponentName("com.meizu.safe", "com.meizu.safe.security.AppSecActivity"));
        return intent;
    }

    /**
     * Smartisan phone to achieve the method.
     */
    private static Intent smartisanApi(Context context) {
        return defaultApi(context);
    }

    /**
     * Samsung phone to achieve the method.
     */
    private static Intent samsungApi(Context context) {
        return defaultApi(context);
    }

问题三

Vivo手机动态权限兼容,无论你如何判断都是之前的权限设置,你去授权后不会更改当前APP运行时权限

测试机vivo x20A

问题四

手机权限被第三方例如360安全卫士给禁止了,但是看到系统中自带的权限管理是允许的,导致一直无法授权通过问题(除了正常的checkselfPermission外,我还做了其他异常判断来确认是否正在具有权限,是在自己异常判断一直不过)





  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值