1.概述
Android中文件操作与Java一致,File类是java中的文件操作工具类,Android其他文件操作API也是基于file操作进行的封装。
文件操作有:
- File
- Properties
- assets原始文件
- raw原始文件
2.File存储与读取
文件有关的操作,一般需要配置app权限,代码中需设置动态申请权限。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAG" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
private void checkPermission(){
PermissionUtil.applyPermission(this ,101, getApplication().getPackageName());
}
2.1字符串写入File
字符串写入文件,一般使用FileOutputStream即可
封装方法如下:
public static void storeTxt(String path, String txtStr) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(path);
fos.write(txtStr.getBytes());
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.2读取File文件中的字符串
从文件读取字符串,一般用FileInputStream
封装方法如下:
public static String readTxt(String path){
String readStr ="";
FileInputStream fis =null;
try {
fis = new FileInputStream(path);
byte[] bytes = new byte[fis.available()];
fis.read(bytes);
readStr = new String(bytes);
} catch (Exception e) {
e.printStackTrace();
}finally {
if (fis != null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return readStr;
}
2.3存储图片
图片的字节数据相对较大,选择io性能更好的BufferedOutputStream和BufferedInputStream
public static void storeBitmap(String path , Bitmap bitmap ,int quality){
BufferedOutputStream bos= null;
FileOutputStream fos=null;
try {
fos = new FileOutputStream(path);
bos = new BufferedOutputStream(fos);
bitmap.compress(Bitmap.CompressFormat.JPEG,quality ,bos);
} catch (Exception e) {
e.printStackTrace();
}finally {
if (fos !=null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bos != null){
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.4读取图片
图片的字节数据相对较大,选择io性能更好的BufferedOutputStream和BufferedInputStream
public static Bitmap loadBitmap(String path ){
Bitmap bitmap = null ;
FileInputStream fis = null;
BufferedInputStream bis = null;
try {
fis = new FileInputStream(path);
bis = new BufferedInputStream(fis);
bitmap = BitmapFactory.decodeStream(bis);
} catch (Exception e) {
e.printStackTrace();
}finally {
if (fis != null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bis != null){
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return bitmap;
}
3.Properties存储与读取
| 方法 | 功能 |
|---|---|
| load() | 加载Properties对象 |
| store() | 保存到Properties文件 |
| getProperty() | 获取属性值 |
| setProperty | 设置属性值 |
| loadFromXML | 从XML格式的属性文件中加载Properties对象 |
| storeToXML | 把属性对象保存到XML格式的Properties文件 |
存储Properties
private void storeProp() {
if (FileStoreHelper.isExStoreUsable()){
PropertiesHelper.getInstance(this).init().open().writeString("auto_update","yes");
}else {
toast("无存储空间或权限");
}
}
读取Properties
private void readProp() {
if (FileStoreHelper.isExStoreUsable()){
String s = PropertiesHelper.getInstance(this).init().readString("auto_update", "no");
tv.append("\n");
tv.append("auto_update:");
tv.append(s);
}else {
toast("无存储空间或权限");
}
}
PropertiesHelper.java
package com.cupster.androidfile;
import android.content.Context;
import android.os.Environment;
import android.util.Log;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Properties;
public class PropertiesHelper {
private static final String TAG = "PropertiesHelper";
private Context mContext;
private String mPath;
private String mFile;
private Properties mProp;
private static PropertiesHelper mPropUtil = null;
public static PropertiesHelper getInstance(Context context) {
if (mPropUtil == null) {
mPropUtil = new PropertiesHelper();
mPropUtil.mContext = context;
mPropUtil.mPath = Environment.getExternalStorageDirectory() + "/ExmKeyValue";
mPropUtil.mFile = "properties.ini";
}
return mPropUtil;
}
public PropertiesHelper setPath(String path) {
mPath = path;
return this;
}
public PropertiesHelper setFile(String file) {
mFile = file;
return this;
}
public PropertiesHelper init() {
Log.d(TAG, "path="+mPath+"/"+mFile);
try {
File dir = new File(mPath);
if (!dir.exists()) {
dir.mkdirs();
}
File file = new File(dir, mFile);
if (!file.exists()) {
file.createNewFile();
}
InputStream is = new FileInputStream(file);
mProp = new Properties();
mProp.load(is);
is.close();
} catch (Exception e) {
e.printStackTrace();
}
return this;
}
public void commit() {
try {
File file = new File(mPath + "/" + mFile);
OutputStream os = new FileOutputStream(file);
mProp.store(os, "");
os.close();
} catch (Exception e) {
e.printStackTrace();
}
mProp.clear();
}
public void clear() {
mProp.clear();
}
public PropertiesHelper open() {
mProp.clear();
try {
File file = new File(mPath + "/" + mFile);
InputStream is = new FileInputStream(file);
mProp = new Properties();
mProp.load(is);
is.close();
} catch (Exception e) {
e.printStackTrace();
}
return this;
}
public void writeString(String name, String value) {
mProp.setProperty(name, value);
commit();
}
public String readString(String name, String defaultValue) {
return mProp.getProperty(name, defaultValue);
}
public void writeInt(String name, int value) {
mProp.setProperty(name, ""+value);
commit();
}
public int readInt(String name, int defaultValue) {
return Integer.parseInt(mProp.getProperty(name, ""+defaultValue));
}
public void writeBoolean(String name, boolean value) {
mProp.setProperty(name, ""+value);
commit();
}
public boolean readBoolean(String name, boolean defaultValue) {
return Boolean.parseBoolean(mProp.getProperty(name, ""+defaultValue));
}
public void writeDouble(String name, double value) {
mProp.setProperty(name, ""+value);
commit();
}
public double readDouble(String name, double defaultValue) {
return Double.parseDouble(mProp.getProperty(name, ""+defaultValue));
}
}
4.其他相关代码
MainActivity.java
package com.cupster.androidfile;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.btn_store_file).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
storeFile("这是存储的一段话");
}
});
findViewById(R.id.btn_read_file).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
readFile();
}
});
findViewById(R.id.btn_store_prop).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
storeProp();
}
});
findViewById(R.id.btn_read_prop).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
readProp();
}
});
tv= findViewById(R.id.tv_content);
checkPermission();
}
private void checkPermission(){
PermissionUtil.applyPermission(this ,101, getApplication().getPackageName());
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode ){
case 101:
if (grantResults.length >0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
}else {
toast("存储读取权限限制");
}
break;
}
}
private void storeFile(String str) {
if (FileStoreHelper.isExStoreUsable()){
FileStoreHelper.storeTxt(Environment.getExternalStorageDirectory().toString() + "/file.txt" ,str);
toast("已保存");
}else {
toast("无存储空间或权限");
}
}
private void readFile() {
if (FileStoreHelper.isExStoreUsable()){
String s = FileStoreHelper.readTxt(Environment.getExternalStorageDirectory().toString() + "/file.txt" );
tv.append("\n");
tv.append("read_txt:");
tv.append(s);
}else {
toast("无存储空间或权限");
}
}
private void storeProp() {
if (FileStoreHelper.isExStoreUsable()){
PropertiesHelper.getInstance(this).init().open().writeString("auto_update","yes");
}else {
toast("无存储空间或权限");
}
}
private void readProp() {
if (FileStoreHelper.isExStoreUsable()){
String s = PropertiesHelper.getInstance(this).init().readString("auto_update", "no");
tv.append("\n");
tv.append("auto_update:");
tv.append(s);
}else {
toast("无存储空间或权限");
}
}
private void toast(String text){
Toast.makeText(this ,text ,Toast.LENGTH_SHORT).show();
}
}
PermissionUtil.java
package com.cupster.androidfile;
import android.Manifest.permission;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
/**
* Encoding by Cupster on 2019/12/24 16:27.
*
* 动态申请权限工具类
*/
public final class PermissionUtil {
public static final String[] GROUP_CALENDAR = {
permission.READ_CALENDAR, permission.WRITE_CALENDAR
};
public static final String[] GROUP_CAMERA = {
permission.CAMERA
};
public static final String[] GROUP_CONTACTS = {
permission.READ_CONTACTS, permission.WRITE_CONTACTS, permission.GET_ACCOUNTS
};
public static final String[] GROUP_LOCATION = {
permission.ACCESS_FINE_LOCATION, permission.ACCESS_COARSE_LOCATION
};
public static final String[] GROUP_MICROPHONE = {
permission.RECORD_AUDIO
};
public static final String[] GROUP_PHONE = {
permission.READ_PHONE_STATE, permission.READ_PHONE_NUMBERS, permission.CALL_PHONE,
permission.READ_CALL_LOG, permission.WRITE_CALL_LOG, permission.ADD_VOICEMAIL,
permission.USE_SIP, permission.PROCESS_OUTGOING_CALLS, permission.ANSWER_PHONE_CALLS
};
public static final String[] GROUP_PHONE_BELOW_O = {
permission.READ_PHONE_STATE, permission.READ_PHONE_NUMBERS, permission.CALL_PHONE,
permission.READ_CALL_LOG, permission.WRITE_CALL_LOG, permission.ADD_VOICEMAIL,
permission.USE_SIP, permission.PROCESS_OUTGOING_CALLS
};
public static final String[] GROUP_SENSORS = {
permission.BODY_SENSORS
};
public static final String[] GROUP_SMS = {
permission.SEND_SMS, permission.RECEIVE_SMS, permission.READ_SMS,
permission.RECEIVE_WAP_PUSH, permission.RECEIVE_MMS,
};
public static final String[] GROUP_STORAGE = {
permission.READ_EXTERNAL_STORAGE, permission.WRITE_EXTERNAL_STORAGE,
};
/**
* 申请所有权限
* 调用后,activity中复写 onRequestPermissionsResult()处理申请权限结果
* PERMISSION_DENIED = -1;
* PERMISSION_GRANTED = 0;
* @param context activity
* @param requestCode 请求码
*/
public static void applyPermission(Activity context ,int requestCode ,String pkg) {
if (needApply(context ,pkg)) {
String[] allpermissions ={};
try {
allpermissions = context.getPackageManager().getPackageInfo(pkg, PackageManager.GET_PERMISSIONS)
.requestedPermissions;
} catch (PackageManager.NameNotFoundException e) {
Log.e("", "app has no request any permission" );
}
ActivityCompat.requestPermissions( context, allpermissions, requestCode);
}
}
/**
* 申请指定权限
* 调用后,activity中复写 onRequestPermissionsResult()处理申请权限结果
* PERMISSION_DENIED = -1;
* PERMISSION_GRANTED = 0;
* @param context activity
* @param permissions 指定的权限
*/
public static void applySignPermission(Activity context,int requestCode ,String[] permissions ) {
if (!checkPermissions(context ,permissions)) {
ActivityCompat.requestPermissions( context, permissions, requestCode);
}
}
public static boolean isGranted(final String... permissions) {
for (String permission : permissions) {
if (!isGranted(permission)) {
return false;
}
}
return true;
}
private static boolean isGranted(Context context ,final String permission) {
return Build.VERSION.SDK_INT < Build.VERSION_CODES.M
|| PackageManager.PERMISSION_GRANTED
== ContextCompat.checkSelfPermission(context.getApplicationContext(), permission);
}
/**
* 判断是否有权限限制
* @param context activity
* @param pkg 包名
* @return 是否需要申请放行权限
*/
public static boolean needApply(Activity context ,String pkg ){
boolean needApply = false;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
String[] allPermissions ={};
try {
allPermissions = context.getPackageManager().getPackageInfo(pkg, PackageManager.GET_PERMISSIONS)
.requestedPermissions;
} catch (PackageManager.NameNotFoundException e) {
Log.e("", "app has no request any permission" );
}
for (String permission : allPermissions) {
int checkPermission = ContextCompat.checkSelfPermission(context.getApplicationContext(),
permission);
if (checkPermission != PackageManager.PERMISSION_GRANTED) {
needApply = true;
}
}
}
return needApply;
}
/**
* 检测权限是否授权
* Activity.onRequestPermissionsResult()中回调使用
* @param permissions 权限数组
* @return true 有权限 false 被拒绝
*/
private static boolean checkPermissions(Context activity ,String[] permissions) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
return true;
}
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(activity, permission) !=
PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
}
public static void skipPermissionSetting(Context context){
// String sdk = android.os.Build.VERSION.SDK; // SDK号
// String model = android.os.Build.MODEL; // 手机型号
// String release = android.os.Build.VERSION.RELEASE; // android系统版本号
String brand = Build.BRAND;//手机厂商
if (TextUtils.equals(brand.toLowerCase(), "redmi") || TextUtils.equals(brand.toLowerCase(), "xiaomi")) {
gotoMiuiPermission(context);//小米
} else if (TextUtils.equals(brand.toLowerCase(), "meizu")) {
gotoMeizuPermission(context);
} else if (TextUtils.equals(brand.toLowerCase(), "huawei") || TextUtils.equals(brand.toLowerCase(), "honor")) {
gotoHuaweiPermission(context);
} else {
context.startActivity(getAppDetailSettingIntent(context));
}
}
/**
* 跳转到miui的权限管理页面
*/
private static void gotoMiuiPermission(Context context) {
try { // MIUI 8
Intent localIntent = new Intent("miui.intent.action.APP_PERM_EDITOR");
localIntent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.PermissionsEditorActivity");
localIntent.putExtra("extra_pkgname", context.getPackageName());
context.startActivity(localIntent);
} catch (Exception e) {
try { // MIUI 5/6/7
Intent localIntent = new Intent("miui.intent.action.APP_PERM_EDITOR");
localIntent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.AppPermissionsEditorActivity");
localIntent.putExtra("extra_pkgname", context.getPackageName());
context.startActivity(localIntent);
} catch (Exception e1) { // 否则跳转到应用详情
context.startActivity(getAppDetailSettingIntent(context));
}
}
}
/**
* 跳转到魅族的权限管理系统
*/
private static void gotoMeizuPermission(Context context) {
try {
Intent intent = new Intent("com.meizu.safe.security.SHOW_APPSEC");
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.putExtra("packageName", context.getPackageName());
context.startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
context.startActivity(getAppDetailSettingIntent(context));
}
}
/**
* 华为的权限管理页面
*/
private static void gotoHuaweiPermission(Context context) {
try {
Intent intent = new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ComponentName comp = new ComponentName("com.huawei.systemmanager", "com.huawei.permissionmanager.ui.MainActivity");//华为权限管理
intent.setComponent(comp);
context.startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
context.startActivity(getAppDetailSettingIntent(context));
}
}
/**
* 获取应用详情页面intent(如果找不到要跳转的界面,也可以先把用户引导到系统设置页面)
*
* @return Intent
*/
private static Intent getAppDetailSettingIntent(Context context) {
Intent localIntent = new Intent();
localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
localIntent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
localIntent.setData(Uri.fromParts("package",context.getPackageName(), null));
} else if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.FROYO) {
localIntent.setAction(Intent.ACTION_VIEW);
localIntent.setClassName("com.android.settings", "com.android.settings.InstalledAppDetails");
localIntent.putExtra("com.android.settings.ApplicationPkgName",context.getPackageName());
}
return localIntent;
}
/**
* Launch the application's details settings.
*/
public static void launchAppDetailsSettings(Context context ,String pkg) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.parse("package:" + pkg));
if (!isIntentAvailable( context ,intent)) return;
context.startActivity(intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
private static boolean isIntentAvailable(Context context ,final Intent intent) {
return context.getApplicationContext().getPackageManager()
.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY)
.size() > 0;
}
}
FileStoreHelper.java
package com.cupster.androidfile;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import androidx.core.app.NavUtils;
/**
* step1: 配置文件声明权限
*/
public class FileStoreHelper {
public static boolean isExStoreUsable() {
return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
}
public static void storeTxt(String path, String txtStr) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(path);
fos.write(txtStr.getBytes());
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static String readTxt(String path){
String readStr ="";
FileInputStream fis =null;
try {
fis = new FileInputStream(path);
byte[] bytes = new byte[fis.available()];
fis.read(bytes);
readStr = new String(bytes);
} catch (Exception e) {
e.printStackTrace();
}finally {
if (fis != null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return readStr;
}
public static void storeBitmap(String path , Bitmap bitmap ,int quality){
BufferedOutputStream bos= null;
FileOutputStream fos=null;
try {
fos = new FileOutputStream(path);
bos = new BufferedOutputStream(fos);
bitmap.compress(Bitmap.CompressFormat.JPEG,quality ,bos);
} catch (Exception e) {
e.printStackTrace();
}finally {
if (fos !=null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bos != null){
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static Bitmap loadBitmap(String path ){
Bitmap bitmap = null ;
FileInputStream fis = null;
BufferedInputStream bis = null;
try {
fis = new FileInputStream(path);
bis = new BufferedInputStream(fis);
bitmap = BitmapFactory.decodeStream(bis);
} catch (Exception e) {
e.printStackTrace();
}finally {
if (fis != null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bis != null){
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return bitmap;
}
}