文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android 保存/读取本地SD卡文件(兼容Android 13)

2023-08-31 09:23

关注

1.manifeast文件

(1)app权限

(2)application配置

(3)组件配置

注意:Android 12以上,组件创建会自动生成以下属性

android:exported="true"

表示”是否支持其它应用调用当前组件”

如果不添加改属性,会报错。

2.动态申请文件存储权限

说明,Android的权限根据版本号分为三种

Android6.0之前

Android6.0-Android 10

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 = {        Manifest.permission.READ_EXTERNAL_STORAGE,        Manifest.permission.WRITE_EXTERNAL_STORAGE};private boolean havePermission = false;
@Overrideprotected void onResume() {    super.onResume();    checkPermission();}
private AlertDialog dialog;private void checkPermission() {    //检查权限(NEED_PERMISSION)是否被授权 PackageManager.PERMISSION_GRANTED表示同意授权    if (Build.VERSION.SDK_INT >= 30) {        if (!Environment.isExternalStorageManager()) {            if (dialog != null) {                dialog.dismiss();                dialog = null;            }            dialog = new AlertDialog.Builder(this)                    .setTitle("提示")//设置                    .setMessage("请开启文件访问权限,否则无法正常使用本应用!")                    .setNegativeButton("取消", new DialogInterface.OnClickListener() {                        @Override                        public void onClick(DialogInterface dialog, int i) {dialog.dismiss();                        }                    })                    .setPositiveButton("确定", new DialogInterface.OnClickListener() {                        @Override                        public void onClick(DialogInterface dialog, int which) {dialog.dismiss();Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);startActivity(intent);                        }                    }).create();            dialog.show();        } else {            havePermission = true;            Log.i("swyLog", "Android 11以上,当前已有权限");        }    } else {        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {                //申请权限                if (dialog != null) {                    dialog.dismiss();                    dialog = null;                }                dialog = new AlertDialog.Builder(this)                        .setTitle("提示")//设置                        .setMessage("请开启文件访问权限,否则无法正常使用本应用!")                        .setPositiveButton("确定", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {    dialog.dismiss();    ActivityCompat.requestPermissions(BrowserActivity.this, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);}                        }).create();                dialog.show();            } else {                havePermission = true;                Log.i("swyLog", "Android 6.0以上,11以下,当前已有权限");            }        } else {            havePermission = true;            Log.i("swyLog", "Android 6.0以下,已获取权限");        }    }}
@Overridepublic void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);    switch (requestCode) {        case REQUEST_EXTERNAL_STORAGE: {            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {                havePermission = true;                Toast.makeText(this, "授权成功!", Toast.LENGTH_SHORT).show();            } else {                havePermission = false;                Toast.makeText(this, "授权被拒绝!", Toast.LENGTH_SHORT).show();            }            return;        }    }}

3.文件操作

(1)定义文件保存的路径及文件名

private String FILE_SAVE_PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + "/MobileReport/";private String FILE_NAME = "user.txt";

(2)保存文件

private void saveLoginAccount(String json) {    if (TextUtils.isEmpty(json)) {        return;    }    Log.i("swyLog", "saveLoginAccount called");    String value = encodeToString(json);    Log.i("swyLog", "save 明文:" + json);    Log.i("swyLog", "save 密文:" + value);    File storage = new File(FILE_SAVE_PATH);    if (!storage.exists()) {        storage.mkdirs();    }    File tmepfile = new File(storage.getPath());    if (!tmepfile.exists()) {        tmepfile.mkdirs();    }    File file = new File(tmepfile, FILE_NAME);    if (file.exists()) {        Log.i("swyLog", "删除原有文件");        file.delete();    }    if (!file.exists()) {        Log.i("swyLog", "文件删除成功");        try {            file.createNewFile();        } catch (IOException e) {            e.printStackTrace();        }    }    FileOutputStream fileOutputStream = null;    try {        fileOutputStream = new FileOutputStream(file);        fileOutputStream.write(value.getBytes());    } catch (Exception e) {        e.printStackTrace();    } finally {        if (fileOutputStream != null) {            try {                fileOutputStream.close();            } catch (IOException e) {                e.printStackTrace();            }        }    }}

(3)读取文件

private String uploadLoginAccount() {    Log.i("swyLog", "uploadLoginAccount called");    InputStream inputStream = null;    Reader reader = null;    BufferedReader bufferedReader = null;    try {        File storage = new File(FILE_SAVE_PATH);        if (!storage.exists()) {            return "";        }        File file = new File(storage, FILE_NAME);        if (!file.exists()) {            return "";        }        inputStream = new FileInputStream(file);        reader = new InputStreamReader(inputStream);        bufferedReader = new BufferedReader(reader);        StringBuilder result = new StringBuilder();        String temp;        while ((temp = bufferedReader.readLine()) != null) {            result.append(temp);        }        String value = decodeToString(result.toString());        Log.i("swyLog", "upload 密文:" + result);        Log.i("swyLog", "upload 明文:" + value);        return value;    } catch (Exception e) {        e.printStackTrace();    } finally {        if (reader != null) {            try {                reader.close();            } catch (IOException e) {                e.printStackTrace();            }        }        if (inputStream != null) {            try {                inputStream.close();            } catch (IOException e) {                e.printStackTrace();            }        }        if (bufferedReader != null) {            try {                bufferedReader.close();            } catch (IOException e) {                e.printStackTrace();            }        }    }    return "";}

(4)删除文件

private void deleteLoginAccount() {    Log.i("swyLog", "deleteLoginAccount called");    File storage = new File(FILE_SAVE_PATH);    if (!storage.exists()) {        storage.mkdirs();    }    File tmepfile = new File(storage.getPath());    if (!tmepfile.exists()) {        tmepfile.mkdirs();    }    File file = new File(tmepfile, FILE_NAME);    if (file.exists()) {        try {            Log.i("swyLog", "删除原有文件");            file.delete();        } catch (Exception e) {            e.printStackTrace();        }    }    if (!file.exists()) {        Log.i("swyLog", "文件删除成功");    }}

(5)base64 加解密方法

public static String encodeToString(String str) {    try {        return Base64.encodeToString(str.getBytes("UTF-8"), Base64.DEFAULT);    } catch (UnsupportedEncodingException e) {        e.printStackTrace();    }    return "";}public static String decodeToString(String str) {    try {        return new String(Base64.decode(str.getBytes("UTF-8"), Base64.DEFAULT));    } catch (UnsupportedEncodingException e) {        e.printStackTrace();    }    return "";}

说明:我这里是从项目中复制的代码,作用是,将字符串加密之后,保存到sd卡种,加密的原因自然不言而喻,因为有些信息是不方便直接展示给用户看的。

来源地址:https://blog.csdn.net/weixin_53324308/article/details/129966403

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