![[Android căn bản] Bài 12: Bộ nhớ trong và bộ nhớ ngoài trong Android.](https://tuandc.com/wp-content/uploads/2017/08/Android.jpg)
[Android căn bản] Bài 12: Bộ nhớ trong và bộ nhớ ngoài trong Android.

Chào các bạn chúng ta lại gặp nhau trong series Android truyền kì rồi. hôm nay mình sẽ giới thiệu đến các bạn cách sử dụng bộ nhớ trong và bộ nhó ngoài trong Android.
Nhắc đến bộ nhớ trong và bộ nhớ ngoài trong Android chắc chẳng ai còn lạ gì nữa đúng không nào. Trong Android có hai loại bộ nhớ là bộ nhớ trong và bộ nhớ ngoài Bộ nhớ trong là bộ nhớ riêng của ứng dúng nó được sử dụng để lưu trữ dữ liệu cho riêng ứng dụng đó và các ứng dụng khác không thể truy cập được còn bộ nhớ ngoài thì bạn có thể ra cửa tiệm mua một cái thẻ nhớ và gắn vô để lưu dữ liệu đó là bộ nhớ ngoài.
Bộ nhớ trong
Thôi chắc khỏi phải dài dòng văn tự làm gì xơi luôn cho nó nòng giống như có có người yêu là phải ăn liền tay :v.
Đầu tiên thiết kế cái giao diện phát.

Giao diện
Đó giao diện ứng dụng đơn giản dễ cởi… à nhầm dễ thiết kế.
Code:
<?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:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="@+id/editText"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:layout_alignParentEnd="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:text="EditText" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="120dp"
android:layout_alignEnd="@+id/editText"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignRight="@+id/editText"
android:layout_below="@+id/editText"
android:text="TextView" />
<Button
android:id="@+id/button_save"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/textView"
android:layout_marginLeft="43dp"
android:layout_marginStart="43dp"
android:layout_marginTop="63dp"
android:text="Lưu File" />
<Button
android:id="@+id/button_read"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/button_save"
android:layout_toEndOf="@+id/button_save"
android:layout_toRightOf="@+id/button_save"
android:text="Đọc File" />
</RelativeLayout>
Rồi tới file MainActivity.java
package com.chamcong.akinosora.memory;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
public class MainActivity extends AppCompatActivity {
private Button saveButton;
private Button readButton;
private TextView textView;
private EditText editText;
// Là một tên file đơn giản.
// Chú ý!! Không cho phép đường dẫn.
private String simpleFileName = "note.txt";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.saveButton = (Button) this.findViewById(R.id.button_save);
this.readButton = (Button) this.findViewById(R.id.button_read);
this.textView = (TextView) this.findViewById(R.id.textView);
this.editText = (EditText) this.findViewById(R.id.editText);
this.saveButton.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View v) {
saveData();
}
});
this.readButton.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View v) {
readData();
}
});
}
private void saveData() {
String data = this.editText.getText().toString();
try {
// Mở một luồng ghi file.
FileOutputStream out = this.openFileOutput(simpleFileName, MODE_PRIVATE);// hàm này có hai tham số truyền vào là tên file và chế độ ghi file.
// Ghi dữ liệu.
out.write(data.getBytes());
out.close();
Toast.makeText(this, "File saved!", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(this, "Error:" + e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
private void readData() {
try {
// Mở một luồng đọc file.
FileInputStream in = this.openFileInput(simpleFileName);
BufferedReader br = new BufferedReader(new InputStreamReader(in));// Khởi tạo bộ nhớ đệm để đọc file
StringBuilder sb = new StringBuilder();
String s = null;
while ((s = br.readLine()) != null) {
sb.append(s).append("\n");
}
this.textView.setText(sb.toString());
} catch (Exception e) {
Toast.makeText(this, "Error:" + e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
}
Xong bây giờ bạn hãy thử chạy ứng dụng và xem điều gì sẽ xảy ra.

Kết quả chạy ứng dụng
Bộ nhớ ngoài.
Không giống bộ nhớ trong chỉ có thể lưu được các file đơn giản không có đường đường mà bộ nhớ ngoài có thể làm việc với các file phức tạp có đường dẫn và những dữ liệu này sẽ không được hệ thống bảo mật.
Phương thức | Trả về |
getDataDirectory() | /data |
getDownloadCacheDirectory() | /cache |
getExternalStorageState() | mounted |
getExternalStoragePublicDirectory(Environment.Music): | /storage/emulated/0/Music |
getDownloadCacheDirectory() | /cache |
getRootDirectory() | /system |
Và để sử dụng bộ nhớ ngoài ta cũng File xin cấp quyền trong AndroidManifest.xml.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
Lưu ý với API >= 23 thì bạn phải hỏi sự đồng ý cấp quyền của người dùng trong code.
Ví dụ về đọc ghi file.
Đầu tên là giao diện ứng dụng.

Giao diện ứng dụng bộ nhớ trong
Đó giao diện đơn giản vậy thôi.
Code:
<?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:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="@+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true">
<requestFocus />
</EditText>
<TextView
android:layout_width="fill_parent"
android:layout_height="120dp"
android:id="@+id/textView"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/editText"
android:layout_above="@+id/button_save"
android:layout_marginTop="10dp" />
<Button
android:id="@+id/button_save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="save"
android:layout_alignParentBottom="true"
android:layout_alignLeft="@+id/textView"
android:layout_alignStart="@+id/textView" />
<Button
android:id="@+id/button_read"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/button_save"
android:layout_alignBottom="@+id/button_save"
android:layout_toRightOf="@+id/button_save"
android:text="read" />
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="List Dirs"
android:id="@+id/button_list"
android:layout_alignBottom="@+id/button_read"
android:layout_toRightOf="@+id/button_read"
android:layout_toEndOf="@+id/button_read" />
</RelativeLayout>
Xong giờ tới phần sử lý tác vụ cho ứng dụng.
Code:
package com.chamcong.akinosora.memory;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class MainActivity extends AppCompatActivity {
private EditText editText;
private TextView textView;
private Button saveButton;
private Button readButton;
private Button listButton;
private static final int REQUEST_ID_READ_PERMISSION = 100;
private static final int REQUEST_ID_WRITE_PERMISSION = 200;
private final String fileName = "note.txt";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = (EditText) findViewById(R.id.editText);
textView = (TextView) findViewById(R.id.textView);
saveButton = (Button) findViewById(R.id.button_save);
readButton = (Button) findViewById(R.id.button_read);
listButton = (Button) findViewById(R.id.button_list);
saveButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
askPermissionAndWriteFile();
}
});
readButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
askPermissionAndReadFile();
}
});
listButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
listExternalStorages();
}
});
}
// Xin cấp quyền ghi file
private void askPermissionAndWriteFile() {
boolean canWrite = this.askPermission(REQUEST_ID_WRITE_PERMISSION,
Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (canWrite) {
this.writeFile();
}
}
// Xin cấp quyền đọc file
private void askPermissionAndReadFile() {
boolean canRead = this.askPermission(REQUEST_ID_READ_PERMISSION,
Manifest.permission.READ_EXTERNAL_STORAGE);
//
if (canRead) {
this.readFile();
}
}
// Với Android Level >= 23 bạn phải hỏi người dùng cho phép các quyền với thiết bị
// (Chẳng hạn đọc/ghi dữ liệu vào thiết bị).
private boolean askPermission(int requestId, String permissionName) {
if (android.os.Build.VERSION.SDK_INT >= 23) {
// Kiểm tra quyền
int permission = ActivityCompat.checkSelfPermission(this, permissionName);
if (permission != PackageManager.PERMISSION_GRANTED) {
// Nếu không có quyền, cần nhắc người dùng cho phép.
this.requestPermissions(
new String[]{permissionName},
requestId
);
return false;
}
}
return true;
}
// Khi yêu cầu hỏi người dùng được trả về (Chấp nhận hoặc không chấp nhận).
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
//
// Chú ý: Nếu yêu cầu bị hủy, mảng kết quả trả về là rỗng.
if (grantResults.length > 0) {
switch (requestCode) {
case REQUEST_ID_READ_PERMISSION: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
readFile();
}
}
case REQUEST_ID_WRITE_PERMISSION: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
writeFile();
}
}
}
} else {
Toast.makeText(getApplicationContext(), "Permission Cancelled!", Toast.LENGTH_SHORT).show();
}
}
private void writeFile() {
// Thư mục gốc của SD Card.
File extStore = Environment.getExternalStorageDirectory();
// ==> /storage/emulated/0/note.txt
String path = extStore.getAbsolutePath() + "/" + fileName;
Log.i("ExternalStorageDemo", "Save to: " + path);
String data = editText.getText().toString();
try {
File myFile = new File(path);
myFile.createNewFile();
FileOutputStream fOut = new FileOutputStream(myFile);
OutputStreamWriter myOutWriter = new OutputStreamWriter(fOut);
myOutWriter.append(data);
myOutWriter.close();
fOut.close();
Toast.makeText(getApplicationContext(), fileName + " saved", Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
}
}
private void readFile() {
// Thư mục gốc của SD Card.
File extStore = Environment.getExternalStorageDirectory();
// ==> /storage/emulated/0/note.txt
String path = extStore.getAbsolutePath() + "/" + fileName;
Log.i("ExternalStorageDemo", "Read file: " + path);
String s = "";
String fileContent = "";
try {
File myFile = new File(path);
FileInputStream fIn = new FileInputStream(myFile);
BufferedReader myReader = new BufferedReader(
new InputStreamReader(fIn));
while ((s = myReader.readLine()) != null) {
fileContent += s + "\n";
}
myReader.close();
this.textView.setText(fileContent);
} catch (IOException e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(), fileContent, Toast.LENGTH_LONG).show();
}
// Hiển thị danh sách thư mục bộ nhớ ngoài
private void listExternalStorages() {
StringBuilder sb = new StringBuilder();
sb.append("Data Directory: ").append("\n - ")
.append(Environment.getDataDirectory().toString()).append("\n");
sb.append("Download Cache Directory: ").append("\n - ")
.append(Environment.getDownloadCacheDirectory().toString()).append("\n");
sb.append("External Storage State: ").append("\n - ")
.append(Environment.getExternalStorageState().toString()).append("\n");
sb.append("External Storage Directory: ").append("\n - ")
.append(Environment.getExternalStorageDirectory().toString()).append("\n");
sb.append("Is External Storage Emulated?: ").append("\n - ")
.append(Environment.isExternalStorageEmulated()).append("\n");
sb.append("Is External Storage Removable?: ").append("\n - ")
.append(Environment.isExternalStorageRemovable()).append("\n");
sb.append("External Storage Public Directory (Music): ").append("\n - ")
.append(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).toString()).append("\n");
sb.append("Download Cache Directory: ").append("\n - ")
.append(Environment.getDownloadCacheDirectory().toString()).append("\n");
sb.append("Root Directory: ").append("\n - ")
.append(Environment.getRootDirectory().toString()).append("\n");
Log.i("ExternalStorageDemo", sb.toString());
this.textView.setText(sb.toString());
}
}
Kết quả:

Giao diện ứng dụng bộ nhớ trong
Vậy là tôi đã giới thiệu với các bạn cách sử dụng hai loại bộ nhớ của Android để lưu trữ dữ liệu trong ứng dụng Android. Cảm ơn các bạn đã theo dõi và xin hẹn gặp lại các bạn ở những bài luyện công tiếp theo của bí kíp Android truyền kì. Xin chào và hẹn gặp lại.
