1

こんにちは、SMS に完全に基づいたアプリを開発しています。必要な番号に正常に送信できますが、コードを使用してインテントフィルターと保留中のインテントの両方の通知を取得している場合でも、送信および配信された通知を取得できないという問題があります。SMS を送信して通知を受信するためのコードは、ブロードキャスト レシーバーを拡張するクラス (SmsHandling.java) 内で行われます。私のプログラムコードはここにあります..

public class SmsHandling extends BroadcastReceiver{
     IntentFilter sendFilter,deliveredFilter;
     Context mcontext;
     String result="got it";
    public SmsHandling(Mobile mobile) {
        // TODO Auto-generated constructor stub
        mcontext=mobile;
    }
    String sendSms(String num,String messege){
        Log.d("inside method", "getting");
        String SENT="SMS_SENT";
        String DELIVERED="SMS_DELIVERED";

        sendFilter=new IntentFilter("SMS_SEND");
        deliveredFilter=new IntentFilter("SMS_DELIVERED");
        PendingIntent sendPI=PendingIntent.getBroadcast(mcontext, 0, new Intent(SENT), 0);
        PendingIntent deliveredPI=PendingIntent.getBroadcast(mcontext, 0, new Intent(DELIVERED), 0);
        mcontext.registerReceiver(sendingSms, sendFilter);
        mcontext.registerReceiver(deliveredSms, deliveredFilter);

        Log.d("inside method 2", "getting 2");
        SmsManager sms=SmsManager.getDefault();
        sms.sendTextMessage(num, null, messege, null, null);
        Log.d("inside method 3", "getting 3");
        return result;

    }
    BroadcastReceiver sendingSms=new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            // TODO Auto-generated method stub
            switch (getResultCode()) {
            case Activity.RESULT_OK:
                Toast.makeText(context, "Sms Send", Toast.LENGTH_SHORT).show();
                break;
            case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                Toast.makeText(context, "Generic Errors", Toast.LENGTH_SHORT).show();
                break;
            case SmsManager.RESULT_ERROR_NO_SERVICE:
                Toast.makeText(context, "No Service", Toast.LENGTH_SHORT).show();
                break;
            case SmsManager.RESULT_ERROR_NULL_PDU:
                Toast.makeText(context, "Null pdu", Toast.LENGTH_SHORT).show();
                break;
            case SmsManager.RESULT_ERROR_RADIO_OFF:
                Toast.makeText(context, "Error Radio", Toast.LENGTH_SHORT).show();
                break;
            default:
                break;
            }
        }
    };
    BroadcastReceiver deliveredSms=new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            // TODO Auto-generated method stub
            switch (getResultCode()) {
            case Activity.RESULT_OK:
                Toast.makeText(context, "Sms Delivered", Toast.LENGTH_SHORT).show();
                break;
            case Activity.RESULT_CANCELED:
                Toast.makeText(context, "Sms Failed", Toast.LENGTH_SHORT).show();
                break;

            default:
                break;
            }
        }
    };
    public void unregisterreciever(){
        mcontext.unregisterReceiver(sendingSms);
        mcontext.unregisterReceiver(deliveredSms);
    }
    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub
        System.out.print("Recieved : "+intent.getAction());
    }

}

マニフェスト ファイルでレシーバーを宣言するのではなく、intentfilter のようなことをする必要がありますか?私のマニフェスト ファイルを以下に示します。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.rrm"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />
    <uses-permission android:name="android.permission.SEND_SMS"/>
    <uses-permission android:name="android.permission.BROADCAST_SMS"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.rrm.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".Mobile"
            android:label="@string/app_name"></activity>
        <activity
            android:name=".Dth"
            android:label="@string/app_name"></activity>
        <activity
            android:name=".Datacard"
            android:label="@string/app_name"></activity>
        <activity
            android:name=".Check"
            android:label="@string/app_name"></activity>
        <activity
            android:name=".Register"
            android:label="@string/app_name"></activity>
        <receiver
            android:name=".SmsHandling"></receiver>
    </application>

</manifest>

また、インテントフィルターについて正しい考えが得られません.マニフェストファイルで使用される理由を誰でも説明できます..また、上記の問題を解決するのに役立ちます

4

3 に答える 3

0

明らかにこれはあなたが聞きたいことではありませんが、Android は、サードパーティのアプリケーションが互いに干渉したり、ユーザーの自由な選択を上書きしたりすることを許可するように設計されていません。

