需求:
单独修改gmail和google日历默认铃声,区别于系统的默认通知音
解决方法:
因为GMS包没有源码,所以无法通过修改apk的方法解决,只能修改获取默认铃声时的uri实现。
具体设计到的文件
/base/media/java/android/media/RingtoneManager.java
/base/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java
/base/services/core/java/com/android/server/notification/NotificationManagerService.java
/providers/MediaProvider/src/com/android/providers/media/RingtonePickerActivity.java
在RingtoneManager.java中主要定义读取默认铃声uri的方法

/*** Check the given uri whether exist in device.** @param context the context.* @param uri the given uri.* @return if exist return true, otherwise false.* @hide* @internal*/private static String getNotificationUriByName(Context context, String ringname) {// TODO Auto-generated method stubCursor cursor = context.getContentResolver().query(MediaStore.Audio.Media.INTERNAL_CONTENT_URI,new String[] { "_id" }, "_display_name=? and is_notification=1",new String[] { ringname }, null);int id = 0;if (cursor != null) {if (cursor.moveToFirst()) {do {id = cursor.getInt(0);} while (cursor.moveToNext());}}Uri ringtoneUri = ContentUris.withAppendedId(MediaStore.Audio.Media.INTERNAL_CONTENT_URI, id);if (cursor != null) {cursor.close();}Log.d(TAG, "getNotificationUriByName ringname = " + ringname + " , ringtoneUri = " + ringtoneUri);return ringtoneUri + "";}/*** Check the given uri whether exist in device.** @param context the context.* @param uri the given uri.* @return if exist return true, otherwise false.* @hide* @internal*/public static String getNotificationUri(Context context) {boolean iccid = "1".equals(android.os.SystemProperties.get("persist.operator.subid", "0")) ? true : false;  //Iccid ==1, return true;boolean is_op07 =  "OP07".equals(android.os.SystemProperties.get("persist.operator.optr", "")) ? true : false; //op07, return true;String mccMnc = android.os.SystemProperties.get("persist.bootanim.mnc", ""); //this is enough for W2100, 334050 or 334090...Log.d(TAG, "LCT dual-perso. iccid = " + iccid + ". is_op07 = " + is_op07 + ". mccMnc = " + mccMnc);String att_ringtone = null;if((is_op07 && ("334090".equals(mccMnc))) || (is_op07 && !iccid && ("334050".equals(mccMnc)))){att_ringtone = getNotificationUriByName(context, "ATT_Email_receive.mp3");}else{att_ringtone = getNotificationUriByName(context, "Success.mp3");}Log.d(TAG, "ATT -> Calendar default notification uri = " + att_ringtone);return att_ringtone;}

如果需要获取电话铃声的uri可以把查询条件换成is_ringtone=1

在RingtonePlayer.java中是在用户还没有手动设置过google日历铃声时,有提示音时需要把默认铃声改为指定默认铃声

        public void playAsync(Uri uri, UserHandle user, boolean looping, AudioAttributes aa) {if (LOGD) Log.d(TAG, "playAsync(uri=" + uri + ", user=" + user + ")");if (Binder.getCallingUid() != Process.SYSTEM_UID) {throw new SecurityException("Async playback only available from system UID.");}if (UserHandle.ALL.equals(user)) {user = UserHandle.SYSTEM;}//Added for dt-4590368 by yonglin.liao 2017/05/04 begin {@if(android.os.SystemProperties.get("ro.lct.tct_mx_att").equals("1")){if (uri.toString().contains("android.resource://com.google.android.calendar/raw/")) {String uriString = RingtoneManager.getNotificationUri(mContext);uri = Uri.parse(uriString);Log.d(TAG, "playAsync(Calendar ATT ringtone uri = " + uri + ")");}}//Added for dt-4590368 by yonglin.liao 2017/05/04 end @}mAsyncPlayer.play(getContextForUser(user), uri, looping, aa);}

因为google日历的默认铃声是加载的自己内部apk里面的资源,uri比较好识别,但是gmail的默认铃声因为是直接调用的系统默认铃声,所以需要在NotificationManagerService.java中处理notification.sound即可

    void enqueueNotificationInternal(final String pkg, final String opPkg, final int callingUid,final int callingPid, final String tag, final int id, final Notification notification,int[] idOut, int incomingUserId) {if (DBG) {Slog.v(TAG, "enqueueNotificationInternal: pkg=" + pkg + " id=" + id+ " notification" + notification);}if(android.os.SystemProperties.get("ro.lct.tct_mx_att").equals("1")){if(notification.sound != null){if(notification.sound.toString().contains("content://settings/system/notification_sound")){if(pkg.contains("com.google.android.gm") || pkg.contains("com.tct.email")){String uriString = RingtoneManager.getNotificationUri(getContext());notification.sound = Uri.parse(uriString);Log.d(TAG, "notification.sound(Calendar ATT ringtone uri = " + uriString + ")");                }}}}

现在在用户还没有设置过默认铃声的情况下,来消息的铃声已经设置成指定的,但是当用户进去铃声列表时默认铃声还是系统的,所以需要在RingtonePickerActivity.java中设置列表的默认选中指定铃声mExistingUri

        mExistingUri = intent.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI);Log.d("TAG","mExistingUri -->befor = " + mExistingUri);// Added for defect 1278683,1251941 by yonglin.liao on 20160126 beginif(android.os.SystemProperties.get("ro.lct.tct_mx_att").equals("1")){if (mExistingUri != null) {if((mExistingUri + "").contains("android.resource://com.google.android.calendar/raw/") || ((mExistingUri + "").contains("content://settings/system/notification_sound") && groundAppPackageName().equals("com.google.android.gm"))) {//Modified for dt-4590368 by yonglin.liao 2017/05/04 begin {@String needChangeCalendarNotification = Settings.System.getString(this.getContentResolver(), "change_calendar_notification");if ((needChangeCalendarNotification != null) && (needChangeCalendarNotification.equals("true"))) {String uriString = Settings.System.getString(this.getContentResolver(), "calendar_att_notification_uri_string");mExistingUri = Uri.parse(uriString);Log.d(TAG, "set mExistingUri = " + mExistingUri);} else {mExistingUri = Settings.System.DEFAULT_NOTIFICATION_URI;}//Modified for dt-4590368 by yonglin.liao 2017/05/04 end @}}}}final AlertController.AlertParams p = mAlertParams;p.mCursor = mCursor;

在这个方法中因为调用的是MediaProvider的Activity,传入的context没有实际意义,没法判断google日历的默认铃声,所以我们要想办法获取RingtonePickerActivity上一个Activity是否是google日历,构造方法如下

    private String groundAppPackageName() {ActivityManager am = (ActivityManager)getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1);MtkLog.e(TAG, "tasks.get(0).baseActivity.getPackageName() = " + tasks.get(0).baseActivity.getPackageName());return tasks.get(0).baseActivity.getPackageName();}

现在设置默认铃声基本都已经设置完成,经过编译版本重新下载检查发现一个bug,进去apk的设置铃声页面,默认铃声还是显示系统默认铃声,但是点击进去列表是选中指定铃声
这是因为apk调用了RingtoneManager中Ringtone getRingtone(final Context context, Uri ringtoneUri, int streamType)方法,需要对ringtoneUri进行重新赋值成指定铃声

    private static Ringtone getRingtone(final Context context, Uri ringtoneUri, int streamType) {Log.d(TAG, "getRingtone() ringtoneUri ---> " + ringtoneUri+ ", streamType = " + streamType);if(android.os.SystemProperties.get("ro.lct.tct_mx_att").equals("1")){boolean iccid = "1".equals(android.os.SystemProperties.get("persist.operator.subid", "0")) ? true : false;  //Iccid ==1, return true;boolean is_op07 =  "OP07".equals(android.os.SystemProperties.get("persist.operator.optr", "")) ? true : false; //op07, return true;String mccMnc = android.os.SystemProperties.get("persist.bootanim.mnc", ""); //this is enough for W2100, 334050 or 334090...Log.d(TAG, "LCT dual-perso. iccid = " + iccid + ". is_op07 = " + is_op07 + ". mccMnc = " + mccMnc);if(context.getPackageName().equals("com.google.android.gm") || context.getPackageName().equals("com.google.android.calendar") || context.getPackageName().equals("com.tct.email")) {String uriString = getNotificationUri(context);if((ringtoneUri + "").contains("content://settings/system/notification_sound")){  //Modified for dt-4590368 by yonglin.liao 2017/05/04 begin {@            ringtoneUri = Uri.parse(uriString);Log.d(TAG, "att getRingtone = " + ringtoneUri);//Modified for dt-4590368 by yonglin.liao 2017/05/04 end @}}if(is_op07 && iccid && ("334050".equals(mccMnc))){//parameter 3; //OP07 + 334050 + iccid is 1;if(isNotificationUri(context,ringtoneUri)) {ringtoneUri = Uri.parse(uriString);}}}if(android.os.SystemProperties.get("ro.lct.tct_mx_att").equals("1")){if(is_op07 && iccid && ("334050".equals(mccMnc))){//parameter 3; //OP07 + 334050 + iccid is 1;if(isNotificationUri(context,ringtoneUri)) {ringtoneUri = getActualDefaultRingtoneUri(context,TYPE_NOTIFICATION);}}}}try {final Ringtone r = new Ringtone(context, true);if (streamType >= 0) {r.setStreamType(streamType);}r.setUri(ringtoneUri);return r;} catch (Exception ex) {Log.e(TAG, "Failed to open ringtone " + ringtoneUri + ": " + ex);}return null;}

到此为止,整个修改gmail和google日历默认铃声的事情全部完成。如果有其他第三方apk需要修改默认铃声的话,此方法同样生效。

Android系统修改gmail和google日历默认铃声,区别于系统的默认通知音相关推荐

  1. linux系统修改主机名会不会影响,在Linux系统中修改主机名

    **知识点:linux常用命令 方法概要: 更改/etc/sysconfig下的network文件,在提示符下输入vi /etc/sysconfig/network,然后将HOSTNAME后面的值改为 ...

  2. linux安装系统修改u盘盘符,U盘安装Centos系统时,如何快速确认U盘盘符

    用U盘安装Centos系统时,经常卡在找不到u盘镜像所在位置 1.安装时,先将光标移到Install centos7,然后根据提示按tab(有的是按e,请根据提示选择按键),编辑路径 将: vmlin ...

  3. 谷歌日历一键删除日程_如何在Google日历中删除新的提醒

    谷歌日历一键删除日程 In December 2015, Google added reminders to the Google Calendar app for Android and iOS u ...

  4. Android替换/修改系统默认输入法

    各大输入法的服务 ro.mtk_default_ime=com.tencent.qqpinyin.QQPYInputMethodService//默认qq输入法 ro.mtk_default_ime= ...

  5. Android 系统默认铃声修改 添加删除铃声

    Android 7.0 修改系统默认铃声: build\target\product\full_base.mk ro.config.ringtone=14_Snowflakes.ogg \ ro.co ...

  6. Android系统修改默认语言为中文

    Android系统修改默认语言为中文 对于Android系统修改默认语言的方法,各个版本的系统方法都差不多一致,至少我在Android5.1和Android9.0使用都成功,具体方法如下: 在buil ...

  7. 2021-01-14 Android系统修改出厂默认语言

    Android系统修改出厂默认语言 一.方法一,修改\build\target\product\languages_full.mk文件,从PRODUCT_LOCALES里选择第一个语言作为默认语言,下 ...

  8. android修改默认遥控器键值,RK3128平台android系统修改添加遥控器键值码值

    本帖最后由 微笑,一路向前 于 2017-1-4 15:34 编辑 最近帮客户定制RK3128平台的固件,涉及到定制新的遥控器,需要添加或修改遥控码值.RK3128平台Android系统修改遥控器码值 ...

  9. android系统默认铃声,Android系统修改默认铃声

    Andriod手机的铃声默认保存在system/media/audio/下面,有四个文件夹,分别是alarms,notifications,ringtones,ui.对应闹钟.通知.铃声.UI音效.r ...

最新文章

  1. 智能车竞赛提问回复-2021-3-25
  2. DOM中元素节点、属性节点、文本节点的理解
  3. 《音乐达人秀:Adobe Audition实战200例》——实例7 定时录制网络音乐节目
  4. 如何在博客中插入背景音乐
  5. linux如何将文件夹添加到书签,桌面应用|[新手技巧] 如何在Ubuntu中添加和删除书签...
  6. Linux下qwt源码编译,QWT的编译与配置
  7. IIS 设置默认首页静态页,无静态页,走路由
  8. 基于SSM的在线课程学习系统
  9. 03.Web大前端时代之:HTML5+CSS3入门系列~H5功能元素
  10. 分享一篇关于代理IP对于python爬虫有多重要
  11. Redisson lua脚本解读
  12. 大数据第一季--Hadoop(day4)-徐培成-专题视频课程
  13. 支付宝小程序获取用户手机号php,小程序登录、获取用户信息、手机号
  14. PHP 实现网页爬虫
  15. Excel冻结多行多列
  16. 根据账户名称筛选收支明细
  17. 全球化观点的生产模式
  18. 通过mac地址查询ip
  19. 这几个宝藏网站助力学好Python
  20. vue+router 404页面制作

热门文章

  1. Flipper-TR®活细胞膜张力检测探针解决方案
  2. 计算机类短视频论文,论新媒体环境下短视频平台的发展--以秒拍为例.docx
  3. obsidian插件无法加载的解决办法
  4. html语言里id是什么意思,HTML中id属性的有效值是什么?
  5. GitEmoji使用指南
  6. C# Winform程序设计运行在高分屏下模糊解决办法
  7. java通过html模板转pdf文件(中文可显示)
  8. python基础知识(三)
  9. VS2019 设置护眼背景色
  10. [W5500应用]用Microduino实现网页控制恒温饮水机以及电灯