Search code examples
androidsmsbroadcastreceiver

Seems the broadcast receiver on SMS didn't fire


the recipe: "Autosending an SMS Based on a Received SMS" in this book (http://www.informit.com/articles/article.aspx?p=2111971&seqNum=2), doesn't work for me,

on the emulator it works fine but on real device no. why? I use an HTC Legend with android 2.3.7 (cyanogenmod). Thanks for your help.

In the following lines I will give more details about my application.

1) ResponderService : the service responsible to listen to incoming message react according.

package tn.a2soft.a2soft_crm;

import java.util.ArrayList;

import android.app.Activity;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.IBinder;
import android.telephony.SmsManager;
import android.telephony.SmsMessage;
import android.util.Log;
import android.widget.Toast;

public class ResponderService extends Service {

    // The Action fired by the Android-System when a SMS was received.
    private static final String RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED";
    private static final String SENT_ACTION = "SENT_SMS";
    private static final String DELIVERED_ACTION = "DELIVERED_SMS";
    String requester;
    String reply = "";


    @Override
    public void onCreate() {
        // TODO Auto-generated method stub
        super.onCreate();
        IntentFilter filter = new IntentFilter(RECEIVED_ACTION);
        filter.setPriority(500);
        registerReceiver(SMSreceiver, filter);

        registerReceiver(sentReceiver, new IntentFilter(SENT_ACTION));

        registerReceiver(deliverReceiver, new IntentFilter(DELIVERED_ACTION));

        //registerReceiver(sender, new IntentFilter(SENT_ACTION));
    }

//  private BroadcastReceiver sender = new BroadcastReceiver() {
//
//      @Override
//      public void onReceive(Context c, Intent i) {
//          if (i.getAction().equals(SENT_ACTION)) {
//              if (getResultCode() != Activity.RESULT_OK) {
//                  String reciptent = i.getStringExtra("recipient");
//                  requestReceived(reciptent);
//              }
//          }
//      }
//  };
    private BroadcastReceiver sentReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context c, Intent in) {
            switch (getResultCode()) {
            case Activity.RESULT_OK:
                // sent SMS message successfully;
                smsSent();
                break;
            default:
                // sent SMS message failed
                smsFailed();
                break;
            }
        }
    };

    private BroadcastReceiver SMSreceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context c, Intent in) {

            // TODO Auto-generated method stub
            Log.v("ResponderService", "On Receive");
            Toast.makeText(c, "Revceive SMS",Toast.LENGTH_LONG).show();
            if (in.getAction().equals(RECEIVED_ACTION)) {
                Log.v("ResponderService", "On SMS RECEIVE");
                Bundle bundle = in.getExtras();
                if (bundle != null) {

                    Object[] pdus = (Object[]) bundle.get("pdus");
                    SmsMessage[] messages = new SmsMessage[pdus.length];

                    for (int i = 0; i < pdus.length; i++) {
                        Log.v("ResponderService", "FOUNDMESSAGE");
                        messages[i] = SmsMessage
                                .createFromPdu((byte[]) pdus[i]);
                    }

                    for (SmsMessage message : messages) {
                        requestReceived(message.getOriginatingAddress());
                    }

                    respond();

                }

            }
        }
    };


    public void smsSent() {
        Toast.makeText(this, "SMS sent", Toast.LENGTH_SHORT).show();
    }

    public void smsFailed() {
        Toast.makeText(this, "SMS sent failed", Toast.LENGTH_SHORT).show();
    }

    public void smsDelivered() {
        Toast.makeText(this, "SMS delivered", Toast.LENGTH_SHORT).show();
    }

    public void requestReceived(String f) {
        Log.v("ResponderService", "In requestReceived");
        requester = f;
    }

    BroadcastReceiver deliverReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context c, Intent in) {
            // SMS delivered actions
            smsDelivered();
        }
    };



    public void respond() {
        Log.v("ResponderService", "Responing to " + requester);

        reply = "Thank you for your message. I am busy now. "
                + "I will call you later";
        SmsManager sms = SmsManager.getDefault();

        Intent sentIn = new Intent(SENT_ACTION);
//      Intent sentIn = new Intent("android.telephony.SmsManager.STATUS_ON_ICC_SENT");
        PendingIntent sentPIn = PendingIntent.getBroadcast(this, 0, sentIn, 0);

        Intent deliverIn = new Intent(DELIVERED_ACTION);
        PendingIntent deliverPIn = PendingIntent.getBroadcast(this, 0,
                deliverIn, 0);

        ArrayList<String> Msgs = sms.divideMessage(reply);
        ArrayList<PendingIntent> sentIns = new ArrayList<PendingIntent>();
        ArrayList<PendingIntent> deliverIns = new ArrayList<PendingIntent>();
        for (int i = 0; i < Msgs.size(); i++) {
            sentIns.add(sentPIn);
            deliverIns.add(deliverPIn);
        }

        sms.sendMultipartTextMessage(requester, null, Msgs, sentIns, deliverIns);
        // sms.sendTextMessage(requester, null, reply, sentPIn, deliverPIn);
    }

    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
    }



    @Override
    public void onDestroy() {
        super.onDestroy();
        unregisterReceiver(SMSreceiver);
        unregisterReceiver(deliverReceiver);
        unregisterReceiver(sentReceiver);
//      unregisterReceiver(sender);
    }

    @Override
    public IBinder onBind(Intent arg0) {
        // TODO Auto-generated method stub
        return null;
    }

}

