การจัดเก็บเป็นสิ่งที่เราทุกคนตระหนักดี แต่มักจะมองข้ามไป ไม่นานมานี้ ทุกๆ การก้าวกระโดดของความจุเพิ่มขึ้นเรื่อยๆ และดูเหมือนจะเป็นไปไม่ได้ ทุกวันนี้ เราไม่ได้คิดเลยแม้แต่น้อยเมื่อพิจารณาว่าอุปกรณ์ของเรามีมากแค่ไหน (และไม่สนใจความแตกต่างเลยสักนิด)
ประเด็นที่ใหญ่กว่าคือการดูวิวัฒนาการของสิ่งที่เก็บไว้ในหน่วยความจำ ก่อนใช้สมาร์ทโฟน เราได้บันทึกภาพบางภาพเป็นครั้งคราว บางเกม และข้อความจำนวนมาก แต่ตอนนี้ โทรศัพท์มาตรฐานทุกรุ่นจะมีแอปพลิเคชั่น เอกสาร รูปภาพ วิดีโอ ไฟล์เพลง และอื่นๆ ที่ผสมกัน มาดูกันว่าเราจะใช้พื้นที่เก็บข้อมูลของอุปกรณ์สำหรับแอปพลิเคชันของเราได้อย่างไร
สิ่งที่เราจะกล่าวถึงในบทความนี้คือ:
- พื้นที่เก็บข้อมูลประเภทต่างๆ บนโทรศัพท์ Android
- ความแตกต่างระหว่างประเภทของการจัดเก็บ
- วิธีใช้พื้นที่เก็บข้อมูลในแอปพลิเคชันของคุณ
แต่ละแอปพลิเคชันมีสิทธิ์เข้าถึงพื้นที่เก็บข้อมูลสองประเภท:ภายใน และ ภายนอก . ที่เก็บข้อมูลทั้งสองประเภทนี้มีความแตกต่างกันอย่างมาก และการรู้ว่าสิ่งเหล่านี้จะช่วยคุณในการออกแบบแอปพลิเคชันครั้งต่อไป
ก่อนที่เราจะเริ่มต้น สิ่งหนึ่งที่ต้องพูดเกี่ยวกับที่เก็บข้อมูลและแคช พื้นที่เก็บข้อมูลมีไว้สำหรับสิ่งที่คุณต้องการบันทึกอย่างต่อเนื่อง ในขณะที่มีแคชไว้เพื่อบันทึกสิ่งต่าง ๆ ชั่วคราว
ที่เก็บข้อมูลภายใน
เมื่อแต่ละแอพพลิเคชั่นทำงานบนระบบปฏิบัติการ แอพพลิเคชั่นนั้นจะมีที่เก็บข้อมูลภายในของตัวเอง พื้นที่เก็บข้อมูลนี้เป็นส่วนตัวและสำหรับการใช้งานแอปพลิเคชันเท่านั้น หมายความว่าแอปพลิเคชันอื่นไม่สามารถเข้าถึงได้และผู้ใช้ก็ไม่สามารถเข้าถึงได้ สิ่งที่ควรทราบเมื่อใช้ที่จัดเก็บข้อมูลภายในก็คือความพร้อมใช้งาน ต่างจากที่จัดเก็บข้อมูลภายนอกตรงที่ที่เก็บข้อมูลภายในจะพร้อมใช้งานสำหรับแอปพลิเคชันของคุณเสมอ
การใช้ที่เก็บข้อมูลนี้มีข้อเสียอยู่ หากผู้ใช้ลบแอปพลิเคชัน ข้อมูลทั้งหมดที่จัดเก็บไว้ในที่จัดเก็บข้อมูลภายในของแอปของคุณจะถูกลบออกด้วย ลองนึกภาพว่าจะเกิดอะไรขึ้นถ้าคุณติดตั้งเกมบนโทรศัพท์ของคุณและบางแห่งที่อยู่ด้านล่างตัดสินใจนำเกมออก คุณต้องการให้เกมของคุณถูกบันทึกไว้ ถ้ามีโอกาสคุณจะติดตั้งเกมอีกครั้ง
แล้วเราจะบันทึกไฟล์ลงในที่จัดเก็บข้อมูลภายในได้อย่างไร
public void saveFileInternalStorage() {
String FILENAME = "hello_world_file";
String inputToFile = "Hello From Internal Storage!";
try {
FileOutputStream fileOutputStream = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fileOutputStream.write(inputToFile.getBytes());
fileOutputStream.close();
Toast.makeText(getApplicationContext(),
"File " + FILENAME + " has been saved successfully",
Toast.LENGTH_SHORT).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),
"File " + FILENAME + " has not been saved successfully due to an exception " + e.getLocalizedMessage(),
Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),
"File " + FILENAME + " has not been saved successfully due to an exception " + e.getLocalizedMessage(),
Toast.LENGTH_SHORT).show();
}
}
ดังที่คุณเห็นในตัวอย่างโค้ด เรากำลังบันทึกไฟล์ชื่อ hello_world_file ที่มีข้อความ “สวัสดีจากที่เก็บข้อมูลภายใน!” . ฉันได้สร้าง catch clause สองอันเพื่อแสดงข้อยกเว้นที่อาจเกิดขึ้นเมื่อพยายามทำสิ่งนี้ แต่คุณสามารถย่อให้เหลือเพียง catch clause เดียวด้วยอ็อบเจกต์ Exception ทั่วไป
สังเกตว่าวิธีการ openFileOutput จะเปิดไฟล์หากมีอยู่แล้ว แต่ถ้าไม่มี จะสร้างไฟล์ขึ้นมา พารามิเตอร์ที่สองของวิธีนี้คือโหมดไฟล์ พารามิเตอร์นี้กำหนดขอบเขตของไฟล์และการเข้าถึง ค่าเริ่มต้นคือ MODE_PRIVATE ซึ่งทำให้แอปพลิเคชันของคุณเข้าถึงไฟล์ได้เท่านั้น
อีกสองค่าสำหรับพารามิเตอร์นี้คือ MODE_WORLD_READABLE และ MODE_WORLD_WRITEABLE แต่เลิกใช้แล้วตั้งแต่ API 17 การแชร์ไฟล์ส่วนตัวกับแอปพลิเคชันอื่นใช้ชุดตรรกะที่แตกต่างกัน ซึ่งคุณสามารถอ่านเพิ่มเติมได้ที่นี่ สุดท้าย เมื่อเขียนไปยังไฟล์ เราจะแปลงสตริงเป็นไบต์และปิดไฟล์ในตอนท้าย
ที่จัดเก็บข้อมูลภายนอก
ตรงกันข้ามกับความหมายของชื่อ นี่คือที่เก็บข้อมูลที่กำหนดโดยข้อเท็จจริงที่ว่ามันไม่สามารถเข้าถึงได้ตลอดเวลา ซึ่งอาจหมายความว่าสามารถเป็นการ์ด SD ภายนอก (ที่จัดเก็บข้อมูลภายนอกสำรอง) แต่ก็สามารถพบที่จัดเก็บข้อมูลในอุปกรณ์ได้ (ที่จัดเก็บข้อมูลภายนอกหลัก)
เพื่อนำความเป็นจริงกลับบ้าน ที่จัดเก็บข้อมูลภายนอกคือที่จัดเก็บข้อมูลที่สามารถเข้าถึงได้เมื่อคุณเชื่อมต่ออุปกรณ์กับคอมพิวเตอร์ผ่านสาย USB อย่างที่คุณอาจเดาได้ ทุกสิ่งที่เก็บไว้ในที่จัดเก็บข้อมูลประเภทนี้สามารถเข้าถึงได้โดยแอปพลิเคชันอื่นบนอุปกรณ์ของคุณ แต่จะถูกเก็บไว้หากคุณถอนการติดตั้งแอปพลิเคชัน
ก่อนที่เราจะสาธิตวิธีบันทึกไฟล์ไปยังที่จัดเก็บข้อมูลภายนอก เราต้องทำสองสิ่ง:
- ตรวจสอบให้แน่ใจว่ามีพื้นที่เพียงพอสำหรับบันทึกไฟล์
- ขออนุญาตระหว่างรันไทม์
ตรวจสอบให้แน่ใจว่ามีพื้นที่จัดเก็บเพียงพอ ต้องใช้รหัสบรรทัดต่อไปนี้:
//Check if you can read/write to external storage
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
}
ในการเข้าถึงที่จัดเก็บข้อมูลภายนอก เราต้องเพิ่มการอนุญาตต่อไปนี้ใน AndroidManifest.xml ของเรา:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
นอกจากนี้ เนื่องจาก API 23 จึงไม่อนุญาตการอนุญาตที่เป็นอันตรายระหว่างเวลาติดตั้ง แต่ระหว่างรันไทม์ การเขียนลงที่จัดเก็บข้อมูลภายนอกถูกจัดประเภทเป็นหนึ่ง ดังนั้นเราจำเป็นต้องเพิ่มตรรกะเพื่อให้ผู้ใช้ตัดสินใจว่าจะให้อนุญาตแอปพลิเคชันหรือไม่
public void saveFileExternalStorage(View view) {
if (isExternalStorageWritable()) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) ==
PackageManager.PERMISSION_GRANTED) {
writeFileToExternalStorage();
} else{
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case 0:
{
writeFileToExternalStorage();
break;
}
}
}
writeFileToExternalStorageของเรา มีลักษณะดังนี้:
public void writeFileToExternalStorage() {
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/saved_files");
if (!myDir.exists()) {
myDir.mkdirs();
}
try {
File file = new File(myDir, "myfile.txt");
FileOutputStream out = new FileOutputStream(file);
out.write(inputToFile.getBytes());
out.close();
Toast.makeText(getApplicationContext(),
"File myfile.txt" + " has been saved successfully to external storage",
Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
}
หากคุณต้องการดูตัวอย่างโค้ดทั้งหมดที่นำเสนอที่นี่ คุณสามารถไปที่ที่เก็บ GitHub นี้ได้
น่ารู้
ข้างต้นเป็นเพียงตัวอย่างง่ายๆ สองตัวอย่างเกี่ยวกับวิธีการทำงานกับพื้นที่จัดเก็บข้อมูลประเภทต่างๆ สำหรับแอปพลิเคชันของคุณ เนื่องจากเรากำลังจัดการกับทรัพยากรที่ระบบจัดการ เราจึงควรทราบถึงพฤติกรรมที่เกี่ยวข้องด้วย
โดยค่าเริ่มต้น แอปพลิเคชันของคุณจะถูกติดตั้งลงในที่จัดเก็บข้อมูลภายใน (ดูคำอธิบายภายในเท่านั้น ) แต่จาก API ระดับ 8 คุณสามารถเพิ่มแอตทริบิวต์ installLocation ไปยังรายการของคุณที่อนุญาตให้ติดตั้งแอปพลิเคชันของคุณไปยังที่จัดเก็บข้อมูลภายนอก เหตุผลหนึ่งในการทำเช่นนั้นคือหากแอปพลิเคชันของคุณมีขนาดใหญ่มาก และคุณต้องการให้ผู้ใช้ติดตั้งแอปพลิเคชันนั้นในที่จัดเก็บข้อมูลภายนอกของอุปกรณ์เนื่องจากมีพื้นที่ว่างมากขึ้น
แอตทริบิวต์นี้มีสามค่า:
- อัตโนมัติ - หมายความว่าคุณไม่มีการตั้งค่าเฉพาะที่จะติดตั้งแอปพลิเคชัน แอปพลิเคชันจะพยายามติดตั้งลงในที่จัดเก็บข้อมูลภายใน แต่ถ้าเต็มก็จะติดตั้งลงในที่จัดเก็บข้อมูลภายนอก
- ภายในเท่านั้น - แอปพลิเคชันจะถูกติดตั้งในที่จัดเก็บข้อมูลภายในเท่านั้น และหากไม่มีพื้นที่เพียงพอ จะไม่มีการติดตั้งแอปพลิเคชันนั้น
- ต้องการภายนอก - หมายความว่าคุณต้องการให้ติดตั้งแอปพลิเคชันของคุณไปยังที่จัดเก็บข้อมูลภายนอก แต่ถ้ามีพื้นที่ไม่เพียงพอ แอปพลิเคชันนั้นจะถูกติดตั้งภายใน
สำหรับทั้งตัวเลือกอัตโนมัติและตัวเลือกที่ต้องการภายนอก ผู้ใช้มีตัวเลือกในการย้ายแอปพลิเคชันจากที่จัดเก็บข้อมูลภายนอกไปยังภายใน และในทางกลับกัน
โปรดทราบว่าเมื่อผู้ใช้เชื่อมต่ออุปกรณ์ของตนกับคอมพิวเตอร์และเปิดใช้งานเพื่อแชร์ข้อมูลหรือยกเลิกการต่อเชื่อมการ์ด SD แอปพลิเคชันทั้งหมดที่ทำงานจากที่จัดเก็บข้อมูลภายนอกจะถูกทำลาย หากแอปพลิเคชันของคุณใช้คุณลักษณะอย่างใดอย่างหนึ่งต่อไปนี้ คุณไม่ควรติดตั้งลงในที่จัดเก็บข้อมูลภายนอก:
บริการต่างๆ (บริการแจ้งเตือน โดยเฉพาะ), เครื่องมือวิธีการป้อนข้อมูล, วอลเปเปอร์เคลื่อนไหว, วิดเจ็ตแอปพลิเคชัน, ผู้จัดการบัญชี, อะแดปเตอร์การซิงค์, ผู้ดูแลอุปกรณ์ และเครื่องรับการออกอากาศที่รับฟังการบูตเสร็จสมบูรณ์