I'm developing an android application that sends an sms message from a window (Activity) then moves to another window(Activity). I'm trying to display a message to the user how is seeing another activity that the message is delivered.
I imagine the solution would be to it fire a thread that send the message and and wait until it's delivered and show a toast or Dialog. but I don't know if it's right or how to do that.
pls help.
sendDataMessage has following parameters for that:
sentIntent - if not NULL this PendingIntent is broadcast when the message is sucessfully sent, or failed.
deliveryIntent - if not NULL this PendingIntent is broadcast when the message is delivered to the recipient.
[edit] - example how to create pending intent
final PendingIntent sentIntent = PendingIntent.getActivity(this, 0, new Intent(this, SmsSendCheck.class), 0);
SmsSendCheck - this is a special activity to show your Toast
Toast is a good way. Otherwise, when your PendingIntent was broadcast after SMS was sent, display something in the current Activity.
Related
I have a service that is activated when alarm is activated. It extends IntentService, and in that service I need to send a message to MainActivity. The MainActivity on receiving this message then performs some necessary work. I send the message to MainActivity using :
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
This works OK if the MainActivity is currently active (displayed). If however the MainActivity is not currently active, I create it using :
PendingIntent mPendingIntent = PendingIntent.getActivity(this, 0,
new Intent(this, MainActivity.class), PendingIntent.FLAG_ONE_SHOT);
mPendingIntent.send(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
If the MainActivity is currently active (displayed), then the message reaches it. However, when I have to re-create the MainActivity using a PendingIntent, the message sent via LocalBroadcastManager does not reach the MainActivity. If I sleep for eg. 2000ms, before sending the message (where the MainActivity has to be recreated), the message does reach the MainActivity.
While this may be understandable, I would prefer to use a fail-safe way of ensuring that the app works as intended.
To guarantee that the MainActivity has received the message, do I need to send a message from the MainActivity to the service to verify that the message has been received?
Is there a better way to handle this?
Is there a better way to handle this?
Only use LocalBroadcastManager when the activity already exists. If you have to start the activity, include the information that you would have sent in the broadcast in the Intent that you use to start the activity. The activity can then look for that information in onCreate() and use it; otherwise, it can behave normally.
I am getting multiple Local notifications of range 1-10..
I am getting getting notifications with its content and title.. but when i click the notification only first notification open and when i click rest the notification disappear and it show activity but the content remain the same that one of first notification.. Here is my code
on clicking notification i applied this code
Intent intent1 = new Intent(context, Message_activity.class);
intent1.putExtra("randomStr", randomStr);
intent1.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pndng = PendingIntent.getActivity(context, id, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
and getting like this in message activity
String message = getIntent().getStringExtra("randomStr");
Log.e("randomStrrandomStr", getIntent().getStringExtra("randomStr"));
fullmsg.setText(message);
Please suggest something Thanks in advance
I guest you used same id for each time you notify a notification by call notify method of NotificationManager. So try to use different id for each time you call notify.
I want to do the following:
Send an SMS
Check if it was sent
Store it in a SQLite instance if it wasn't.
Resend any SMS that got stored before.
So you got a main SMS sending action, which will require feedback on its status (to tell the user if it could be sent or not), and a background SMS sending action which will just try to resend previously unsent SMS silently.
The solution I came up with involves an IntentService which has two actions:
Send an SMS message.
Try to send previously stored SMS messages.
So far so good, this exact same thing worked wonders for sending a TCP message to a server. Now the issue is that I can't seem to be able to send SMS from the IntentService.
The idea was to have the IntentService create a PendingIntent, stuff the main Activity provided PendingIntent inside (thats basically the callback to tell the activity the SMS was sent), then send the SMS with it.
Then with a static receiver fetch the PendingIntent and start a new action on the IntentService to delete the SMS from the SQLite instance if it was sent properly.
This is the main message sending method in the IntentService:
private void sendMessage(Configuration cfg, SMSMessage msg, PendingIntent resultIntent) {
final Intent smsIntent;
// Select which kind of intent we're creating.
if (resultIntent == null) {
// This one is the silent background SMS.
smsIntent = new Intent(this.getApplicationContext(), RedirectPendingMessages.class);
} else {
// This one is the one from the application.
smsIntent = new Intent(this.getApplicationContext(), RedirectMessage.class);
smsIntent.putExtra(EXTRA_PENDING_RESULT, resultIntent);
}
// Now store the message.
smsIntent.putExtra(EXTRA_SMS, msg);
// Construct broadcast intent.
PendingIntent pi = PendingIntent.getBroadcast(this.getApplicationContext(), 0, smsIntent, 0);
// Now send message.
SmsManager smsMng = SmsManager.getDefault();
smsMng.sendTextMessage(cfg.phoneNumberFor(msg.level), null, msg.content, pi, null);
}
It gets to the 'SmsManager.sendTextMessage' method fine but nothing happens, even if I hardcode the phone number and dont pass any PendingIntent the SMS still doesn't gets sent. It might be because the IntentService ceases to exist after the method call?
The receivers both just grab the broadcasted Intent, fetch the data inside, and start appropiate actions in the IntentService to delete the SMSs if they have been sent, and to broadcast the application's PendingIntent so the UI can give some feedback to the user ("SMS sent", "Error", etc).
My TCP implementation of the same thing pretty much just has a Socket write instead of that 'sendTextMessage', it blocks the IntentService until its done and works fine.
Any ideas on why the SMS isn't being sent or how to better implement this?
It seems that your message exceeds the character limit for the alphabet you're using, which is causing the SmsManager#sendTextMessage() method to fail silently.
For the basic 7-bit default alphabet, the character limit is 160; for 8-bit, it's 140; and for 16-bit, which sounds like your situation, it's 70, explaining why your 120-character message split into two parts.
As you discovered, you can use the SmsManager#divideMessage() method to split a message into useable parts, and the SmsManager#sendMultipartTextMessage() to send the parts correctly.
SmsManager Reference
I've a problem with my application. I use a class to manage push notification from Azure, extending NotificationsHandler.All works,the method onReceive "catch" the incoming notification,using bundle i can read each field of the json from azure server.If i click on the notification i can start the activity as follows:
fragment_richiesta_tabsV2 dettaglioTabs= new fragment_richiesta_tabsV2();
Intent myIntent = new Intent(contesto, dettaglioTabs.getClass());
contentIntent = PendingIntent.getActivity(contesto, 0,myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
the problem is when the app is closed from the recent apps.The notification arrives,but if i click on the app crash...how can i solve?
thanks
My question is a bit complicated so I am going to describe it briefly what I want to achieve. My application receives messages from GCM without any issue. When application is running and is visible to the user I am not displaying notification in Action Bar, I am displaying this message in dialog alert. I use BroadcastReceiver to achieve this.
The main issue is that, when app gets a few notifications in no time. When main activity is visible to the user, the first notification will be shown in dialog alert. And next will be placed in Action Bar as usual Android notifications. And at this moment user disposes the dialog alert and is going to choose a next notification from Action Bar. At this moment I am using in my CloudService (extends IntentService) intent with flag Intent.FLAG_ACTIVITY_CLEAR_TOP and also PendingIntent.FLAG_UPDATE_CURRENT flag for pendingIntent. PendingIntent is just the contentIntent for my NotificationCompat.Builder.
It works in this way that for each user click on the notification from Action Bar, my activity is refreshing (floats to the lower device edge and then floats from the upper edge with dialog alert with message - I am getting the extras from the intent in onResume method). This action is quite OK. Activity has only one instance in that case - I don't have to break through the few instances of the same activity while I have opened few notifications. But the big problem is that when user chooses any of the notifications in each case the last one will open in dialog alert. Activity seems to has the same intent despite of PendingIntent.FLAG_UPDATE_CURRENT.
There are two methods in CloudService which handle cloud messages:
private void showNotification(Bundle extras) {
notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
String message = extras.getString(CloudMetaData.MESSAGE);
if (App.isMyActivityVisible() && !CloudMessageDialogFragment.isAttached()) {
sendBroadcast(message, NOTIFICATION_ID);
} else {
Intent intent = new Intent(this, MyParentActivity.class);
intent.putExtra(CloudMetaData.MESSAGE, message);
intent.putExtra(CloudMetaData.NOTIFICATION_ID, NOTIFICATION_ID);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setSmallIcon(R.drawable.ic_launcher);
builder.setContentTitle(getString(R.string.app_name));
builder.setStyle(new NotificationCompat.BigTextStyle().bigText(alert));
builder.setContentText(alert);
builder.setAutoCancel(true);
builder.setDefaults(Notification.DEFAULT_SOUND);
builder.setContentIntent(contentIntent);
notificationManager.notify(NOTIFICATION_ID, builder.build());
}
NOTIFICATION_ID++;
}
And method which send broadcast is just like that:
private void sendBroadcast(String message, int notificationId) {
Intent intent = new Intent();
intent.setAction(ACTION_FROM_CLOUD_SERVICE);
intent.putExtra(CloudMetaData.MESSAGE, message);
intent.putExtra(CloudMetaData.NOTIFICATION_ID, notificationId);
sendBroadcast(intent);
}
In which way can I achieve similar solution? But it is important for user of course to open notification from Action Bar and shown him its correct message.
EDIT
I have switched my dialog alert into the dialog activity. This is its definition in AndroidManifest:
<activity
android:name="com.myapp.activity.CloudMessageDialogActivity"
android:theme="#android:style/Theme.Dialog"
android:parentActivityName="com.myapp.activity.MyParentActivity"/>
But the result is still the same - when app receives a few notifications, clicking on one of them will open the dialog with the intent for the last received notification.
But the big problem is that when user chooses any of the notifications in each case the last one will open in dialog alert. Activity seems to has the same intent despite of PendingIntent.FLAG_UPDATE_CURRENT.
That's because you are using the same request code (i.e., 0) for all PendingIntents here:
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
By doing so, you are ultimately receiving the same intent, because the platform is failing to see the difference between the intents and delivering the same object everytime:
... it is important to know when two Intents are considered to be the same for purposes of retrieving a PendingIntent. A common mistake people make is to create multiple PendingIntent objects with Intents that only vary in their "extra" contents, expecting to get a different PendingIntent each time. This does not happen. The parts of the Intent that are used for matching are the same ones defined by Intent.filterEquals. If you use two Intent objects that are equivalent as per Intent.filterEquals, then you will get the same PendingIntent for both of them.
So, instead of a constant value, please use a unique request code. For e.g. change the above line with:
PendingIntent contentIntent = PendingIntent.getActivity(this, NOTIFICATION_ID,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
Hope this helps.