I want show Activity when device enter the fixed zone. I have startActivity in recivier(GpsAlarmRecivier). Code below works, but when I close Activity, it crash. I know it' s because i must unregister recivier.
But I want use addProximityAlart for all application, even after close my activity(for example, move to previous). Is it possible ?
Intent myIntent = new Intent("gpsup.namespace.ProximityAlert");
PendingIntent proximityIntent = PendingIntent.getBroadcast(cxt, 0, myIntent, 0);
locationManager.addProximityAlert(records.get(pos).x, records.get(pos).y, records.get(pos).r,
-1, proximityIntent);
IntentFilter filter = new IntentFilter("gpsup.namespace.ProximityAlert");
actv.getApplicationContext().registerReceiver(new GpsAlarmReceiver(), filter);
I want use addProximityAlert, even if I close activity, when i created recivier. Thanks for any advices.
I don't believe that there is a way to directly register a system GPSBroadcastReceiver in your application. If that was the case you could just put it in your manifest and it'll get resolved when an update comes out and then you can fire off you custom intent after performing your checks.
I believe that is actually the reason why they don't allow it (I may be wrong). It would be problematic if every application was woken up when a GPS update came out. They would be spanking the battery in the background.
A suggestion that I can give is to create a Service that listens for your GPS updates and then Broadcasts your intents. While you can have it running in the background forever, it certainly has a longer life cycle than an Activity does.
Related
I am running into a weird situation where I previous has created a pending intent for activity recognition updates
PendingIntent pendingIntent = PendingIntent.getService(mContext, getIntentID(), intent,
PendingIntent.FLAG_UPDATE_CURRENT);
my getIntentID code is
private static int getIntentID(){
if(intentID == 0)
return intentID = (int)(System.currentTimeMillis());
return intentID;
}
I did this because I wanted to be sure the id was unique everytime I stop and start my service.
However now when I am in my intentService reading the activities that are being sent I am pretty sure it is not my most recent pendingintent calling making the request. I believe it is from a previous one. However I don't know how to cancel it since I don't know the id from the previous one.
1. Why don't I know the previous id? well when I cancelled the updates via the remove updates I did use my getIntentID which I thought was working correctly however when I stopped my app, started it again but didnt launch the update() code for the activity recognition, I noticed I was still getting activities, when I used the debugger.
Here is my update request
ActivityRecognition.ActivityRecognitionApi.requestActivityUpdates(getActivityRecognitionClient(),
Utility.DETECTION_INTERVAL_TIME, pendingIntent())
Here is my remove code
ActivityRecognition.ActivityRecognitionApi.removeActivityUpdates(getActivityRecognitionClient(),
pendingIntent())
So my question is, is there a way to cancel all calls period to the activity recog. even if I dont know the pendingintent info?
So my question is, is there a way to cancel all calls period to the
activity recog.
If you refer the API of ActivityRecognitionApi it contains only two methods
https://developers.google.com/android/reference/com/google/android/gms/location/ActivityRecognitionApi
one for requesting updates
requestActivityUpdates(GoogleApiClient client, long detectionIntervalMillis, PendingIntent callbackIntent)
and
second one to remove updates
removeActivityUpdates(GoogleApiClient client, PendingIntent callbackIntent)
both methods need PendingIntent.
So obviously answer is NO.
Hope this will helps you.
Okay there seems to be no way to cancel the pending intents to the activity recog. LIke Nag stated however what I ended up doing was changing the name of my intentservice class and using it instead and keeping track of the pending Id info. Now I don't have any request coming in from previous calls
I've got a somewhat graphically complex Android homescreen (via AppWidgetProvider) widget that I simply can't get to respond to touch events. The general idea is that tapping the widget should make it change modes for the next 4-5 seconds to display different information, but for the life of me it's showing no sign of ever receiving the Touch event.
The steps I've taken are as follows:
I've implemented an intent-filter within the Manifest.xml like so...
<action android:name="foo.kung.fancywidget.TOUCHED" />;
... and it's inside the <receiver /> container for the widget, right next to the expected APPWIDGET_UPDATE entry that Android Studio helpfully adds.
I've ensured that the Layout being used has the clickable attribute set to true on every single element (just to be thorough) including the top-level RelativeLayout itself.
I've defined the static string for the thing at the top of the ExtraFancyWidget.class, like so...
public static final String TOUCHED = "foo.kung.fancywidget.TOUCHED";
...and according to what I've been reading it should come through as the broadcast via the onRecieve handler when done like this...
if (TOUCHED.equals(intent.getAction())) {
Log.i("onReceive", "Touch event received");
}
...but with a Log.d entry at the top of the onReceive handler I can tell I'm not getting any sort of signals through there at all aside from the heartbeat coming from the system service every ten seconds.
Lastly, I'm assigning the intent just like I've been reading about
private PendingIntent createOnClickIntent(Context context) {
Intent intent = new Intent(context, ExtraFancyWidget.class);
intent.setAction(TOUCHED); // WHY DOESN'T THIS WORK?!?!?
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
...and it's literally the last thing happening in onUpdate before the view is updated
views.setOnClickPendingIntent(R.id.TheWholeWidget, createOnClickIntent(context));
appWidgetManager.updateAppWidget(appWidgetId, views);
What could I possibly be overlooking or not seeing at this point? I don't know of anything else I'm supposed to be doing or changing to make this work... it just mysteriously ignores the user. ADB never shows me any of the log entries (although it does show a number of other, silly log messages so I know that's working) that would indicate the widget ever sees me tapping it.
The problem is in step 5, where you're creating the intent. Do NOT set a specific class to the intent, rather create it with only an action, like this:
Intent intent = new Intent();
intent.setAction(TOUCHED); // this should work now
or the shorthand
Intent intent = new Intent(TOUCHED);
If it still doesn't work, consider putting a requestCode other than 0 when building the PendingIntent. Depending on the Android version you're building from, there were some bugs when using just 0.
return PendingIntent.getBroadcast(context, 1000, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Lastly, if this broadcast will be used only within your app (which is highly probable), consider using a LocalBroadcastManager.
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 have an app widget with a Button in it's layout.
When clicking the button, an intent is fired which calls my broadcast receiver.
It works just fine, but occasionally, after using the "Clear memory" button in the Task Manager, the widget gets stuck - clicking on it does nothing. But it can still receive updates from my app, if its running.
I'm not sure if the fact that the pending intent isn't fired is the memory clearing fault, or my fault.
Anyway, here's the code:
Registering the pending intent (onUpdate method of the app widget)
Intent intent = new Intent(context, ServiceControl.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget);
views.setOnClickPendingIntent(R.id.appwidgetbutton, pendingIntent);
and then updating the widgets with the views.
Here is the decleration of the app widget provider:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="72dp"
android:minHeight="72dp"
android:initialLayout="#layout/appwidget"
android:updatePeriodMillis="0">
</appwidget-provider>
I don't want the system to call widget updates, I only update it from my app itself.
So why does the pending intent stop firing?
Thanks in advance.
#Jong
#CommonsWare
Hi guys, I figured it out. Ofc this is an Android issue, the receiver should ALWAYS receive.
Now how to get around it? Obviously all the widgets are working, so there must have been a simple out there.
I read on SO somewhere (trying to find the guy) reminding us all that the widget class is actually extending a BroadcastReceiver.
So, you could register the widget (in the manifest) to receive the threats itself. Thus the entire system is self-contained in the class instance of AppWidgetProvider.
Now, for communicating back with the app, you can in the onReceive call any static class of your app, and LocalBroadcastManager won't fail you if the app is active. If it's not active, your buttons should be starting activities anyway!
Should you want the code, I can detail it.
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.