1

您好我正在开发一个完全基于短信的应用程序。我可以将成功发送到所需的号码,但我的问题是我没有收到发送和传递的通知,即使我使用代码通过意图过滤器和待处理意图获取通知。发送短信和接收通知的代码在扩展广播接收器的类 (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());
    }

}

我是否需要做更多类似意图过滤器的事情,而不是在清单文件中声明接收者我的清单文件如下所示:

<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>

而且我对 Intent 过滤器没有正确的想法,任何人都可以解释为什么在清单文件中使用它。并且还可以帮助我解决上述问题

4

3 回答 3

0

显然这不是您想听到的,但 Android 根本不允许第三方应用程序相互干扰或覆盖用户的自由选择。

它不提供“钩子”类型的机制来硬拦截基本功能,除非修改安装在设备上的 Android 本身的构建。

设备管理员界面不包含任何用于管理短信的内容。

是的,有时人们会在某种程度上利用各种“hack”方法来完成这些事情,但它们与平台的设计相悖,因此在对 android 进行各种“bug fix”类型的改进时要么不可靠,要么可能会崩溃. 或者它们具有范围限制,例如更换主屏幕,从而限制易于启动的内容 - 但前提是该主屏幕应用程序保持选中状态,并且无法调节其他意图来源。

您可能会发现一个足够吸引人的想法以至于您决定使用它,但请记住,除非它是未来对用于执行此类事情的 API 的介绍,否则您很可能会利用平台设计中的疏忽它很可能很快就会得到纠正。

你将不得不做这样的事情:

缓存手机上所有消息的hash码 为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;
}

更新清单以授予您的应用接收短信的权限(WRITE_SMS、READ_SMS、RECEIVE_SMS)不要使用接收者意图过滤器更新清单!(每个在线示例代码似乎都这样做)在您的服务中,在您的服务类中创建一个嵌套的广播接收器类

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 回答
0

事实证明,您无法使用 getResultCode() 来确定 SMS 是否真的已送达。您必须解析 pdu。Android 可以解析它,但你必须解释状态码。根据是 GSM 还是 CDMA,“delivered ok”状态码将为 0 或 2。

有关更多详细信息,请参阅: Android SMS 发送失败通知:误报

于 2015-10-23T12:21:15.063 回答