文件
(1)app权限
<!--存储权限-->
<uses-permission android:name=".WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name=".READ_EXTERNAL_STORAGE"/>
<uses-permission android:name=".MANAGE_EXTERNAL_STORAGE"/>
(2)application配置
<application
...
android:requestLegacyExternalStorage="true"
android:usesCleartextTraffic="true"
...>
(3)组件配置
注意:Android 12以上,组件创建会自动生成以下属性
android:exported="true"
表示”是否支持其它应用调用当前组件”
如果不添加改属性,会报错。
2.动态申请文件存储权限
说明,Android的权限根据版本号分为三种
1:Android6.0之前
2:Android6.0-Android 10
3:Android 11以后
其中,6.0之前不需要动态申请权限,只需要在manifest文件中申请即可。从6.0之后,app需要动态申请权限,即弹框询问用户,是否给用户授权。Android 11以后,对权限的控制进一步收紧,很多的权限申请发生改变,例如,此前操作文件,只需要声明读写权限即可,但是现在划分了图片、音频、视频等等,并且操作普通文件的权限也变为MANAGE_EXTERNAL_STORAGE
代码如下:
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
.READ_EXTERNAL_STORAGE,
.WRITE_EXTERNAL_STORAGE
};
private boolean havePermission = false;
@Override
protected void onResume() {
();
checkPermission();
}
private AlertDialog dialog;
private void checkPermission() {
//检查权限(NEED_PERMISSION)是否被授权 PackageManager.PERMISSION_GRANTED表示同意授权
if (.SDK_INT >= 30) {
if (!()) {
if (dialog != null) {
();
dialog = null;
}
dialog = new (this)
.setTitle("提示")//设置标题
.setMessage("请开启文件访问权限,否则无法正常使用本应用!")
.setNegativeButton("取消", new () {
@Override
public void onClick(DialogInterface dialog, int i) {
();
}
})
.setPositiveButton("确定", new () {
@Override
public void onClick(DialogInterface dialog, int which) {
();
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
(("package:" + getPackageName()));
startActivity(intent);
}
}).create();
();
} else {
havePermission = true;
("swyLog", "Android 11以上,当前已有权限");
}
} else {
if (.SDK_INT > Build.VERSION_CODES.M) {
if ((this, .WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
//申请权限
if (dialog != null) {
();
dialog = null;
}
dialog = new (this)
.setTitle("提示")//设置标题
.setMessage("请开启文件访问权限,否则无法正常使用本应用!")
.setPositiveButton("确定", new () {
@Override
public void onClick(DialogInterface dialog, int which) {
();
(, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);
}
}).create();
();
} else {
havePermission = true;
("swyLog", "Android 6.0以上,11以下,当前已有权限");
}
} else {
havePermission = true;
("swyLog", "Android 6.0以下,已获取权限");
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST_EXTERNAL_STORAGE: {
if ( > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
havePermission = true;
(this, "授权成功!", Toast.LENGTH_SHORT).show();
} else {
havePermission = false;
(this, "授权被拒绝!", Toast.LENGTH_SHORT).show();
}
return;
}
}
}
3.文件操作
(1)定义文件保存的路径及文件名
private String FILE_SAVE_PATH = ().getAbsolutePath() + "/MobileReport/";
private String FILE_NAME = "";
(2)保存文件
private void saveLoginAccount(String json) {
if ((json)) {
return;
}
("swyLog", "saveLoginAccount called");
String value = encodeToString(json);
("swyLog", "save 明文:" + json);
("swyLog", "save 密文:" + value);
File storage = new File(FILE_SAVE_PATH);
if (!()) {
();
}
File tmepfile = new File(());
if (!()) {
();
}
File file = new File(tmepfile, FILE_NAME);
if (()) {
("swyLog", "删除原有文件");
();
}
if (!()) {
("swyLog", "文件删除成功");
try {
();
} catch (IOException e) {
();
}
}
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(file);
(());
} catch (Exception e) {
();
} finally {
if (fileOutputStream != null) {
try {
();
} catch (IOException e) {
();
}
}
}
}
(3)读取文件
private String uploadLoginAccount() {
("swyLog", "uploadLoginAccount called");
InputStream inputStream = null;
Reader reader = null;
BufferedReader bufferedReader = null;
try {
File storage = new File(FILE_SAVE_PATH);
if (!()) {
return "";
}
File file = new File(storage, FILE_NAME);
if (!()) {
return "";
}
inputStream = new FileInputStream(file);
reader = new InputStreamReader(inputStream);
bufferedReader = new BufferedReader(reader);
StringBuilder result = new StringBuilder();
String temp;
while ((temp = ()) != null) {
(temp);
}
String value = decodeToString(());
("swyLog", "upload 密文:" + result);
("swyLog", "upload 明文:" + value);
return value;
} catch (Exception e) {
();
} finally {
if (reader != null) {
try {
();
} catch (IOException e) {
();
}
}
if (inputStream != null) {
try {
();
} catch (IOException e) {
();
}
}
if (bufferedReader != null) {
try {
();
} catch (IOException e) {
();
}
}
}
return "";
}
(4)删除文件
private void deleteLoginAccount() {
("swyLog", "deleteLoginAccount called");
File storage = new File(FILE_SAVE_PATH);
if (!()) {
();
}
File tmepfile = new File(());
if (!()) {
();
}
File file = new File(tmepfile, FILE_NAME);
if (()) {
try {
("swyLog", "删除原有文件");
();
} catch (Exception e) {
();
}
}
if (!()) {
("swyLog", "文件删除成功");
}
}
(5)base64 加解密方法
/**
* 字符Base64加密
*
* @param str
* @return
*/
public static String encodeToString(String str) {
try {
return (("UTF-8"), );
} catch (UnsupportedEncodingException e) {
();
}
return "";
}
/**
* 字符Base64解密
*
* @param str
* @return
*/
public static String decodeToString(String str) {
try {
return new String((("UTF-8"), ));
} catch (UnsupportedEncodingException e) {
();
}
return "";
}
说明:我这里是从项目中复制的代码,作用是,将字符串加密之后,保存到sd卡种,加密的原因自然不言而喻,因为有些信息是不方便直接展示给用户看的。