权限问题

来源:互联网 发布:加厚行美工刀架 编辑:程序博客网 时间:2024/06/07 09:01
声明:此文非本人原创,为整理网络资料加自己的一些注解所得。
android 7  n   android 6  m    android 5  l
权限问题:
一. 在Android M及更高版本中使用 Settings.System 抛出异常"You cannot keep your settings in the secure settings. " (7.0项目访客模式torch的状态码存在Settings.System中导致报停)
    调用Settings.System.putStringForUser最终都是对数据库SettingsProvider进行操作。
frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.Java
在M版本中,在Settings.System表中执行更新或者删除操作时,都要会调用函数warnOrThrowForUndesiredSecureSettingsMutationForTargetSdk,该函数是M新增。当app尝试更新Settings.System的时候,会进行版本校验,如果targetSDK 小于等于Build.VERSION_CODES.LOLLIPOP_MR1,即低版本的apk时,给出warning,保证代码的兼容性。
而当tagetSDK大于Build.VERSION_CODES.LOLLIPOP_MR1,即M版本及更高的版本的时候,则会抛出异常,禁止apk写或者删除SettingsProvider数据库中的System表。
解决方案:
1. 如果对targetSDK没有要求,则将targetSDK降为Build.VERSION_CODES.LOLLIPOP_MR1以下,利用Android程序向前兼容性,规避问题,但是这样的方法并不是最优方案,有可能在后续版本中,Android甚至可能放弃兼容,直接抛出异常。
2. 放弃写Settings.System,改用Settings.Global保存共享数据。
二. 动态申请权限
  系统权限分成两类:normal和dangerous两类:
     Normal类的权限不会直接涉及到用户隐私风险。如果APP在Manifest文件中声明了Normal类的权限,系统会自动授予这些权限。

     Dangerous类的权限可能会让APP涉及到用户机密的数据。如果APP在Manifest文件中声明了Normal类的权限,系统会自动授予这些权限。如果在Manifest文件中添加了Dangerous类的权限,用户必须明确的授予对应的权限后APP才具有这些权限。

permission-group

危险权限,在android6.0中,属于动态权限管理,需要用户主动授权才能使用。一旦组内的某个权限被赋予了,那么这个组的其他权限也将自动被赋予。

private static final int PERMISSION_REQUEST_POWER_ON = 100;private static final int PERMISSION_REQUEST_CODE_SAVED_RECORDING = 101;

SoundRecorder开始按钮的点击事件

if (recordPermission()) {return;}else if (storagePermission()){return;}
startRecord();

public boolean recordPermission(){    int recordAudioPermission = checkSelfPermission(Manifest.permission.RECORD_AUDIO);    List<String> mPermissionStrings = new ArrayList<String>();    boolean mRequest = false;    if (recordAudioPermission != PackageManager.PERMISSION_GRANTED) {        mPermissionStrings.add(Manifest.permission.RECORD_AUDIO);        mRequest = true;    }    if (mRequest == true) {        String[] mPermissionList = new String[mPermissionStrings.size()];        mPermissionList = mPermissionStrings.toArray(mPermissionList);        requestPermissions(mPermissionList, PERMISSION_REQUEST_POWER_ON);        return true;    }    return false;}

public boolean storagePermission(){    int readExtStorage = checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE);    int writeExtStorage = checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);    List<String> mPermissionStrings = new ArrayList<String>();    boolean mRequest = false;    if (readExtStorage != PackageManager.PERMISSION_GRANTED) {        mPermissionStrings.add(Manifest.permission.READ_EXTERNAL_STORAGE);        mRequest = true;    }    if (writeExtStorage != PackageManager.PERMISSION_GRANTED) {        mPermissionStrings.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);        mRequest = true;    }    if (mRequest == true) {        String[] mPermissionList = new String[mPermissionStrings.size()];        mPermissionList = mPermissionStrings.toArray(mPermissionList);        requestPermissions(mPermissionList, PERMISSION_REQUEST_CODE_SAVED_RECORDING);        return true;    }    return false;}
判断用户是否确认了权限

