I have a widget in my app and it gets screwed up (one of it's resources, a counter, has to be visible only if greater than 0 and it does not react anymore to a press) every time I install/remove/update a 3rd party app because the onUpdate() method probably gets called and the code I have written is not executed properly.
It is certain that the AppWidgetManager reacts to the following intents:
android.intent.action.PACKAGE_ADDED
android.intent.action.PACKAGE_REMOVED
android.intent.action.PACKAGE_RESTARTED
But how can I make the widget not react to such intents, it is not even registered for them in the manifest?
try adding those actions to the manifest .. and avoid reacting to them in the onReceive method, it's somehow trivial solution but it will do !
Have you tried overriding the onReceive method and check for the intent? I have provided a quick example.
if(intent.getAction().compareTo("android.intent.action.PACKAGE_ADDED") != 0) {
//do something cool;
}
This should allow you to check the incoming intent and filter out what you don't want
Related
I want to start service if screen is on.I think I have to use Intent.ACTION_SCREEN_ON. But I'm not sure where should I declare it in AndroidManifest or through RegisterReceiver method? As I understood if I will declare this action in the AndroidManifest my service will be started even if user hasn't reached specific point in my app cause action was committed. So if want to start service after user has reached that specific point and also screen is on I should use RegisterReceiver method, right?
But I'm not sure where should I declare it in AndroidManifest or through RegisterReceiver method?
ACTION_SCREEN_ON only works via registerReceiver().
How can I call a method while my application is closed on Android?
I've tried:
Onpause(), OnDestroy(), and OnStop(). With no luck.
What I want is receiving something from the database and do my reaction
based upon when the application is closed.
I think you can use broadcast or service to do it.
You could create a base activity (BaseActivity class) from which all your activities would have to be derived. Then inside BaseActivity.onCreate - you would increase some SharedPreferences counter, and inside BaseActivity.onDestroy you would decrease it. Now when that counter is equal to zero, you might assume your application is closed - but the process might still run in the background.
What I want is receiving something from the database
now I assume you already know how to "receive something from database". This could be background Service, where you could check SharedPreferences and do your processing.
What is the trigger?
Part 1 : Intent -
By example, you can set an alarm, that launch an Intent.
Part 2 : Broadcast Receiver - You must create a Broadcast Receiver (which reacts to an intent).
Part 3 : Service - The Broadcast Intent will launch a service that will execute when the application is not open.
How can I tell from my Application whether it was started/resumed from my BroadcastReceiver or not?
I intercept outgoing calls (android.intent.action.NEW_OUTGOING_CALL). If getString(Intent.EXTRA_PHONE_NUMBER) is one of a set of numbers, I abort that call (setResultData(null)) and instead startActivity my app, putExtraing the particular number. If (and only if) coming from the BroadcastReceiver, I want to be able to put up an alert that's basically "use this app with this number/return to call". However, sometimes when I return to the app from elsewhere, the number still seems to be in the extras of the intent, even though I haven't come from the BroadcastReceiver. I tried checking for the FLAG_ACTIVITY_NEW_TASK flag, but it shows up sometimes when not coming from the BroadcastReceiver.
As you said: you can pass any parameters to your activity, indicating that it was called from your BroadcastReceiver. However, when resuming to your activity some code might be executed again - potentially causing unwanted outcomes. When I had once a similar issue I stored/overwrote some information in the intent, e.g.
myActivity.getIntent().putExtra("phoneNumber", "nil");
What worked for me was, that I overwrote the extra in the intent after it has been processed while finishing an ActionMode (let's say with "nil"). So later I was able to evaluate that information in onResume(), e.g.:
#Override
public void onResume() {
super.onResume();
String phoneNumber = getIntent().getExtras().getString("phoneNumber")
if ("nil".equals(PhoneNumber)) {
...
}
}
Just did a small test and it works pretty well.
Hope this helps ... Cheers!
In general i have a service that sends an intent to my activity which is ALWAYS on every 6 sec and a BroadcastReceiver everytime on receive updates a timer.
I found by accident that after a while ( this is random ) that the particular receiver stops working.
OnPause i unregister it and onResume i register it again.
Also this happens randomly in any devices and android versions.
I found by researching on the web , that after onReceive the receiver is ready to killed by Android but mine keeps getting intents.
"Receiver Lifecycle
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.
"
FYI i have declare it like this inside my activity
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context arg0, Intent intent) {
Log.i("Intent received", "+_ " + intent.getAction());
if (intent.getAction().equals(TEST)) {
//do sth
} else {
//do sth else
}
}
}
Thans a lot even for taking the time to read :).
I dont declare anythin to my manifest and as for my logcat i must be over my phone the moment it happens. The service is a simple send broadcast after one async task. The last test i made was ensuring that the code from the service was running by logging the beeing sent. And the service kept on.
I am away from my code write now but i think there will be no help because is very simple. Thnaks
Well i could still figure out but I find a solution to my problem
Timer now is in the activity and receiver is sending the event but after 10000 tries i want to trigger the END EVENT. Now the receiver since he didn't work i couldn't get it but now i Start an intent with extras for the same activity always with flags new_task and clear_top.
No matter if my receiver is working or not, since the service is ok i will start the specific Activity and pseudo-show the END EVENT.
PS:: This behavior isn't always trigger but sometimes. So now i am ok.
If i am not understood please comment and ask anything. Thanks
What I want to achieve is to give user a button saying 'Start broadcast receiving' and another one saying 'Stop broadcast receiving'.
I'm registering BroadcastReceiver for "android.provider.Telephony.SMS_RECEIVED" intent ('Start broadcast receiving' functionality):
incomingSmsReceiver = new IncomingSmsReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("android.provider.Telephony.SMS_RECEIVED");
getApplicationContext().registerReceiver(incomingSmsReceiver, filter);
Then I'm using unregisterReceiver() for 'Stop broadcast receiving':
getApplicationContext().unregisterReceiver(incomingSmsReceiver);
As you can see it's using the same reference (private static BroadcastReceiver incomingSmsReceiver;).
The problem is:
This works fine as long as my app's process is not terminated. When user click 'Start receiving broadcast' and after that my app is been killed by Android I'm loosing incomingSmsReceiver reference (when I run my app next time it's set to null by default). There's no way for user to stop receiving broadcast as the reference is lost.
How to persist this reference? And how to make it possible to call getApplicationContext().unregisterReceiver(incomingSmsReceiver); after recreating app's process by Android?
I've found better solution for such problem: Enable and disable a Broadcast Receiver (CommonsWare's answer).
The solution is to register BroadcastReceiver in AndroidManifest file. Then to use PackageManager.setComponentEnabledSetting(...) to enable / disable this component.
AFAIK, you don't need to hold on to the exact same BroadcastReciever reference. Create a new reference in the exact same way in which you would create one normally and pass it to unregisterService.