How chat apps (e. g. Messenger) listen to incoming messages even if their activity haven't been started yet since in android 3.1 and later this is not possible:
Manifest:
<service android:name=".ManagerService" android:enabled="true" />
<receiver
android:name=".BootFinishedReceiver"
android:directBootAware="true"
android:enabled="true"
android:exported="false"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
Receiver:
public class BootFinishedReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent serviceIntent = new Intent(context, ManagerService.class);
context.startService(serviceIntent);
}
}
There have to be some way around as chat apps are still working this way.
Thanks for any informations or ideas
Your question is quite open-ended and broad. But to the link that you have pointed about the broadcast receiver when the app is not running.
There is a comment on the same answer that says:
Applications are in a stopped state when they are first installed but are not yet launched and when they are manually stopped by the user (in Manage Applications). That means, the user should launch the app at least once after installation to activate the application, then the app can receive all implicit broadcast from OS as normal.
The app is stopped when it is just installed. As soon as you launch the app for the first time, The application can listen to broadcast receivers and can run background services even when the app is closed.
The chat applications basically implement socket.io that keeps up the communication on both ends. Furthermore, you may implement FCM to get notifications and messages even when the app is killed.
I hope you, understand the concept :).
I have a custom receiver that handles INSTALL_REFERRER intents when the application is installed. It was called once or twice during testing but now doesn't get called at all. I am using an emulator for testing and have gone through the instructions in this test documentation to broadcast an install intent to the emulator. I have also made sure that I hooked up my Android SDK ADB to the emulator, so it should be receiving the broadcasts. In the terminal, it says that my broadcast succeeded, however when I launch the app from the a fresh install the onReceive is never called.
Here the skeleton of my Receiver:
public class CustomReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
//do stuff
//log stuff
}
}
And here is my manifest:
<receiver
android:name="path.to.CustomReceiver"
android:exported="true">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER"/>
</intent-filter>
</receiver>
I've tried starting with a new emulator to make sure it wasn't blacklisting the calls, and looked through all the documentation and posts about this that I could find, but nothing seems to work. I appreciate any help.
The docs you refer to are from 2013. More recent docs suggest using an InstallReferrerReceiver, which is specifically designed to handle that intent:
The Google Play com.android.vending.INSTALL_REFERRER Intent is broadcast when an app is installed from the Google Play Store. [InstallReferrerReceiver] listens for that Intent, passing the install referrer data to GTM for Mobile Apps and Google Analytics.
I am making a system app. In that I have a requirement is to run a service after boot load WITHOUT A SINGLE TIME LUNCHING THE APP.
this question is bit similar to this
System App auto starting
But it does not have any appropriate solution.
Also read that BOOT_COMPLETE_RECEIVER works only when app launched at once.
Use Broadcast Receiver for getting action after that start service from that broad cast receiver and use START_STICKY service so that if it is killed because of some priority than it's recreate and if you want to continuously run this service in background than WAKE_Lock that service and using Alarm Manager check it is runnig or not.
Set this in manifest
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<receiver
android:name="AutoStart"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
AutoStart class
public class AutoStart extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equalsIgnoreCase(Intent.ACTION_BOOT_COMPLETED)) {
// Start your service here..
}
}
}
Thanks all for your effort, I finally got answer.
Solution:
As I stated my app is system app, System work even they not opened at once. Because they are not in stopped state i.e enforce after android 3.1.
Secondly If a user app wants this then Its manifest don't have any "android.intent.category.LAUNCHER" category in activity.
Also by adb you can enable your app by using this command
adb shell am broadcast -a com.example.demo.action.LAUNCH --include-stopped-packages (This is not tested)
Some good link to this:
http://droidyue.com/blog/2014/01/04/package-stop-state-since-android-3-dot-1/
Static BroadcastReceiver not Working after Installation from ADB
I am working on app which needs to executes a web-service at app install and only once.
Currently i used Shared Preferences for this, But if user clear app data then it lost Shared Preferences value and my code detracts that app is newly created and my code executes web-service further.
So i need solution which broadcast event of my own app install.
I also create broadcast for that but broadcasts only when other app install.
This code i used...
For Check Status
private void checkAppStatus() {
boolean isOpen = AppMethod.getBooleanPreference(MainActivity.this, AppConstant.PREF_IS_OPEN);
if (!isOpen) {
executeWS();
}
}
Broadcast
public class AppInfoReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.e("My App", "Install");
}
}
Manifest
<receiver android:name=".receiver.AppInfoReceiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_INSTALL" />
<action android:name="android.intent.action.PACKAGE_ADDED" />
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<data android:scheme="package" />
</intent-filter>
</receiver>
If you have a server, you can save status in your server and get the status before execute task
You have following options:
You can create a file in hidden directory on external memory with
needed information.
You can create and use your web service for those needs.
Your code doesn't work because your application not installed at that time when broadcast created and because in android your application can receive broadcasts only if it was launched at least one time by user.
As I understood, first option doesn't fit your needs too, cause there is some probability that external memory would be erased or replaced. Android devices doesn't provide any kind of memory that 100% would be persistent in time, and if you really need information about installation of your application you should run your server that receives android device id and sends back to your application information about rather it is first installation or re installation. However I suppose that you should assume clearing app data as application reinstall and run your web service one more time. Simplest solution: just pass to your service android device id and do your things if it is new id or not if it is already done.
I've looked around here for similiar problems, but for some reason my BroadcastReceiver never ends up receiving the android.intent.action.BOOT_COMPLETED Intent.
Here is my (relative) Android.Manifest File:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses-permission>
<receiver android:name=".BootReceiver"
android:enabled="true"
android:exported="true"
android:label="BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"></action>
</intent-filter>
</receiver>
And Here is the actual Receiver.
public class BootReceiver extends BroadcastReceiver {
private static final String TAG="BootReceiver";
#Override public void onReceive(Context context,Intent intent){
try{
context.startService(new Intent(context,ConnectivityListener.class));
Log.i(TAG,"Starting Service ConnectivityListener");
}catch(Exception e){
Log.e(TAG,e.toString());
}
}
}
Thanks! Any help is greatly appreciated
You can emulate all broadcast actions by connecting via adb to the device and open a device shell.
Here we go:
open console/terminal and navigating to /platform-tools
type adb shell or on linux/mac ./adb shell
in the shell type am broadcast -a android.intent.action.BOOT_COMPLETED or whatever action you want to fire
There are a bunch of nice commands coming with adb or the adb shell. Just try it
Regards
Flo
edit: oh damn, i wanted this answer as an answer on the "had to turn phone on/off every time". sorry folks
I'm posting this in the hope that it will be helpful to someone who has tried everything but still cannot get it to run on boot after installation or it used to work before and doesn't work anymore.
So assuming you have added the permission:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
And registered your receiver:
<receiver android:name="com.example.startuptest.StartUpBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
And coded your BroadcastReceiver:
public class StartUpBootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
Log.d("startuptest", "StartUpBootReceiver BOOT_COMPLETED");
...
}
}
}
Starting with Android 3.1 all applications, upon installation, are placed in a "stopped" state.(This is the same state that the application ends up in after the user force-stops the app from the Settings application.)
While in "stopped" state, the application will not run for any reason, except by a manual launch of an activity. (Meaning no BroadcastRecevier(ACTION_PACKAGE_INSTALLED, BOOT_COMPLETED etc. will be invoked, regardless of the event for which they have registered, until the user runs the app manually.)
This is a design decision by Google to prevent malware apps. Google has advocated that users should launch an activity from the launcher first, before that application can do much. Preventing BOOT_COMPLETED from being delivered until the activity is launched is a logical consequence of that argument.
Once a user runs any activity in your app once, you will receive the BOOT_COMPLETED broadcast after all future boots.
More details about this:
http://developer.android.com/about/versions/android-3.1.html#launchcontrols
http://commonsware.com/blog/2011/07/05/boot-completed-regression.html
http://devmaze.wordpress.com/2011/12/05/activating-applications/
If your app installed on external storage(SD card), you will never receive Boot Complete action. So you have to specify android:installLocation="internalOnly" in the manifest tag.
Your <uses-permission> element needs to be an immediate child of the <manifest> element, and your code listing above suggests that it is not.
Here is a sample project demonstrating the use of BOOT_COMPLETED.
Turns out the receiver wasn't in the tag of the manifest. Whoops! Thanks for your help guys! The worst part about testing this is having to keep turning off and on the phone. :P
This seems to be the forefront thread for this problem, so I wanted to add a solution for my C# colleagues. I racked my brain trying to figure out what I was doing wrong after trying everything here, to no avail. I finally figure out what was wrong, and it differs a bit from the advice here for C# Mono development. Basically, it boils down to something I've just learned the hard way. With C# DO NOT MODIFY AndroidManifest.xml manually!
See this guide for reference:
Xamarin: Working with AndroidManifest.xml
More directly for this problem, here is how you get this done.
First, in your project properties, under the Manifest Tab, there is a checkbox list for choosing the permissions you want to provide, one of which is RECEIVE_BOOT_COMPLETED. Check that to provide these permissions.
Secondly, you need to put the proper tags on your BroacastReceiver class.
[BroadcastReceiver]
[IntentFilter(new String[]{ Intent.ActionBootCompleted }, Priority = (int)IntentFilterPriority.LowPriority)]
public class MyBootReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
// Do your boot work here, set alarms, show toasts, whatever
}
}
The final part of [IntentFilter()] dealing with priority isn't required, it just lets other higher priority stuff get done first on boot, and is good practice if your App isn't a high priority thing.
As you'll see in the linked article, using these tags in your code will cause the AndroidManifest.xml file to be created at build time, with everything the way it should be. What I found was that when modifying the manifest manually to include the receiver tag, the system was causing it to look for the class one level too deep, thus throwing a ClassNotFound exception. It was trying to instantiate [Namespace].[Namespace].[BroadcastReceiver] which was wrong. And it was doing that because of the manual manifest edits.
Anyway, hope this helps.
Also, another quick tip with the adb tool. If you want to get an easier to read version of the log, try this:
C:\Android\platform-tools\adb logcat >> C:\log.txt
This will dump the logcat to a text file you can open and read a bit easier than in the command prompt window. Makes cut and paste of things a bit easier too.
Pertaining to some devices running Android Kitkat 4.4.4_r2/r1.
There seems to be a bug in Android that make android.intent.action.BOOT_COMPLETED no being broadcasted.
See:
BOOT FAILURE making Package Manager Service ready
In most cases this is not the answer to your problems (more likely because permissions etc), but if you are running Kitkat then you might have a look and see if this seems to be the case for you.
I had this problem and android.intent.action.BOOT_COMPLETED would simply not be broadcasted some of the times it had started up!
Other answers here already covered how to perfectly implement the Broadcast Receiver so that it'll work, however I still had problems receiving the BOOT_COMPLETED Intent until I realized the app was actually working when started from the phone/emulator by pressing on the app icon.
Whenever I start my app with the debug/run commands from Android Studio the BOOT_COMPLETED Intent won't be delivered, unless the app is opened and running.
I hope this can help someone who, like me, was struggling for hours with this problem.
Moreover, if anyone has an explanation for this behavior, I'd be really happy to know more about it.
on adding <category android:name="android.intent.category.HOME" /> this to my manifest file solve my problem and works.
<receiver android:name=".BroadCastRecieverClass">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<category android:name="android.intent.category.HOME" />
</intent-filter>
</receiver>