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