Mobilock app starts before BOOT_COMPLETED broadcast... How is it possible? - android

There is a kiosk app called Mobilock. This app starts way faster (Almost 5 seconds before) than my own app which starts with BOOT_COMPLETED broadcast.
My own app has the highest priority which is max value of integer. So this is not about the priority.
These guys have found a way to start their application 5 second sooner than BOOT_COMPLETED broadcast.
Has anyone got an idea about what they are doing?

Oh my god! I've luckily found it. :)
This Page Says : Apps must register their components with the system before they can run during Direct Boot mode or access device encrypted storage. Apps register with the system by marking components as encryption aware. To mark your component as encryption aware, set the android:directBootAware attribute to true in your manifest.
Encryption aware components can register to receive a ACTION_LOCKED_BOOT_COMPLETED broadcast message from the system when the device has been restarted. At this point device encrypted storage is available, and your component can execute tasks that need to be run during Direct Boot mode, such as triggering a scheduled alarm.
You just need to put
android:directBootAware="true"
So the code in manifest is;
<receiver
android:directBootAware="true" >
...
<intent-filter>
<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
</intent-filter>
</receiver>

Listen also to android.intent.action.QUICKBOOT_POWERON and android.intent.action.LOCKED_BOOT_COMPLETED.
It seems to be device-dependant, which broadcast is sent first.

Related

How reliable are Broadcast Receivers across different brand phones?

I have manifest declared Broadcasts for android.intent.action.PHONE_STATE and android.intent.action.NEW_OUTGOING_CALL. I tested my app after I removed it from Recent apps screen. I tested it on two phones:
MOTO G4 Play(Nougat)- After I removed my app from Recent apps screen on this phone I was receiving broadcasts.
ASUS(Lollipop)- After I removed my app from Recent apps screen on this phone I was not receiving broadcasts.
One way after reading such questions on SO I got is that I can do it by starting a sticky service so what it will do is not terminate my process and I will continue to get broadcasts.
What should I do to ensure that I receive broadcasts on every phone without using a service ?
Edit-1:I register my broadcasts as follows in Manifest
`
<receiver android:name=".PhonecallReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE"
android:enabled="true"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL"
android:enabled="true"/>
</intent-filter>
</receiver>
`
#Override
public void onReceive(Context context, Intent intent) {
Log.e("onReceive ","Called"); //This is how I check whether broadcast was called or not
//... other code
}
Think of notification broad cast that can be used to generate notification for your app, so broadcast is pretty reliable.
You are using manifest declared broad cast so theoretically, you should be able to receive broadcast regardless of whether your app is in foreground or background ( similar behavior was expected in all phone since your app targets same API). But there has been cases where mobile devices has ignored/bug some of the contract as a result some expected behavior breaks. It is very likely that similar thing happened in your ASUS based test.
From the broadcast manager documentation ,
If you declare a broadcast receiver in your manifest, the system
launches your app (if the app is not already running) when the
broadcast is sent.
However there is exception .Android has some updates on this behavior recently to restrict some of this features.
Note: If your app targets API level 26 or higher, you cannot use the manifest to declare a receiver for implicit broadcasts (broadcasts that do not target your app specifically), except for a few implicit broadcasts that are exempted from that restriction. In most cases, you can use scheduled jobs instead.
So what I believe is you should be receiving all broadcasts as long as you target API level less than 26 regardless of your app being active or not. Moving forward to API 26 or greater, you will receive broadcast regardless only if it is explicit OR exempted broadcast as per above quote.
What you encountered is probably that device specific issue which was not supposed to happen. Try testing in few more devices to rule this out.
You may want to read this for more clarification.
p.s. try not using error logging for info/debug like Log.e("onReceive ","Called");

Weird BOOT_COMPLETED behavior

I was expecting my app to load the BroadcastReceiver AutoStartOnBoot when I reboot my device.
I uninstall and install the app. Which means that all existing settings are deleted. I then power down the phone. And power it back up, the Broadcast receiver is never called.
I now, power down the device one more time and power it up again. Yet, broadcast receiver is not called.
I now launch the app once. Clear data. And power it down. I power it up. Now, the broadcast receiver is called.
Manifest
<receiver
android:name=".AutoStartOnBoot"
android:enabled="true"
android:exported="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
I have the permission setup
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
Edit:
From your First two Points
1.I uninstall and install the app. Which means that all existing settings are deleted. I then power down the phone. And power it back up, the Broadcast receiver is never called.
2.I now, power down the device one more time and power it up again. Yet, broadcast receiver is not called.
Why it is not working??
Here your just installed the app but not launched.In android after first launch only all your manifest data is registered and all receivers work.But in your third case its working because you are launched the app so here all receivers gets registered.
For more check here Broadcast Receiver not working immediately after package installation
You have to add this permission outside of the <application> tag in manifest file
instead of this
<android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
Add this like
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
The behavior that you describe is perfectly normal. Something needs to use an explicit Intent to start up one of your components before your manifest-registered receivers will work. Typically, that will be the user tapping on your home screen launcher icon.
See the Android 3.1 release notes for more about this.
All answers are correct. This behavior is as per expectation. The app is inactive when installed, until its manually launched by the owner. Only after that is the BOOT_COMPLETED broadcast receiver registered to the OS.
Unless we put the app in the system folder, which keeps all apps in active state. We are device company, adb push your.apk /system/app is possible for us.
Some interesting links, here and here

