Open a PopUpWindow from an AppWidget - android

As it doesn't appear to be possible to put an EditText in an AppWidget, I would like to open a PopUpWindow with an EditText when I click on it.
I know how to open an Activity from an AppWidget and I also know how open a PopUpWindow from an Activity. I don't, however, know how to open a PopUpWindow from an AppWidget. I've looked into many classes in the javadoc (Intent, RemoteViews, PendingIntent, etc.), but I can't find how to start this PopUpWindow. Any help would be appreciated.

You know that AppWidgetProvider is a BroadcastReceiver.Android Doc says:
A BroadcastReceiver object is only valid for the duration of the call
to onReceive(Context, Intent). Once your code returns from this
function, the system considers the object to be finished and no longer
active.
This has important repercussions to what you can do in an
onReceive(Context, Intent) implementation: anything that requires
asynchronous operation is not available, because you will need to
return from the function to handle the asynchronous operation, but at
that point the BroadcastReceiver is no longer active and thus the
system is free to kill its process before the asynchronous operation
completes.
In particular, you may not show a dialog or bind to a service from
within a BroadcastReceiver. For the former, you should instead use the
NotificationManager API. For the latter, you can use
Context.startService() to send a command to the service.
It seems you have three ways:
Use a service to show popup(see How to display alert diaolog(popup) from backgroung running service?)
Use notification manager(see AlarmManager never calling onRecieve in AlarmReceiver/BroadcastReceiver).
Create an activity whit dialog theme(so it looks like a popup) and display it when user click your AppWidget.

You could have the appWidget open an activity which then shows a dialog fragment, or make the activity look like a dialog using a dialog style.

Related

Call Activity's method on notification

I have an Activity with 2 buttons. A play and a pause button.
When this activity gets in the background, which means when the onStop() method has bean called, this creates a permanent notification that is only destroyed when the activity is resumed.
The notification does provide the play and pause buttons too. How do I call the activity's play() and pause() methods when the notification's buttons are clicked?
I really have no clue on how to address that issue.
I'm using a RemoteViews to construct a custom layout. And I know you can call
setOnClickPendingIntent() to bind an Intent to a view.
big thanks.
Instead of calling activity methods, you can use a service to initialize a media player instance and play or pause by passing intent extras. This way you would have more and easier control over the player.
I followed your advise by writting a Service that receives all input from The Notification. I then use the LocalBroadcastManager to send appropriate message to a BroadcastReceiver, which is responsible for updating the notification. The Activity also has a inner BroadcastReceiver. That way both receivers receive intent from the Service and can update their UIs independently.

How to pass context to BroadcastReceiver?

