演示了如何读写外部存储卡。演示了三种情况:
* 1.向存储卡的共享目录中的图片目录中写入一张图片:
* 位置为:/storage/sdcard/Pictures
* 2.向本地应用的图片目录中写入一张图片
* 位置为:/storage/sdcard/ Android /data/包名/files/Pictures
* 3.向本地应用的目录中写入一个文件
实现功能代码
* 1.向存储卡的共享目录中的图片目录中写入一张图片:
* 位置为:/storage/sdcard/Pictures
* 2.向本地应用的图片目录中写入一张图片
* 位置为:/storage/sdcard/ Android /data/包名/files/Pictures
* 3.向本地应用的目录中写入一个文件
* 位置为:/storage/sdcard/android/data/包名/files/
首先来看下布局和代码吧
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none" >
<LinearLayout
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
</LinearLayout>
</ScrollView>
item布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="@+id/label"
style="?android:attr/textAppearanceMediumInverse"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:background="#888"
android:padding="4dip"
android:singleLine="true"
android:color="?android:attr/textColorPrimaryInverse" />
<TextView
android:id="@+id/path"
style="?android:attr/textAppearanceSmall"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:padding="4dip"
android:singleLine="true" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<View
android:layout_width="0dip"
android:layout_height="0dip"
android:layout_weight="1" />
<Button
android:id="@+id/create"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/create" />
<View
android:layout_width="0dip"
android:layout_height="0dip"
android:layout_weight="1" />
<Button
android:id="@+id/delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/delete" />
<View
android:layout_width="0dip"
android:layout_height="0dip"
android:layout_weight="1" />
</LinearLayout>
</LinearLayout>
实现功能代码
public class ExternalStorage extends Activity {
ViewGroup mLayout;
//定义一个类,用于管理每种情况的布局,因为是一样的布局,所以可以达到利用的目的
static class Item {
View mRoot;
Button mCreate;
Button mDelete;
}
// 定义三种情况下的布局
Item mExternalStoragePublicPicture;
Item mExternalStoragePrivatePicture;
Item mExternalStoragePrivateFile;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.external_storage);
mLayout = (ViewGroup)findViewById(R.id.layout);
mExternalStoragePublicPicture = createStorageControls(
"Picture: getExternalStoragePublicDirectory",
Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES),
new View.OnClickListener() {
public void onClick(View v) {
createExternalStoragePublicPicture();
updateExternalStorageState();
}
},
new View.OnClickListener() {
public void onClick(View v) {
deleteExternalStoragePublicPicture();
updateExternalStorageState();
}
});
mLayout.addView(mExternalStoragePublicPicture.mRoot);
// 注意这个方法不在Environment里面而是在Activity当中
mExternalStoragePrivatePicture = createStorageControls(
"Picture getExternalFilesDir",
getExternalFilesDir(Environment.DIRECTORY_PICTURES),
new View.OnClickListener() {
public void onClick(View v) {
createExternalStoragePrivatePicture();
updateExternalStorageState();
}
},
new View.OnClickListener() {
public void onClick(View v) {
deleteExternalStoragePrivatePicture();
updateExternalStorageState();
}
});
mLayout.addView(mExternalStoragePrivatePicture.mRoot);
mExternalStoragePrivateFile = createStorageControls(
"File getExternalFilesDir",
getExternalFilesDir(null),
new View.OnClickListener() {
public void onClick(View v) {
createExternalStoragePrivateFile();
updateExternalStorageState();
}
},
new View.OnClickListener() {
public void onClick(View v) {
deleteExternalStoragePrivateFile();
updateExternalStorageState();
}
});
mLayout.addView(mExternalStoragePrivateFile.mRoot);
startWatchingExternalStorage();
}
@Override
protected void onDestroy() {
super.onDestroy();
stopWatchingExternalStorage();
}
void handleExternalStorageState(boolean available, boolean writeable) {
boolean has = hasExternalStoragePublicPicture();
mExternalStoragePublicPicture.mCreate.setEnabled(writeable && !has);
mExternalStoragePublicPicture.mDelete.setEnabled(writeable && has);
has = hasExternalStoragePrivatePicture();
mExternalStoragePrivatePicture.mCreate.setEnabled(writeable && !has);
mExternalStoragePrivatePicture.mDelete.setEnabled(writeable && has);
has = hasExternalStoragePrivateFile();
mExternalStoragePrivateFile.mCreate.setEnabled(writeable && !has);
mExternalStoragePrivateFile.mDelete.setEnabled(writeable && has);
}
//定义一个广播接收者,用于监视外部存储卡的挂载状态
BroadcastReceiver mExternalStorageReceiver;
boolean mExternalStorageAvailable = false;
boolean mExternalStorageWriteable = false;
void updateExternalStorageState() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
mExternalStorageAvailable = mExternalStorageWriteable = true;
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
mExternalStorageAvailable = true;
mExternalStorageWriteable = false;
} else {
mExternalStorageAvailable = mExternalStorageWriteable = false;
}
handleExternalStorageState(mExternalStorageAvailable,
mExternalStorageWriteable);
}
void startWatchingExternalStorage() {
mExternalStorageReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.i("test", "Storage: " + intent.getData());
updateExternalStorageState();
}
};
//注册广播接收者
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_MEDIA_MOUNTED);
filter.addAction(Intent.ACTION_MEDIA_REMOVED);
registerReceiver(mExternalStorageReceiver, filter);
updateExternalStorageState();
}
void stopWatchingExternalStorage() {
unregisterReceiver(mExternalStorageReceiver);
}
void createExternalStoragePublicPicture() {
// Create a path where we will place our picture in the user's
// public pictures directory. Note that you should be careful about
// what you place here, since the user often manages these files. For
// pictures and other media owned by the application, consider
// Context.getExternalMediaDir().
File path = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
File file = new File(path, "DemoPicture.jpg");
try {
// Make sure the Pictures directory exists.
path.mkdirs();
// Very simple code to copy a picture from the application's
// resource into the external file. Note that this code does
// no error checking, and assumes the picture is small (does not
// try to copy it in chunks). Note that if external storage is
// not currently mounted this will silently fail.
InputStream is = getResources().openRawResource(R.drawable.balloons);
OutputStream os = new FileOutputStream(file);
byte[] data = new byte[is.available()];
is.read(data);
os.write(data);
is.close();
os.close();
// Tell the media scanner about the new file so that it is
// immediately available to the user.
MediaScannerConnection.scanFile(this,
new String[] { file.toString() }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
} catch (IOException e) {
// Unable to create file, likely because external storage is
// not currently mounted.
Log.w("ExternalStorage", "Error writing " + file, e);
}
}
void deleteExternalStoragePublicPicture() {
// Create a path where we will place our picture in the user's
// public pictures directory and delete the file. If external
// storage is not currently mounted this will fail.
File path = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
File file = new File(path, "DemoPicture.jpg");
file.delete();
}
boolean hasExternalStoragePublicPicture() {
// Create a path where we will place our picture in the user's
// public pictures directory and check if the file exists. If
// external storage is not currently mounted this will think the
// picture doesn't exist.
File path = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
File file = new File(path, "DemoPicture.jpg");
return file.exists();
}
void createExternalStoragePrivatePicture() {
// Create a path where we will place our picture in our own private
// pictures directory. Note that we don't really need to place a
// picture in DIRECTORY_PICTURES, since the media scanner will see
// all media in these directories; this may be useful with other
// media types such as DIRECTORY_MUSIC however to help it classify
// your media for display to the user.
File path = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File file = new File(path, "DemoPicture.jpg");
try {
// Very simple code to copy a picture from the application's
// resource into the external file. Note that this code does
// no error checking, and assumes the picture is small (does not
// try to copy it in chunks). Note that if external storage is
// not currently mounted this will silently fail.
InputStream is = getResources().openRawResource(R.drawable.balloons);
OutputStream os = new FileOutputStream(file);
byte[] data = new byte[is.available()];
is.read(data);
os.write(data);
is.close();
os.close();
// Tell the media scanner about the new file so that it is
// immediately available to the user.
MediaScannerConnection.scanFile(this,
new String[] { file.toString() }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
} catch (IOException e) {
// Unable to create file, likely because external storage is
// not currently mounted.
Log.w("ExternalStorage", "Error writing " + file, e);
}
}
void deleteExternalStoragePrivatePicture() {
//
File path = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
if (path != null) {
File file = new File(path, "DemoPicture.jpg");
file.delete();
}
}
boolean hasExternalStoragePrivatePicture() {
// 该方法将一张图片复制到外部存储卡本地应用目录下的图片目录下
File path = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
if (path != null) {
File file = new File(path, "DemoPicture.jpg");
return file.exists();
}
return false;
}
// 该方法将一张图片复制到外部存储卡本地应用目录下
void createExternalStoragePrivateFile() {
//
File file = new File(getExternalFilesDir(null), "DemoFile.jpg");
try {
//
InputStream is = getResources().openRawResource(R.drawable.balloons);
OutputStream os = new FileOutputStream(file);
byte[] data = new byte[is.available()];
is.read(data);
os.write(data);
is.close();
os.close();
} catch (IOException e) {
Log.w("ExternalStorage", "Error writing " + file, e);
}
}
void deleteExternalStoragePrivateFile() {
// 删除已存在的文件
File file = new File(getExternalFilesDir(null), "DemoFile.jpg");
if (file != null) {
file.delete();
}
}
boolean hasExternalStoragePrivateFile() {
// 判断是否已经存在该名字的文件
File file = new File(getExternalFilesDir(null), "DemoFile.jpg");
if (file != null) {
return file.exists();
}
return false;
}
/*
* 创建每种情况下的布局
*/
Item createStorageControls(CharSequence label, File path,
View.OnClickListener createClick,
View.OnClickListener deleteClick) {
LayoutInflater inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
Item item = new Item();
item.mRoot = inflater.inflate(R.layout.external_storage_item, null);
TextView tv = (TextView)item.mRoot.findViewById(R.id.label);
tv.setText(label);
if (path != null) {
tv = (TextView)item.mRoot.findViewById(R.id.path);
tv.setText(path.toString());
}
item.mCreate = (Button)item.mRoot.findViewById(R.id.create);
item.mCreate.setOnClickListener(createClick);
item.mDelete = (Button)item.mRoot.findViewById(R.id.delete);
item.mDelete.setOnClickListener(deleteClick);
return item;
}
}