@Overridepublic void onRequestPermissionsResult(int requestCode, String[] permissions,                                       int[] grantResults) {    boolean granted = true;    boolean mShowPermission = true;    if (permissions.length <= 0 || grantResults.length <= 0) {        Log.d(TAG, "permission length not sufficient");        showToast(getString(R.string.missing_required_permission));        return;    }    if (requestCode == PERMISSION_REQUEST_POWER_ON) {        granted = (grantResults[0] == PackageManager.PERMISSION_GRANTED);        if (!granted) {            mShowPermission = shouldShowRequestPermissionRationale(permissions[0]);        }        Log.i(TAG, "<onRequestPermissionsResult> Record audio soundrecorder granted" + granted);        if (granted == true) {            storagePermission();        } else if (!mShowPermission) {            showToast(getString(R.string.missing_required_permission));        }    }else if (requestCode == PERMISSION_REQUEST_CODE_SAVED_RECORDING){        for (int counter = 0; counter < permissions.length; counter++) {            boolean permissionGranted = false;            permissionGranted = (grantResults[counter] ==                    PackageManager.PERMISSION_GRANTED);            granted = granted && permissionGranted;            if (!permissionGranted) {                mShowPermission = mShowPermission && shouldShowRequestPermissionRationale(                        permissions[counter]);            }        }        Log.i(TAG, "<onRequestPermissionsResult> savefile soundrecorder granted" + granted);        if (granted == true) {            startRecord();        } else if (!mShowPermission) {            showToast(getString(R.string.missing_required_permission));        }    }}

文件存储

权限:

<uses-permission android:name="android.permission.INTERNET" /><!-- SDCard写入数据权限 --><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><!-- SDCard中创建与删除文件权限 --><uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />

内置存储

   try {                        String fileInnerName = "/inner/img"; //目录名                        //   内置存储文件目录                        File fileDir = new File(this.getFilesDir(), fileInnerName);   //      /data/data/*****/inner/img                        //内置存储缓存目录                        File fileCache = new File(this.getCacheDir(), fileInnerName); //     /data/data/*****/cache/inner/img                        if (!fileDir.exists()) {                            boolean isInner = fileDir.mkdirs();                            System.out.println(isInner);                        }                        if (!fileCache.exists()) {                              boolean isInner = fileCache.mkdirs();                            System.out.println(isInner);                        }                        Log.i(" wqtest ", fileDir.getAbsolutePath() + "  " + fileCache.getAbsolutePath());                        mPathView.save(fileCache.getAbsolutePath() + File.separator + System.currentTimeMillis() + "wq.jpg", true, 10);                        mPathView.save(fileDir.getAbsolutePath() + File.separator + System.currentTimeMillis() + "wq.jpg", true, 10);//                        setResult(100);                    } catch (IOException e) {                        e.printStackTrace();                    }

外部私有目录 (context.getExternalCacheDir())

                String fileOutName = "/AutDir/fileOut";                if (!isExternalStorageWritable()) {                    return;                }                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {                    File fileOut = new File(getActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES) + fileOutName);  //   /storage/emulated/0/Android/data/com.android.imageloaderstorage/files/Pictures/AutDir/fileOut                    boolean flag = fileOut.mkdirs();                    Log.i("FileFragment", fileOut.getAbsolutePath());                }                //缓存目录                File fileOutCache = new File(getActivity().getExternalCacheDir() + fileOutName); //  /storage/emulated/0/Android/data/com.android.imageloaderstorage/cache/AutDir/fileOut                Boolean isInner = fileOutCache.mkdirs();                Log.i("FileFragment", " 路径 " + fileOutCache.getAbsolutePath());
外部公共目录

 protected void createOutPublicDir() {     if (!isExternalStorageWritable()) {            return;        }        File filePublic = new File(Environment.getExternalStorageDirectory() + fileOutPublicName);   //   /storage/emulated/0/AutPublic/outDir        if (!filePublic.exists()) {            filePublic.mkdirs();        }    }



原创粉丝点击