这二天,在联系人(Contacts)的新建编辑界面添加了一个来电手机铃声的功能,现在把一些关键的地方写出来,做一个小笔记吧。

1. 功能需求:

      在新建编辑联系人界面,添加一个手机铃声入口,点击可以进入铃声选择界面,返回一个手机铃声的url.


2. 一些说明:

这主要涉及到的db数据库:

data/data/com.android.providers.contacts/databases/contacts2.db


表:contacts


url:  android.provider.ContactsContract.Contacts.CONTENT_URI


我们到时候,主要要用到的,还是lookup和custom_ringtone这二个字段。



3. 关键的逻辑处理代码:

(1)在RawContactEditorView.java文件中,添加手机铃声界面,当点击来电铃声时,发出选择来电铃声的Intent

1. private void doPickRingtone() {  
2. new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);  
3. true);  
4.     intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_RINGTONE);  
5. false);   
6.     Uri ringtoneUri;  
7. /**
8.     if (mCustomRingtone != null) {
9.         ringtoneUri = Uri.parse(mCustomRingtone);
10.     } else {
11.         ringtoneUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
12.     }
13.     **/  
14.      ringtoneUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);  
15.     intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, ringtoneUri);  
16.     ((Activity)mContext).startActivityForResult(intent, REQUEST_CODE_PICK_RINGTONE);  
17. "set_ring_tone","((Activity)mContext):"+((Activity)mContext));  
18. }



(2).在ContactEditorActivity 中得到返回的铃声uri:

1. //add by wingtech hexiaoming for add_ring_tone  20141107 start    
2. public static Uri pickedUri = null;    
3. @Override  
4. public void onActivityResult(int requestCode, int resultCode, Intent data) {  
5. if (resultCode != Activity.RESULT_OK) {  
6. return;  
7.        }  
8.   
9. switch (requestCode) {  
10. case RawContactEditorView.REQUEST_CODE_PICK_RINGTONE: {  
11.                pickedUri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);  
12. //handleRingtonePicked(pickedUri);  
13. "set_ring_tone","pickedUri:"+pickedUri);  
14.                String ringtone_title = getRingtoneName(pickedUri);  
15.                updateRingtone(ringtone_title);                                 
16. break;  
17.            }  
18.        }  
19.    }     
20. //add by wingtech hexiaoming for add_ring_tone  20141107 end


(3).用铃声的uri值得到铃声的名称:

1. public  String  getRingtoneName(Uri ringtone) {  
2. null;  
3. try {  
4.          Cursor cursor = getContentResolver().query(ringtone,  
5. new String[] { MediaStore.Audio.Media.TITLE }, null, null, null);  
6. if (cursor != null) {  
7. if (cursor.moveToFirst()) {  
8. 0);                 
9.              }  
10.               cursor.close();  
11.          }           
12. catch (SQLiteException sqle) {  
13. // Unknown title for the ringtone  
14.              sqle.printStackTrace();  
15.          }     
16. return ringtone_title;          
17.  }



(4)更新来电铃声的名称:

    1. private void  updateRingtone(String ringtone_title) {  
    2.     mFragment.updateRingtone(ringtone_title);  
    3. }




    (5)在ContactEditorFragment.java 我们保存来电铃声的uri,这个其实主要是靠mLookupUri 来做条件,来对应的保存:

    1. private void handleRingtonePicked(Uri pickedUri) {  
    2. if (pickedUri == null || RingtoneManager.isDefault(pickedUri)) {  
    3. null;  
    4. else {  
    5.             mCustomRingtone = pickedUri.toString();  
    6.         }  
    7.         Intent intent = ContactSaveService.createSetRingtone(  
    8.                 mContext, mLookupUri, mCustomRingtone);  
    9.         mContext.startService(intent);  
    10.     }



    我们在ContactEditorFragment----save方法的,调用handleRingtonePicked此方法,就OK。


     


    但是,这有一个在新建时,mLookupUri 为null的情况,所以,我们还是要在ContactSaveService -----saveContact 方法中,找到lookupUri的不为null值的地方加上:

      1. //add by wingtech hexiaoming for add_ring_tone  20141107 start  
      2. android.util.Log.i("saveContact","lookupUri_3:"+lookupUri);  
      3. if(ContactEditorActivity.pickedUri != null){  
      4. this, lookupUri, ContactEditorActivity.pickedUri.toString());  
      5.     startService(intent_save_ringtone);         
      6. }  
      7. //add by wingtech hexiaoming for add_ring_tone  20141107 end



      (6)当我们刚进来时,我们就要读取根据lookup的值来读取custom_ringtone,然后,再根据custom_ringtone读取(getRingtoneName)铃声的名称,显示出来。

      1. public  String getRingtoneFromLookup(String lookup) {  
      2.     Cursor cursor = mContext.getContentResolver().query(  
      3.         android.provider.ContactsContract.Contacts.CONTENT_URI,    
      4. new String[]{android.provider.ContactsContract.Contacts.CUSTOM_RINGTONE},   
      5. "= ?",   
      6. new String[]{lookup},   
      7. null);   
      8. try {  
      9. if (cursor.moveToFirst()) {  
      10. "ContactEditorFragment","cursor.getString(0):"+cursor.getString(0));  
      11. return cursor.getString(0);  
      12.         }  
      13. finally {  
      14.         cursor.close();             
      15.     }  
      16. return null;  
      17. }



      4. 一些总结:


      做这个功能,个人觉得,做到最后,还是发现用的东西都是一些基础的东西,如ContentProvider,Intent,Activity等,所以,自己的基础一定要打好,基本的掌握好了,做东西的时候,心中就会知道要做什么,用到的东西在那里,要如何一步一步的实现。


             还有就是许多小细节,也是要我们自己打LOG,看明白,到底是怎么回事。特别是我们做二次开发,有许多东西,我们只要找到我们关心的部分,把东西打印出来,就会清楚的明白代码是怎么运行的,然后再添加自己要做的东西。


             最后,可能有人问,我怎么没有把界面那部分写也来,我个人觉得那部分太简单了,唯一有点难度的,可能就是在设置来电铃声的名称的一些细节,对于细节问题,我想说,这不是问题,只要你把东西打印出来,基本上就能解决的。