<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
為了這個系列,我的程式碼已經準備到了第150天了。接下來的內容會越來越精彩,我們也越來越開始進入Android的一些高階功能上的程式設計了。今天我們就要講Android中對本地檔案進行讀寫的全過程。
以上一共我們有3個目標,根據目標下面開始教學。
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/LinearLayout1" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="清輸入檔名" /> <EditText android:id="@+id/editFileName" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="檔名" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="清輸入檔案內容" /> <EditText android:id="@+id/editFileContents" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="檔案內容" /> <Button android:id="@+id/buttonSave" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="儲存到SD卡" /> <Button android:id="@+id/buttonClean" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="清空" /> <Button android:id="@+id/buttonRead" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="讀取sd卡中的檔案" /> </LinearLayout>
我們的UI端很簡單,用LinearLayout從上到下依次把一系列元素都設定好。接著我們來看我們的後端程式碼。
靜態授權-AndroidManifest.xml檔案內容
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <!-- 在SDCard中建立與刪除檔案許可權 --> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" tools:ignore="ProtectedPermissions" /> <!-- 往SDCard寫入資料許可權 --> <uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION"/> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" tools:ignore="ScopedStorage" /> <!--外部儲存的寫許可權--> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!--外部儲存的讀許可權--> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <application android:requestLegacyExternalStorage="true" android:allowBackup="true" android:dataExtractionRules="@xml/data_extraction_rules" android:fullBackupContent="@xml/backup_rules" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.DemoSimpleFile" tools:targetApi="31"> <activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <meta-data android:name="android.app.lib_name" android:value="" /> <meta-data android:name="ScopedStorage" android:value="true" /> </activity> </application> </manifest>
注意以上的4行<uses-permission>。
檔案讀寫幫助類-SDFileUtility.java
package org.mk.android.demo; import android.content.Context; import android.os.Environment; import android.util.Log; import android.widget.Toast; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class SDFileUtility { private final static String TAG = "DemoSimpleFile"; private Context context; public SDFileUtility() { } public SDFileUtility(Context context) { super(); this.context = context; } //往SD卡寫入檔案的方法 public void savaFileToSD(String fileName, String fileContents) throws Exception { //如果手機已插入sd卡,且app具有讀寫sd卡的許可權 if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { fileName = Environment.getExternalStorageDirectory().getCanonicalPath() + "/" + fileName; //這裡就不要用openFileOutput了,那個是往手機記憶體中寫資料的 FileOutputStream output = null; try { output = new FileOutputStream(fileName); output.write(fileContents.getBytes()); //將String字串以位元組流的形式寫入到輸出流中 } catch (Exception e) { Log.e(TAG, "saveFileTOSD error: " + e.getMessage(), e); } finally { try { output.close(); //關閉輸出流 } catch (Exception e) { } } } else Toast.makeText(context, "SD卡不存在或者不可讀寫", Toast.LENGTH_SHORT).show(); } //讀取SD卡中檔案的方法 //定義讀取檔案的方法: public String readFromSD(String fileName) throws IOException { StringBuilder sb = new StringBuilder(""); if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { fileName = Environment.getExternalStorageDirectory().getCanonicalPath() + "/" + fileName; FileInputStream input = null; try { //開啟檔案輸入流 input = new FileInputStream(fileName); byte[] temp = new byte[1024]; int len = 0; //讀取檔案內容: while ((len = input.read(temp)) > 0) { sb.append(new String(temp, 0, len)); } } catch (Exception e) { Log.e(TAG, "readFromSD error: " + e.getMessage(), e); } finally { try { //關閉輸入流 input.close(); } catch (Exception e) { } } } return sb.toString(); } }
後端主互動類-MainActivity.java
package org.mk.android.demo; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import android.Manifest; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.provider.Settings; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; public class MainActivity extends AppCompatActivity implements View.OnClickListener { private EditText editFileName; private EditText editContents; private Button buttonSave; private Button buttonClean; private Button buttonRead; private Context mContext; private final static String TAG = "DemoSimpleFile"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mContext = getApplicationContext(); bindViews(); } private void bindViews() { editFileName = (EditText) findViewById(R.id.editFileName); editContents = (EditText) findViewById(R.id.editFileContents); buttonSave = (Button) findViewById(R.id.buttonSave); buttonClean = (Button) findViewById(R.id.buttonClean); buttonRead = (Button) findViewById(R.id.buttonRead); buttonSave.setOnClickListener(this); buttonClean.setOnClickListener(this); buttonRead.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.buttonClean: editContents.setText(""); editFileName.setText(""); break; case R.id.buttonSave: if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.R) { Log.i(TAG,">>>>>>version.SDK->"+Build.VERSION.SDK_INT); if (!Environment.isExternalStorageManager()) { Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION); this.startActivity(intent); return; } } Log.i(TAG,">>>>>>start to writeFile"); writeFile(); Log.i(TAG,">>>>>>write success"); break; case R.id.buttonRead: if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.R) { Log.i(TAG,">>>>>>version.SDK->"+Build.VERSION.SDK_INT); if (!Environment.isExternalStorageManager()) { Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION); this.startActivity(intent); return; } } Log.i(TAG,">>>>>>start to readFile"); readFile(); Log.i(TAG,">>>>>>read success"); break; } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == 1 && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) { //writeFile(); Log.i(TAG,">>>>>>onRequestPermissionsResult"); } } private void writeFile() { String fileName = editFileName.getText().toString(); String fileContents = editContents.getText().toString(); SDFileUtility sdHelper = new SDFileUtility(mContext); try { sdHelper.savaFileToSD(fileName, fileContents); Toast.makeText(getApplicationContext(), "資料寫入成功", Toast.LENGTH_SHORT).show(); } catch (Exception e) { Log.e(TAG, "save contents into file has errors: " + e.getMessage(), e); Toast.makeText(getApplicationContext(), "資料寫入失敗", Toast.LENGTH_SHORT).show(); } } private void readFile() { String detail = ""; SDFileUtility sdHelper2 = new SDFileUtility(mContext); try { String fileName2 = editFileName.getText().toString(); detail = sdHelper2.readFromSD(fileName2); } catch (Exception e) { Log.e(TAG, "read contents from file has errors: " + e.getMessage(), e); } Toast.makeText(getApplicationContext(), detail, Toast.LENGTH_SHORT).show(); } }
核心程式碼導讀
讀寫手機SD卡,我們除了在AndroidManifest.xml檔案中靜態申請許可權外還需要使用程式碼動態申請許可權,這是Android6後的許可權限制帶來的問題。
case R.id.buttonSave: if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.R) { Log.i(TAG,">>>>>>version.SDK->"+Build.VERSION.SDK_INT); if (!Environment.isExternalStorageManager()) { Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION); his.startActivity(intent); return; } }
這一段程式碼就是使用程式碼在寫檔案前動態申請許可權用的,當這段程式碼執行後會彈出以下這樣的一個對話方塊
點選這個APP應用,然後來到第二個對話方塊
點選我紅圈處標出的開關按鈕
然後重新執行APP即可。
到此這篇關於Android入門之讀寫本地檔案的實現的文章就介紹到這了,更多相關Android讀寫本地檔案內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45