027-Android存储(2):文件&Properties详解

371 阅读5分钟

1.概述

Android中文件操作与Java一致,File类是java中的文件操作工具类,Android其他文件操作API也是基于file操作进行的封装。

文件操作有:

  1. File
  2. Properties
  3. assets原始文件
  4. 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;
    }




}