短信的接收和发送,有Broadcast发送出来。
而对于彩信,接收时有Broadcast,但是发送时却没有。
并且对于彩信,也没有合适的Uri可以实现对数据库的监听。
大概看了下彩信MMS的发送流程,发现可以通过监听android.net.conn.CONNECTIVITY_CHANGE这个广播来监听彩信的发送。
下面是流程分析
发送彩信最终会调用com.android.mms.transactionTransactionService的processTransaction()
在这里函数里面会将手机的连接类型设置为ConnectivityManager.TYPE_MOBILE_MMS
在beginMmsConnectivity()中开始设置手机连接类型:
而本身的MMS处理模块此时也会停下来监听这个广播继续下一步的操作:
所以根据上面的分析,可以通过监听这个广播来达到监听发送彩信的目的,代码如下:
package com.test.emm401; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.Build; import android.os.Handler; import android.os.Looper; import android.widget.Toast; public class ConnectivityChangeReceiver extends BroadcastReceiver { private static final String TAG = ConnectivityChangeReceiver.class.getSimpleName(); /** * 发送MMS会触发TYPE_MOBILE_MMS类型的ConnectivityManager.CONNECTIVITY_ACTION广播,但是 * 系统会发出两条完全一致的广播,所以使用handler来避免操作两次。 */ private static final long DELAY_TIME = 1000 * 2; private static Handler sHanler = new Handler(Looper.getMainLooper()); private static Runnable sHandleMmsTask = new Runnable() { @Override public void run() { onMmsSend(); } }; private static void onMmsSend() { Toast.makeText(MainActivity.sConext,"监听到有彩信发送出去...",Toast.LENGTH_SHORT).show(); } @Override public void onReceive(Context context, Intent intent) { handleMmsSendIntent(intent, context); } private static void handleMmsSendIntent(Intent intent, Context context) { int type = getConnectivityChangeNetworkType(intent); if (type != ConnectivityManager.TYPE_MOBILE_MMS) { return; } sHanler.removeCallbacks(sHandleMmsTask); sHanler.postDelayed(sHandleMmsTask, DELAY_TIME); } /** * The absence of a connection type. */ private static final int TYPE_NONE = -1; /** * Get the network type of the connectivity change * * @param intent the broadcast intent of connectivity change * @return The change's network type */ private static int getConnectivityChangeNetworkType(final Intent intent) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { return intent.getIntExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, TYPE_NONE); } else { final NetworkInfo info = intent.getParcelableExtra( ConnectivityManager.EXTRA_NETWORK_INFO); if (info != null) { return info.getType(); } } return TYPE_NONE; } } AndroidManifest.xml: <receiver android:name=".ConnectivityChangeReceiver"> <intent-filter> <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/> </intent-filter> </receiver>
