android 如何读写文件?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android 如何读写文件?相关的知识,希望对你有一定的参考价值。
我百度了很多方法 有在assent里的 有res里的 但是我发现很多方法都是只能读不能写的 但我需要在一个地方放.txt文件 然后我既可以读取这个文件 又可以写入这个文件 有什么方法呢?方便给我相信的写一下嘛?
读文件:
1、通过File获取文件
2、打开输入流,读取文件
写文件:
1、创建文件
2、打开输出流,写入文件内容
示例:
读文件:String content = ""; //文件内容字符串
//通过路径/sdcard/foo.txt打开文件
File file = new File("/sdcard/foo.txt");
try
InputStream instream = new FileInputStream(file);//读取输入流
InputStreamReader inputreader = new InputStreamReader(instream);//设置流读取方式
BufferedReader buffreader = new BufferedReader(inputreader);
while (( line = buffreader.readLine()) != null)
content += line + "\\n";//读取的文件内容
catch(Exception ex)
写文件:
File file = new File("/sdcard/foo.txt");//
if(!file.exists())
file.createNewFile();//如果文件不存在,创建foo.txt
try
OutputStream outstream = new FileOutputStream(file);//设置输出流
OutputStreamWriter out = new OutputStreamWriter(outstream);//设置内容输出方式
out.write("文字内容");//输出内容到文件中
out.close();
catch (java.io.IOException e)
e.printStackTrace();
参考技术A
有两个地方是可以给你放东西的:
你应用程序自己的内部存储空间
通过Context.getFilesDir().getAbsolutePath()来获得目录。
SD卡
通过Environment.getExternalStorageDirectory().getAbsolutePath()获得根目录。SD卡中还有一个应用程序专属目录(类似上面的1),通过Context.getExternalFilesDir(null)获得。
所以你需要做的是在这两个地方去读取或者写入文件。写入方式同一般java文件读写,这个我想不用我再讲了。你也可以看一下上面几个API的文档,写得很清楚。虽然是英语,但都特别通俗,你肯定可以读懂。
追问额 对不起我看你第一个方法看起来比较简单 但是...不太懂Context.getFilesDir().getAbsolutePath()来获得目录。。我是先要把我的.txt file 复制粘贴到某个地方。。。然后告诉java这个文件的目录吧?? 为何要反过来获得目录?
追答Context.getFilesDir()是系统分配给你的目录(其实一般就是“/data/data/你应用程序的包名”),在内部存储空间,内部存储空间的其他区域你没有root权限是不能随便访问的。
你可以在这个目录下创建一个文件,然后把你的文件拷贝进去,然后再修改。这是通过程序拷贝文件到内部存储空间的一般做法。
你要手工拷贝的话,用adb可以,但是要有root权限。
SD卡不存在这些限制。随便你折腾,通过Context.getExternalFilesDir(null)获得的目录会随着你的应用程序的卸载而自动删除,别的和SD根目录(Environment.getExternalStorageDirectory())没有太大区别。
你可以先把myfile.txt放在assets下,然后在初始化的时候再用我附件里面的copyFile示例代码拷贝到Context.getFilesDir()目录下。然后就可以读取和写入了。
Android 11及以上授予文件管理权限
背景
安卓11改变了此前安卓系统对于文件管理的规则,在安卓11上,文件读写变成了特殊权限。应用默认只能读写自己的目录/android/data/包名
gradle配置
Android11系统对应用写入权限做了严格的限制。本文介绍如何获取文件读写权限。
项目中 build.gradle 的targetSdkVersion >= 29 ,会出现读写问题
- 当targetSdkVersion = 29,通过设置requestLegacyExternalStorage=“true”,还能解决
- 当targetSdkVersion = 30后,需要申请所有文件权限才能获取到写入权限
为了能直接usb安装,gradle.properties 需要设置(否则,在安装时会报异常:-15)
android.injected.testOnly=false
AndroidManifest添加权限设置
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- Android11额外添加 -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<application
...
android:requestLegacyExternalStorage="true"
...
>
语法说明
申请权限,主要用到如下4个函数
- 检查权限
int checkSelfPermission(String)
- 申请权限
void requestPermissions(int, String...)
- 是否应该显示请求权限的说明
boolean shouldShowRequestPermissionRationale(String)
- 处理权限结果回调
void onRequestPermissionsResult(int,String[],int[])
上述四个方法中,前三个方法在support-v4的ActivityCompat中都有,建议使用兼容库中的方法。最后一个方法是用户授权或者拒绝某个权限组时系统会回调Activity或者Fragment中的方法。
checkSelfPermission
的返回值有如下两种
- 已拒绝
PackageManager.PERMISSION_DENIED
- 已授权
PackageManager.PERMISSION_GRANTED
动态权限申请
Android 6.0之上Android11以下申请权限
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) // 6.0
String[] perms =
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_PHONE_STATE;
for (String p : perms)
int ret = ContextCompat.checkSelfPermission(activity, p);
if (ret != PackageManager.PERMISSION_GRANTED)
//TODO 跳转到权限页,请求权限
return;
Android11申请权限
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
//判断是否有管理外部存储的权限
if (!Environment.isExternalStorageManager())
//TODO 跳转到权限页,请求权限
跳转系统授权页面
跳转到“应用信息”页面
安卓默认只能跳转到 "应用信息"页面,但是国内手机厂商大多支持各自自定义的Intent,直接跳到应用程序权限页面
/**
* 当前应用详情页面(在该页面单击权限,进入的是权限组页面)
*/
public static void goAppDetailsSettings(Context context)
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.fromParts("package", context.getPackageName(), null));
context.startActivity(intent);
跳转到应用信息页面,页面包含如下内容
- 存储
- 电量
- 流量
- 通知
- 权限
- 默认打开
需要手动点击“权限”按钮,进入“应用权限”页面,然后开始设置相应的数据
跳转到“所有文件访问权限”
谷歌官方的安卓11在“应用权限”页面隐藏了对“存储”权限的设置(当然,很多国产机,即使到了安卓12,依旧支持原先的存储权限;但也存在部分不支持的,比如:OPPO Reno9 Pro+)
取而代之的是“所有文件访问权限”页面,该页面用来授予“所有文件的管理权限”,允许此应用读取、修改和删除此设备或任意已连接存储卷上的所有文件。如果您授予该权限,应用无需明确通知您即可访问文件
/**
* 进入Android 11或更高版本的文件访问权限页面
*/
private void goManagerFileAccess(AppCompatActivity activity)
// Android 11 (Api 30)或更高版本的写文件权限需要特殊申请,需要动态申请管理所有文件的权限
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
Intent appIntent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
appIntent.setData(Uri.parse("package:" + getPackageName()));
//appIntent.setData(Uri.fromParts("package", activity.getPackageName(), null));
try
activity.startActivity(appIntent);
catch (ActivityNotFoundException ex)
ex.printStackTrace();
Intent allFileIntent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
activity.startActivity(allFileIntent);
这里面涉及到两个Settings
- 当前应用的文件访问权限:ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION
- 所有需要文件访问权限的应用:ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION
切记,不要在安卓11以下调用该Intent,会导致闪退
测试存储权限是否授权
安卓11及以后,有如下几个函数判断是否赋予存储权限
- 老版读权限
ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
- 老版写权限
ActivityCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
- 安卓11新出的管理外置存储权限
ActivityCompat.checkSelfPermission(context, Manifest.permission.MANAGE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
- 安卓11新出的判断是否是外置存储管理器
Environment.isExternalStorageManager()
具体实验(VIVO Y77,安卓12)
- 初始化状态
isExternalStorageManager => false
READ_EXTERNAL_STORAGE => false
READ_EXTERNAL_STORAGE => false
MANAGE_EXTERNAL_STORAGE => false
- 仅在“应用权限”页面,打开存储权限中的“允许管理所有文件”
isExternalStorageManager => true
READ_EXTERNAL_STORAGE => true
WRITE_EXTERNAL_STORAGE => true
MANAGE_EXTERNAL_STORAGE => false
- 仅在“应用权限”页面,打开存储权限中的“仅允许访问媒体文件”
isExternalStorageManager => false
READ_EXTERNAL_STORAGE => true
WRITE_EXTERNAL_STORAGE => true
MANAGE_EXTERNAL_STORAGE => false
- 仅在“所有文件访问权限”页面,授予权限
isExternalStorageManager => true
READ_EXTERNAL_STORAGE => false
WRITE_EXTERNAL_STORAGE => false
MANAGE_EXTERNAL_STORAGE => false
因此,可以得出如下结论
- 不要尝试判断
MANAGE_EXTERNAL_STORAGE
权限,因为其永远为false isExternalStorageManager
、ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION
、ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION
API,只能在安卓11及以上版本调用(低版本调用会闪退)- “应用权限”页面,打开存储权限中的“允许管理所有文件”会使得
isExternalStorageManager
变为true;但反之在“所有文件访问权限”页面授予权限,并不会改变WRITE_EXTERNAL_STORAGE
的允许情况
因此,为了兼容 安卓4.4-安卓12,在11以下,建议使用checkSelfPermission
方法进行存储权限判断;而安卓11及以上使用Environment.isExternalStorageManager
即可
以上是关于android 如何读写文件?的主要内容,如果未能解决你的问题,请参考以下文章