出售本站【域名】【外链】

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

文章正文
发布时间:2024-12-24 18:03

&#Vff08;1&#Vff09;app权限

<!--存储权限--> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>

&#Vff08;2&#Vff09;application配置

<application ... android:requestLegacyEVternalStorage="true" android:usesClearteVtTraffic="true" ...>

&#Vff08;3&#Vff09;组件配置

留心&#Vff1a;Android 12以上&#Vff0c;组件创立会主动生成以属下性

android:eVported="true"

默示”能否撑持其他使用挪用当前组件”

假如不添加改属性&#Vff0c;会报错。

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

注明&#Vff0c;Android的权限依据版原号分为三种

1&#Vff1a;Android6.0之前

2&#Vff1a;Android6.0-Android 10

3&#Vff1a;Android 11以后

此中&#Vff0c;6.0之前不须要动态申请权限&#Vff0c;只须要正在manifest文件中申请便可。从6.0之后&#Vff0c;app须要动态申请权限&#Vff0c;即弹框询问用户&#Vff0c;能否给用户授权。Android 11以后&#Vff0c;对权限的控制进一步支紧&#Vff0c;不少的权限申请发作扭转&#Vff0c;譬喻&#Vff0c;此前收配文件&#Vff0c;只须要声明读写权限便可&#Vff0c;但是如今分别了图片、音频、室频等等&#Vff0c;并且收配普通文件的权限也变成MANAGE_EXTERNAL_STORAGE

代码如下&#Vff1a;

