2023年3月16日 星期四

Android Studio - Android 12 外部存儲空間讀寫檔案程式(一百一十)

Android Studio - Android 12 外部存儲空間讀寫檔案程式(一百一十):

筆者將 Android 12 外部存儲空間(External Storage)的路徑放入程式內作測試,外部存儲空間路徑也是蠻多,所以將資料匯集紀錄,因為很多時候需要讀寫本地檔的操作,將來作參考作用。這個程式是使用了 SAF(Storage Access Framework)框架,暫時解決了 Android 12 外部存儲空間讀寫檔案程式問題。


Android 12 外部存儲空間讀寫程式
操作系統:Windows 7 64-bit 版本
開發環境:Android Studio 4.0.1 版本
最低 SDK 版本:minSdkVersion 24
測試手機:Samsung Galaxy M33 5G
測試手機系統版本:Android 12(Snow Cone / 2021)
原程式:C:\Development\Development_Android\DIY-Android-190-15d Android12ReadWriteFile bugworkshop 20230304 - ReadWriteFileExt
程式:C:\Development\Development_Android\Android_Project\DIY-Android-190-15d Android12ReadWriteFile bugworkshop 20230304 - ReadWriteFileExt

MainActivity.java:

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_readwrite_ext);

 

        mbtn_save = (Button)findViewById(R.id.btn_save);

        mbtn_load = (Button)findViewById(R.id.btn_load);

        mtxt_filepath = (TextView) findViewById(R.id.text_path);

        mtxt_filecontent= (TextView) findViewById(R.id.text_content);

        mtxt_filecontent.setMovementMethod(new ScrollingMovementMethod());

        mlist_file = findViewById(R.id.list_file);

        medit_input = (EditText) findViewById(R.id.edittext_input);

 

        myfolder= getFilesDir();

        myFilename = new File(getFilesDir(), filename);

 

        mbtn_save.setOnClickListener(new View.OnClickListener()

        {

            @Override

            public void onClick(View v) {

                filePicker(false);

            }

        });

 

        mbtn_load.setOnClickListener(new View.OnClickListener()

        {

            @Override

            public void onClick(View v) {

                read();

            }

        });

}

 

   ActivityResultLauncher<Intent> mLaunchFilePicker = registerForActivityResult(

            new ActivityResultContracts.StartActivityForResult(), result -> {

                Intent data = result.getData();

                if (result.getResultCode() == Activity.RESULT_OK && data != null) {

                    handleFileResult(data,true);

                }

            });

 

    ActivityResultLauncher<Intent> mLaunchFileSaver = registerForActivityResult(

            new ActivityResultContracts.StartActivityForResult(), result -> {

                Intent data = result.getData();

                if (result.getResultCode() == Activity.RESULT_OK && data != null) {

                    handleFileResult(data,false);

                }

            });

 

    void filePicker(boolean readOrWrite) {

        if (readOrWrite) {

            intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);

            intent.setType("*/*");

            intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);

            intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);

            mLaunchFilePicker.launch(intent);

        } else {

            intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);

            intent.setType("text/*");

            intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);

            intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);

            mLaunchFileSaver.launch(intent);

 

        }

    }

 

    private void handleFileResult(Intent data, boolean readOrWrite) {

        mFileUri = data.getData();

 

        if (mFileUri != null) {

            try {

                getContentResolver().takePersistableUriPermission(mFileUri, Intent.FLAG_GRANT_READ_URI_PERMISSION);

            } catch (SecurityException e) {

                e.printStackTrace();

            }

            if (readOrWrite) {

                read();

            } else {

                write();

            }

        }

    }


MainActivity.java - Read External Storage File:

    void read() {

 

        try {

            InputStreamReader inputStreamReader = new InputStreamReader(getContentResolver().openInputStream(mFileUri));

            BufferedReader reader = new BufferedReader(inputStreamReader);

            StringBuilder builder = new StringBuilder();

            try {

                String fileContentLine;

                while ((fileContentLine = reader.readLine()) != null) {

                    fileContentLine += "\n";

                    builder.append(fileContentLine);

                }

                String fileContent = builder.toString();

                mtxt_filecontent.setText(fileContent);

                medit_input.setText(fileContent);

            } finally {

                mtxt_filepath.setText(mFileUri.toString());

                reader.close();

                inputStreamReader.close();

            }

        } catch (IOException e) {

            e.printStackTrace();

        }

    }


