短信的接收和发送,有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>