I am programming a Geofence app. When user arrives at some point, geofence triggers, and sends a Mail.
This works just perfect. But I need to control the case in which there is no connectivity so that the app sends the mail when connectivity becomes available.
I achieved this, with a Broadcast Receiver, which listens for CONNECTIVITY_CHANGE.
My problem is that I need to retrieve from database the details (receiver of the mail and text), and for that I need an "ID", but I can't find the way to pass this ID to the BroadcastReceiver.
This is my code:
I've an Intent that detects the Geofence, and if there is no Internet, activates the BroacasReceiver:
public class GeofenceIntentService extends IntentService implements com.google.android.gms.location.LocationListener {
[...]
#Override
protected void onHandleIntent(Intent intent) {
GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
extras = intent.getExtras();
Log.e(TAG, String.valueOf(extras.getLong("id")));
ID = extras.getLong("id");
sendMail(ID);
}
}
[...]
private void sendMail(long ID) {
dbHelper = new DBHelper(context);
dbHelper.getWritableDatabase();
cursor = dbHelper.getRegister(ID);
dbHelper.close();
tomail = cursor.getString(cursor.getColumnIndex("tomail"));
where = cursor.getString(cursor.getColumnIndex("where"));
texttosend = cursor.getString(cursor.getColumnIndex("texttosend"));
if (getConnectivityStatus(context) == 1 || getConnectivityStatus(context) == 2) {
Mail m = new Mail("***", "****");
String[] toArr = {tomail};
m.setTo(toArr);
m.setFrom("*****");
m.setSubject(getString(R.string.justtrying));
m.setBody(texttosend);
try {
if (m.send()) {
Log.v(TAG, "Email was sent successfully.");
} else {
Log.v(TAG, "Email was not sent.");
}
} catch (Exception e) {
Log.e("MailApp", "Could not send email", e);
}
} else {
Log.v(TAG, "Waiting for Internet Connection.");
registerForBroadcasts(context);
}
}
public void registerForBroadcasts(Context context) {
ComponentName component = new ComponentName(context, NetworkChangeReceiver.class);
PackageManager pm1 = context.getPackageManager();
pm1.setComponentEnabledSetting(
component,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
}
An then the receiver on the manifest:
<receiver
android:name=".NetworkChangeReceiver"
android:enabled="false"
android:label="NetworkChangeReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
As I said, this works, but then onReceive, I need to know the ID to get the contact info to send the mail. The Broadcast as an Intent variable, but I don't know how to edit it. This would be the idea:
#Override
public void onReceive(final Context context, final Intent intent) {
final Context mContext = context;
String action = intent.getAction();
extras = intent.getExtras();
ID = extras.getLong("id");
Any ideas? The only alternative I can find is to keep checking for connectivity every 30secs, from the GeofenceIntent, but I think it would be much more effective to listen to Connectivity Change.
EDIT:
Finaly I solved this situation, by adding a "pending" column, on database, and from BroadcastReceiver checking all registers, where Pending = true.
Anyway I still have the doubt if there were any other way.
Related
I have tried to get sms using SmsRetrieverClient through its broadcast receiver, what actually problem is when SMS comes onReceive never calls to process it further but later on after 5 mins it calls receiver's timeout method.
Actually I tried library to get SMS and its working fine but asking for SMS read permission which unfortunately will face Google policy issue at the time of uploading app on playstore.
Below is my code.
Below is the SmsRetrieverClient method in my Activity:
private void startSMSListener() {
SmsRetrieverClient smsRetrieverClient = SmsRetriever.getClient(this);
Task<Void> retriever = smsRetrieverClient.startSmsRetriever();
retriever.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
SMSBroadcastReceiver.OTPListener otpListener = new SMSBroadcastReceiver.OTPListener() {
#Override
public void onOTPReceived(String otpData) {
inputOTP.setText(otpData);
}
#Override
public void onOTPTimeOut() {
inputOTP.setText("");
Toast.makeText(ctx, "TimeOut", Toast.LENGTH_SHORT).show();
}
};
smsBroadcastReceiver.injectOTPListener(otpListener);
registerReceiver(smsBroadcastReceiver, new IntentFilter(SmsRetriever.SMS_RETRIEVED_ACTION));
}
});
retriever.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(ctx, "Problem to start listener", Toast.LENGTH_SHORT).show();
}
});
}
Below code is of receiving SMS from broadcast receiver:
public class SMSBroadcastReceiver extends BroadcastReceiver {
private OTPListener otpReceiver;
public void injectOTPListener(OTPListener receiver) {
this.otpReceiver = receiver;
}
#Override
public void onReceive(Context context, Intent intent) {
if (SmsRetriever.SMS_RETRIEVED_ACTION.equals(intent.getAction())) {
Bundle extras = intent.getExtras();
Status status = (Status) extras.get(SmsRetriever.EXTRA_STATUS);
System.out.println("SMS verification code::SMSBroadcastReceiver:0: "+ status);
switch (status.getStatusCode()) {
case CommonStatusCodes.SUCCESS:
String message = (String)extras.get(SmsRetriever.EXTRA_SMS_MESSAGE);
Pattern pattern = Pattern.compile("\\d{4}");
Matcher matcher = pattern.matcher(message);
System.out.println("SMS verification code::SMSBroadcastReceiver:1: "+ message);
if (matcher.find()) {
if (otpReceiver != null){
otpReceiver.onOTPReceived(matcher.group(0));
}
}
break;
case CommonStatusCodes.TIMEOUT:
System.out.println("SMS verification code::SMSBroadcastReceiver:2: TIMEOUT");
if (otpReceiver != null){
otpReceiver.onOTPTimeOut();
}
break;
}
}
}
public interface OTPListener {
void onOTPReceived(String otp);
void onOTPTimeOut();
}
}
And in manifest:
<receiver android:name=".SMSBroadcastReceiver"
android:exported="true">
<intent-filter>
<action
android:name="com.google.android.gms.auth.api.phone.SMS_RETRIEVED"/>
</intent-filter>
</receiver>
Big Thanks for contributing your solutions,
But I found out the solution after so many attempts the reason why broadcast was not receiving SMS otp is due to 2 reason:
1) The message should be of 140 bytes as in below link:
https://developers.google.com/identity/sms-retriever/verify#1_construct_a_verification_message
2) I found that at the time of developing broadcast I got 2 to 3 broadcast java files which I added in my app for testing the SMS each with different code which I registered in manifest all the SMS broadcast receivers with same action which was meaningless.
So lastly removing all the other registered receivers from manifest of same action as "com.google.android.gms.auth.api.phone.SMS_RETRIEVED" and just worked on single broadcast receiver with single declaration in manifest with its action solved my problem.
In creating a watch face for Android Wear, I would like to have a simple configuration (a toggle switch?) that set which mode the user wanted the watch face to looks like (for example, white or black watch face).
I would prefer the toggle switch to be on the watch itself, prefer not to communicate with the phone for such simple action, and hopefully to avoid all the GoogleApiClient communications between watch and phones. Is there a way to do this easily, similar to doing Settings or SharedPreferences on Android?
I tried using a Broadcast receiver. I can get the changes in Broadcast receiver, but how do I get the CanvasWatchFaceService.Engine to update?
Yes, that's possible.
You have to follow this documentation.
First Create an Activity displaying the settings you want the user to change.
Then in your Manifest file, add this meta data to your Watchface service:
<meta-data
android:name=
"com.google.android.wearable.watchface.wearableConfigurationAction"
android:value=
"com.example.android.wearable.watchface.CONFIG_DIGITAL" />
And this IntentFilter to your Activity:
<intent-filter>
<action android:name=
"com.example.android.wearable.watchface.CONFIG_DIGITAL" />
<category android:name=
"com.google.android.wearable.watchface.category.WEARABLE_CONFIGURATION" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
Of course, you will have to replace "com.example.android" by your package name.
Then a small setting icon will appear below your watchface preview in the Watchface selector screen.
Do not forget to synchronize the setting between your Activity and Watchface in order to make it appear instantly (with a BroadcastReceiver for example)
I addressed this with a LocalBroadcastManager that registers 3 intents
Get Initial Data, sent from Config Activity, expected by Watch Service
Initial Data, sent by Watch Service in response to the message above
Data Changed, sent by Config Activity when user makes selections.
Everything is wrapped in a single class which exposes two interfaces for interactions (one for Watch Service, the other for Config Activity. Probably not the easiest solution but the best I could come up with after 3 days of digging :(
For the record, here is the class sharing 2 variables (bezelMode and time24).
You will need to instantiate it from your watch service (implementing WatchConfig.Service) and you configuration activity (implementing WatchConfig.Editor)
Communication is based on LocalBroadcastManager
public class WatchConfig {
// private static final String TAG = "Config";
// Used when data has changed
public static final String CONFIG_DATA_CHANGED = "/config/changed";
// Used to provide initial data
public static final String CONFIG_INITIAL_DATA = "/config/inital-data";
// Used to query initial data
public static final String CONFIG_INITIAL_QUERY = "/config/initial-query";
private int m_BezelMode;
private boolean m_Time24;
private LocalBroadcastManager localBroadcastManager;
BroadcastReceiver broadcastReceiverDataChanged;
BroadcastReceiver broadcastReceiverInitialDataRequest;
BroadcastReceiver broadcastReceiverInitialData;
private Service service;
private Editor editor;
WatchConfig(Context context, Service service) {
initialize( context, service, null);
}
WatchConfig(Context context, Editor editor) {
initialize( context, null, editor);
}
void initialize( Context context, Service service, Editor editor) {
this.localBroadcastManager = LocalBroadcastManager.getInstance( context);
this.service = service;
this.editor = editor;
}
interface Service {
void onConfigDataUpdated(boolean time24, int bezelMode);
void onConfigInitialRequest();
}
interface Editor {
void onConfigInitialize(boolean time24, int bezelMode);
}
/**
* Registers all proper receivers
*/
public void connect() {
if( this.service != null) {
IntentFilter intentFilterDataChanged = new IntentFilter(CONFIG_DATA_CHANGED);
this.broadcastReceiverDataChanged = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Log.d(TAG,"Data Changed Notification");
service.onConfigDataUpdated(intent.getBooleanExtra("time24", true), intent.getIntExtra("bezel", 24));
}
};
this.localBroadcastManager.registerReceiver(broadcastReceiverDataChanged, intentFilterDataChanged);
IntentFilter intentFilterInitialDataRequesy = new IntentFilter(CONFIG_INITIAL_QUERY);
this.broadcastReceiverInitialDataRequest = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Log.d(TAG,"Initial Query Notification");
service.onConfigInitialRequest();
}
};
this.localBroadcastManager.registerReceiver(broadcastReceiverInitialDataRequest, intentFilterInitialDataRequesy);
} else {
this.broadcastReceiverDataChanged = null;
this.broadcastReceiverInitialDataRequest = null;
}
if( this.editor != null) {
IntentFilter intentFilterInitalData = new IntentFilter(CONFIG_INITIAL_DATA);
this.broadcastReceiverInitialData = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Log.d(TAG,"Initial Data notification");
editor.onConfigInitialize(intent.getBooleanExtra("time24", true), intent.getIntExtra("bezel", 24));
}
};
this.localBroadcastManager.registerReceiver(broadcastReceiverInitialData, intentFilterInitalData);
// Editors need intial data
Intent intentInitialDataRequest = new Intent( CONFIG_INITIAL_QUERY);
this.localBroadcastManager.sendBroadcast( intentInitialDataRequest);
} else {
this.broadcastReceiverInitialData = null;
}
}
public void disconnect() {
if( this.broadcastReceiverDataChanged != null) {
this.localBroadcastManager.unregisterReceiver(this.broadcastReceiverDataChanged);
}
if( this.broadcastReceiverInitialDataRequest != null) {
this.localBroadcastManager.unregisterReceiver(this.broadcastReceiverInitialDataRequest);
}
if( this.broadcastReceiverInitialData != null) {
this.localBroadcastManager.unregisterReceiver(this.broadcastReceiverInitialData);
}
}
/**
* Used to publish changes in configuration
*/
protected void publishInitialData(boolean time24, int bezel) {
this.m_Time24 = time24;
this.m_BezelMode = bezel;
Intent intent = new Intent( CONFIG_INITIAL_DATA);
intent.putExtra("time24", this.m_Time24);
intent.putExtra("bezel", this.m_BezelMode);
this.localBroadcastManager.sendBroadcast(intent);
}
/**
* Used to publish changes in configuration
*/
protected void publishUpdate() {
Intent intent = new Intent( CONFIG_DATA_CHANGED);
intent.putExtra("time24", this.m_Time24);
intent.putExtra("bezel", this.m_BezelMode);
this.localBroadcastManager.sendBroadcast(intent);
}
public void setTime24(boolean time24) {
this.m_Time24 = time24;
}
public void setBezelMode(int bezelMode) {
this.m_BezelMode = bezelMode;
}
}
I have problem when I'm trying to use geofence with my app. I have succeed to register geofence but I have never get the notification.
First I follow the example that provide in http://developer.android.com/training/location/geofencing.html ,but the code never trigger intent service even I'm walking toward or away from area.
My code for register geofence and calling the intent service as follow :
inside manifest :
<service
android:name="com.example.zukami.apps.blynk.geofence.ReceiveTransitionsIntentService"
android:exported="true" >
</service>
in my MainActivity
private boolean registerGeofence() {
mRequestType = GeofenceUtils.REQUEST_TYPE.ADD;
if (!servicesConnected()) {
return false;
}
SimpleGeofence testGeo = new SimpleGeofence(Flag.GEOFENCE + "_"
+ 1, Double.valueOf("1.317342"),
Double.valueOf("103.841998"), (float) (200),
GEOFENCE_EXPIRATION_IN_HOURS,
Geofence.GEOFENCE_TRANSITION_ENTER);
mPrefs.setGeofence(Flag.GEOFENCE + "_" + 1, testGeo);
mCurrentGeofences.add(testGeo.toGeofence());
SimpleGeofence testGeo2 = new SimpleGeofence(Flag.GEOFENCE + "_"
+ 2, Double.valueOf("1.303961"),
Double.valueOf("103.909356"), (float) (200),
GEOFENCE_EXPIRATION_IN_HOURS,
Geofence.GEOFENCE_TRANSITION_ENTER);
mPrefs.setGeofence(Flag.GEOFENCE + "_" + 2, testGeo2);
mCurrentGeofences.add(testGeo2.toGeofence());
// end deleted this code after testing
try {
mGeofenceRequester.addGeofences(mCurrentGeofences);
Log.e(TAG, "ADDING GEOFENCE ??? YES WE DID IT");
} catch (UnsupportedOperationException e) {
Toast.makeText(this,
R.string.add_geofences_already_requested_error,
Toast.LENGTH_LONG).show();
}
return true;
}
#Override
protected void onResume() {
super.onResume();
// Register the broadcast receiver to receive status updates
LocalBroadcastManager.getInstance(this).registerReceiver(mBroadcastReceiver, mIntentFilter);
in my GeofenceRequester
private PendingIntent createRequestPendingIntent() {
Log.e(TAG, "CREATE REQUEST PENDING INTENT");
// If the PendingIntent already exists
if (null != mGeofencePendingIntent) {
Log.e(TAG, "PENDING INTENT NOT NULL");
return mGeofencePendingIntent;
// If no PendingIntent exists
} else {
Log.e(TAG, "PENDING INTENT NULL, LET'S CREATED IT");
// Create an Intent pointing to the IntentService
Intent intent = new Intent(mActivity,
ReceiveTransitionsIntentService.class);
Log.e(TAG,
return PendingIntent.getService(mActivity, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
}
and in class that subclass from IntentService remain same as an example.
I do search for this problem and found this solutions that describe on this link :
Android Geofence eventually stop getting transition intents ,so I change my code exactly as per suggestion, but still I cannot getting the notification, from my code inside GeofenceReceiver class, the code in this line
LocationClient.getGeofenceTransition(intent);
always return me -1 that means I never enter or leave the area (indicate GEOFENCE NEVER_EXPIRED),so I never get the notification. Please find below my GeofenceReceiver class :
public class GeofenceReceiver extends BroadcastReceiver {
public static String TAG = GeofenceReceiver.class.getCanonicalName();
Context context;
Intent broadcastIntent = new Intent();
#Override
public void onReceive(Context context, Intent intent) {
this.context = context;
broadcastIntent.addCategory(GeofenceUtils.CATEGORY_LOCATION_SERVICES);
if (LocationClient.hasError(intent)) {
handleError(intent);
} else {
handleEnterExit(intent);
}
}
private void handleError(Intent intent) {
int errorCode = LocationClient.getErrorCode(intent);
String errorMessage = LocationServiceErrorMessages.getErrorString(
context, errorCode);
Log.e(GeofenceUtils.APPTAG, context.getString(
R.string.geofence_transition_error_detail, errorMessage));
broadcastIntent.setAction(GeofenceUtils.ACTION_GEOFENCE_ERROR)
.putExtra(GeofenceUtils.EXTRA_GEOFENCE_STATUS, errorMessage);
LocalBroadcastManager.getInstance(context).sendBroadcast(
broadcastIntent);
}
private void handleEnterExit(Intent intent) {
int transition = LocationClient.getGeofenceTransition(intent);
// Test that a valid transition was reported
if ((transition == Geofence.GEOFENCE_TRANSITION_ENTER)
|| (transition == Geofence.GEOFENCE_TRANSITION_EXIT)) {
// Post a notification
List<Geofence> geofences = LocationClient
.getTriggeringGeofences(intent);
String[] geofenceIds = new String[geofences.size()];
String ids = TextUtils.join(GeofenceUtils.GEOFENCE_ID_DELIMITER,
geofenceIds);
String transitionType = getTransitionString(transition);
for (int index = 0; index < geofences.size(); index++) {
Geofence geofence = geofences.get(index);
geofenceIds[index] = geofences.get(index).getRequestId();
}
sendNotification(transitionType, ids);
// Create an Intent to broadcast to the app
broadcastIntent
.setAction(GeofenceUtils.ACTION_GEOFENCE_TRANSITION)
.addCategory(GeofenceUtils.CATEGORY_LOCATION_SERVICES)
.putExtra(GeofenceUtils.EXTRA_GEOFENCE_ID, geofenceIds)
.putExtra(GeofenceUtils.EXTRA_GEOFENCE_TRANSITION_TYPE,
transitionType);
LocalBroadcastManager.getInstance(context).sendBroadcast(
broadcastIntent);
// Log the transition type and a message
Log.e(GeofenceUtils.APPTAG, transitionType + ": " + ids);
Log.e(GeofenceUtils.APPTAG, context
.getString(R.string.geofence_transition_notification_text));
Log.e(GeofenceUtils.APPTAG, "transition");
} else {
// Always log as an error
Log.e(TAG, "TRANSITION = " + transition);
}
}
Kindly advise what should I do for fix this code and really appreciate for any kind help.
for me I just changed some lines of code in createPendingIntent method
private PendingIntent createRequestPendingIntent() {
Log.e(TAG, "CREATE REQUEST PENDING INTENT");
// If the PendingIntent already exists
if (null != mGeofencePendingIntent) {
Log.e(TAG, "PENDING INTENT NOT NULL");
return mGeofencePendingIntent;
// If no PendingIntent exists
} else {
Log.e(TAG, "PENDING INTENT NULL, LET'S CREATED IT");
// Create an Intent pointing to the IntentService
Intent intent = new Intent(mActivity,
ReceiveTransitionsIntentService.class);
Log.e(TAG,
return PendingIntent.getService(mActivity, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
}
So in place of return PendingIntent.getService(mActivity, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
use this piece of cake
return PendingIntent.getBroadcast(mActivity, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
and make sure you have declared your BroadcastReceiver in application manisfest file.Good luck!!!!
Beware: Geofences are indeed being removed when Location Provider Settings change or the device is restarted. Unfortunately the Android documentation doesn't mention this anywhere.
To counter this, you can register for a Boot-Completed Receiver and a Location Provider Changed Receiver:
<!-- Boot Completed Receiver -->
<receiver android:name="com.mydemoapp.geofencing.BootCompleteReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<!-- Location Service Provider Changed Receiver -->
<receiver android:name="com.mydemoapp.geofencing.LocationProviderChangedReceiver">
<intent-filter>
<action android:name="android.location.PROVIDERS_CHANGED" />
</intent-filter>
</receiver>
Inside these two BroadcastReceivers you can implement your logic of re-registering your previously deleted geofences.
In the Manifest you have registered the Service.
<service
android:name="com.example.zukami.apps.blynk.geofence.ReceiveTransitionsIntentService"
android:exported="true" >
</service>
But you have used broadcast receiver so can be an issue there. I am not sure about the broadcast receiver but with ReceiveTransitionIntent it does work as per the documentation.
However now i am stuck because when Location Service is Disabled or When Device is restarted i think Geofences are removed and I am not able to Add the Geofences back in Background.
Can u help me find out why the registration of broadcast receiver returns null?
this is the code:
ScoIntent = new IntentFilter(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
sReceiver = new ScoReceiver(context, Tmp);
if (context.registerReceiver(sReceiver, ScoIntent) == null) {
Log("FBR.GetBlueConnect:Error", "Can not find receiver ACTION_CONNECTION_STATE_CHANGED");
HFS.DisplayText("Can not connect to Bluetooth Headset, Please Exit", true);
}
and this is the reciver:
class ScoReceiver extends BroadcastReceiver {
public ScoReceiver(Context mcontext, Tools t){
bContext = mcontext;
tools = t;
}
#Override
public void onReceive(Context context, Intent arg1) {
tools.Log("ScoReceiver:onReceive", "In");
//arg1 = new Intent(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED);
String action = arg1.getAction();
tools.Log("ScoReceiver:onReceive", ">>> Bluetooth SCO state changed !!! ");
if(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
int status = arg1.getIntExtra(BluetoothHeadset.EXTRA_STATE, AudioManager.SCO_AUDIO_STATE_ERROR );
}
The javadocs say,
Returns the first sticky intent found that matches filter, or null if
there are none.
Does this receiver have a sticky intent? Here's a post that talks about the difference between a stick and non-sticky intent,
what is the difference between sendStickyBroadcast and sendBroadcast in Android
I've been successfully testing my app which sends a text message to another phone number. The problem came when I sent this to a buddy that has the Nexus One. I added a pending intent to sendTextMessage() and saw I'm hitting: RESULT_ERROR_GENERIC_FAILURE.
Generic Error is non specific error, sometimes it is shown if our
Network provider don't send sms on non existing numbers, I have found
this after research, I have 2 androids, both are from different
Providers, one provider sends Message on non existing phone numbers,
so I am not facing Generic Error Problem in this sim, on the other
hand the 2nd Network Provider Don't sends the message on non existing
phone number, so the generic error is appear in this Case. Guys kindly
check your Programs with other Networks, May be It solves your
Problem. thanks.
Mi problem is the same and how Jonathan Akers said, the RESULT_ERROR_GENERIC_FAILURE, is triggered by the sender mobile (Nexus One) to any other, so, nothing sms message is send use this mobile phone by programmatically mode without use intent sms messaging.
All works fine using two android emulators.
I use BroadcastReceiver for listen sms events like as:
public class ConfigSMS {
private static final String CLASS_NAME = "smsTestClass";
private static PendingIntent sentPI = null;
private static PendingIntent deliverPI = null;
//--------------- Getters & Setters --------------------------//
public static PendingIntent getSentPI() {
if (sentPI == null)
initPI();
return sentPI;
}
public static void setSentPI(PendingIntent sentPI) {
ConfigSMS.sentPI = sentPI;
}
public static PendingIntent getDeliverPI() {
if (deliverPI == null)
initPI();
return deliverPI;
}
public static void setDeliverPI(PendingIntent deliverPI) {
ConfigSMS.deliverPI = deliverPI;
}
//------------------------------------------------------------------------//
/**
* Initialize the Intents and BroadcastReceivers
*/
public static void initPI () {
monitoringSMS();
}
/**
* Create the inits and BroadcastReceivers for listen sms actions
*/
private static void monitoringSMS () {
try {
final String SENT_SMS_ACTION = "SENT_SMS_ACTION";
final String DELIVERED_SMS_ACTION = "DELIVERED_SMS_ACTION";
//Create the setIntent parameter
Intent sentIntent = new Intent(SENT_SMS_ACTION);
sentPI = PendingIntent.getBroadcast(
ConfigAppValues.getContext(),
0,
sentIntent,
0);
//Create the deliveryIntetn parameter
Intent deliveryIntent = new Intent(DELIVERED_SMS_ACTION);
deliverPI = PendingIntent.getBroadcast(
ConfigAppValues.getContext(),
0,
deliveryIntent,
0);
//Register the Broadcast Receivers
ConfigAppValues.getContext().registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
switch (getResultCode()) {
case Activity.RESULT_OK:
Log.d(CLASS_NAME, "Successful transmission!!");
showNotificationToast("Successful transmission!!");
break;
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
Log.d(CLASS_NAME, "Nonspecific Failure!!");
showNotificationToast("Nonspecific Failure!!");
break;
case SmsManager.RESULT_ERROR_RADIO_OFF:
Log.d(CLASS_NAME, "Radio is turned Off!!");
showNotificationToast("Nonspecific Failure!!");
break;
case SmsManager.RESULT_ERROR_NULL_PDU:
Log.d(CLASS_NAME, "PDU Failure");
showNotificationToast("PDU Failure");
break;
}
}
}, new IntentFilter(SENT_SMS_ACTION));
ConfigAppValues.getContext().registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Log.d(CLASS_NAME, "The user have been receive the SMS message!!");
}
}, new IntentFilter(DELIVERED_SMS_ACTION));
}catch (Exception e) {
Log.e(CLASS_NAME, ExceptionUtils.exceptionTraceToString(
e.toString(),
e.getStackTrace()));
}
}
private static void showNotificationToast (String message) {
try {
//Show the toast message
Toast.makeText(
ConfigAppValues.getContext(),
message,
Toast.LENGTH_SHORT).show();
}catch (Exception e) {
Log.e(CLASS_NAME, ExceptionUtils.exceptionTraceToString(e.toString(), e.getStackTrace()));
}
}
}
`
And for send sms message i use this PendingInents how has been put at the application launch, my logs said that all was right except for this, that launch the RESULT_ERROR_GENERIC_FAILURE flag.
The code is:
SmsManager smsManager = SmsManager.getDefault();
Log.d(CLASS_NAME, "SmsText: " + smsText);
//String test = "5556";
smsManager.sendTextMessage(
receiver,
null,
smsText,
ConfigSMS.getSentPI(),
ConfigSMS.getDeliverPI());
And that is all i don't have idea that is for my mobile phone or anything, how i said all works fine using two android emulators, Activity.RESULT_OK is launched and the sms message is received for the listen emulator.
Thanks for all!!