デバイスにインストールされている Android 自体のビルドを変更しない限り、基本機能をハード インターセプトするための「フック」タイプのメカニズムは提供されません。

デバイス管理者インターフェイスには、SMS を規制するための機能は含まれていません。

はい、ときどき人々はさまざまな「ハック」方法を利用してそのようなことをある程度達成する製品を作成しますが、それらはプラットフォームの設計に反するため、Android にさまざまな「バグ修正」タイプの改善が行われると、信頼性が低くなるか、壊れる可能性があります。 . または、ホーム画面を置き換えて簡単に起動できるものを制限するなど、範囲に制限がありますが、ホーム画面のアプリが選択されている場合に限り、他のインテントのソースを規制することはできません.

アイデアが魅力的で、それを実行することを決定する場合もありますが、それがこの種のことを行うことを目的とした API の将来の導入でない限り、プラットフォームの設計の見落としを利用する可能性が最も高いことに注意してください。すぐに修正される可能性が高いです。

次のようにする必要があります。

電話ですべてのメッセージのハッシュ コードをキャッシュする content://sms のコンテンツ オブザーバーを登録する オブザーバーの onChange メソッドで、すべてのメッセージを列挙してキャッシュにあるかどうかを確認します。あなたのプロジェクトで頑張ってください:-)

編集: md5 メソッド (到着日 + メッセージ) テキストを取得して、一意の md5 出力を取得できます。

private String md5(String in) {
    MessageDigest digest;
    try {
        digest = MessageDigest.getInstance("MD5");
        digest.reset();        
        digest.update(in.getBytes());
        byte[] a = digest.digest();
        int len = a.length;
        StringBuilder sb = new StringBuilder(len << 1);
        for (int i = 0; i < len; i++) {
            sb.append(Character.forDigit((a[i] & 0xf0) >> 4, 16));
            sb.append(Character.forDigit(a[i] & 0x0f, 16));
        }
        return sb.toString();
    } catch (NoSuchAlgorithmException e) { e.printStackTrace(); }
    return null;
}

マニフェストを更新して、SMS (WRITE_SMS、READ_SMS、RECEIVE_SMS) を受信する権限をアプリに付与します。レシーバー インテント フィルターでマニフェストを更新しないでください。(これは、オンラインのすべてのサンプル コードで行われているようです) Service で、Service クラス内にネストされた BroadcastReceiver クラスを作成します。

private class SMSreceiver extends BroadcastReceiver
{
    private final String TAG = this.getClass().getSimpleName();

    @Override
    public void onReceive(Context context, Intent intent)
    {
        Bundle extras = intent.getExtras();

        String strMessage = "";

        if ( extras != null )
        {
            Object[] smsextras = (Object[]) extras.get( "pdus" );

            for ( int i = 0; i < smsextras.length; i++ )
            {
                SmsMessage smsmsg = SmsMessage.createFromPdu((byte[])smsextras[i]);

                String strMsgBody = smsmsg.getMessageBody().toString();
                String strMsgSrc = smsmsg.getOriginatingAddress();

                strMessage += "SMS from " + strMsgSrc + " : " + strMsgBody;                    

                Log.i(TAG, strMessage);
            }

        }

    }

}

Service クラスで、android.provider.Telephony.SMS_RECEIVED インテント フィルターを受信するように登録します。

public class ServiceCommunicator extends Service
{
    private SMSreceiver mSMSreceiver;
    private IntentFilter mIntentFilter;

    @Override
    public void onCreate()
    {
        super.onCreate();

        //SMS event receiver
        mSMSreceiver = new SMSreceiver();
        mIntentFilter = new IntentFilter();
        mIntentFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
        registerReceiver(mSMSreceiver, mIntentFilter);
    }

    @Override
    public void onDestroy()
    {
        super.onDestroy();

        // Unregister the SMS receiver
        unregisterReceiver(mSMSreceiver);
    }
}

それでおしまい !

注: 別の BroadcastReceiver クラス内からサービスにバインドしなかった理由を疑問に思っている場合は、bindService() が利用できないため機能しません。

于 2013-10-09T10:11:19.820 に答える
0

この行を変更

sms.sendTextMessage(num, null, messege, null, null);

sms.sendTextMessage(num, null, messege, sendPI, deliverdPI);

ここで sendTextMessageのリファレンスを参照してください

于 2014-03-13T09:45:40.877 に答える