stack notification received from parse - android

I want to stack multiple received notification from parse,when received notification is more than 1 notify and display to user in one notification. I searched so much but i can not find the right solution. is that possible anyway?

What you need is a custome PushReceiver, so according to Parse docs you declare receiver in the manifest
<receiver
<!-- Put here path to a class that will handle pushes -->
android:name="com.domain.ReceiverClass"
android:exported="false">
<intent-filter>
<action android:name="com.parse.push.intent.RECEIVE"/>
<action android:name="com.parse.push.intent.DELETE"/>
<action android:name="com.parse.push.intent.OPEN"/>
</intent-filter>
</receiver>
And in this PushReceiver class you implement all needed logic concerning displaying of pushes
public class PushReceiver extends ParsePushBroadcastReceiver {
#Override
protected void onPushReceive(Context context, Intent intent) {
//Don't call super.onPushReceive!
JSONObject pushData = new JSONObject(intent.getStringExtra(KEY_PUSH_DATA));
//Here is how you obtain data
String alert = pushData.optString("alert", "Notification received.");
//Any manipulations with stacking go here
}
}
EDIT. So everything depends on your requirements. You can for example just accumulate notifications in the receiver and schedule AlarmManager to wake up after 5 mins. Pass current number of notificaitons as an extra and then check if new pushes arrived. If so - wait for the next alarm, if not - show everything.
SharedPreferences prefs = context.getSharedPreferences(KEY_NOTIFICATIONS,
Context.MODE_PRIVATE
);
JSONArray stacked = new JSONArray(prefs.getString(KEY_STACKED, ""));
stacked.put(alert);
prefs.edit().putString(KEY_STACKED, stacked.toString()).apply();
Intent i = new Intent(context, ActualProcessor.class);
i.putExtra(EXTRA_COUNT, stacked.length());
PendingIntent receiver = PendingIntent.getBroadcast(context, CODE, i, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(5),
receiver
);

Related

AlarmManager alarm start when system time is changed by user?

i am using AlarmManager class for setting Alarms it is working fine.
But if i set alarm like 9pm and current time is 8pm and i changed the system time to 10pm
then alarm 9pm alarm start automatically. so to solve this issue
i have searched so much but did not found any good answer
Please help
here is my code for alarm setting
final int id = (int) System.currentTimeMillis();
Intent intent = new Intent(this, AlarmReceiver.class);
intent.putExtra("requestCode", id);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 2*60*1000, pendingIntent);
One of the options is to store all set alarms in database, then create a BroadcastReceiver which will listen for ACTION_TIME_CHANGE action. When user changes time it will be triggered. Then create a IntentService which will be responsible for resetting alarms. In this service class:
Read db and identify all passed alarms.
Cancel passed alarms
Set alarms for next day
Your code may look like as below:
In your Manifest:
<uses-permission android:name="android.permission.ACTION_TIME_CHANGE"/>
and below activities:
<receiver android:name=".TimeChangedReceiver" android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.TIME_SET" />
</intent-filter>
</receiver>
<service android:name=".RestartAlarmsService"/>
Create class "TimeChangedReceiver" inside of which:
public class TimeChangedReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if("android.intent.action.TIME_SET".equals(intent.getAction())) {
Intent i = new Intent(context, RestartAlarmsService.class);
ComponentName service = context.startService(i);
}
}
}
Create "RestartAlarmsService" class inside of which:
public class RestartAlarmsService extends IntentService {
public RestartAlarmsService() {
super("RestartAlarmsService");
}
#Override
protected void onHandleIntent(Intent intent) {
// read db here
// then cancel passed alarms
// reset them to next day
}
}
You can find many tutorials on how to use Databases and implement it in your code. Hope my answer is somehow helpful.
yes it will give you broadcast, as your pending intent object is still attached to that event while you change time that is greater than you alarm firing time.
solution- validate your condition while you receive broadcast from alarm manager

Android My BroadcastReceiver Class no receive the action send from Notification

In my IntentService class, i create a Notification and assign ID=1213, and the notification will show up once the apps is open.
Intent cancelScan = new Intent();
cancelScan.setAction(CANCEL);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1213, cancelScan, PendingIntent.FLAG_UPDATE_CURRENT);
mNbuilder.addAction(android.R.drawable.ic_menu_close_clear_cancel,"Cancel Scanning",pendingIntent);
NotificationManager manager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(NOTIFICATION_ID, mNbuilder.build());
in my BroadcastReceiver class
if(CANCEL.equals(intent.getAction())){
Log.i(TAG,"Received Broadcasr Receiver");
NotificationManager nm = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
//context.stopService(new Intent(context,ScanService.class));
nm.cancel(NOTIFICATION_ID);
}
}
and, my Manifest.XML
<receiver android:name=".WifiScanReceiver" android:enabled="true">
<intent-filter>
<action android:name="CANCEL"/>
</intent-filter>
</receiver>
I had tried couple times when i click the action button beneath the notification, but the Logcat did not print anything. Which parts i had done wrong? Thank in Advance.
The values of CANCEL and the value declared as action ("CANCEL") in your manifest must be equal, or it won't work. Your's don't, that's why you don't reach your if statement. Your receiver is triggered though, because you send a broadcast with the correct action.
To make sure you use the correct values in your code, you can declare a static final in your WifiScanReceiver:
public class WifiScanReceiver {
public static final String CANCEL = "CANCEL";
...
}
So you can also use it in you code when you send the broadcast:
Intent cancelScan = new Intent();
cancelScan.setAction(WifiScanReceiver.CANCEL);
That way you are always certain that you use the same value. The only one that you have to make sure is also correct, is the one in your manifest.