2) the only and main activity that contain one button that by clicking on it I start the service :

package tn.a2soft.a2soft_crm;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity {
    Button startService;
    ComponentName cn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        startService = (Button) this.findViewById(R.id.startservice);
        startService.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                try {
                    // start Service
                    Intent svc = new Intent(MainActivity.this,
                            ResponderService.class);
                    cn = (ComponentName)startService(svc);
                    Toast.makeText(MainActivity.this, cn.getClassName(),
                            Toast.LENGTH_LONG).show();
                } catch (Exception e) {
                    Log.e("onCreate", "service creation problem", e);
                    Toast.makeText(MainActivity.this,
                            "service creation problem", Toast.LENGTH_LONG)
                            .show();
                }
//              Intent in = new Intent(MainActivity.this, SMSResponder.class);
//              startActivity(in);
            }
        });

    }

    @Override
    protected void onStop() {
        // TODO Auto-generated method stub
        super.onStop();

    }
    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        //stopService(new Intent(MainActivity.this,ResponderService.class));
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

}

3) the manifest file :

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="tn.a2soft.a2soft_crm"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="9"
        android:targetSdkVersion="16" />

    <uses-permission android:name="android.permission.SEND_SMS" />
    <uses-permission android:name="android.permission.READ_SMS" />
    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <uses-permission android:name="android.permission.WRITE_SMS" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppBaseTheme" >
        <activity
            android:name="tn.a2soft.a2soft_crm.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="tn.a2soft.a2soft_crm.SMSResponder"
            android:label="@string/app_name" >
        </activity>

<!--         <receiver
            android:name=".SMSReceiver"
            android:enabled="true"
            android:exported="true"
            android:permission="android.permission.BROADCAST_SMS" >
            <intent-filter android:priority="999" >
                <action android:name="android.provider.Telephony.SMS_RECEIVED" />
            </intent-filter>
        </receiver> -->

        <service
            android:name=".ResponderService"
            android:enabled="true" >
        </service>
    </application>

</manifest>

As I told you before the example work on emulator but not on real device. Thanks for your helps I really had a headache.


Solution

  • the stackoverflow forum is the pradise for programmer, I find the solution and I have tested it and it works fine for me on this link (set the broadcastreceiver's priority to Integer.MAX_VALUE) here in this forum. Thank you for all your help and specially for "PVS" who tried to help me.