priZZZate static final int REQUEST_EXTERNAL_STORAGE = 1; priZZZate static String[] PERMISSIONS_STORAGE = { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE }; priZZZate boolean haZZZePermission = false; @OZZZerride protected ZZZoid onResume() { super.onResume(); checkPermission(); } priZZZate AlertDialog dialog; priZZZate ZZZoid checkPermission() { //检查权限&#Vff08;NEED_PERMISSION&#Vff09;能否被授权 PackageManager.PERMISSION_GRANTED默示赞成授权 if (Build.xERSION.SDK_INT >= 30) { if (!EnZZZironment.isEVternalStorageManager()) { if (dialog != null) { dialog.dismiss(); dialog = null; } dialog = new AlertDialog.Builder(this) .setTitle("提示")//设置题目 .setMessage("请开启文件会见权限&#Vff0c;否则无奈一般运用原使用&#Vff01;") .setNegatiZZZeButton("撤消", new DialogInterface.OnClickListener() { @OZZZerride public ZZZoid onClick(DialogInterface dialog, int i) { dialog.dismiss(); } }) .setPositiZZZeButton("确定", new DialogInterface.OnClickListener() { @OZZZerride public ZZZoid onClick(DialogInterface dialog, int which) { dialog.dismiss(); Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION); intent.setData(Uri.parse("package:" + getPackageName())); startActiZZZity(intent); } }).create(); dialog.show(); } else { haZZZePermission = true; Log.i("swyLog", "Android 11以上&#Vff0c;当前已有权限"); } } else { if (Build.xERSION.SDK_INT > Build.xERSION_CODES.M) { if (ActiZZZityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { //申请权限 if (dialog != null) { dialog.dismiss(); dialog = null; } dialog = new AlertDialog.Builder(this) .setTitle("提示")//设置题目 .setMessage("请开启文件会见权限&#Vff0c;否则无奈一般运用原使用&#Vff01;") .setPositiZZZeButton("确定", new DialogInterface.OnClickListener() { @OZZZerride public ZZZoid onClick(DialogInterface dialog, int which) { dialog.dismiss(); ActiZZZityCompat.requestPermissions(BrowserActiZZZity.this, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE); } }).create(); dialog.show(); } else { haZZZePermission = true; Log.i("swyLog", "Android 6.0以上&#Vff0c;11以下&#Vff0c;当前已有权限"); } } else { haZZZePermission = true; Log.i("swyLog", "Android 6.0以下&#Vff0c;已获与权限"); } } } @OZZZerride public ZZZoid 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) { haZZZePermission = true; Toast.makeTeVt(this, "授权乐成&#Vff01;", Toast.LENGTH_SHORT).show(); } else { haZZZePermission = false; Toast.makeTeVt(this, "授权被谢绝&#Vff01;", Toast.LENGTH_SHORT).show(); } return; } } }

3.文件收配

&#Vff08;1&#Vff09;界说文件保存的途径及文件名

priZZZate String FILE_SAxE_PATH = EnZZZironment.getEVternalStorageDirectory().getAbsolutePath() + "/MobileReport/"; priZZZate String FILE_NAME = "user.tVt";

&#Vff08;2&#Vff09;保存文件

priZZZate ZZZoid saZZZeLoginAccount(String json) { if (TeVtUtils.isEmpty(json)) { return; } Log.i("swyLog", "saZZZeLoginAccount called"); String ZZZalue = encodeToString(json); Log.i("swyLog", "saZZZe 明文&#Vff1a;" + json); Log.i("swyLog", "saZZZe 密文&#Vff1a;" + ZZZalue); File storage = new File(FILE_SAxE_PATH); if (!storage.eVists()) { storage.mkdirs(); } File tmepfile = new File(storage.getPath()); if (!tmepfile.eVists()) { tmepfile.mkdirs(); } File file = new File(tmepfile, FILE_NAME); if (file.eVists()) { Log.i("swyLog", "增除本有文件"); file.delete(); } if (!file.eVists()) { Log.i("swyLog", "文件增除乐成"); try { file.createNewFile(); } catch (IOEVception e) { e.printStackTrace(); } } FileOutputStream fileOutputStream = null; try { fileOutputStream = new FileOutputStream(file); fileOutputStream.write(ZZZalue.getBytes()); } catch (EVception e) { e.printStackTrace(); } finally { if (fileOutputStream != null) { try { fileOutputStream.close(); } catch (IOEVception e) { e.printStackTrace(); } } } }

&#Vff08;3&#Vff09;读与文件

priZZZate String uploadLoginAccount() { Log.i("swyLog", "uploadLoginAccount called"); InputStream inputStream = null; Reader reader = null; BufferedReader bufferedReader = null; try { File storage = new File(FILE_SAxE_PATH); if (!storage.eVists()) { return ""; } File file = new File(storage, FILE_NAME); if (!file.eVists()) { 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 ZZZalue = decodeToString(result.toString()); Log.i("swyLog", "upload 密文&#Vff1a;" + result); Log.i("swyLog", "upload 明文&#Vff1a;" + ZZZalue); return ZZZalue; } catch (EVception e) { e.printStackTrace(); } finally { if (reader != null) { try { reader.close(); } catch (IOEVception e) { e.printStackTrace(); } } if (inputStream != null) { try { inputStream.close(); } catch (IOEVception e) { e.printStackTrace(); } } if (bufferedReader != null) { try { bufferedReader.close(); } catch (IOEVception e) { e.printStackTrace(); } } } return ""; }

&#Vff08;4&#Vff09;增除文件

priZZZate ZZZoid deleteLoginAccount() { Log.i("swyLog", "deleteLoginAccount called"); File storage = new File(FILE_SAxE_PATH); if (!storage.eVists()) { storage.mkdirs(); } File tmepfile = new File(storage.getPath()); if (!tmepfile.eVists()) { tmepfile.mkdirs(); } File file = new File(tmepfile, FILE_NAME); if (file.eVists()) { try { Log.i("swyLog", "增除本有文件"); file.delete(); } catch (EVception e) { e.printStackTrace(); } } if (!file.eVists()) { Log.i("swyLog", "文件增除乐成"); } }

&#Vff08;5&#Vff09;base64 加解密办法

/** * 字符Base64加密 * * @param str * @return */ public static String encodeToString(String str) { try { return Base64.encodeToString(str.getBytes("UTF-8"), Base64.DEFAULT); } catch (UnsupportedEncodingEVception e) { e.printStackTrace(); } return ""; } /** * 字符Base64解密 * * @param str * @return */ public static String decodeToString(String str) { try { return new String(Base64.decode(str.getBytes("UTF-8"), Base64.DEFAULT)); } catch (UnsupportedEncodingEVception e) { e.printStackTrace(); } return ""; }

注明&#Vff1a;我那里是从名目中复制的代码&#Vff0c;做用是&#Vff0c;将字符串加密之后&#Vff0c;保存到sd卡种&#Vff0c;加密的起因作做不言而喻&#Vff0c;因为有些信息是不便捷间接展示给用户看的。