I have following method which is saving three values into intent which is appended to created alarm.
public static Boolean setUniqueAlarm(Long alarmId, String occurenceTime, Context context) {
Boolean saveResult = null;
try {
DateTime dt = TimeHelper.getDateTimeObject(occurenceTime);
Logger.d("Year: " + dt.getYear() + ", month: " + dt.getYear() + ", day: " + dt.getDayOfMonth() + ", hour: " + dt.getHourOfDay() + ", minute: " + dt.getMinuteOfHour());
Logger.d("Occurrence time to save: "+occurenceTime);
AlarmManager alarmManager = (AlarmManager) context.getApplicationContext().getSystemService(Context.ALARM_SERVICE);
Intent alarmIntent = new Intent(context, AlarmBroadcastReceiver.class);
// Pass the intent type and other additional values into bundle
Bundle bundle = new Bundle();
bundle.putString(Constants.Global.ALARM_TYPE, Constants.Global.ALARM_TYPE_UNIQUE);
bundle.putString(Constants.Global.ALARM_OCCURRENCE_TIME, "123456");
bundle.putLong(Constants.Global.ALARM_UNIQUE_ID, alarmId);
alarmIntent.putExtras(bundle);
PendingIntent pendingAlarmIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, 0);
alarmManager.set(AlarmManager.RTC_WAKEUP, dt.getMillis(), pendingAlarmIntent);
saveResult = true;
} catch (Exception e) {
Logger.e(e.getMessage());
saveResult = false;
}
return saveResult;
}
In receiver i have following code:
#Override
public void onReceive(Context context, Intent intent) {
try {
Logger.d("ALARM RECEIVED!!!");
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
// Device battery life will be significantly affected by the use of this API.
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "TAG");
// Acquire the lock
wl.acquire();
//Release the lock
wl.release();
// Get the intent type (or stored variables)
Bundle extras = intent.getExtras();
mAlarmType = extras.getString(Constants.Global.ALARM_TYPE);
mAlarmId = extras.getLong(Constants.Global.ALARM_UNIQUE_ID, 0);
mOccurenceTime = extras.getString(Constants.Global.ALARM_OCCURRENCE_TIME, "nothing");
triggerActionBasedOnTheAlarmType(mAlarmType, mAlarmId, mOccurenceTime, context);
} catch (Exception e) {
TrackingEventLogHelper.logException(e, Constants.Global.EXCEPTION,
Constants.ExceptionMessage.EXC_CANNOT_PROCESS_RECEIVED_ALARM, true);
}
}
Problem is that variable mOccurenceTime is always null, rsp. "nothing".
I tried to get values from intent and from Bundle but still without the success. Is not bundle count of items limited?
How can i get value mOccurenceTime in the right way?
Many thanks for any advice.
This is the right way to do it - specify a flag !
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, uniqueRequestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Instead of the:
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, uniqueRequestCode, intent, 0);
Because the 0 for the flags is what will cause you a headache
This is probably such a popular problem because Google's sample code neglected to include Extra's in an Alarm.
Solved here:
Android cannot pass intent extras though AlarmManager
Related
I am currently trying to send a local notification with an action. The action will push a string to the activity when selected. Unfortunately, when I try to pass a String I am unable to receive it on the activity, I have multiple log statements with different objects to see if maybe the system is recognizing it as something else but no luck. Event when I tried to send it in as a bundle, the bundle is sent but not the string! if I pass an int it works great! Any help would be appreciated, and yes I have been digging around for this and tried multiple solutions.
Code:
Intent intent = new Intent(context, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.setAction("action");
intent.putExtra("idforaction", 12345);
//intent.putExtra("test", "test message");
Bundle bundle = new Bundle();
bundle.putString("othertest","test message 2");
intent.putExtra("test", bundle);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
MainActivity:
int notificationNum = getIntent().getIntExtra(idfoaction, -1);
Log.e(TAG, "get Extras " + notificationNum);
Log.e(TAG, "STRING? " + getIntent().getStringExtra("test"));
Log.e(TAG, "CHARSEQ? " + getIntent().getCharSequenceExtra("test"));
Log.e(TAG, "CHARS?" + (getIntent().getCharArrayExtra("test") != null ? getIntent().getCharArrayExtra("test").length + "" : "null"));
Log.e(TAG, "PARCELABLE?" + (getIntent().getParcelableExtra("test") != null ? getIntent().getParcelableExtra("test").toString(): "null"));
Log.e(TAG, "BUNDLE?" + (getIntent().getBundleExtra("test") != null ? "not null" : "null"));
Log.e(TAG, "BUNDLE?" + (getIntent().getExtras() != null ? "not null" : "null"));
if (getIntent().getExtras() != null) {
Log.e(TAG, "bundle " + getIntent().getExtras().getString("othertest", ""));
Log.e(TAG, "bundle " + getIntent().getExtras().get("othertest"));
}
Try this:
Intent intent = new Intent(context, MainActivity.class);
intent.putExtra("my_key", "my_key_value");
And read:
Intent intent = getIntent()
String myValue = intent.getStringExtra("my_key"); // "my_key_value"
I am facing consistency issue while setting alarms inside my application wherein the alarm gets delivered sometimes but other times the pending intent does not gets delivered to my application.
The way I am trying to test is by changing my local device time and check if I am getting the alarm or not.
I can see the alarm getting triggered from the alarm manager because this log comes up
V AlarmManager: Triggering alarm #0: 0 when =1508253750804 package=com.x.xoperation =*walarm*:com.x.x/x.AlarmReceiver
Does android control the delivery of an alarm based upon whether the application is in the background or not? Any insights around this area would really help.
Code For AlarmManager
public static void SetNotification(int id, long delayMs, String title, String message, String ticker, int sound, int vibrate,
int lights, String largeIconResource, String smallIconResource, int bgColor, String bundle, String dataString)
{
Context currentActivity = UnityPlayer.currentActivity;
AlarmManager am = (AlarmManager)currentActivity.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(currentActivity, AlarmReceiver.class);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.putExtra("ticker", ticker);
intent.putExtra("title", title);
String arr[] = new String[]{id+"", delayMs+"", title, message, ticker, sound+""};
String fStr = "";
for (String temp:arr
) {
fStr += temp+":";
}
Log.d(Constants.TAG, "Input message = "+fStr);
intent.putExtra("message", message);
intent.putExtra("id", id);
intent.putExtra("color", bgColor);
intent.putExtra("sound", sound == 1);
intent.putExtra("vibrate", vibrate == 1);
intent.putExtra("lights", lights == 1);
intent.putExtra("l_icon", largeIconResource);
intent.putExtra("s_icon", smallIconResource);
intent.putExtra("bundle", bundle);
intent.putExtra("dataString", dataString);
PendingIntent pendingIntent = PendingIntent.getBroadcast(currentActivity,
id, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
am.cancel(pendingIntent);
long finalTime = System.currentTimeMillis() + delayMs;
am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,finalTime, pendingIntent);
Log.d(Constants.TAG, "event fired finalTime = "+ finalTime);
}
Is this because of the doze and app standby which android has introduced ? or is because of some issue on our side.
I have two alarms and a broadcastreceiver:
AlarmManager am2=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent2 = new Intent(context, MyReceiverAlarm.class);
intent2.putExtra("name", "juan");
PendingIntent pi2 = PendingIntent.getBroadcast(context, 0, intent2, 0);
am2.set(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+1000, pi2);
AlarmManager am=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, MyReceiverAlarm.class);
intent.putExtra("name", "jose");
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
am.set(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+8000, pi);
However, I'm always receiving the first one, only. I always get "juan" and the alarm is fires after 8 seconds.
I don't understand the reason...If i have two alarms why fires one ?
My BroadcastReceiver:
Toast.makeText(context, extras.getString("nombre") + "", Toast.LENGTH_LONG).show();
String name=extras.getString("nombre");
if (extras != null && name.equals("juan") {
String callForwardString = PHONE ;
Intent intentCallForward = new Intent(Intent.ACTION_CALL);
Uri uri2 = Uri.fromParts("tel", callForwardString, "#");
intentCallForward.setData(uri2);
intentCallForward.addFlags(intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intentCallForward);
} else {
...
}
Is not possible to program two alarms?
Thanks in advance
Try to change the request code (second parameter passed to getBroadcast():
PendingIntent pi2 = PendingIntent.getBroadcast(context, 2, intent2, 0);
PendingIntent pi = PendingIntent.getBroadcast(context, 1, intent, 0);
I am working with GCM, and this is my onMessage function:
#Override
protected void onMessage(Context context, Intent intent) {
if (intent != null && intent.getExtras() != null) {
try {
String message = intent.getExtras().getString("message");
String userId = intent.getExtras().getString("user_id");
Log.i("","postda user id is:" + userId);
Log.i("","will enter here FRIENDS: ");
generateNotification(context, message, userId);
} catch (Exception e) {
Utils.appendLog("onMessage errror : " + e.getMessage());
Log.i(TAG, e.getMessage(), e);
}
}
}
This is my CreateNotification function:
private static void generateNotification(Context context, String message, String userID) {
Log.i("", "postda user message " + message + ".... userid: " + userID);
String title = context.getString(R.string.passenger_name);
Intent notificationIntent = new Intent(context, PSProfileActivity.class);
notificationIntent.putExtra("id", userID);
Log.i("", "postda ---------- userid: "+ userID);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP| Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent intent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
Log.i("", "postda message: " + message + "....userID " + userID );
PSLocationCenter.getInstance().pref.setDataChanged(context, true);
PSLocationCenter.getInstance().pref.setDataChangedProfile(context, true);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context);
mBuilder.setContentTitle(title).setContentText(message).setSmallIcon(R.drawable.notification_icon);
mBuilder.setContentIntent(intent);
Notification notification = mBuilder.build();
notification.flags |= Notification.FLAG_AUTO_CANCEL;
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(1, notification);
playTone(context);
}
And this is the PSProfileActivity onCreate function:
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
ButterKnife.inject(this);
mHeader = new ProfileHeader(this, backFromHeader);
mData = new ProfileData(this);
mButtons = new ProfileViewPagerButtons(PSProfileActivity.this, firstPage);
Bundle bundle = getIntent().getExtras();
if(bundle != null) id = bundle.getString("id");
Log.i("", "postda in profile id is:" + id);
if(!id.contentEquals(String.valueOf(PSLocationCenter.getInstance().pref.getUserId(PSProfileActivity.this)))){
findViewById(R.id.action_settings).setVisibility(View.INVISIBLE);
}
Log.i("", "postda in profile id is 2:" + id);
}
And this is my Logcat response:
04-17 15:33:53.650 9699-11695/nl.hgrams.passenger I/﹕ postda user id is:23
04-17 15:33:53.651 9699-11695/nl.hgrams.passenger I/﹕ postda user message alin reddd accepted your friend request..... userid: 23
04-17 15:33:53.651 9699-11695/nl.hgrams.passenger I/﹕ postda ---------- userid: 23
04-17 15:33:53.652 9699-11695/nl.hgrams.passenger I/﹕ postda message: alin reddd accepted your friend request.....userID 23
04-17 15:33:58.812 9699-9699/nl.hgrams.passenger I/﹕ postda in profile id is:28
04-17 15:33:58.814 9699-9699/nl.hgrams.passenger I/﹕ postda in profile id is 2:28
As you can see, I'm sending via the bundle an ID, but the one that I get on the other page, is a totally different id (it's actually the last ID that should have been gotten here). This is really weird, does anyone know why this is happening?
Use unique identitier in the PendingIntent:
int iUniqueId = (int) (System.currentTimeMillis() & 0xfffffff);
PendingIntent.getActivity(context, iUniqueId, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
You are generating intent with the same id always. You need to pass the unique identifier as the second parameter and also need to add the Flag FLAG_UPDATE_CURRENT so that the extras get updated and you always get the latest extras that you passed .
So you have to generate intent like this :
PendingIntent intent = PendingIntent.getActivity(context, identifier , notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT );
identifier can be anything unique like auto increment variable or current timestamp
The problem may be that you are only using extras to modify the PendingIntent. Try embedding the id in the data field of notificationIntent instead.
From http://developer.android.com/reference/android/app/PendingIntent.html
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.
I think you have to use this flag, FLAG_UPDATE_CURRENT.
Like this:
PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
This would refresh the old intents with the new extras that you are passing via bundle and get correct data that matches the ID.
I am having a big problem with Bundle, Intent and Android.
I send an SMS and therefore I create a Bundle with its text and number in it.
Now when I want to change my number and my text, my application always sends the same first SMS.
I have tried nearly everything but I do not know how to solve my problem!
What I tried was that:
Updating my PendingIntent with a FLAG, but it does not help.
Maybe, someone can help me?
Here is my code:
Intent myIntent = new Intent(Parkschein.this, MyAlarmService.class);
Bundle bundle = new Bundle();
bundle.putCharSequence("extraSmsNumber", smsNumber);
bundle.putCharSequence("extraSmsText", smsText);
pendingIntent = PendingIntent.getActivity(Parkschein.this, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
myIntent.putExtras(bundle);
pendingIntent = PendingIntent.getService(Parkschein.this, 0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 2);
if(smsMinutes.equals(""))
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
else {
Long smsMinutesInLong = Long.parseLong(smsMinutes);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), smsMinutesInLong*60000, pendingIntent);
}
and here is my service class, where the sms is sent:
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
pendingIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_ONE_SHOT + PendingIntent.FLAG_UPDATE_CURRENT);
Bundle bundle = new Bundle();
bundle = intent.getExtras();
smsNumberToSend = (String) bundle.getCharSequence("extraSmsNumber");
smsTextToSend = (String) bundle.getCharSequence("extraSmsText");
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(smsNumberToSend, null, smsTextToSend, null, null);
}
Thanks in advance!
Android caches objects like PendingIntent for later usage. Are you sure you've added flags to correct PE? You probably need to do this
pendingIntent = PendingIntent.getService(Parkschein.this, 0, myIntent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT);