I'm developing a location based alarm which is an Android application.
All the coding part has been done.
But the alarm alert dialog is not displaying when the application is closed.
Please help me, I'm trying to pop up the alarm even when user is using another application or is in the home screen.
The code of my alarm at the moment is shown below:
final MediaPlayer mp = MediaPlayer.create(LocAlarmProject.this, R.raw.airtel);
mp.start();
// LocAlarmProject.this below is what's causing the problem:
final AlertDialog.Builder builder=new AlertDialog.Builder(LocAlarmProject.this);
builder.setTitle(disp_title);
builder.setMessage(disp_desc);
builder.setIcon(R.drawable.alarm);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mp.stop();
}
});
builder.show();
I am pretty sure you are looking for Service.
Copied and Paste:
A Service is an application component representing either an
application's desire to perform a longer-running operation while not
interacting with the user or to supply functionality for other
applications to use. Each service class must have a corresponding
declaration in its package's AndroidManifest.xml. Services
can be started with Context.startService() and Context.bindService().
Use Notification service to keep track of the status.....visit......http://developer.android.com/guide/topics/ui/notifiers/notifications.html
The proper way to do this requires a few steps. Sorry, it's not trivial if you haven't done it before:
First, you're going to use Android's built-in AlarmManager to schedule the time you want your app to be activated. You schedule a new alarm with the time to wake up and a PendingIntent.
Second, create your PendingIntent that's used to activate your app for the time to show the alarm.
Third, you can handle this Intent several ways, the most common is to create a class that extends BroadcastReceiver to receive the Intent. This class is notified when it's time to show the alarm. The Intent that you created and put inside your PendingIntent is passed to its onReceive() method. You pass this information to your app to display the alert dialog. --- You can alternatively just register your main app to receive the Intent instead, then override the onNewIntent(Intent) method in your Activity.
Four, register your BroadcastReceiver in your AndroidManifest.xml file. This is also the place to register this receiver to listen for the Intent you created. You do this using the <intent-filter> tag.
Five, (optional) if you want your alarm to display even if the phone is asleep, and you want to make sure it doesn't go back to sleep before the user acknowledges the alarm, you'll need to obtain a WAKE_LOCK to do so.
The reason this is preferable to using a Service is it doesn't consume resources just to wait for the alarm, and also it still works if Android decides to kill your app free up memory. Good luck and happy coding!
Related
I was playing around with services and dialogs, and I got a doubt. Within a dialog, I am starting a service like this:
Intent lock = new Intent(getActivity(),AppLockService.class);
getActivity().stopService(lock);
getActivity().startService(lock);
Now the first time I call the dialog through
dialog_name.show(getFragmentManager(), "dropbox");
Upon pressing the OK button, the intent is launched. Now later, during the same app execution, the dialog is triggered again ( which is according to my code logic -- nothing wrong here). The code in the dialog then stops the previously triggered intent and starts the new intent.
My question is this:
lock is a local intent variable as per my definition. So how does it know that it has to stop that particular service I have triggered here the first time? Would someone please explain this to me?
You don't have to keep track of the service in a variable because Android does it for you.
The way that the OS treats a service is that it will not allow more than one instance of the service be to running at any time.
So at any moment there are 0 or 1 instances of your service. If there are 0, no problem, the OS will ignore the call to StopService. If there is 1 instance, it must be the instance you started previously - so it will be stop that one.
I'm using a running service to detect whether network is available or not. When it is not available, it calls an activity to start that displays a blank screen with "no network available" on it. When the network is back, it sends a broadcast to finish this activity.
The only problem is that this activity may start at any time (as a popup), even when using other apps. I want it to start (or be visible) only if the network is out and my app is in the foreground. Any help?
One option would be to have your foreground activity register for the broadcast, and then display the relevant notification from within the activity.
Alternatively you could start your service when your foreground activity starts/resumes (i.e, onResume), and stop it when your activity leaves the foreground.
You can use START_STICKY in your service to ensure it stays around until you stop it, like so:
#Override
public int onStartCommand(Intent intent, int flags, int startId){
//On start work here
return START_STICKY;
}
and then stop the service using stopService when your activity leaves the foreground (i.e onPause).
If you need the former behaviour across multiple activities you can register broadcast receivers programmatically:
BroadcastReceiver myBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if(MY_ACTION.equals(intent.getAction()))
{
//show appropriate dialog
}
}
};
IntentFilter myIntentFilter = new IntentFilter();
myIntentFilter.addAction(MY_ACTION);
registerReceiver(myBroadcastReceiver,myIntentFilter);
You can unregister like so:
unregisterReceiver(myBroadcastReceiver);
You could extend Activity and make your own custom subclass that reuses similar code to register and unregister whilst entering/leaving the foreground. Or you can extract this into utility methods/classes and call from the appropriate places.
I think you need Shared Preference to do this. store one Boolean value on finish you activity (you can use onpause() or onStop()) and for showing popup check the value and do what you want
for understnding to use sharePreference see this and developer.android.com
Try the following:
Intent intent = new Intent(this, YourActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplicationContext().startActivity(intent);
This worked in the context of my own app already running, I'm not sure if it will start your app if it is not already running in the background
EDIT: Not sure if I understand your question entirely. If you only want this activity to come to the foreground while your app is in the foreground, get rid of the addFlags line, also you can do some boolean stuff to check if your app is in the foreground like so, this way your code won't even run if the app isn't in the foreground.
EDIT: There are a few ways to check if your app is in the foreground, the link I posted above has one such solution, another one is to create a static boolean isForeground variable: in the onResume() methods of your app set isForeground = true and in onPuase() set isForeground = false. This isn't the best practice, using ActivityManager is better, but for purposes of testing this should be ok.
Then have something like the following:
if(isForeground){
//Start your activity
}
This should be quick to write, if this is the behavior you want, I would recommend replacing the isForeground static variable with the test for foreground provided by ActivityManager in the link I posted.
So, I seem to have fallen down a rabbit hole trying to figure out the best way to notify a user of an alarm going off.
Basically, I want some kind of notification/dialog to come up at a certain time, and it should come up no matter what the user is doing, and block further use until acted upon (dismissed or otherwise).
Right now, I have an AlarmManager, and the BroadcastReceiver that is registered with it starts a new service.
Every time I thought I was heading in the right direction, I hit a problem where someone online had a similar issue, and was told "don't do it that way." (Having a service create/show an AlertDialog, for instance.)
I was hoping someone could give me a brief list of what their recommendation would be; I don't need code (at least I shouldn't), just some high level abstraction.
Go with Notification, which plays a sound perhaps, that would pull your user's attention to your notification, just like the default alarm does.
And make the notification an ongoing one. Which can't be removed by the user, until and unless some action is performed to change the state of the notification.
Android: How to create an "Ongoing" notification?
Dialogs for this situation would be annoying for me. The docs also suggest not to use them in these scenarios.
Have a look at this Sample Open Source Project
I did it in this way and it work fine for me.
Create a class and Call it something like ScheduledService it extends IntentService, in this class you'll do what you want to do when alarm goes off.
public class ScheduledService extends IntentService {
public ScheduledService() {
super("My service");
}
#Override
protected void onHandleIntent(Intent intent) {
//Do something, fire a notification or whatever you want to do here
Log.d("debug", "Ring Rind !");
}
}
then in you activity to start the alarm use the following:
AlarmManager mgr = (AlarmManager) YourActivity.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(YourActivity, ScheduledService.class);
PendingIntent pi = PendingIntent.getService(YourActivity, 0, i, 0);
mgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + PERIOD, pi);
Which PERIOD is after how much milliseconds you want the alarm to goes off.
To cancel stop the timer and cancel the alarm use:
if (mgr != null)
mgr.cancel(pi);
Finally for all this to work you need to register your ScheduledService class as a Service.
In your manifest add this tou your application:
<application
... />
...
<service android:name=".ScheduledService" >
</service>
</application>
This way the Android OS will take care of firing the alarm when it's time. even if other application is running or even if your app process is terminated.
Hope this help.
Regards.
Just a crazy idea: Create an activity and set it's theme to be fullscreen with no title bar and a button to stop the alarm maybe, instead of doing a notification just make an intent that starts that activity "maybe you will need This" to work even when phone is locked and play some annoying sounds, "This" may help, when the activity starts. you can also override the onBackPressed() to do nothing.
I'm currently writing an app, what has an on-boot service. This service simply pops up a notification after a time, and update it in given periods with new info. Currently there's no need for any further battery saving, I just want the update sequence to work.
I've hit a problem tho. Created the boot BroadcastReceiver what then starts my Service. It it, I do the work via a Timer and a TimerTask. But as I saw, there's no easy way to check if the notification was deleted, and thus not try to update it, but re-create it.
What I want to do:
private Notification n;
NotifTask extends TimerTask {
public void run() {
if(n.exists){
// Update notification
}else{
n = Notification.Builder(context).[customize it].build();
}
}
}
And in the service's onStart, set up a timer what runs this task every 10 seconds.
Now, my question is: is there any way to do the "n.exists" part easily, without intents?
If you post a notification and this notification already exists, it will just get updated with the new information. If it doesn't exist it will be created. I don't think you need to do anything special to get the behaviour you want.
From the documentation for NotificationManager.notifiy():
Post a notification to be shown in the status bar. If a notification
with the same id has already been posted by your application and has
not yet been canceled, it will be replaced by the updated information.
Im trying to make an scheduled activity go off every hour or so, all working in the background.
Right now i have a BroadcastReceiver that picks up when the device is booted.
The BroadcastReceiver creates a PendingIntent to an activity (Called AlarmController) that creates has all necessary methods that i need for making the scheduled activity to go off.
How ever, this doesnt seem to work.
This is how my BroadcastReciever class onReceive{} looks like and is indentical to my main activity onCreate{}(Only for testing)
Intent intent = new Intent(serviceactivirt.this, AlarmController.class);
PendingIntent sender = PendingIntent.getActivity(serviceactivirt.this, 0, intent, 0);
try {
sender.send();
} catch (CanceledException e) {
Toast.makeText(getApplicationContext(), "FEJLSAN", Toast.LENGTH_LONG).show();
}
This actually works, except that my app crashes at launch, but the scheduled activity is working...
Any ideas? Is this "The way to do it" or is there a more recommended way?
Cheers!
Solution:
Instead of having a BroadcastReciever calling an Activity, i made the BroadcastReciever starting a Service. And changed my Activity to a Service, programmaticly and in manifest.
Works great!
Im trying to make an scheduled activity go off every hour or so, all working in the background.
Please allow users to configure other options, such as using a Notification, rather than being interrupted by an activity taking over the foreground.
Right now i have a BroadcastReceiver that picks up when the device is booted.
You would only need that to set up an AlarmManager schedule for your hourly events. Your PendingIntent for the AlarmManager could be one you obtain via getActivity().
How ever, this doesnt seem to work.
If you want to start an activity, call startActivity(). Do not create a PendingIntent, then immediately send() the PendingIntent.
Also, get rid of getApplicationContext() and simply use this.
except that my app crashes at launch
Use adb logcat, DDMS, or the DDMS perspective in Eclipse to examine LogCat and look at the stack trace associated with your crash.