先说一下为何要将媒体文件添加到ContentProvider中,不是将如视频,MP3这样的文件通过输入输出流写入到手机的外部存储器中就表示保存好了数据了吗?确实,这样保存了,并且我们也能通过文件管理器来找到这些视频音频了。可是,我们想要使用这些媒体文件必须要知道这些文件的保存路径,而其它应用程序是不会知道你保存的路径的。你只有把这些媒体文件的内容添加到系统自带的一个媒体的内容提供者中,其他应用程序才能通过这个内容提供者搜索到这个媒体文件,并且使用它。这也从另外一方面展现了内容提供者的用处。
向ContentProvider中添加媒体文件共有两种方法,一种是ContentValues,第二种是MediaScanner,第二种方法通过发送一个广播来添加媒体文件的。这两种方法各有优缺点。媒体文件有很多自带的数据,比如媒体的作者,媒体的标题,媒体的类型等。第一种方法可以自行设置这些属性,第二种方法则是使用原来媒体自带的属性,无需再手动设置。
1.ContentValues、
/*
* 此方法虽好,但是要手动添加很多值,比如说这个MP3的作者并不是安卓,但却写成了android,其实这些媒体的数据在媒体文件中已经自带了,可以不用自己设置。
*/
public void onLoop1Click(View v) {
// 判断是否能使用sd卡
if (!canWriteInExternalStorage()) {
Toast.makeText(this, "Can't write file", Toast.LENGTH_SHORT).show();
return;
}
Log.d("TAG", "LOOP1: " + LOOP1_PATH);
// 先将媒体文件保存到外部存储器中,这需要自己完成,不是java自带的方法。见最下方。
MediaUtils.saveRaw(this, R.raw.loop1, LOOP1_PATH);
// 设置ContentValues的值
ContentValues values = new ContentValues(5);
values.put(Media.ARTIST, "Android");
values.put(Media.ALBUM, "60AH");
values.put(Media.TITLE, "hack043");
values.put(Media.MIME_TYPE, "audio/mp3");
values.put(Media.DATA, LOOP1_PATH);
// 将媒体添加到ContentProvider中
getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, values);
}
2。MediaScanner
/*
* 使用MediaScanner添加MP3文件,这种方法可以避免手动添加这些值
*/
public void onLoop2Click(View v) {
if (!canWriteInExternalStorage()) {
Toast.makeText(this, "Can't write file", Toast.LENGTH_SHORT).show();
return;
}
// 首先,将文件保存到外部存储器中。
MediaUtils.saveRaw(this, R.raw.loop2, LOOP2_PATH);
// 发送广播,请求扫描并添加指定文件的文件
Uri uri = Uri.parse("file://" + LOOP2_PATH);
Intent i = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri);
sendBroadcast(i);
}
另外,判断sd卡是否能读的代码如下:
/*
* 判断外部存储器是否能读能写
*/
private boolean canWriteInExternalStorage() {
boolean mExternalStorageAvailable = false;
boolean mExternalStorageWriteable = false;
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
// We can read and write the media
mExternalStorageAvailable = mExternalStorageWriteable = true;
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
// We can only read the media
mExternalStorageAvailable = true;
mExternalStorageWriteable = false;
} else {
// Something else is wrong. It may be one of many other states,
// but all we need to know is we can neither read nor write
mExternalStorageAvailable = mExternalStorageWriteable = false;
}
return mExternalStorageAvailable && mExternalStorageWriteable;
}
保存文件到外部存储器中
/*******************************************************************************
* Copyright (c) 2012 Manning
* See the file license.txt for copying permission.
******************************************************************************/
package com.manning.androidhacks.hack037;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import android.content.Context;
import android.os.Environment;
import android.util.Log;
public final class MediaUtils {
private static final String TAG = MediaUtils.class.getCanonicalName();
private MediaUtils() {
}
public static void saveRaw(Context context, int raw, String path) {
File completePath = new File(
Environment.getExternalStorageDirectory(), path);
try {
completePath.getParentFile().mkdirs();
completePath.createNewFile();
BufferedOutputStream bos = new BufferedOutputStream(
(new FileOutputStream(completePath)));
BufferedInputStream bis = new BufferedInputStream(context
.getResources().openRawResource(raw));
byte[] buff = new byte[32 * 1024];
int len;
while ((len = bis.read(buff)) > 0) {
bos.write(buff, 0, len);
}
bos.flush();
bos.close();
} catch (IOException io) {
Log.e(TAG, "Error: " + io);
}
}
}