2

現在、システムからSMS_Received Broadcastを取得しており、他のブロードキャストレシーバーが取得する前にインテントの値を変更しようとしています(デフォルトのメッセージングアプリなど)。

ただし、どのようにインテントを変更しようとしても、ブロードキャストリスナーには更新された値が表示されません。また、システムではSMS_Receivedブロードキャストを送信できないため、これを中止して再送信することはできません。私は何か間違ったことをしていますか、それともこれを行う方法はありませんか?

//私が試したいくつかのサンプルコード

Intent updatedIntent = changeIncomingIntent(intent, context);
intent.putExtras(updatedIntent.getExtras());
intent.replaceExtras(updatedIntent.getExtras());
4

2 に答える 2

4

受信したインテントを変更することはできませんが、受信したSMSを変更する場合は、順序付けられたブロードキャストであるため、ブロードキャストを停止し、インテントのエクストラを変更してから、再ブロードキャストできます。

Applicationタグの前にApplicationManifest.xmlに以下を追加します。

<uses-permission android:name="android.permission.BROADCAST_SMS" />

これは、Playストアのアプリの権限ページに表示されることに注意してください。それを説明する準備をしてください。

そして、これをレシーバーのIntent-Filterタグに追加します。

android:priority="2147483647"

これはJavaで可能な最高の整数であり、レシーバーが最優先されるようにします。他のアプリケーション(特にGO SMS)の受信者は、これと同じ戦略を使用している可能性があることに注意してください。これは、2つの受信者がメッセージをめぐって争うことを意味する場合があります。これが発生した場合は、おそらく他のアプリをアンインストールする必要があります。

そしてあなたの受信機で:

public void onReceive(Context context, Intent intent){

    //Messages are delivered as extras in the intent

    Bundle bundle = intent.getExtras();

    //If this intent was rebroadcasted already, ignore it.
    if(bundle.getBooleanExtra("rebroadcast", false)        
         return;

    //Abort the broadcast
    abortBroadcast();

    //Some examples use regular arrays,
    // but I prefer a more sophisticated solution.
    ArrayList<SmsMessage> msgs = new ArrayList<SmsMessage>();

    //Check to make sure we actually have a message
    if(bundle != null){

        //Get the SMS messages
        //They are delivered in a raw format, 
        //called Protocol Description Units or PDUs

        //Messages can sometimes be delivered in bulk,
        //so that's why it's an array

        Object[] pdus = (Object[]) bundle.get("pdus");

        //I prefer the enhanced for-loop. Why reinvent the wheel?
        for(Object pdu : pdus)
            msgs.add(SmsMessage.createFromPdu((byte[])pdu));

        //Do stuff with the message.                                
        ArrayList<SmsMessage> newMessages = smsReceived(msgs);

        //Convert back to PDUs
        ArrayList<Object> pdus;
        Iterator<SmsMessage> iterator = newMessages.iterator();

        //Iterate over the messages and convert them
        while(iterator.hasNext()){
            pdus.add(iterator.next().getPdu())
        }

        //Convert back to an Object[] for bundling
        Object[] pduArr = pdus.toArray();

        //Redefine the intent.

        //It already has the broadcast action on it, 
        //so we just need to update the extras
        bundle.putExtra("pdus", pduArr);

        //Set a rebroadcast indicator so we don't process it again
        //and create an infinite loop
        bundle.putExtra("rebroadcast", true);

        intent.putExtras(bundle);

        //Finally, broadcast the modified intent with the original permission
        sendOrderedBroadcast(intent, "android.permission.RECEIVE_SMS");

    else{
        //For some reason, there was no message in the message.
        //What do you plan to do about that? I'd just ignore it.
    }
}

これは機能的な例ですが、メッセージ処理がプロセッサを集中的に使用する場合にUIスレッドをブロックしないように、このほとんどを新しいスレッドで実行することをお勧めします。たとえば、私はメッセージを操作するために多くの正規表現を使用し、メッセージに関連してかなり重いデータベースクエリを実行するため、私の中でそれを行いました。

私が何か間違ったことをしたか、もっとうまくできたかもしれないなら、遠慮なく私を訂正してください。このコードのほとんどは私自身のプロジェクトにあり、その機能を保証できるようにしたいと思います。

良い1日を。

于 2012-10-24T13:21:44.067 に答える
0

(1) Intent オブジェクトだけを変更することはできません。これは、インスタンス専用のローカル オブジェクトです。

(2) 受信機から結果データを返すための API (結果の設定など) がありますが、これらは、ブロードキャストが順序付きブロードキャストとして送信されている場合にのみ使用できます。この方法で送信されるものはほとんどありません。ドキュメントには、それらがいつであるかが記載されている必要があります。

通常、ブロードキャストは並行して行われるため、他のユーザーが受信する内容を変更しようとしても意味がありません。ユーザーとまったく同じ時間にブロードキャストが実行されている可能性があります。

于 2011-06-17T21:14:25.397 に答える