一手遮天 Android - 存儲: Android 11 使用外部存儲
示例如下:
/storage/Android11Demo1.java
/**
* 本例用於演示如何在 android 11.0 或以上系統且 targetSdkVersion 大於等於 30 時使用外部存儲
*
* 1、android 10.0 或以上系統且 targetSdkVersion 小於等於 29 時使用外部存儲
* 在 AndroidManifest 的 application 節點配置 requestLegacyExternalStorage="true"
*
* 2、android 11.0 或以上系統且 targetSdkVersion 大於等於 30 時使用外部存儲
* 在 AndroidManifest 配置 <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
* 這個需要用戶先去設置頁打開相關權限
*
* 3、android 11.0 或以上系統且 targetSdkVersion 大於等於 30 時不使用外部存儲,但是需要對老程序做外部存儲到內部存儲的遷移
* 在 AndroidManifest 的 application 節點配置 preserveLegacyExternalStorage="true"
* 這樣的話,如果你是更新老版程序則可使用外部存儲,如果是新裝程序則不可使用外部存儲
*/
package com.webabcd.androiddemo.storage;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.Settings;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.webabcd.androiddemo.R;
import com.webabcd.androiddemo.utils.Helper;
import java.io.File;
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.Locale;
public class Android11Demo1 extends AppCompatActivity {
private Button _button1;
private TextView _textView1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_storage_android11demo1);
_button1 = findViewById(R.id.button1);
_textView1 = findViewById(R.id.textView1);
// 演示如何在 android 11.0 或以上系統且 targetSdkVersion 大於等於 30 時使用外部存儲
sample();
}
private void sample() {
_button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
createFile();
}
});
}
private void createFile() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
appendLog("本例需要在 android 11 或以上系統中運行");
return;
}
// 判斷是否有使用外部存儲的權限
if (Environment.isExternalStorageManager()) {
String dirPath = Environment.getExternalStorageDirectory() + "/wanglei_test/";
File dir = new File(dirPath);
if (!dir.exists()) {
// 沒有權限的話會返回 false
boolean isOk = dir.mkdirs();
appendLog(String.format(Locale.ENGLISH, "%s mkdirs: %b", dirPath, isOk));
} else {
appendLog(String.format(Locale.ENGLISH, "文件夾存在: %s", dirPath));
}
// 新建文件
String stringContent = Helper.formatDate(new Date(), "HH:mm:ss\n");
byte[] bytesContent = stringContent.getBytes(StandardCharsets.UTF_8);
File file = new File(dirPath, new Date().getTime() + ".txt");
try {
FileOutputStream fos = new FileOutputStream(file);
fos.write(bytesContent);
fos.close();
appendLog(String.format(Locale.ENGLISH, "新建文件成功: %s", file.getAbsolutePath()));
} catch (Exception ex) {
appendLog(String.format(Locale.ENGLISH, "新建文件失敗: %s", ex.toString()));
}
} else {
appendLog("請先去設置頁打開相關權限");
// 跳轉到 ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION 權限設置頁
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
intent.setData(Uri.parse("package:" + this.getPackageName()));
startActivityForResult(intent, 123);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 123) {
if (Environment.isExternalStorageManager()) {
appendLog("打開了 ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION 權限");
} else {
appendLog("關閉了 ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION 權限");
}
}
}
private void appendLog(String message) {
_textView1.append(message);
_textView1.append("\n");
}
}
/layout/activity_storage_android11demo1.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAllCaps="false"
android:text="在外部存儲新建一個文件" />
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp" />
</LinearLayout>