在storage文件夹下创建文件可能需要动态申请权限

在相应Activity.java里添加以下代码,这里以 WRITE_EXTERNAL_STORAGE 为例

public void requestPower() {
    if(ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
        if(ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.WRITE_EXTERNAL_STORAGE)){
            //第一次上面这个方法返回的是false,之后就一直返回true
        }else{
            ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);//核心
            //此处会弹出一个框框询问你是否给予权限
       }
    }

}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    if(requestCode==1){
        for(int i=0;i<permissions.length;i++){//可能有多个权限,需要观测是否为PERMISSION_GRANTED状态
            if(grantResults[i]==PackageManager.PERMISSION_GRANTED){
                Toast.makeText(this, "权限" + permissions[i] + "申请成功", Toast.LENGTH_SHORT).show();
            }else{
                Toast.makeText(this, "权限" + permissions[i] + "申请失败", Toast.LENGTH_SHORT).show();
            }
        }
    }
}
弹出的询问框无论选择 是 还是 否,之后都不再会询问,因为ActivityCompat.shouldShowRequestPermissionRationale会返回true。

//显然这块代码的核心是ActivityCompat.requestPermissions(Context context, String[] permissions, int requestCode);这个方法


通过Environment.getExternalStorageDirectory().getAbsolutePath()拿到sd卡路径 filePath(String) 后 ,通过File file = new File(filePath + "/xxx");来创建之前,加上 requestPower();

当然,既然是动态申请,在Manifest文件里也要记得添加好要动态申请的这个权限。


总结

1.判读是否获得权限

if(ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
    //还没获得这个权限
}


2.申请权限(这个方法被调用时就会出现一个框框)

ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);


3.权限申请的回调方法

public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    if(requestCode==1){
        for(int i=0;i<permissions.length;i++){//可能有多个权限,需要观测是否为PERMISSION_GRANTED状态
            if(grantResults[i]==PackageManager.PERMISSION_GRANTED){
                Toast.makeText(this, "权限" + permissions[i] + "申请成功", Toast.LENGTH_SHORT).show();
            }else{
                Toast.makeText(this, "权限" + permissions[i] + "申请失败", Toast.LENGTH_SHORT).show();
            }
        }
    }
}




顺便随便说说我遇到的一个问题:

由于app在sd目录下已经创建了一个一个xxx文件夹,卸载这个应用后此文件依然会存在

再安装测试,此时在弹出权限选择框之前app发生崩溃

报错行代码为:

FileOutputStream fos = new FileOutputStream(path);

分析发现报错原因并不是path不存在,而正是因为存在才引起的问题

原因是弹出权限框时,此时说明还没有得到写入权限,但由于有了以前创建的那个xxx文件夹,之后的代码便以已经有权限的状态去尝试写入修改,当然会崩溃了。(我的处理方式是 若没有xxx文件夹时会创建,若失败(说明还没有权限)会返回false,之后跳出不再执行之后的代码,若已有xxx文件,则直接执行之后的代码)

总的来说,因为有了xxx文件,让其误以为已经有写入权限,毕竟有了xxx文件夹并不代表可以再创建文件,因为xxx文件可能是之前被卸载的app所留下的东西,而此时并没有写入的权限

解决只要在之后的代码前加上一个简单的 if 判断即可




猜你喜欢

转载自blog.csdn.net/Tz_AndHac/article/details/81034866