I need to pass activity context to onReceive of MyAlarmReceiver extends BroadcastReceiver class. For that, I pass the context while setting intent:
myAlarmManager.set(AlarmManager.RTC_WAKEUP, d.getTime(),
PendingIntent.getBroadcast(MainActivity.this, 1,
myIntentAlarm, PendingIntent.FLAG_ONE_SHOT));
However, context in onReceive is not the same as one passed in myAlarmManager. Why?
The Context provided to a BroadcastReceiver is not the same as what is used to create the BroadcastReceiver or anything you can modify. It is a limited variant of a Context and that is intentional by the framework. If you have anything significant to do in your BroadcastReceiver, you'll need to start your own Service or use some other mechanism to trigger it.
and there this context is used to create and show AlertDialog
Triggering a dialog based on an alarm is fairly dangerous to the user. You have no idea what the user is doing at that time, and the dialog may interfere with the user (e.g., you pop up a dialog over their real-time turn-by-turn navigation session). Please use a Notification, either all the time or based on a user preference.
Beyond that, you cannot rely on your original MainActivity instance to exist anymore at the time the alarm goes off. After all, it should be fairly obvious that if you schedule an alarm to occur a week from now, your original activity instance will have been long since destroyed.
You are welcome to post an event on an event bus (LocalBroadcastManager, greenrobot's EventBus, etc.). That way, if you do happen to have UI in the foreground, it can display the dialog. And, if you don't happen to have UI in the foreground, you can do something else (e.g., display a Notification). I have sample apps that show this for LocalBroadcastManager and for greenrobot's EventBus.

Launching dialog activity from services caused 'MainActivity' to also launch

I am designing an app that is used for emergency alerts. The alerts come from a server and a connection to that server is maintained in service.
If the service receives an emergency request from the server it checks to see if a specific activity is open. If it is it lets it know an emergency has been triggered and the activity launches a dialog activity with some options. It then handles results from this new dialog activity.
However, if the service notes that the activity is NOT open I want it to launch the dialog anyway. I know that this isn't good practise but because of the importance of this emergency I don't want to rely on Notifications (which are already in use if the activity is closed to let the user know that the app is still listening for emergencies).
What currently happens is that the below code is executed in the service and the dialog launches. However, the 'main' activity (the only other activity in the app) also opens behind the dialog. What I really want to happen is that either...
1) The service launches the main activity which then opens the dialog so that I can easily capture the results.
2) The service launches only the dialog activity and I use a broadcast receiver to capture results from this activity.
1 would use the mechanics that already exist for capturing results from an activity. However I don't like the idea of chaining the activities together in this way.
2 means I can ignore the main activity all together (because I don't really need it in this instance) but seems more of a get around.
What I am really asking is two things. What is best practise given my circumstances and how do i achieve number 2? Here is the launch code in my service. Notification in this code is referring to the dialog activity that will open.
if (MainActivity.isActivityInUI) {
//Dealt with by activity
sendMessageAlert(message);
} else {
//Launch dialog directly from service
Intent notification = new Intent(this,
EmergencyNotificationActivity.class);
Bundle args = new Bundle();
args.putString(MobileMessage.EXTRA_LOCATION_NAME,
message.locationName);
args.putString(MobileMessage.EXTRA_ID,
String.valueOf(message.id));
args.putDouble(MobileMessage.EXTRA_LATITUDE,
Double.valueOf(message.latitude));
args.putDouble(MobileMessage.EXTRA_LONGITUDE,
Double.valueOf(message.longitude));
//and the flag to let the notification know this is from a service...
args.putBoolean(EXTRA_FROM_SERVICE, true);
notification.putExtras(args);
//add flag because this is being called from outside of an activity
notification.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |ActivityInfo.LAUNCH_SINGLE_INSTANCE);
startActivity(notification);
I think instead of trying to show a dialog without visibly showing an Activity, you should consider launching an Activity that is themed like a Dialog. Just apply the following theme: http://developer.android.com/reference/android/R.style.html#Theme_Dialog (or similar themes) to your EmergencyNotificationActivity. You probably would have to tweak your class to behave like a dialog instead of launching one (which I am assuming is what you're doing currently).
This method would also allow you to not have to check if an Activity already exists.

how do I get a response/set callback from startService()

I've inherited a project and I don't understand how to either get a response, or set a callback from the following code:
startService(new Intent(this, VenueUpdateService.class));
At the moment the application continues even if the VenueUpdateService fails. I want to change it so that the application waits for a success/fail from VenueUpdateService.
I get a response within the VenueUpdateService class about success/fail. But how do I pass this back to the activity that started the service?
Thanks,
James.
What you're asking to do seems kind of strange to me. A Service will always succeed in being started if you call startService. It's not as if startService is some risky behavior that needs be wrapped in a try/call block.
But I suppose your Activity could register a BroadcastReceiver that receives a broadcast sent from the service in onStartCommand.
Or maybe you're looking to bind to the service, in which case you'll know when you're bound. see here
What I did was change the IntentService to an AsyncTask.
I basically wanted to stop the user interacting with the app while the VenueUpdateService did it's thing as it had to succeed at least once before the user could continue using the app.
So now I have:
VenueUpdateTask task = new VenueUpdateTask();
task.execute(response);
Within that class I show a progress dialog, do update venues.

Data exchange between a service and an activity

I have to publish the progress from a background service on the UI continuously on a progress bar. Any ideas on how to go about it. Intents won't work I guess coz they can only send the data once the activity is started. Ant other suggestions?
Update : The progress on the UI happens on a progress Bar
Extend Application, which is created once for entire application.
When Activity starts, store its reference to a field in your Application object. (Note that you can access Application using Activity.getApplication). Set this field to Activity reference or null in onPause/onResume calls.
Then in Service, you have also access to your Application by Service.getApplication. So look if your Activity reference is non-null, meaning that your Activity is shown to user, and update UI as needed in such case, by calling methods on your Activity.
Thanks for the help mice, but since I needed to update progress bars on different activities in my app depending on which one was visible, I found it easier to implement through Broadcast Intents and Recievers and Intent Filters. All I had to do was to Broadcast the progress in my service wrapped up in a bundle via a broadcast Intent (with a custom Intent Filter applied) and register (in onResume()) an inner subclass of BroadcastReciever in the activities which needed the progress (having the same intent filter). One can also unregister these recievers in the onPause() method of the activity to save memory headspace.

Categories

Resources