يمكن استخدام التخزين الخارجي في نظام Android للكتابة وحفظ البيانات، وقراءة ملفات التكوين، إلخ. هذه المقالة هي استكمال لدروس التخزين الداخلي في نظام Android في سلسلة دروس تخزين البيانات المنظمة في Android.
التخزين الخارجي في Android
يمكن للتخزين الخارجي مثل بطاقة SD تخزين بيانات التطبيق، ولا يوجد أي تطبيق للأمان على الملفات التي تم حفظها في التخزين الخارجي. بشكل عام، هناك نوعان من التخزين الخارجي:
- التخزين الخارجي الأساسي: التخزين المشترك الموجود بالفعل والذي يمكن الوصول إليه “بواسطة المستخدم عند توصيل كابل USB وتركيبه كمحرك أقراص على جهاز الكمبيوتر المضيف”. مثال: عندما نتحدث عن نيكسوس 5 بسعة 32 جيجابايت.
- التخزين الخارجي الثانوي: التخزين القابل للإزالة. مثال: بطاقة SD
يمكن لجميع التطبيقات قراءة وكتابة الملفات الموجودة في التخزين الخارجي ويمكن للمستخدم إزالتها. يجب علينا التحقق مما إذا كانت بطاقة SD متاحة وإذا كان بإمكاننا الكتابة عليها. بمجرد التحقق من توفر التخزين الخارجي، يمكننا فقط بعدها الكتابة عليه، وإلا سيتم تعطيل زر الحفظ.
هيكل مشروع مثال تخزين البيانات الخارجية لأندرويد
أولاً، نحتاج إلى التأكد من أن التطبيق لديه إذن لقراءة وكتابة البيانات إلى بطاقة SD للمستخدمين، لذا دعنا نفتح
AndroidManifest.xml
ونضيف الأذونات التالية:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
كما يمكن أن يكون التخزين الخارجي مرتبطًا بمستخدم قام بتوصيله كجهاز تخزين USB. لذا نحتاج للتحقق مما إذا كان التخزين الخارجي متاحًا وليس له قراءة فقط.
if (!isExternalStorageAvailable() || isExternalStorageReadOnly()) {
saveButton.setEnabled(false);
}
private static boolean isExternalStorageReadOnly() {
String extStorageState = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(extStorageState)) {
return true;
}
return false;
}
private static boolean isExternalStorageAvailable() {
String extStorageState = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(extStorageState)) {
return true;
}
return false;
}
getExternalStorageState()
هو طريقة ثابتة في Environment
لتحديد ما إذا كان التخزين الخارجي متاحًا حاليًا أم لا. كما يمكنك رؤية أنه إذا كانت الشرط غير صحيحة، قمنا بتعطيل زر الحفظ.
كود مثال تخزين البيانات الخارجية لأندرويد
تم تعريف تخطيط activity_main.xml على النحو التالي:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:orientation="vertical">
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Reading and Writing to External Storage"
android:textSize="24sp"/>
<EditText android:id="@+id/myInputText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10" android:lines="5"
android:minLines="3" android:gravity="top|left"
android:inputType="textMultiLine">
<requestFocus />
</EditText>
<LinearLayout
android:layout_width="match_parent" android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="1.0"
android:layout_marginTop="20dp">
<Button android:id="@+id/saveExternalStorage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="SAVE"
android:layout_weight="0.5"/>
<Button android:id="@+id/getExternalStorage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:text="READ" />
</LinearLayout>
<TextView android:id="@+id/response"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:padding="5dp"
android:text=""
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
هنا بخلاف أزرار الحفظ والقراءة من التخزين الخارجي، نعرض استجابة الحفظ/القراءة إلى/من التخزين الخارجي في textview بدلاً من الـ android toast الذي كان معروضًا في الدرس السابق. كما يُعطى في الأسفل كود الـ MainActivity.java:
package com.journaldev.externalstorage;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import android.os.Bundle;
import android.app.Activity;
import android.os.Environment;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends Activity {
EditText inputText;
TextView response;
Button saveButton,readButton;
private String filename = "SampleFile.txt";
private String filepath = "MyFileStorage";
File myExternalFile;
String myData = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
inputText = (EditText) findViewById(R.id.myInputText);
response = (TextView) findViewById(R.id.response);
saveButton =
(Button) findViewById(R.id.saveExternalStorage);
saveButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
try {
FileOutputStream fos = new FileOutputStream(myExternalFile);
fos.write(inputText.getText().toString().getBytes());
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
inputText.setText("");
response.setText("SampleFile.txt saved to External Storage...");
}
});
readButton = (Button) findViewById(R.id.getExternalStorage);
readButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
try {
FileInputStream fis = new FileInputStream(myExternalFile);
DataInputStream in = new DataInputStream(fis);
BufferedReader br =
new BufferedReader(new InputStreamReader(in));
String strLine;
while ((strLine = br.readLine()) != null) {
myData = myData + strLine;
}
in.close();
} catch (IOException e) {
e.printStackTrace();
}
inputText.setText(myData);
response.setText("SampleFile.txt data retrieved from Internal Storage...");
}
});
if (!isExternalStorageAvailable() || isExternalStorageReadOnly()) {
saveButton.setEnabled(false);
}
else {
myExternalFile = new File(getExternalFilesDir(filepath), filename);
}
}
private static boolean isExternalStorageReadOnly() {
String extStorageState = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(extStorageState)) {
return true;
}
return false;
}
private static boolean isExternalStorageAvailable() {
String extStorageState = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(extStorageState)) {
return true;
}
return false;
}
}
- Environment.getExternalStorageState(): يُرجع مسار نقطة تثبيت بطاقة الذاكرة الداخلية مثل “/mnt/sdcard”
- getExternalFilesDir(): يُعيد المسار إلى مجلد الملفات داخل Android/data/data/application_package/ على بطاقة الذاكرة. يُستخدم لتخزين أي ملفات مطلوبة لتطبيقك (مثل الصور المُنزّلة من الويب أو ملفات الذاكرة المؤقتة). بمجرد إلغاء تثبيت التطبيق، يختفي أي بيانات مخزنة في هذا المجلد أيضًا.
يتم تعطيل زر الحفظ عندما لا يكون التخزين الخارجي متاحًا باستخدام الشرط “if” الذي تم مناقشته في وقت سابق من هذا البرنامج التعليمي. أدناه تعمل تطبيقنا في محاكي Android، حيث نقوم بكتابة البيانات إلى ملف ثم قراءته. ملاحظة: تأكد من تكوين محاكي Android الخاص بك بحيث يحتوي على بطاقة SD كما هو موضح في صورة الحوار من AVD أدناه. اذهب إلى Tools->Android->Android Virtual Device، قم بتحرير التكوينات->إظهار الإعدادات المتقدمة.
ينتهي هنا هذا البرنامج التعليمي. سنناقش التخزين باستخدام Shared Preferences في البرنامج التعليمي القادم. يمكنك تنزيل مشروع Android External Storage النهائي من الرابط أدناه.
Source:
https://www.digitalocean.com/community/tutorials/android-external-storage-read-write-save-file