編輯:關於Android編程
從上一篇獲取符合默認短信應用來看,獲取思路是正確的,但是還很不完善,但是這歸根結底是google整出來的一套規范,如何去找到符合規范的應用呢,這得google告訴我們。
因此,我看了一下android源碼,關鍵是SmsApplication中的SmsApplicationData, 裡面有個函數叫getApplicationCollection(Context context),這就是android4.4中系統用於獲取符合默認短信應用要求的應用信息的代碼,如下:
/** * Returns the list of available SMS apps defined as apps that are registered for both the * SMS_RECEIVED_ACTION (SMS) and WAP_PUSH_RECEIVED_ACTION (MMS) broadcasts (and their broadcast * receivers are enabled) * * Requirements to be an SMS application: * Implement SMS_DELIVER_ACTION broadcast receiver. * Require BROADCAST_SMS permission. * * Implement WAP_PUSH_DELIVER_ACTION broadcast receiver. * Require BROADCAST_WAP_PUSH permission. * * Implement RESPOND_VIA_MESSAGE intent. * Support smsto Uri scheme. * Require SEND_RESPOND_VIA_MESSAGE permission. * * Implement ACTION_SENDTO intent. * Support smsto Uri scheme. */ public static CollectiongetApplicationCollection(Context context) { PackageManager packageManager = context.getPackageManager(); // Get the list of apps registered for SMS Intent intent = new Intent(Intents.SMS_DELIVER_ACTION); List smsReceivers = packageManager.queryBroadcastReceivers(intent, 0); HashMap receivers = new HashMap (); // Add one entry to the map for every sms receiver (ignoring duplicate sms receivers) for (ResolveInfo resolveInfo : smsReceivers) { final ActivityInfo activityInfo = resolveInfo.activityInfo; if (activityInfo == null) { continue; } if (!permission.BROADCAST_SMS.equals(activityInfo.permission)) { continue; } final String packageName = activityInfo.packageName; if (!receivers.containsKey(packageName)) { final String applicationName = resolveInfo.loadLabel(packageManager).toString(); final SmsApplicationData smsApplicationData = new SmsApplicationData( applicationName, packageName, activityInfo.applicationInfo.uid); smsApplicationData.mSmsReceiverClass = activityInfo.name; receivers.put(packageName, smsApplicationData); } } // Update any existing entries with mms receiver class intent = new Intent(Intents.WAP_PUSH_DELIVER_ACTION); intent.setDataAndType(null, "application/vnd.wap.mms-message"); List mmsReceivers = packageManager.queryBroadcastReceivers(intent, 0); for (ResolveInfo resolveInfo : mmsReceivers) { final ActivityInfo activityInfo = resolveInfo.activityInfo; if (activityInfo == null) { continue; } if (!permission.BROADCAST_WAP_PUSH.equals(activityInfo.permission)) { continue; } final String packageName = activityInfo.packageName; final SmsApplicationData smsApplicationData = receivers.get(packageName); if (smsApplicationData != null) { smsApplicationData.mMmsReceiverClass = activityInfo.name; } } // Update any existing entries with respond via message intent class. intent = new Intent(TelephonyManager.ACTION_RESPOND_VIA_MESSAGE, Uri.fromParts("smsto", "", null)); List respondServices = packageManager.queryIntentServices(intent, 0); for (ResolveInfo resolveInfo : respondServices) { final ServiceInfo serviceInfo = resolveInfo.serviceInfo; if (serviceInfo == null) { continue; } if (!permission.SEND_RESPOND_VIA_MESSAGE.equals(serviceInfo.permission)) { continue; } final String packageName = serviceInfo.packageName; final SmsApplicationData smsApplicationData = receivers.get(packageName); if (smsApplicationData != null) { smsApplicationData.mRespondViaMessageClass = serviceInfo.name; } } // Update any existing entries with supports send to. intent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts("smsto", "", null)); List sendToActivities = packageManager.queryIntentActivities(intent, 0); for (ResolveInfo resolveInfo : sendToActivities) { final ActivityInfo activityInfo = resolveInfo.activityInfo; if (activityInfo == null) { continue; } final String packageName = activityInfo.packageName; final SmsApplicationData smsApplicationData = receivers.get(packageName); if (smsApplicationData != null) { smsApplicationData.mSendToClass = activityInfo.name; } } // Remove any entries for which we did not find all required intents. for (ResolveInfo resolveInfo : smsReceivers) { final ActivityInfo activityInfo = resolveInfo.activityInfo; if (activityInfo == null) { continue; } final String packageName = activityInfo.packageName; final SmsApplicationData smsApplicationData = receivers.get(packageName); if (smsApplicationData != null) { if (!smsApplicationData.isComplete()) { receivers.remove(packageName); } } } return receivers.values(); } /** * Checks to see if we have a valid installed SMS application for the specified package name * @return Data for the specified package name or null if there isn't one */ private static SmsApplicationData getApplicationForPackage( Collection applications, String packageName) { if (packageName == null) { return null; } // Is there an entry in the application list for the specified package? for (SmsApplicationData application : applications) { if (application.mPackageName.contentEquals(packageName)) { return application; } } return null; }
由於這個是隱藏的類和函數,我們獲取不到,用反射又會相當麻煩,直接把實現給拷出來不失為一個良策。
要判斷拿到的collection中的某一個是不是完全符合默認短信應用的要求怎麼辦呢?調用一下SmsApplication.isComplete()就OK了。
前言1.什麼是內存洩漏?這個問題說來話太長了,似乎盤古開天劈地以來就有的話題一樣,這個問題一直在困擾著程序員,內存洩露 memory leak,是指程序在申請內存後,無法
效果: 代碼:https://github.com/ldb-github/Layout_Tab1、布局:使用LinearLayout布置標簽;再使用FrameL
先通過一個頁面看下事情的來龍去脈,頁面如下所示: 這個頁面剛好一屏幕大小,所以沒有滾動條,因為“保存”鍵上面那個項目備注是需要用戶去填寫的,當他點擊後就會出現虛
本篇博客主要講解怎樣自定義一個circleIndicator控件?下一遍博客主要講解怎樣更改ViewPager切換的效果, 預計明天晚上之前更新。效果圖如下1)首先我們先