MainActivity.java - Write External Storage File:

    void write() {

        mtxt_filepath.setText("Save File=" + mFileUri.toString());

 

        try {

            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(getContentResolver().openOutputStream(mFileUri));

            BufferedWriter writer = new BufferedWriter(outputStreamWriter);

            String textContent = medit_input.getText().toString();

 

            try {

                writer.write(textContent);

            } finally {

                writer.close();

                outputStreamWriter.close();

            }

        } catch (IOException e) {

            e.printStackTrace();

        }

    }


Android 12 外部存儲空間寫入程式
Android 12 外部存儲空間寫入程式
Android 12 外部存儲空間讀取程式




2023年3月14日 星期二

Android Studio - Android 12 外部存儲空間路徑程式(一百零九)

Android Studio - Android 12 外部存儲空間路徑程式(一百零九):

筆者完成了 Android 12 內部存儲空間(Internal Storage)的路徑測試程式,也開始實驗 Android 12 外部存儲空間(External Storage)的路徑測試程式。

Android Studio - Android 12 外部存儲空間路徑程式(一百零九):

操作系統:Windows 7 64-bit 版本
開發環境:Android Studio 4.0.1 版本
最低 SDK 版本:minSdkVersion 24
測試手機:Samsung Galaxy M33 5G
測試手機系統版本:Android 12(Snow Cone / 2021)
原程式:C:\Development\Development_Android\DIY-Android-190-15d Android12ReadWriteFile bugworkshop 20230304 - ReadWriteFileStorage
程式:C:\Development\Development_Android\Android_Project\DIY-Android-190-15d Android12ReadWriteFile bugworkshop 20230304 - ReadWriteFileStorage

MainActivity.java:

    public void externallStorage(){

 

        mtxt_hello.setText("External - Read Write Storage");

        String PackageName = getPackageName();

        Log.d(MainActivity.TAG, "ReadWriteFileInt.internalStorage().getPackageName=" + PackageName );

 

        // File

        File getExternalFilesDir = new File(getExternalFilesDir(""), "fileName");

        File getExternalCacheDir = new File(getExternalCacheDir(), "fileName");

 

        //File[] getExternalMediaDirs = new File(getExternalCacheDirs(), "fileName");

 

        // String

        String getExternalStorageDirectory = Environment.getExternalStorageDirectory().getPath();

        String getExternalStoragePublicDirectory = Environment.getExternalStoragePublicDirectory("file").getPath();

        String getExternalStorageState = Environment.getExternalStorageState();

 

        // String

        File dcimgetExternalStoragePublicDirectory = new File(getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), "fileName");

        String dcimDirectory = Environment.DIRECTORY_DCIM;

        String musicDirectory = Environment.DIRECTORY_MUSIC;

        String podcastsDirectory = Environment.DIRECTORY_PODCASTS;

        String ringtonesDirectory = Environment.DIRECTORY_RINGTONES;

        String alarmDirectory = Environment.DIRECTORY_ALARMS;

        String notificationDirectory = Environment.DIRECTORY_NOTIFICATIONS;

        String picturesDirectory = Environment.DIRECTORY_PICTURES;

        String moviesDirectory = Environment.DIRECTORY_MOVIES;

        String downloadsDirectory = Environment.DIRECTORY_DOWNLOADS;

        String documentsDirectory = Environment.DIRECTORY_DOCUMENTS;

 

        String content = "";

        // File

        content = content + "getExternalFilesDir=" + getExternalFilesDir + "\n";

        content = content + "getExternalCacheDir=" + getExternalCacheDir  + "\n";

        content = content + "Environment.getExternalStorageDirectory=" + getExternalStorageDirectory  + "\n";

        content = content + "Environment.getExternalStoragePublicDirectory=" + getExternalStoragePublicDirectory  + "\n";

        content = content + "Environment.getExternalStorageState=" + getExternalStorageState  + "\n";

 

        // String

        content = content + "Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)==" + dcimgetExternalStoragePublicDirectory  + "\n";

        content = content + "Environment.DIRECTORY_DCIM=" + dcimDirectory  + "\n";

        content = content + "Environment.DIRECTORY_MUSIC=" + musicDirectory  + "\n";

        content = content + "Environment.DIRECTORY_PODCASTS=" + podcastsDirectory  + "\n";

        content = content + "Environment.DIRECTORY_RINGTONES=" + ringtonesDirectory  + "\n";

        content = content + "Environment.DIRECTORY_ALARMS=" + alarmDirectory  + "\n";

        content = content + "Environment.DIRECTORY_NOTIFICATIONS=" + notificationDirectory  + "\n";

        content = content + "Environment.DIRECTORY_PICTURES=" + picturesDirectory  + "\n";

        content = content + "Environment.DIRECTORY_MOVIES=" + moviesDirectory  + "\n";

        content = content + "Environment.DIRECTORY_DOWNLOADS=" + downloadsDirectory  + "\n";

        content = content + "Environment.DIRECTORY_DOCUMENTS=" + documentsDirectory  + "\n";

 

        mtxt_filecontent.setText(content);

    }