AlarmManager Stops after removing app from recents apps

I am new to this part of android, and here I aim to use alarm manager to run a code snippet every 2 minute which will poll a server (using the website's api) and based on the returned JSON generate notification.
After a looking up the web I thought one of the best option in my case will be using intent service and android.
Manifest of Services and Recievers
<service
android:name=".NotifyService"
android:enabled="true"
android:exported="false" >
</service>
<receiver
android:name=".TheReceiver"
android:enabled="true"
android:exported="true" >
</receiver>
<receiver
android:name=".OnOffReceiver"
android:enabled="true"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
Part in the flash screen activity where I call the intent service which is responsible for polling for notification:
Intent msgIntent = new Intent(this, NotifyService.class);
startService(msgIntent);
The receiver to start the alarm on device start:
public class OnOffReceiver extends BroadcastReceiver
{
private AlarmManager alarmMgr;
private PendingIntent alarmIntent;
public OnOffReceiver(){}
#Override
public void onReceive(Context context, Intent intent)
{
Intent service = new Intent(context, NotifyService.class);
service.setAction(NotifyService.CREATE);
context.startService(service);
}
}
The IntentService Class
public class NotifyService extends IntentService
{
public NotifyService()
{
super("NotifyService");
}
public static final int STATUS_RUNNING = 0;
public static final int STATUS_FINISHED = 1;
public static final int STATUS_ERROR = 2;
#Override
protected void onHandleIntent(Intent intent)
{
if (intent != null)
{
final String action = intent.getAction();
}
StartStuff();
}
public void StartStuff()
{
Intent intent = new Intent(this, TheReceiver.class);
PendingIntent pend_intent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,1200,1200, pend_intent);
//1200ms to make it easier to test
}
}
The receiver class which sets notification, for testing pupose I am not doing any network related work here just making a simple notification to check if the app is running in all situations
public class TheReceiver extends BroadcastReceiver
{
public TheReceiver(){}
#Override
public void onReceive(Context context, Intent intent)
{
Toast.makeText(context, " Success ", Toast.LENGTH_SHORT).show();
Log.d("Notification", "The Receiver Successful");
showNotification(context);
}
private void showNotification(Context context)
{
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context).setContentTitle("My notification").setContentText("Hello World!");
mBuilder.setDefaults(Notification.DEFAULT_SOUND);
mBuilder.setAutoCancel(true);
NotificationManager mNotificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(1, mBuilder.build());
}
}
However the notification come only when the app is running or in the recent apps tray.
It does not start notifying when the phone reboots, nor does it notify after the app is removes from the recent apps tray.
The app needs Notify users like other apps (like gmail, whatsapp) do, even if they are swiped out of the recent apps tray.
Timeliness and punctuality are not very big issue as delay up to 5 to 10 minutes are tolerable. (I intend to poll ever 2 minutes though.)
Where am I going wrong? Also, is there a better way to go about the problem?
To keep a receiver active after closing the app is to use
android:process=":remote"
in the manifest file for the receiver that needs to be kept alive.
<receiver
android:name=".TheAlarmReceiver"
android:process=":remote">
</receiver>
in the manifest for the receiver (TheReceiver in this case) that we need to keep active after the app closes.
P.S. : I also changed the way I use IntentsService and AlarmManager for the application, as my previous(above) implementation is not a very good way to go around it.
If an App is killed from recent apps or from "force stop" it won't restart by itself. The user has to start the app again in order to make it run again. There is no way to prevent this. It's just the way android works.
However there is a way to make your app run oon boot. Check out this link.

android services life time continuation

