I am able to read message of user when the application gets installed. But what I want is that even after the application is closed, I should be able to read user message after a fixed interval of time. For example, application like Walnut that reads specific message and gives alerts automatically if any new message has come. How can I do the same.
Use Alarm manager and Pending Intent
Initiate Alarm manager here.
AlarmManager alarmMgr = (AlarmManager) this
.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
new Intent(this, AlarmReceiver_update.class),
PendingIntent.FLAG_CANCEL_CURRENT);
alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
0, yourTimeInterval, pendingIntent);
And in AlarmReceiver_update class:
public class AlarmReceiver_update extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
// Do whatever you want
}
}
And in Your AndroidManifest file register your receiver:
<receiver android:name="com.x.y.AlarmReceiver_update" >
<intent-filter>
<action android:name="android.test.BROADCAST" />
</intent-filter>
</receiver>
This is not complete just sample you have any doubt just comment.
You shuold use an alarm manager to set a repeating alarm.
Then you should setup a BroadcastReceiver Service that read the user messages onRecieve.
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Run the task to read the user messages
}
}
This is a good tutorial
Have a look at the below links to learn how to notify the user if you found new message.
http://javatechig.com/android/repeat-alarm-example-in-android#3-defining-alarm-broadcastreceiver
http://developer.android.com/training/notify-user/build-notification.html
Related
I am working on an interval timer which make an alarm every interval (E.g. 30mins).
I want to make the timer work in background or when device is in sleep and show a notification,
I was told to use Intent Service but its deprecated. what should i use?
-I want to support until API 21
You need to create a BroadcastReceiver. For example, using AlarmManager:
int repeatTime = 30; //Repeat alarm time in seconds
AlarmManager processTimer = (AlarmManager)getSystemService(ALARM_SERVICE);
Intent intent = new Intent(this, processTimerReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
//Repeat alarm every second
processTimer.setRepeating(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis(),repeatTime*1000, pendingIntent);
And create your processTimerReciever class:
//This is called every second (depends on repeatTime)
public class processTimerReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
//Do something every 30 seconds
}
}
Remember to register into Manifest:
<receiver android:name="processTimer" >
<intent-filter>
<action android:name="processTimerReceiver" >
</action>
</intent-filter>
</receiver>
EDIT:
If your app use an internet connection, you can send every 30 mins a notification using Firebase
I am writing my first app and I'm trying to fire a notification at a specific time every day that reports some information.
For starter, I created the following class that I use to restart the alarms after a reboot and to start the alarms from the main app (this to have just one piece of code to reuse).
public class SetAlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
startReminderService(context);
}
public void checkServiceRunning(Context context) {
Intent reminderIntent = new Intent(context, AlarmReceiver.class);
reminderIntent.setAction("MyReminder");
// I check if a reminder is already active
boolean reminderActive = (PendingIntent.getBroadcast(context, REMINDER_SERVICE,
reminderIntent,
PendingIntent.FLAG_NO_CREATE) != null);
Log.d("test", "The reminder is active?" + reminderActive);
if (!reminderActive) {
startReminderService(context);
}
}
public void startReminderService(Context context) {
Calendar serviceNotificationTime = Calendar.getInstance();
serviceNotificationTime.set(Calendar.HOUR_OF_DAY, 9);
serviceNotificationTime.set(Calendar.MINUTE, 0);
serviceNotificationTime.set(Calendar.SECOND, 0);
Intent reminderIntent = new Intent(context, AlarmReceiver.class);
reminderIntent.setAction("MyReminder");
PendingIntent pendingIntent = PendingIntent.getBroadcast(
context,
REMINDER_SERVICE,
reminderIntent,
PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager serviceAlarmManager = (AlarmManager) context.getSystemService(ALARM_SERVICE);
serviceAlarmManager.setRepeating(
AlarmManager.RTC_WAKEUP,
serviceNotificationTime.getTimeInMillis(),
AlarmManager.INTERVAL_DAY,
pendingIntent);
if (pendingIntent != null) {
Log.d("test", "Background service set up and running.");
} else {
Log.d("test", "Failed to set up background service!");
}
}
}
After that I updated the manifest with the following lines:
<receiver
android:name="com.mycompany.myapp.services.SetAlarmReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver
android:name="com.mycompany.myapp.services.AlarmReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="MyReminder" />
</intent-filter>
</receiver>
So far, everything goes right. When the phone reboots, the reminder is correctly restarted and (if the reminder time is in the past) it fires immediately.
The AlarmReceiver class is the following:
public class AlarmReceiver extends BroadcastReceiver {
private Context ctx;
#Override
public void onReceive(Context context, Intent intent) {
this.ctx = context;
remindStuff();
}
private void remindStuff() {
....
some code
....
// I check if the alarm is still on (probably awful, since it just fired)
SetAlarmReceiver setAlarmReceiver = new SetAlarmReceiver();
setAlarmReceiver.checkServiceRunning(ctx);
}
}
I use the same approach to check if the alarm is on from the main activity:
private void checkServicesRunning() {
SetAlarmReceiver setAlarmReceiver = new SetAlarmReceiver();
setAlarmReceiver.checkServiceRunning(getApplicationContext());
}
Everything looks correct to me, I've tried any solution I found, reading tons of questions like mine on StackOverflow but I still can't understand what I'm doing wrong.
The alarm fires correctly right after BOOT_COMPLETED is triggered by the system and it fires correctly when I just enabled the alarm (only if the notification time is in the past - f.e. when it's 10pm and the alarm must fire at 9am).
When the checkServiceRunning method runs, it tells me that the alarm is already enabled (returning true in the Logcat) but when I close the app and I re-run it after a while, the alarm looks like it's been canceled and it's being recreated by the app.
Any hint?
Thanks.
EDIT: I tried the command 'adb shell dumpsys alarm' and it actually shows my alarm running correctly so, at this point, I think the issue is something else but I cannot understand what...
I have a music application in which I am trying to add some action button on the notification bar.
I tried something like this:
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.start();
Intent onPreparedIntent=new Intent("MEDIA_PLAYER_PREPARED").putExtra("CURR_SONG",songposn);
LocalBroadcastManager.getInstance(this).sendBroadcast(onPreparedIntent);
Intent notintent = new Intent(this, MainActivity.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Notification.Builder builder=new Notification.Builder(this);
PendingIntent pendingIntent=PendingIntent.getActivity(this,0,notintent,PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent prevPendingIntent=PendingIntent.getActivity
(this,1,new Intent().setAction("PREVIOUS"),PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent pausePendingIntent=PendingIntent.getActivity
(this,2,new Intent().setAction("PAUSE"),PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent nextPendingIntent=PendingIntent.getActivity
(this,3,new Intent().setAction("NEXT"),PendingIntent.FLAG_UPDATE_CURRENT);;
builder.setContentIntent(pendingIntent).setSmallIcon(R.drawable.playicon)
.addAction(R.drawable.back, "Previous", prevPendingIntent)
.addAction(R.drawable.playsmall, "Pause", pausePendingIntent)
.addAction(R.drawable.forw, "Next", nextPendingIntent)
.setTicker(songArtist)
.setOngoing(true).setContentTitle(songTitle).setContentText(songArtist);
Notification not=builder.build();
startForeground(MusicService.NOTIFY_ID,not);
}
I declared a NotificationReciever class inside this service
public class NotificationReciever extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Log.e("here","here");
String action=intent.getAction();
if(action!=null){
switch (action){
case "PREVIOUS":{
playPrev();
break;
}
case "PAUSE":{
pausePlayer();
LocalBroadcastManager.getInstance(MusicService.this).sendBroadcast(new Intent("STOP_THREAD"));
break;
}
case "NEXT":{
playNext();
break;
}
}
}
}
}
Structure looks something like this:
-MusicService extends Service
--NotificationReciever extends BroadcastReceiver
My manifest file contains reciever like this:
<receiver android:name=".MusicService$NotificationReciever">
<intent-filter>
<action android:name="PREVIOUS"/>
<action android:name="PAUSE"/>
<action android:name="NEXT"/>
</intent-filter>
</receiver>
When I run my music play, notification does come up with buttons but they don't seem to fire the onReceive function?
What am I missing here?
Update:
Followed hasif sayed answer and I seem to found an error
java.lang.RuntimeException: Unable to instantiate receiver com.example.tilak.imusicplay.MusicService$NotificationReciev‌​er: java.lang.InstantiationException:java.lang.Class has no zero argument constructor
Googling about it, I found that I have to use a static class or I have to register/unregister in the parent class.
So this is what I did:
public void onCreate() {
super.onCreate();
//
LocalBroadcastManager.getInstance(this).registerReceiver(
new NotificationReciever(),new IntentFilter("PREVIOUS"));
LocalBroadcastManager.getInstance(this).registerReceiver(
new NotificationReciever(),new IntentFilter("PAUSE"));
LocalBroadcastManager.getInstance(this).registerReceiver(
new NotificationReciever(),new IntentFilter("NEXT"));
}
PendingIntent prevPendingIntent=PendingIntent.getBroadcast
(this,1,new Intent().setAction("PREVIOUS"),PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent pausePendingIntent=PendingIntent.getBroadcast
(this,2,new Intent().setAction("PAUSE"),PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent nextPendingIntent=PendingIntent.getBroadcast
(this,3,new Intent().setAction("NEXT"),PendingIntent.FLAG_UPDATE_CURRENT);
Now I don't get this above error but onReceive is not working again.
Actually the reason why your broadcast reciever is not called when you click on pause,previous and next button is because ,you have set the pending intent to fire an acitivity,instead you have to set the pending intent to fire a boradcast
instead of this code snippet
PendingIntent nextPendingIntent=PendingIntent.getActivity
(this,3,new Intent().setAction("NEXT"),PendingIntent.FLAG_UPDATE_CURRENT);;
you have to correct it like this
PendingIntent nextPendingIntent=PendingIntent.getBroadcast
(this,3,new Intent().setAction("NEXT"),PendingIntent.FLAG_UPDATE_CURRENT);;
make corrections in all the three pending intent code which you have written
UPDATE
The reason why you still not receiving the broadcast in your Broadcast Receiver is because you are programitically registering your Receiver as LocalBroadCast
When using with PendingIntent, LocalBroadcast will not receive the Broadcast
so please remove this Line
LocalBroadcastManager.getInstance(this).registerReceiver(
new NotificationReciever(),new IntentFilter("PREVIOUS"));
LocalBroadcastManager.getInstance(this).registerReceiver(
new NotificationReciever(),new IntentFilter("PAUSE"));
LocalBroadcastManager.getInstance(this).registerReceiver(
new NotificationReciever(),new IntentFilter("NEXT"));
Instead, you only have to register the receiver in the Manifest.xml file
or
programitically you can register in code as
NotificationReciever mReciever = new NotificationReciever();
this.registerReceiver(
mReciever,new IntentFilter("PREVIOUS"));
this.registerReceiver(
mReciever,new IntentFilter("PAUSE"));
this.registerReceiver(
mReciever,new IntentFilter("NEXT"));
but if you register this programitically, make sure you unregister it while service is getting destroyed. Otherwise you may LEAK the BroadcastReceiver Object
I have two notification actions, one to stop the service and one to restart it.
I am successfully starting the service but I can't stop it with this code:
PendingIntent show = PendingIntent.getService(this, 1, svc, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent hide = PendingIntent.getService(this, 1, svc, PendingIntent.FLAG_CANCEL_CURRENT);
Any ideas?
Not a duplicate as my question is specifically about notification actions, not buttons (I have no problems getting my buttons to stop and start the service).
That flag alone will not stop the service. I would recommend that you make the stop action instead fire a custom BroadcastReceiver class which runs the stopService() method inside of its onReceive(). Let me know if you need help setting something like that up in more detail.
Edited answer:
Change your Intent and PendingIntent for the hide action to this:
Intent intentHide = new Intent(this, StopServiceReceiver.class);
PendingIntent hide = PendingIntent.getBroadcast(this, (int) System.currentTimeMillis(), intentHide, PendingIntent.FLAG_CANCEL_CURRENT);
Then make the StopServiceReceiver like this, where ServiceYouWantStopped.class is the service to be stopped:
public class StopServiceReceiver extends BroadcastReceiver {
public static final int REQUEST_CODE = 333;
#Override
public void onReceive(Context context, Intent intent) {
Intent service = new Intent(context, ServiceYouWantStopped.class);
context.stopService(service);
}
}
Make sure the BroadcastReceiver you just made is declared in your manifest file:
<receiver
android:name=".StopServiceReceiver"
android:enabled="true"
android:process=":remote" />
Hope this helps!
I want to send a heartbeat from my application to the GCM server, so the connection will stay alive.
How can I do that, and how can I know the URL of my GCM server??
Thanks in advance!!
How to send the heartbeat
This class can sent the proper intents
public class GcmKeepAlive {
protected CountDownTimer timer;
protected Context mContext;
protected Intent gTalkHeartBeatIntent;
protected Intent mcsHeartBeatIntent;
public GcmKeepAlive(Context context) {
mContext = context;
gTalkHeartBeatIntent = new Intent(
"com.google.android.intent.action.GTALK_HEARTBEAT");
mcsHeartBeatIntent = new Intent(
"com.google.android.intent.action.MCS_HEARTBEAT");
}
public void broadcastIntents() {
System.out.println("sending heart beat to keep gcm alive");
mContext.sendBroadcast(gTalkHeartBeatIntent);
mContext.sendBroadcast(mcsHeartBeatIntent);
}
}
if you just want to send the heartbeat you can do the following in an Activity
GcmKeepAlive gcmKeepAlive = new GcmKeepAlive(this);
gcmKeepAlive.broadcastIntents();
I don't think you need to set any additional permissions for this but here are the gcm related permissions I have in my manifest
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission
android:name=your_package_name.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="your_package_name.permission.C2D_MESSAGE" />
One way to send the heartbeats on a regular basis
If you want to send them on a regular basis, here is how I am doing that:
public class GcmKeepAliveBroadcastReceiver extends BroadcastReceiver {
private GcmKeepAlive gcmKeepAlive;
#Override
public void onReceive(Context context, Intent intent) {
System.out.println("inside gcm keep alive receiver");
gcmKeepAlive = new GcmKeepAlive(context);
gcmKeepAlive.broadcastIntents();
}
}
I also have a service that has an Dagger injected alarmmanger and pendingintent
#Inject AlarmManager alarmManager;
#Inject PendingIntent gcmKeepAlivePendingIntent;
alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, 1000, 4*60*1000, gcmKeepAlivePendingIntent);
Here is the section of the Dagger module that provides the alarm manager and pending intent.
There are several ways to have an alarm manager periodically call a method, so assuming you don't use Dagger, you should still be able to pull out the relevant parts. Your question was how to send the heartbeat, not how to use an alarm manager. There are lots of answers to that already so search on that.
#Provides PendingIntent provideGcmKeepAlivePendingIntent() {
System.out.println("pending intent provider");
Intent gcmKeepAliveIntent = new Intent("com.gmail.npnster.first_project.gcmKeepAlive");
return PendingIntent.getBroadcast(mContext, 0, gcmKeepAliveIntent, PendingIntent.FLAG_CANCEL_CURRENT);
}
#Provides AlarmManager provideGcmKeepAliveAlarmManager() {
return (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
}