2023年3月13日 星期一

Android Studio - Android 12 外部存儲空間介紹(一百零八)

Android Studio - Android 外部存儲空間介紹(一百零八):

介紹了 Android 12 內部存儲空間(Internal Storage),重點是在 Android 12 使用外部存儲空間(External Storage),在 Android 4 ~ Android 9 使用外部存儲器其基本上和內部存儲空間相同,但在 Android 10 開始,要使用外部存儲空間是比較嚴謹。

Android Studio - Android 外部存儲空間介紹(一百零八):
外部存儲空間(External Storage) 區分基礎外部儲存空間(Primary External Storage) 及附加外部儲存空間(Secondary External Storage) 兩種類型,每個類型還區分 APP 專屬目錄及共享目錄。這幾種類型主要差異只有目錄取得的方式,後續的各項操作都大同小異。基礎外部儲存空間是位於手機內部的儲存空間,因此無論有沒有 SD卡,APP 都一定有基礎外部儲存空間可以使用。附加外部儲存空間就是指在基礎外部儲存空間以外的儲存空間,一般常見的就是 SD卡 或是 USB 外接隨身碟。

外部存儲空間(External Storage)分區的特點:
  • 外部分區並不總是可用。
  • 保存在這裡的檔可能被其他程式訪問。
  • 當使用者卸載 APP 時,系統僅僅會刪除 External 中的緩存目錄(Context.getExternalCacheDir())和file目錄(Context.getExternalFilesDir())下的相關檔。
  • 需要申請 WRITE_EXTERNAL_STORAGE 或 READ_EXTERNAL_STORAGE 許可權。

外部存儲空間(External Storage)路徑:

Class

Description

屬性

 

getExternalFilesDir()

/storage/emulated/0/Android/data/ packagename /files/fileName

File

Context

getExternalCacheDir()

/storage/emulated/0/Android/data/ packagename /cache/fileName

File

Context

getExternalMediaDir()

 

File

Context

getExternalStorageDirectory()

/storage/emulated/0

String

Environment

getExternalStoragePublicDirectory()

/storage/emulated/0/file

String

Environment

getExternalStorageState()

mounted

String

Environment

getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)

/storage/emulated/0/DCIM/fileName

File

Environment

DIRECTORY_DCIM=DCIM

DCIM

String

Environment

DIRECTORY_MUSIC

Music

String

Environment

DIRECTORY_PODCASTS

Podcasts

String

Environment

DIRECTORY_RINGTONES

Ringtones

String

Environment

DIRECTORY_ALARMS

Alarms

String

Environment

DIRECTORY_NOTIFICATIONS

Notifications

String

Environment

DIRECTORY_PICTURES

Pictures

String

Environment

DIRECTORY_MOVIES

Movies

String

Environment

DIRECTORY_DOWNLOADS

Download

String

Environment

DIRECTORY_DOCUMENTS

Documents

String

Environment


Android 12 引入了以下存儲空間管理功能:
  • 當應用檢索與給定文檔提供程式 URI 等效的媒體 URI 時,媒體庫支持 MediaDocumentsProvider。
  • 用於錄音的目錄。
  • MANAGE_MEDIA 許可權,此許可權允許應用執行媒體管理操作,而無需針對每項操作向使用者顯示確認對話方塊。
  • 同時具有 MANAGE_EXTERNAL_STORAGE 許可權和 QUERY_ALL_PACKAGES 許可權的應用(例如檔管理應用)可以調用自訂 activity 來管理另一個應用的存儲空間,前提是另一個應用會創建自訂 activity。

2023年 3月 13日(Mon)天氣報告
氣溫:41.0°F / 5.0°C @ 07:00
風速:每小時 14公里
降雨機會:94%
相對濕度:百分之 91%
天氣:雨