基于Android 10(Q),即SdkVersion > 28
Android 10存储方式发生改变, Q版本 访问自己应用的专有目录无需读写权限。
媒体收藏(图片,视频,音频等)需要申请权限,并借助MediaStorage
下载(文档与电子书等)无需权限。
在应用的专有目录创建文件无需读写权限:
应用的专有目录:
basePath1= "/storage/emulated/0/Android/data/com.example.storage1/files/Documents/";
basePath2= getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath()+ "/";
使用basePath1 这种路径的写法,是Android10 以下版本的写法,需要权限申请,配置方法如方法2.
1、 ActivityManifest.xml 配置
关键两点:
2. activity_main.xml
视图为:
3. MainActivity.java
package com.example.storage1;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends AppCompatActivity{
private Button save,show;
private EditText editText, editText2, editTextFilePath, editTextRootPath;
private static String basePath= "/storage/emulated/0/Android/data/";
private static String baseDir="";
private static String fileName="";
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
save= (Button) findViewById(R.id.save);
show= (Button) findViewById(R.id.show);
editText=(EditText) findViewById(R.id.text);
editText2=(EditText) findViewById(R.id.text2);
editTextFilePath=(EditText) findViewById(R.id.filepath);
editTextRootPath=(EditText) findViewById(R.id.rootpath);
editTextRootPath.setText(basePath);
// 申请权限,否则手机默认禁止存储
ActivityCompat.requestPermissions(MainActivity.this,new String[ ]{
"android.permission.WRITE_EXTERNAL_STORAGE",
"android.permission.READ_EXTERNAL_STORAGE"},1);
// 开始逻辑
basePath= basePath + getPackageName()+"/files/";
save.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String relatedPath= editTextFilePath.getText().toString();
String[] allP= getBaseDirAndFileName(relatedPath);
baseDir = allP[0];
fileName = allP[1];
//获取应用目录File filePictures = getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS);
String str= editText.getText().toString();
F.save(str,baseDir, fileName);
ToastUtil.showMsg(MainActivity.this, "保存数据成功");
}
});
show.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
editText2.setText(F.read(baseDir+fileName));
}
});
}
public static String[] getBaseDirAndFileName(String relatedPath){
String[] dirFile= relatedPath.split("/");
int sLength=dirFile.length;
String fileName= dirFile[sLength-1];
String fileDir= "";
for (int i=0;i
4. ToastUtil.java 用于显示提示信息
package com.example.storage1;
import android.content.Context;
import android.widget.Toast;
public class ToastUtil {
public static Toast mToast;
public static void showMsg(Context context, String msg){
if (mToast==null){
mToast= Toast.makeText(context, msg, Toast.LENGTH_LONG);
}
else{
mToast.setText(msg);
}
mToast.show();
}
}
ToastUtil.showMsg(MainActivity.this, "保存数据成功");
5. 读取与写入文件:
package com.example.storage1;
import android.util.Log;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.File;
public class F {
private static MainActivity mainActivity;
// Android 10 外部存储
// 必须存储至应用/storage/emulated/0/Android/data/包名/files/内
public static void save(String str, String filePath, String fileName){
try{
File fileDir = new File(filePath);
if (fileDir.exists()) {
File file= new File(fileDir,fileName);
FileOutputStream fos = new FileOutputStream(file);
fos.write(str.getBytes());
fos.flush();
fos.close();
}else if (fileDir.mkdirs()) {//如果该文件夹不存在,则新建
File file= new File(fileDir,fileName);
FileOutputStream fos = new FileOutputStream(file);
fos.write(str.getBytes());
fos.flush();
fos.close();
}
}catch (IOException e) {e.printStackTrace();}
}
public static String read(String filePath)
{
try {
File file= new File(filePath);
if (!file.exists()){
Log.d("读取的文件夹不存在:",file.toString());
return null;
}
FileInputStream fis= new FileInputStream(file);
byte[] buff=new byte[1024];
StringBuilder sb= new StringBuilder();
int len=0;
while((len=fis.read(buff))>0)
{
sb.append(new String(buff,0,len));
}
fis.close();
return sb.toString();
}
catch (IOException e) {}
return null;
}
}
运行: 效果展示,我用的是手机HUAWEIMate20 Android 10 系统
借鉴博客:https://blog.csdn.net/zhendong_hu/article/details/104921985
https://blog.csdn.net/zw904448290/article/details/114316496
https://blog.csdn.net/yehui928186846/article/details/101706238?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-4.control&dist_request_id=&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-4.control
google开发手册: https://developer.android.google.cn/training/data-storage/app-specific#java