我也花了一些时间调查这个问题。而且似乎没有公共 API 可以做到这一点。但我可以分享一些我的逆向工程研究结果...
我的三星 Galaxy S 能够接收 CB 消息,所以我反编译了 SMS 应用程序并查看了代码。它的清单文件中有以下BroadcastReceiver:
<receiver android:name=".transaction.PrivilegedSmsReceiver">
...
<intent-filter>
<action android:name="android.provider.Telephony.CB_RECEIVED" />
</intent-filter>
<intent-filter>
<action android:name="android.provider.Telephony.CB_SETTINGS_AVAILABLE" />
</intent-filter>
<intent-filter>
<action android:name="android.provider.Telephony.SET_CB_ERR_RECEIVED" />
</intent-filter>
<intent-filter>
<action android:name="android.provider.Telephony.GET_CB_ERR_RECEIVED" />
</intent-filter>
</receiver>
注意android.provider.Telephony.CB_RECEIVED 意图过滤器。我没有找到任何有关它的文档,但从它的名称来看,我认为它是我现在需要捕获的唯一广播。
然后查了一下反编译的apk代码,发现它使用android.provider.Telephony.Sms.Intents->getCbMessagesFromIntent()接口访问retrieve CB消息,返回CbMessage类实例。即使对于简单的 SMS 消息,此界面也已过时,因此我假设 CbMessage 应该与 pdus 一起使用,就像 SmsMessage 一样。最后我找到了source of SmsCbMessage 类,它与API 上的SmsMessage 非常相似。它依赖于 5-6 个内部 Android java 文件,所以为了简单起见,我只是从同一个站点获取它们并将它们包含到我的项目中。
broadcastReceiver 和你的一样,除了 SmsMessage 被 SmsCbMessage 替换:
public class CbReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//---get the CB message passed in---
Bundle bundle = intent.getExtras();
SmsCbMessage[] msgs = null;
String str = "";
if (bundle != null) {
//---retrieve the SMS message received---
Object[] pdus = (Object[]) bundle.get("pdus");
msgs = new SmsCbMessage[pdus.length];
for (int i=0; i<msgs.length; i++) {
msgs[i] = SmsCbMessage.createFromPdu((byte[])pdus[i]);
str += "CB lang " + msgs[i].getLanguageCode();
str += " :";
str += msgs[i].getMessageBody().toString();
str += "\n";
}
//---display the new CB message---
abortBroadcast();
Toast.makeText(context, str, Toast.LENGTH_SHORT).show();
}
}
}
使用上述接收器将我的应用程序安装到我的 SGS 手机中并启用在手机 SMS 应用程序中接收 CB 消息后,我的应用程序能够在通过标准 SMS 应用程序接收它们的同时显示 CB 消息。
问题仍有待解决:
- 如何启用/禁用/配置我的 CB 消息的通道
应用?短信应用使用
getCbSettings()/setCbSettings()功能,
但我没有找到他们。所以暂时我使用了其他应用程序。
- 如何
中止CB消息广播,让其他应用收不到?它
似乎
abortBroadcast()在这里不起作用,因为广播
消息未排序(isOrderedBroadcast() 返回false)。