HDU-安卓程式開發之簡單儲存/內部儲存/外部儲存 & 捉蟲
前言
大三上學期可以說是各工科學生課最難最多的一學期了,又因下學期大家普遍需要找工作,所以都壓力比較大吧…
安卓作為我本學期選的五門專業課中學的最認真的(因為每週都有佈置作業),所以我對它相對比較瞭解,下面來給大家分享一下【第8章資料儲存與訪問-簡單儲存/內部儲存/外部儲存】的原始碼和心得
介面和原始碼
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="fourvolt69.lesson">
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"> </uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"> </uses-permission>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"> </uses-permission>
//另外,外部儲存因為需要訪問程式資料之外的儲存空間,所以需要在安卓機的設定(app permission->storage)把storage的許可權給到本程式
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="fourvolt69.lesson.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:id="@+id/textView" />
<Button
android:text="簡單讀"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button2"
android:layout_alignBaseline="@+id/button"
android:layout_alignBottom="@+id/button"
android:layout_alignParentEnd="true"
android:layout_marginEnd="73dp" />
<Button
android:text="簡單寫"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="69dp"
android:id="@+id/button"
android:layout_below="@+id/editText3"
android:layout_toEndOf="@+id/textView" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:ems="10"
android:layout_marginTop="20dp"
android:id="@+id/editText3"
android:layout_below="@+id/editText2"
android:layout_centerHorizontal="true"
android:hint="height" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:ems="10"
android:layout_marginTop="20dp"
android:id="@+id/editText2"
android:layout_below="@+id/editText"
android:layout_alignStart="@+id/editText3"
android:hint="age" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:ems="10"
android:layout_marginTop="20dp"
android:id="@+id/editText"
android:layout_below="@+id/textView"
android:layout_alignStart="@+id/editText2"
android:hint="name" />
<Button
android:text="內部讀"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button4"
android:layout_alignBaseline="@+id/button3"
android:layout_alignBottom="@+id/button3"
android:layout_alignStart="@+id/button2" />
<Button
android:text="外部讀"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button6"
android:layout_alignBaseline="@+id/button5"
android:layout_alignBottom="@+id/button5"
android:layout_alignStart="@+id/button4" />
<Button
android:text="外部寫"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button5"
android:layout_marginTop="15dp"
android:layout_below="@+id/button3"
android:layout_alignStart="@+id/button3" />
<Button
android:text="內部寫"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:id="@+id/button3"
android:layout_below="@+id/button"
android:layout_alignStart="@+id/button" />
</RelativeLayout>
MainActivity.java
package fourvolt69.lesson;
import android.content.Context;
import android.content.SharedPreferences;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.os.Environment;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
EditText nameText, ageText, heightText;
SharedPreferences sharedPreferences;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final String tag="sdCardReadWrite";
setContentView(R.layout.activity_main);
nameText = (EditText) findViewById(R.id.editText);
ageText = (EditText) findViewById(R.id.editText2);
heightText = (EditText) findViewById(R.id.editText3);
Button shSave = (Button) findViewById(R.id.button);
Button shRead = (Button) findViewById(R.id.button2);
Button inSave = (Button) findViewById(R.id.button3);
Button inRead = (Button) findViewById(R.id.button4);
Button sdSave = (Button) findViewById(R.id.button5);
Button sdRead = (Button) findViewById(R.id.button6);
/*
簡單儲存
sharedPreferences = getSharedPreferences("sp1",MODE_PRIVATE);
shSave.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
SharedPreferences.Editor editor=sharedPreferences.edit();
editor.putString("name",nameText.getText().toString());
editor.putInt("age",Integer.valueOf(ageText.getText().toString()));
editor.putFloat("height",Float.valueOf(heightText.getText().toString()));
editor.commit();
}
});
shRead.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String name=sharedPreferences.getString("name","杭電學生");
int age=sharedPreferences.getInt("age",20);
float height=sharedPreferences.getFloat("height",1.70F);
nameText.setText(name);
ageText.setText(String.valueOf(age));
heightText.setText(String.valueOf(height));
}
});
*/
/*
內部儲存
inSave.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view){
String text = nameText.getText().toString();
FileOutputStream fos = null;
try {
fos = openFileOutput("myName", Context.MODE_APPEND);
try{
fos.write(text.getBytes());
fos.flush();
}catch (IOException e){
e.printStackTrace();
}
}catch (FileNotFoundException e){
e.printStackTrace();
}finally {
try{
fos.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
});
inRead.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view){
FileInputStream fis=null;
try {
fis=openFileInput("myName");
try{
byte[] readBytes=new byte[fis.available()];
while (fis.read(readBytes)!=-1){
}
String s = new String(readBytes);
nameText.setText(s);
} catch (IOException e){
e.printStackTrace();
}
}catch (FileNotFoundException e){
e.printStackTrace();
}finally {
try{
fis.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
});
*/
sdSave.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
File dir = new File(Environment.getExternalStorageDirectory().toString());
if(dir.exists()&&dir.canWrite()){
Log.d(tag,"該目錄存在 且 可寫");
File newFile = new File(Environment.getExternalStorageDirectory(),"myName2.txt");
FileOutputStream fos = null;
try{
newFile.createNewFile();
fos = new FileOutputStream(newFile);
fos.write(nameText.getText().toString().getBytes());
fos.flush();
Log.d(tag,"成功寫入");
}catch (IOException e){
e.printStackTrace();
}finally {
try{
fos.close();
Log.d(tag,"關閉fos");
}catch (IOException e){
e.printStackTrace();
}
}
}
else {
Log.d(tag,"該目錄不存在 或 不可寫");
}
}
});
sdRead.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
File dir1 = new File(Environment.getExternalStorageDirectory(),"myName2.txt");
if(dir1.exists()&&dir1.canRead()){
Log.d(tag,"該目錄存在 且 可讀");
FileInputStream fis = null;
try{
fis = new FileInputStream(dir1);
try {
byte[] readBytes = new byte[fis.available()];
while (fis.read(readBytes)!=-1){
}
String s = new String(readBytes);
nameText.setText(s);
Log.d(tag,"讀取成功");
}catch (IOException e){
e.printStackTrace();
}
}catch (IOException e){
e.printStackTrace();
}finally {
try{
fis.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
else{
Log.d(tag,"該目錄不存在 或 不可讀");
}
}
});
}
@Override
protected void onStop() {
super.onStop();
}
}
心得
此三塊內容課時為3 * 45分鐘,總的來說簡單儲存和內部儲存算是比較簡單的,我也沒有遇到什麼麻煩,而外部儲存則比較苦惱,下面列舉一些容易忽略的知識點和容易觸發的小bug
- try & catch
//openFileOutput函式
String FILE_NAME = "fileDemo.txt";
FileOutputStream fos = openFileOutput(FILE_NAME,Context.MODE_PRIVATE)
String text = “Some data”;
fos.write(text.getBytes());
fos.flush();
fos.close();
//openFileInput()函式
String FILE_NAME = "fileDemo.txt";
FileInputStream fis = openFileInput(FILE_NAME);
//fis.available():fis的有效位元組數
byte[] readBytes = new byte[fis.available()];
while(fis.read(readBytes) != -1){//從fis讀取位元組並存入陣列readBytes,讀到位元組最後時會返回-1,迴圈就結束了
}
上面的兩部分程式碼在實際使用過程中會遇到錯誤提示,因為檔案操作可能會遇到各種問題而最終導致操作失敗,因此程式碼應該使用try / catch捕獲可能產生的異常
2. 在Android File Explorer中想要檢視寫入的檔案,卻發現白屏
關於此問題請前往站內部落格:解決Android studio中的Android 7.0 在 Android Device Monitor(DDMS)的 File Explorer不顯示目錄樹的問題
https://blog.csdn.net/itxiaolong3/article/details/70156276
3. 在Android File Explorer中想要檢視寫入的檔案,發現/data打不開
當我們去點選/data/目錄時,發現什麼都沒有,這是怎麼回事呢?原因是我們許可權不夠,當前的使用者沒有許可權訪問data目錄。
經大佬指點,改正後仍未解決,決定日後解決了再來更新。
據老師步驟,接下來應該是
4. 外部儲存需要在安卓機的設定中賦予storage許可權
如果在這個列表中沒有出現你的程式,建議重啟,再編譯,應該就不會有問題啦!
5. 千萬不要這樣寫路徑,例如:"/mnt/sdcard/""/sdcard/storage/"
一想到Android中到SdCard就要想到 Environment,寫入到路徑一定要用Environment,讀取到路徑一定要要用Environment,因為每部手機到SdCard到路徑都會不同Environment.getExternalStorageDirectory()
結語
經過餘老師課上的悉心指導和課後佈置的作業,我意外的有很多收穫,在本學期課程完成之後我還會將所有課後作業和期末大作業上傳至本平臺,並更新部落格,希望能夠幫到廣大網友和學弟學妹( X D )
相關文章
- Android-內部儲存和外部儲存Android
- Android內部儲存和外部儲存,以及讀取Android讀取RAM,ROM內部儲存和外部儲存卡容量Android
- 安卓開發之資料儲存方式安卓
- 外部儲存器
- Android 外部儲存Android
- 儲存學習之開源儲存軟體
- MySQL入門系列:儲存程式(三)之儲存過程簡介MySql儲存過程
- MySQL入門系列:儲存程式(二)之儲存函式簡介MySql儲存函式
- 塊儲存 檔案儲存 物件儲存物件
- Flutter持久化儲存之檔案儲存Flutter持久化
- MongoDB 儲存引擎與內部原理MongoDB儲存引擎
- 行式儲存 列式儲存
- 儲存—物件儲存_Minio物件
- 低程式碼平臺+阿里雲端儲存:讓業務開發更簡單,資料儲存更安全阿里
- 自動儲存、靜態儲存和動態儲存
- mysql儲存函過程和儲存函式都屬於儲存程式MySql儲存函式
- Flutter持久化儲存之key-value儲存Flutter持久化
- Flutter持久化儲存之資料庫儲存Flutter持久化資料庫
- MyISAM 儲存引擎,Innodb 儲存引擎儲存引擎
- 資料儲存--檔案儲存
- 【Python3網路爬蟲開發實戰】5-資料儲存-1 檔案儲存-1 TXT文字儲存Python爬蟲
- 數值在Oracle的內部儲存Oracle
- k8s之資料儲存-配置儲存K8S
- 儲存系統設計指南之儲存分類
- IOS資料儲存之檔案沙盒儲存iOS
- Android——儲存圖片到外部儲存並進行原生分享Android
- 儲存
- 物件儲存 vs 檔案儲存 vs 塊儲存,選哪個?物件
- Azure 儲存簡介
- 儲存引擎簡介儲存引擎
- 儲存單位表
- Oracle儲存單位Oracle
- 簡單認識MySQL儲存引擎MySql儲存引擎
- Aspose.Slides.NET 19.2 解析ppt內容儲存svg 儲存ppt內部圖片IDESVG
- 儲存過程與儲存函式儲存過程儲存函式
- PostgreSQL儲存智慧-空間聚集儲存SQL
- Redis儲存結構以及儲存格式Redis
- 聚焦資料時代新儲存需求,浪潮儲存的新儲存之道