In my application, there's a feature that allows users to dial a specific number and brings up an activity to front. I have the following receiver, and the only receiver registered in AndroidManifest.xml.
<receiver android:name="com.example.myapp.OutgoingCallListener" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
Please note there's no BOOT_COMPLETED intent or service.
Now here's the thing I couldn't figure out. When I reboot my device, go check the Running Apps, my application is not listed there. But, if I dial the specific number, my application starts and the activity is brought to front.
My question is: If the app is not a service, and not started on boot, how could it recieve intent from Android? That is, in my case, how could my app listen to NEW_OUTGOING_CALL while it's not started at all?
A BroadcastReceiver that is registered in the manifest is always capable of responding to a matching broadcast. If your process is not running for any reason, Android will start up a process for you.
Related
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
I have two apps that I have complete control over. Both are signed with the same cert and both use the exact same intent filter. One sends the broadcast from a fragment, the other is suppose to receive it and do something. This however is not working:
Strings.FILTER_INIT_REGISTER = "com.app.FILTER_INIT_REGISTER"
Intent intent = new Intent(Strings.FILTER_INIT_REGISTER);
getActivity().sendBroadcast(intent);
I have registered the receiver in the Manifest app tag for the app containing the ReportingReceiver class:
<receiver
android:name=".receivers.ReportingReceiver"
android:exported="true"
>
<intent-filter>
<action android:name="com.app.FILTER_INIT_REGISTER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
Curious why the ReportingReceiver class is not getting the intent call?
If your application only has a service and receivers then this won't work in Android 3.1 and later. The reason is that the system will not send broadcast Intents to application that are in the STOPPED STATE. An application is in the STOPPED STATE when it is first installed. It is removed from the STOPPED STATE when the user manually starts the application for the first time. It is returned to the STOPPED STATE if the user forces the application to stop using the application manager tool.
Since your application has no Activities, there is no way for the user to "start" it. Therefore it will never come out of the stopped state.
See http://developer.android.com/about/versions/android-3.1.html#launchcontrols
As Android Addict says in his comment to David Wasser's answer ... there is a way around this behaviour.
Just add the following flag to the calling Intent. This will ensure that you also reach broadcast receivers from "stopped" applications.
http://developer.android.com/reference/android/content/Intent.html#FLAG_INCLUDE_STOPPED_PACKAGES
You can read more about this Android 3.1 change here
http://developer.android.com/about/versions/android-3.1.html#launchcontrols
and here
http://code.google.com/p/android/issues/detail?id=18225
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.
I have a very simple IntentReceiver to receive event when time changes. Here's the code:
public class IntentRec extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("IntentRec", intent.getAction());
}
}
<application android:label="#string/app_name" android:icon="#drawable/ic_launcher">
<receiver android:name=".IntentRec">
<intent-filter>
<action android:name="android.intent.action.TIME_SET"/>
</intent-filter>
</receiver>
<activity android:name="MyActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
However, I receive the intent while the application is running. But if I shutdown (using Force Close) the app, onReceive is not called. So my question is, do I receive intents only when listener app is running? I thought that intents was designed to run target listener class when the app was not running.
Thanks
The solution is simple: stop clicking Force Close.
On Android 3.1+, Force Close will prevent anything in your app from running again, until the user runs an activity of yours manually, or something else (e.g., third-party app) starts up your app.
UPDATE
I suspect that you are being confused by multiple meanings of the word "stopped". Let's walk through the process, avoiding the word "stopped", to see if it helps.
When your app is first installed on an Android device, is in a state known to some as "snicklefritzed". While the app is in this "snicklefritzed" state, no manifest-registered BroadcastReceiver will work. To move an app out of the "snicklefritzed" state, some third-party app (like the home screen launcher) must explicitly request to run something in your app (like an activity). So, the normal course of events is that the user downloads your app, clicks on the launcher icon for it, and your app is moved into the "normal" state and away from the "snickelfritzed" state. While in the "normal" state, your BroadcastReceiver will work fine.
Let's suppose that your BroadcastReceiver is for the ACTION_BOOT_COMPLETED broadcast. The "snicklefritzed" state has nothing to do with whether your app is presently running or not -- it is dependent only upon if your app has ever run or not. Hence, if the user installs your app, but reboots their phone before doing anything with your app, your ACTION_BOOT_COMPLETED receiver will not get control at boot time. If, however, the user runs something in your app, then reboots the phone, your receiver will receive the ACTION_BOOT_COMPLETED broadcast as normal.
Normally, apps move out of the "snicklefritzed" state and never return to that state. One thing that will cause an app to be "snicklefritzed" again is if the user clicks on Force Close for this app in Settings. Here, the user is expressly telling Android that your app is misbehaving and should not run again until the user says otherwise. If, of course, the user launches your activity again, you move back to "normal" state.
You have to add android:process=":remote" in order for the BroadcastReceiver to receive independent of your Activity.
<receiver android:name=".IntentRec"
android:process=":remote"> //We declare that this is in a remote process
<intent-filter>
<action android:name="android.intent.action.TIME_SET"/>
</intent-filter>
</receiver>
Cheers,
Zed
I have an application without launcher activity that works properly from Android 1.5 to Android 2.3.4. It is started by my broadcast receiver. However, on Honeycomb (Motorola Xoom), my broadcast receiver doesn't work at all (it does not catch any intents). If I add launcher activity to my manifest:
<activity android:label="#string/app_name" android:name="com.myapp.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> </intent-filter>
</activity>
Then my app works properly (broadcast receiver catches all necessary intents and starts my services).
I would be very grateful for help!
Are you running Honeycomb 3.1 or above? If yes take a look here.
When your application is installed, it is in stopped state. When the application is first launched, it is moved out of stopped state.
A application in stopped state won't get started by all broadcast intents. The sender of the broadcast intent has to specify the Intent.FLAG_INCLUDE_STOPPED_PACKAGES flag if it wants to launch stopped applications too.
Intent intent = new Intent(MY_INTENT_ACTION);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
sendBroadcast(intent);
If you can't change the code which sends the intent, your best bet would be to keep the launcher activity. Whenever the user launches your application after installation, it will be moved out of the stopped state and you will start receiving broadcasts.
Note the the user can move your application back to the stopped state from Manage Applications in device settings.
On Android 3.1 and higher, BroadcastReceivers will not be invoked until the user has started the application at least once by some other means, such as launching an activity.
Since users tend to get very confused by applications that do not have an activity, you really should have had an activity in the first place, for online help if nothing else. With Android 3.1, that is even more important.