正文  多媒体 > 音频/Audio >

Android实现自定义铃音

不知道大家知道不知 道,Android手机设置铃音这个功能跟其他手机平台不太一样,其他平台设置的时候一般可以浏览本地铃音库或者曲库,然后选中即可设置。而 Android中不行,它只有手机出厂时内置的几种铃音可选......

不知道大家知道不知 道,Android手机设置铃音这个功能跟其他手机平台不太一样,其他平台设置的时候一般可以浏览本地铃音库或者曲库,然后选中即可设置。而 Android中不行,它只有手机出厂时内置的几种铃音可选。这个我觉得做的不是很好,给用户的体验不高,不够人性化。一个用户如果想设置自己下载的铃 音,现在一般有两种方法。

第一种:使用第三方软件设置,这种缺点就是每次设置时都需要打开这个软件。
第二种:比较死的方法,在sd卡里建立一个media的文件夹,再在这个文件夹里面建立名为audio的文件夹,最后再在audio文件夹里建立三个文件 夹,分别是notifications(放置在这个文件夹里的铃声可以设置短信音)、ringtones(这个用于设置来电铃声)、ALARMS(这个用 于设置闹铃声),把你不同用途的铃声放到不同的文件夹下手机就可以自动找到。
那么第三方软件是怎么实现设置的呢?先看一下效果:
设置之前:

设置之后:

代码实现起来也比较简单,里面有注释:
Activity:

package org.sunchao;

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class RingtoneSettingActivity extends Activity {
	private Button setting;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		setting = (Button) findViewById(R.id.setting);
		setting.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// 外部调用传入一个url
				RingtoneSetting.setmUrl(Environment
						.getExternalStorageDirectory().toString()
						+ "/Music/胡歌-忘记时间.mp3");
				// 开始设置
				RingtoneSetting.setting(RingtoneSettingActivity.this);
			}
		});
	}
}
供外部调用的实现类:
package org.sunchao;

import java.io.File;

import android.content.ContentValues;
import android.content.Context;
import android.media.RingtoneManager;
import android.net.Uri;
import android.provider.MediaStore;

public class RingtoneSetting {
	private static String mUrl;
	private static Context mContext;

	public static void setmUrl(String url) {
		mUrl = url;
	}

	public static void setting(Context context) {
		// 外部调用者传来的context
		mContext = context;
		// 设置歌曲路径
		File filePath = new File(mUrl);
		ContentValues values = new ContentValues();
		// The data stream for the file
		values.put(MediaStore.MediaColumns.DATA, filePath.getAbsolutePath());
		// The title of the content
		values.put(MediaStore.MediaColumns.TITLE, filePath.getName());
		// The MIME type of the file
		values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/mp3");
		// values.put(MediaStore.Audio.Media.ARTIST, "Madonna");
		// values.put(MediaStore.Audio.Media.DURATION, 230);
		// 来电铃声
		// 第二个参数若是true则会在铃音库中显示
		values.put(MediaStore.Audio.Media.IS_RINGTONE, true);
		// 通知/短信铃声
		values.put(MediaStore.Audio.Media.IS_NOTIFICATION, true);
		// 闹钟铃声
		values.put(MediaStore.Audio.Media.IS_ALARM, true);
		// 系统铃声
		values.put(MediaStore.Audio.Media.IS_MUSIC, true);
		// Insert it into the database
		Uri uri = MediaStore.Audio.Media.getContentUriForPath(filePath
				.getAbsolutePath());
		// 下面这一句很重要
		mContext.getContentResolver().delete(
				uri,
				MediaStore.MediaColumns.DATA + "=\""
						+ filePath.getAbsolutePath() + "\"", null);
		Uri newUri = mContext.getContentResolver().insert(uri, values);
		RingtoneManager.setActualDefaultRingtoneUri(mContext,
				RingtoneManager.TYPE_RINGTONE, newUri);

	}
}
上面代码中注释“// 下面这一句很重要”,刚开始我是没加这一句,但是会出现如下错误,08-12 22:11:13.486: ERROR/Database(2974): Error inserting is_alarm=false is_ringtone=true artist_id=37 is_music=false album_id=-1 title=tl.mp3 duration=230 is_notification=false title_key=Ttlmp3 mime_type=audio/mp3 date_added=1313158273 _display_name=tl.mp3 _size=8474325 _data=/sdcard/Music/tl.mp3
至于原因,我在这里找到了答案,主要看这个回答:
Remember to be careful about testing this code! It only truthfully works the first time. If you try running the same code again, you'll be trying to shove a duplicate entry in MediaStore's table, and the SQLite database won't allow you, giving you that exact same error. You have to either rename your file and add another instance of it, or go in, remove the entry, and then try again. To do this, you could use RingDroid. Just make sure you have all audio visible, and search for your filename, then delete it from there. Alternately, you could look at their source for deleting from the table.


最后不要忘记加权限:
<uses-permission android:name="android.permission.WRITE_SETTINGS"></uses-permission>