Android Broadcast receiver not executed on application close

I have an android application, where I schedule to an event (location update) to be executed in the future using Alarm manager. The scheduled event executes as expected as long as the application runs in the foreground or in the background. But once I force close the application under task manager or when android system kills the application due to memory issue when the app is at background, I am no longer able to receive the broadcast from the alarm manager.
As suggested by various posts and blogs i tried using
1) Intent.Flag_Include_Stopped_Packages
2) receiver android:process=":remote" in manifest
3) receiver android:exported="true" in manifest
In Service:
Intent locationIntent = new Intent("com.dummy.intent");
locationIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
locationIntent.putExtra(LocationLibraryConstants.LOCATION_BROADCAST_EXTRA_LOCATIONINFO, locationInfo);
context.sendBroadcast(locationIntent, "android.permission.ACCESS_FINE_LOCATION");
In Manifest:
<receiver android:name=".NearestStationBroadcastReceiver" android:enabled="true"
android:exported="true"
android:process=":remote">
<intent-filter>
<action android:name="com.dummy.intent" />
</intent-filter>
</receiver>
Can someone please help me out?
But once I force close the application under task manager or when android system kills the application due to memory issue when the app is at background, I am no longer able to receive the broadcast from the alarm manager.
These have nothing to do with each other, so if you have been simulating "when android system kills the application due to memory issue" by using Force Stop, that is your problem. An app that has been force-stopped through Settings has its alarms removed, among other things. A better way to simulate your process being terminated is to terminate it from DDMS.
1) Intent.Flag_Include_Stopped_Packages 2) receiver android:process=":remote" in manifest 3) receiver android:exported="true" in manifest
None of those are related to your problem, and android:exported="true" (and your use of an <intent-filter>) raises security issues, as now anyone can cause your BroadcastReceiver to be run at any time, for any reason.
Here is a sample application that successfully processes alarm events, even after the process has been terminated by DDMS.
You have to add your app in the Android Settings > Protected Apps section on the phone. This lets the user control which apps to allow running in the background.
You could also write a service to listen to the location broadcasts which will run in the background without problem if you get the necessary permissions.

Restarting an app via an external Broadcast Receiver

I have implemented an app that is basically a custom app store for updating and launching a family of related apps. It also needs to update itself, which works, but the app is killed without warning during the install process. I want to automatically restart the app in this case so that the user can continue to use it immediately after an update.
So I made a separate application including only a single Broadcast Receiver that listens for package events for the first app's package name and starts a new activity. That receiver is never called:
<application android:icon="#drawable/ic_launcher"
android:label="#string/app_name">
<receiver android:name=".AppUpdateReceiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REPLACED"/>
<action android:name="android.intent.action.PACKAGE_ADDED"/>
<action android:name="android.intent.action.PACKAGE_INSTALL"/>
<data android:scheme="package" />
</intent-filter>
</receiver>
In searching for similar implementations I have seen directly contradictory information on whether an application with only a receiver will ever execute, and whether a receiver will be called if its app is not already running. I've even come across example code of an application containing only a receiver, with a manifest very similar to my own. So what do I need in this application to ensure that the receiver is called whenever another package is installed?
If there is a better solution, I'd be happy to hear it.
Depending on the version of Android, you might need to start an application component in order for the BroadcastReceiver to be registered. By this I mean there will need to be a launcher Activity which must be started manually by the user.
From Honeycomb (I think) onwards it isn't possible to have application components 'active' unless the app has been manually started in some way. The reasoning behind this is the potential for insecure code executing without the end-users' knowledge.
I suspect this is what you're experiencing. To test it, add a simple "Hello World" Activity to the app that has the BroadcastReceiver in it. Launch the Activity and then check to see if the BroadcastReceiver then gets called after your other package is updated.

app isn't woken up on receiving gcm message broadcast

I've recently added GCM messaging to my app using google's helper classes (GCMBroadcastReceiver, GCMBaseIntentService). It works beautifully when the app is running, both when it's in the foreground and when it's not. However, when it's not running, nothing works.
As a test, I extended GCMBroadcastReceiver and added log statements to getGCMIntentServiceClassName() and peekService(). When the app is running and a message arrives I see the former called. The OS then instantiates my service class, which eventually results in onMessage() being called.
When the app isn't running getGCMIntentServiceClassName() never gets called.
My manifest is pretty much the boiler-plate code from Google's GCM examples.
Is there an extra permission or flag I need to set in order for the OS to wake up my app when it's not running and a message arrives w/ the correct intent category? My receiver is defined as:
<receiver
android:name=".GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="PACKAGENAME" />
</intent-filter>
</receiver>
Bear in mind: this works when the app is running in the background.
Bleh. Figured it out. David Wasser's answer here:
BroadcastReceiver isn't working
explains why I'm not seeing the broadcasts when my app isn't running. I was force quitting it from Manage Applications, which puts it into the "stopped" state (and thereby causes the system to exclude it from broadcasts by default).
When I install the app, launch it, power down the device, then power it on again, I'm receiving the broadcasts properly.
I had same issue and fixed by just running the through RUN button from Android Studio.
I think in Debug Mode it doesn't work

Categories

Resources