目录
一、写在前面
辣鸡realme,连闹钟默认铃声都不能修改,每次都要手动重新选择,realme社区那么多反馈这个问题的帖子,不知道官方是觉得加个功能麻烦还是觉得只有极少数用户用这个功能。
二、完整代码与APK安装包
- 完整代码github地址:GitHub - Ye-Changpeng/RingtoneSettings: android设置闹钟默认铃声
- 安装包:
- github: Releases · Ye-Changpeng/RingtoneSettings · GitHub
- 百度网盘:链接:https://pan.baidu.com/s/1LPwUb9RRa5OBMVHppLok3Q?pwd=1ru9 提取码:1ru9
- 夸克网盘:链接:https://pan.quark.cn/s/745680305365 提取码:639G
三、APK界面截图
四、主要代码说明
(一)获得当前闹钟默认铃声名称
默认铃声uri使用RingtoneManager.getActualDefaultRingtoneUri进行获取
铃声分为三种类型:系统铃声、本地铃声(只自己下载的音频文件)、在线铃声(未做适配),下面分开说明
1、当前闹钟默认铃声是系统铃声
直接使用getTitle获得标题作为铃声名称
Uri uri = RingtoneManager.getActualDefaultRingtoneUri(this, RingtoneManager.TYPE_ALARM);
Ringtone ringtone = RingtoneManager.getRingtone(this, uri);
String title = ringtone.getTitle(this);
未解决的问题:realme手机选择系统自带的铃声,通过getTitle获得的标题是ringtone_编号,不知道什么原因,未解决
2、当前闹钟默认铃声是本地铃声
本地铃声是在外部存储位置的铃声,使用getTitle获得到的是歌曲的标题,感觉直接使用歌曲文件名作为铃声名称更加直观,歌曲标题与文件名的区别如下图(此处是Windows文件管理器里的截图)
如何得到歌曲文件名称:根据uri从MediaData中得到MediaStore.Audio.Media.DATA字段的值得到文件的实际存储路径,再去除文件的后缀得到不带后缀的文件名称
Uri uri = RingtoneManager.getActualDefaultRingtoneUri(this, RingtoneManager.TYPE_ALARM);
String ringtoneName = Utils.removeFilenameSuffix(Utils.getMediaDataFromURI(this, uri, MediaStore.Audio.Media.DATA));
public class Utils {
public static String getMediaDataFromURI(Context context, Uri contentUri, String dataType) {
String[] projection = { dataType };
Cursor cursor = context.getContentResolver().query(contentUri, projection, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
int columnIndex = cursor.getColumnIndexOrThrow(dataType);
String filePath = cursor.getString(columnIndex);
cursor.close();
return filePath;
}
return null;
}
public static String removeFilenameSuffix(String filePath) {
if (filePath == null)
return "";
File file = new File(filePath);
String fileName = file.getName();
int lastDotIndex = fileName.lastIndexOf('.');
if (lastDotIndex == -1) {
return fileName; // No extension found
}
return fileName.substring(0, lastDotIndex);
}
public static boolean isExternalResource(Uri uri) {
// 检查 URI 是否为外部存储
return uri != null && uri.toString().contains("//media/external");
}
}
另外此处涉及到对外部存储文件的访问,所以需要在AndroidManifest.xml添加权限,代码中的动态权限申请框架使用的是EasyPermissions
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
3、当前闹钟默认铃声是在线铃声
未做测试,未做适配
(二)设置闹钟铃声
设置铃声需要有“修改系统设置”的权限,在AndroidManifest.xml中添加权限,注意添加:tools:ignore="ProtectedPermissions"
<uses-permission android:name="android.permission.WRITE_SETTINGS"
tools:ignore="ProtectedPermissions" />
跳转到系统铃声选择界面,选择铃声
// 打开系统铃声设置
Intent intent = new Intent(
RingtoneManager.ACTION_RINGTONE_PICKER);
Uri currentTone = RingtoneManager.getActualDefaultRingtoneUri(RingtoneActivity.this,
RingtoneManager.TYPE_ALARM);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, currentTone);
// 设置铃声类型和title
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE,
RingtoneManager.TYPE_ALARM);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE,
getString(R.string.select_ringtone));
// 当设置完毕之后返回到当前的Activity
startActivityForResult(intent, REQUEST_CODE_SELECT_RINGTONE);
在onActivityResult回调函数中根据返回的uri修改铃声,通过data.getParcelableExtra获得用户选择的铃声;使用RingtoneManager.setActualDefaultRingtoneUri修改铃声
Uri pickedUri = data
.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
RingtoneManager.setActualDefaultRingtoneUri(this,
RingtoneManager.TYPE_ALARM, pickedUri);