前景提示:

关于系统铃声闹铃的设置使用的是frameworks/base/media/java/android/media/RingtoneManager.java

设置铃声:RingtoneManager.setActualDefaultRingtoneUri()方法

public static void setActualDefaultRingtoneUri(Context context, int type, Uri ringtoneUri) {

String setting = getSettingForType(type);

if (setting == null) return;

final ContentResolver resolver = context.getContentResolver();

if (Settings.Secure.getIntForUser(resolver, Settings.Secure.SYNC_PARENT_SOUNDS, 0,

context.getUserId()) == 1) {

// Parent sound override is enabled. Disable it using the audio service.

disableSyncFromParent(context);

}

if(!isInternalRingtoneUri(ringtoneUri)) {

ringtoneUri = ContentProvider.maybeAddUserId(ringtoneUri, context.getUserId());

}

Settings.System.putStringForUser(resolver, setting,

ringtoneUri != null ? ringtoneUri.toString() : null, context.getUserId());

// Stream selected ringtone into cache so it's available for playback

// when CE storage is still locked

if (ringtoneUri != null) {

//*******这里有个新增声音种类bug,添加一个过滤if直接return*****

//这块代码大概是要做一个声音的存储调取缓存的操作,若是我们新增声音进行存储调取的话,会出现io错误,还是直接屏蔽了,有大手子其他理解可交流下

//过滤返回代码 if(setting .equals(Settings.System.MODEL_TIMER) ))return;

final Uri cacheUri = getCacheForType(type, context.getUserId());

try (InputStream in = openRingtone(context, ringtoneUri);

OutputStream out = resolver.openOutputStream(cacheUri)) {

FileUtils.copy(in, out);

} catch (IOException e) {

Log.w(TAG, "Failed to cache ringtone: " + e);

}

}

}

获取铃声:

RingtoneManager.getActualDefaultRingtoneUri();

关于默认铃声设置修改的方法第一种:网上搜索到的几乎都是这种默认修改参数文件路径的方式

build/make/target/product/full_base.mk 或者是其他能编译到的.mk文件

PRODUCT_PROPERTY_OVERRIDES := \

ro.config.ringtone=Ring_Synth_04.ogg \(这个对应的是铃声默认文件,Ring_Synth_04.ogg不过当你解析出来后title是 Flutey Phone,这是因为在数据库中被修改了title值)

ro.config.notification_sound=pixiedust.ogg

/data/sounds下.mk文件中有很多铃声资源文件供查找替换.mk的Ring_Synth_04.ogg使用/frameworks/base/data/sounds/AudioPackageGo.mk

关于系统默认资源文件修改操作:

添加资源路径/frameworks/base/packages/SettingsProvider/res/values/defaults.xml

/product/media/audio/ui/Dock.ogg

/product/media/audio/ui/Undock.ogg

/product/media/audio/ui/Dock.ogg

/product/media/audio/ui/Undock.ogg

1

/product/media/audio/ui/Lock.ogg

/product/media/audio/ui/Unlock.ogg

/product/media/audio/ui/Trusted.ogg

/product/media/audio/ui/WirelessChargingStarted.ogg

/product/media/audio/ui/ChargingStarted.ogg

存储默认值/frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java

例如:loadSetting(stmt, Settings.System.VIBRATE_ON, vibrate);

存储安全等级可选择system global secure第二种 新增铃声种类,这种方式可以使用上述“关于系统默认资源文件修改操作”方式添加默认资源文件并存储。

这里说一种参考ringtone设置来电铃声闹铃的默认存储方式/frameworks/base/media/java/android/media/RingtoneManager.java

网上有一些关于电铃声闹铃的默认扫描存储代码流程,但几乎都是Android11之前的mediaScan类说明,根据其提供的代码文件查找会发现都被删除或启用,本文是依据Android11的代码进行说明

关键方法ensureDefaultRingtones()方法

@SystemApi

@RequiresPermission(android.Manifest.permission.WRITE_SETTINGS)

public static void ensureDefaultRingtones(@NonNull Context context) {

for (int type : new int[] {

TYPE_RINGTONE,

TYPE_NOTIFICATION,

TYPE_ALARM,

TYPE_OTHER,//新增铃声类型,其需要全局对象配置

}) {

// Skip if we've already defined it at least once, so we don't

// overwrite the user changing to null

final String setting = getDefaultRingtoneSetting(type);

if (Settings.System.getInt(context.getContentResolver(), setting, 0) != 0) {

continue;

}

// Try finding the scanned ringtone

final String filename = getDefaultRingtoneFilename(type);

final Uri baseUri = MediaStore.Audio.Media.INTERNAL_CONTENT_URI;

try (Cursor cursor = context.getContentResolver().query(baseUri,

new String[] { MediaColumns._ID },

MediaColumns.DISPLAY_NAME + "=?",

new String[] { filename }, null)) {

if (cursor.moveToFirst()) {

final Uri ringtoneUri = context.getContentResolver().canonicalizeOrElse(

ContentUris.withAppendedId(baseUri, cursor.getLong(0)));

//设置默认的铃声值,这里说个区别为什么得到的uri是content://开头的原因,而不是绝对路径/product/media/audio/alarms/Alarm_Rooster_02.ogg

//上述有特殊说明,当新增存储时需要setActualDefaultRingtoneUri方法中进行屏蔽

RingtoneManager.setActualDefaultRingtoneUri(context, type, ringtoneUri);

Settings.System.putInt(context.getContentResolver(), setting, 1);

}

}

}

}

private static String getDefaultRingtoneSetting(int type) {

switch (type) {

case TYPE_RINGTONE: return "ringtone_set";

case TYPE_NOTIFICATION: return "notification_sound_set";

case TYPE_ALARM: return "alarm_alert_set";

case TYPE_OTHER: return "sound_timer_set";

default: throw new IllegalArgumentException();

}

}

//该方法获取上述.mk中配置的默认值,然后根据文件名称去数据库中查找对应的uri*****ro.config.ringtone=Ring_Synth_04.ogg

private static String getDefaultRingtoneFilename(int type) {

switch (type) {

case TYPE_RINGTONE: return SystemProperties.get("ro.config.ringtone");

case TYPE_NOTIFICATION: return SystemProperties.get("ro.config.notification_sound");

case TYPE_ALARM: return SystemProperties.get("ro.config.alarm_alert");

//这里直接使用了alerm的默认铃声,若是你需要其他默认铃声,可根据自己的具体需求提供路径文件名称

case TYPE_OTHER: return SystemProperties.get("ro.config.alarm_alert");

default: throw new IllegalArgumentException();

}

}