In mainactivity
I have Broadcast Receiver, pending intent, and alarm manager. It triggers as per selected time (System.currentTimeMillis() + smstimeinmilliseconds).
Intent intent = new Intent(this, DBBroadcastReceiver.class);
intent.putExtra("message", message);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, id, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + smstimeinmilliseconds, pendingIntent);
On selected time, this pending intent triggers broadcast receiver.
public class DBBroadcastReceiver extends BroadcastReceiver
#Override
public void onReceive(Context context, Intent intent)
{
message = intent.getStringExtra("message");
}
I can set message in activity and set time in alarm manager.
Every thing works flawless. I can activate and deactivate this. But if i set few alarm mangers in future time and reboot my mobile. all alarm manager destroy .....
Kindly tell me in steps and sequence what to do with activity , broadcast receiver and do i need service , if yes then how can i use it.
You need a BoradcastReceiver to be called on boot up.
Then you need in your manifest :
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<receiver
android:name=".broadcasts.YourBroadcastReceiverName">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
And this broadcast receiver needs to schedule again all the alarms.
Something like :
public class YourBroadcastReceiverName extends BroadcastReceiver {
private AlarmManagerFacade alarmManager;
#Override
public void onReceive(Context context, Intent intent) {
// Retreive data related to alarms
Cursor cursor = context.getContentResolver().query(Alarm.CONTENT_URI, null,
Alarm.COLUMN_ACTIVE + " = ? ",
new String[] { String.valueOf(1) }, "");
if (cursor.moveToFirst()) {
// Schedule all the active alarms.
alarmManager = new AlarmManagerFacade(context);
do {
// TODO : Schedule alarm according to data in cursor.
} while (cursor.moveToNext());
}
cursor.close();
}
}
(This code is coming from one of my app, some of the objects are not available in the Android SDK)
In order to be able to re schedule all the alarms, you need to have them stored somewhere.
You can write your own ContentProvider for example.
It works well with other android components thanks to the CursorAdapter widget.
It is not the easiest solution but it's the way to go if you want to follow android guidelines.
There may be other simpler alternative to store your alarms, like SharedPreferences.
It's easy to use.
But you will need to hack around to store multiple alarms in a friendly manner.
One last alternative is that you can create an object containing the information, serialize it and store it as a file on the SD Card.
It's ugly and not flexible.
But it not that hard to implement ...
If you want to have a closer look to each storage options, you can read about it in the docs here : http://developer.android.com/guide/topics/data/data-storage.html
I hope all this help you. :)

How to run a service every day at noon, and on every boot

In my app I have SQLite database that has one table with date rows in milliseconds. I would like to have a notification shown every day IF 30 days has passed since the last date value stored in my database. A service seems to be a good way to accomplish this check up.
I ran into Commonsware's WakefulIntentService and thought it could be the answer but I really don't know how should I implement it. In the demo it starts a service after 5 minutes since boot is complete which is just fine but what do I need to add to get it also start at every noon. (... but only to show one notification / day, not both, as from boot and regular daily check up)
I know this could be solved using AlarmManager but really don't know how. So, the help I need is to give me some samples / key points to get the service start on every boot and/or every day without app running.
thanks
Android alarmmanager is your answer. use it with a broadcast receiver which also resets the alarms on phone wake.
Now with code example:
Setting alarm inside a method:
Intent intent = new Intent(context, AlarmReceiver.class);
intent.setAction("packagename.ACTION");
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarm.cancel(pendingIntent);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
Receiver for your interval:
public class AlarmReceiver extends BroadcastReceiver {
private final String SOMEACTION = "packagename.ACTION"; //packagename is com.whatever.www
#Override
public void onReceive(Context context, Intent intent) {
Time now = new Time();
now.setToNow();
String time = FileHandler.timeFormat(now);
String action = intent.getAction();
if(SOMEACTION.equals(action)) {
// here you call a service etc.
}
Receiver for resetting alarms whenever phone has been shut down.
public class AlarmSetter extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// get preferences
SharedPreferences preferences = context.getSharedPreferences("name_of_your_pref", 0);
Map<String, ?> scheduleData = preferences.getAll();
// set the schedule time
if(scheduleData.containsKey("fromHour") && scheduleData.containsKey("toHour")) {
int fromHour = (Integer) scheduleData.get("fromHour");
int fromMinute = (Integer) scheduleData.get("fromMinute");
int toHour = (Integer) scheduleData.get("toHour");
int toMinute = (Integer) scheduleData.get("toMinute");
//Do some action
}
}
}
Manifest very important, this is added under application:
<receiver android:name="AlarmReceiver">
<intent-filter>
<action android:name="packagename.ACTION"/>
<action android:name="packagename.ACTION2"/>
</intent-filter>
</receiver>
<receiver android:name="AlarmSetter" >
<intent-filter>
<action
android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
Also in order for this to work you need to add permission to receive the boot Broadcast in the manifest with following line:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
Hope this cleared things up, if any errors plz tell.
Edit (added alarmsetter example):
public class AlarmSetter extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Do your stuff
}
}
This answer seems pretty old.
Now, I would totally recommend people to check out SyncAdapter framework provided by Google.
It is custom made for such things.
Here's the link: https://developer.android.com/training/sync-adapters/index.html
In the demo it starts a service after 5 minutes since boot is complete which is just fine but what do I need to add to get it also start at every noon.
Change the initial time of the setRepeating() call. The example shows one minute from now -- you would need to do the calculations to determine when the next noon is.
You can see an example of that sort of calculation in this OnBootReceiver from a different sample project. Here, I am setting up the alarm to go off every day at a user-specified time.

Categories

Resources