I originally asked this question, about passing parameters through a market link into my app on install.
Everyone seems to be saying to create a BroadcastListener with the intent-filter action of com.android.vending.INSTALL_REFERRER. All the documentation on that seems to imply this is a capability of Google Analytics (the documentation is in v1, but I can only download v2 SDK at this point... so that's what I am using). I can't get these links to pass data through. I have my full manifest and my broadcast listener. I have included Google Analytics just in case that was a requirement.
Google Analytics Reference
Generated link to market from here
Link to my app in the store
Link with parameters in the store
It doesn't work at all. My broadcast listener is never called, nothing gets printed out in the logs. Help!
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.robotsidekick.webbrowser"
android:versionCode="4"
android:versionName="4.0">
<uses-sdk android:minSdkVersion="17"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:label="#string/app_name"
android:icon="#drawable/ic_launcher">
<activity
android:name="WebBrowser"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<receiver
android:exported="true"
android:name="com.robotsidekick.webbrowser.InstallReceiver">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
</application>
</manifest>
Broadcast Listener
public class InstallReceiver extends BroadcastReceiver
{
private static final String TAG = "InstallReceiver";
public void onReceive(Context context, Intent intent)
{
Log.e(TAG, "Context: " + context);
Bundle extras = intent.getExtras();
if (extras != null)
{
Log.e(TAG, "Extras:");
for (String keys : extras.keySet())
{
Log.e(TAG, keys + " -> " + extras.get(keys));
}
}
else
{
Log.e(TAG, "Extras are null");
}
}
}
So xbakesx says that it seems to work if his receiver extends com.google.analytics.tracking.android.AnalyticsReceiver.
I think the key is that the intent has permissions for ...AnalyticsReceiver and so no other class that is not extending it can pick up the intent. If you look at their test broadcast https://developers.google.com/analytics/solutions/testing-play-campaigns it does appear specific for that class.
If you change that test broadcast so that your class replaces com.google.analytics.tracking.android.AnalyticsReceiver you can then receive it. The biggest problem is they seemed to have locked down this class in beta 4 or 5. If anyone has a link to beta 3 we could test this, or if xbakex could confirm with playing around with the new jars that would rock!
Update:
BAM! So permissions are not an issue. I created a test project and used the PlayStores alpha testing to test out referrer links, which you can build here: https://developers.google.com/analytics/devguides/collection/android/v2/campaigns.
The cool thing is you don't need any GA jar at all! Checkout my test project here: https://github.com/twotoasters/AnalyticsTest/ This project also shows you how to parse the link to get all of the information that you need.
After many failed attempts i could finally see the passed referral parameters in logcat.
Along the way, i figured out a few things, i am not too sure if i am doing it rite or wrong, but for some reasons, these worked. If someones still stuck, they can get some pointers from my learnings.
A. creating a custom BroadcastReceiver where you can ready the intent. (this will executed, only once you have successfully fired the Install_referrer intent from the ADB for testing). Also make sure, if you need to do a post back of the referrer information to a server, it will have to be on a separate thread.
public class CustomBR extends BroadcastReceiver {
private static final String D_TAG = "BR";
#Override
public void onReceive(Context context, Intent intent) {
Log.d(D_TAG, "CustomReceiver onReceive (context, intent)");
try {
String referrer = intent.getStringExtra("referrer");
// pass the referrer string to another singleton class to post it to server
HandleServerComm.getInstance().postData(referrer);
} catch (Exception e) {
e.printStackTrace();
}
}
}
B. update the androidmanifest.xml file to reflect the custom receiver you have created
<receiver android:exported="true" android:name="com.example.myapp.CustomBR" android:enabled="true">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
C. make sure you have adb installed correctly to test this on local environment. you will also need a device to be connected via USB with remote debugging enabled.
D. run the adb shell command to remotely broadcast a install_referrer on the device and pass it parameters.
The command is
adb shell am broadcast -a com.android.vending.INSTALL_REFERRER -n com.example.myapp/.CustomBR --es "token" "sample_token" --es "source" "banner"
Note that the important parts of this command is com.example.myapp/.CustomBR and --es "token" "sample_token" where --es is the additional parameters that are being sent along with the intent. the first quote after --es is the querystring / parameter name and the second quote is the value. Similarly, if you have to add more than one value, replicate it as shown in the example above.
E. Finally the most important part that kept me frustrated all the while - the app installed on the device itself. Your app should be installed on the device but not running at all. To do this, you will have to "Force Close" the app and then fire the adb shell command to fire up the install_referrer. thats when, you should see the logcat light up with required data.
F. You might also want to uninstall the update on google play store app and restore it to factory settings. at times (not confirmed) the version of google play determines what data is being passed to the app via the install_referrer or if the referrer is called at all.
Hope this helps someone.
Registering a BroadcastReceiver in your app's AndroidManifest.xml with an intent filter is the correct solution to app install referrals whether using Google Analytics or not.
<receiver
android:exported="true"
android:name="com.yourcompany.package.receivers.InstallReceiver">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
If you're already using Google Analytics you simply specify android:name="com.google.android.gms.analytics.CampaignTrackingReceiver" for your receiver and the following service as well. Both are included in the Google Play services client library so there isn't any Java code to write. If you haven't already, you will also have to go through the initial setup instructions for Google Analytics for your App.
<service android:name="com.google.android.gms.analytics.CampaignTrackingService" />
If you're not using Google Analytics then you'll need to define your own BroadcastReceiver in your java code. You will want it to inspect the extras on the received intent when implementing onReceive.
The referrer parameter in the URL that is received by Google Play (the store) is the only parameter passed through to the Android app for the referral so it's very common to encode a few parameters within it. For Google Analytics that means industry standard utm_* parameters, but you can use others. Here's the test adb command I typically use for opening Google Play to install and test the full flow.
adb shell "am start -a android.intent.action.VIEW -d \"https://play.google.com/store/apps/details?id=com.somecompany.package&referrer=utm_source%253Dtest_campaign_source%2526utm_medium%253Dtest_campaign_medium%2526utm_term%253Dtest_campaign_term%2526utm_content%253Dtest_campaign_content%2526utm_campaign%253Dtest_campaign_name\""
Testing Notes:
When testing this flow it's very important to check that the above command resulted in an output where the Intent was logged to your console with the FULL referrer information still attached. It's very easy for the escaping to be incorrect and silently drop the referrer.
Remember that the APK must have been installed by Google Play (the Store) on to the device you're testing on (you can't side-load). Therefore, you usually need to use your Alpha distribution channel in Google Play to test this.
It's important to note that if the device is >= Honeycomb MR1 the INSTALL_REFERRER intent is broadcast after the App is first launched rather than after the app is installed.
You will need to reinstall your app every time you need to test the referrer flow.
Install referrals are tracked when the app is installed from the Android Google Play app, but not the web version of the store.
Related
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'm setting up campaign tracking using custom analytics (not google analytics) and setting up a receiver for that. My receiver seems to be working, but when I install I get an android lint warning:
ExportedReceiver: Receiver does not require permission
It looks like any old android app could call my application with the com.android.vending.INSTALL_REFERRER intent which I do not want. It should only be the Google Play Store (or any other android system application that would install my app from the play store) sending that intent to my application.
So I've tried to figure out how to set up a permission that limits the valid applications to the play store, but I can't figure out the correct way to set up the permission according to the documentation:
https://developer.android.com/guide/topics/manifest/permission-element.html
Could someone help me setup a permission that limits the applications my application will accept this intent from to the play store? Here's my current receiver config:
<receiver
android:name=".referrals.MyCampaignTrackingReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER"/>
</intent-filter>
</receiver>
I tried setting a permission for the receiver at the normal level but that prevented the app from receiving the intent from the playstore.
You need to set android:permission attribute on your receiver. So that it will look something like this:
<receiver
android:name=".referrals.MyCampaignTrackingReceiver"
android:enabled="true"
android:exported="true"
android:permission="android.permission.CLEAR_APP_CACHE">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER"/>
</intent-filter>
</receiver>
Usage of "android.permission.CLEAR_APP_CACHE" here is arbitrary, you can use any permission that Play Store has AND is not possible for third-party apps to have (because CLEAR_APP_CACHEs protection level is system|signature only system apps or apps signed with the same certificate as the application that declared this permission; in this case the platform). For example, looking through Play Store's manifest suggests, "com.android.vending.permission.C2D_MESSAGE" could be another good candidate.
Hope this helps.
INSTALL_REFERRER broadcast permission is not a great concern. Assuming you know you need to handle this broadcast only once, right after install, and you take measures to handle it only once, an attacker will have to know when your app has been installed and somehow send this broadcast before the playstore app, which seems unlikely.
3rd party apps can not broadcast this intent. It is blocked. And permission to send is only granted to system apps.
I started to Implement Campaign Measurement with Google Analytics V4 referring the link
https://developers.google.com/analytics/devguides/collection/android/v4/ .
Facing an issue when Tested Campign Measurement as mentioned in https://developers.google.com/analytics/solutions/testing-play-campaigns. Every time my logs showing "No Campaign data found"
I imported google Play services (Rev :18) in to my workspace and referred it in my project
Added below lines in my Manifest file
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<meta-data android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<meta-data android:name="com.google.android.gms.analytics.globalConfigResource"
android:resource="#xml/global_tracker" />
and also below code
<service android:name="com.google.android.gms.analytics.CampaignTrackingService"/>
<receiver android:name="com.google.android.gms.analytics.CampaignTrackingReceiver"
android:exported="true">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
later created global_tracker.xml file under res->xml. Below is my xml file
<?xml version="1.0" encoding="utf-8" ?>
<resources xmlns:tools="http://schemas.android.com/tools"
tools:ignore="TypographyDashes"
>
<integer name="ga_sessionTimeout">300</integer>
<!-- Enable automatic Activity measurement -->
<bool name="ga_autoActivityTracking">true</bool>
<bool name="ga_debug">true</bool>
<string name="ga_logLevel">verbose</string>
<string name="ga_dryrun">true</string>
<!-- The screen names that will appear in reports -->
<!-- The following value should be replaced with correct property id. -->
<string name="ga_trackingId">UA-xxxxxxx-1</string>
</resources>
replaced Tracking Id with my tracking id
while testing campaign measurement, i first installed my app on to my device (Moto G (4.4.2)) through adb install. Made sure the app is not running and broadcasted the intent as mentioned in the above Link . i got success log when broadcasted the intent.
Intent
E:\xxxxxxx\adt-bundle-windows-x86_64-20140321\sdk\platform-tools
>adb shell am broadcast -a com.android.vending.INSTALL_REFERRER -n <My Package name>/com.google.android.gms.analytics.CampaignTrackingReceiver --es "referrer" "utm_source=testsource"
Response:
Broadcasting: Intent { act=com.android.vending.INSTALL_REFERRER cmp=<My Package name>
>/com.google.android.gms.analytics.CampaignTrackingReceiver (has extras) }
Broadcast completed: result=0
When i opened my application i always got " I/GAV2(7342): Thread[GAThread,5,main]: No campaign data found." error in my logs.
Can please someone let me know why am i not getting Campaign data ? where i am going wrong.
Also, why it is Showing "GAV2" in logs when i am using GAV4
GA Logs:
07-09 12:59:26.542: W/GAV2(20502): Thread[main,5,main]: Need to call initialize() and be in fallback mode to start dispatch.
07-09 12:59:31.568: I/GAV2(20502): Thread[GAThread,5,main]: No campaign data found.
Note: This is the first time i am working with Google Analytics. As i want to check whether i am receiving Campaign data or not first, i didn't implemented any trackers to GA
Edit : When i manually trigger the Broadcast intent on button click in my App. I am able to see "Campaign found" log when i restarted my app. But the same not happening when triggered intent using "adb shell" command as mentioned above. I doubt may be intent is not reaching to my device . Is there any way to find whether the intent is received or not ?
Please help
1> ok for the starters you are mixing two things.
this link is for Google Analytics-v4 https://developers.google.com/analytics/devguides/collection/android/v4/
and this link https://developers.google.com/analytics/solutions/testing-play-campaigns is not for v4( the page is too old, there was no GAV4 when this page was published.
2> Check the physical-device(Google play services) version and update it to 5.0, if not already done.
3> you dont need the boiler plate code mentioned below. I think this is for GAV3 and not GAV4
<service android:name="com.google.android.gms.analytics.CampaignTrackingService"/>
<receiver android:name="com.google.android.gms.analytics.CampaignTrackingReceiver"
android:exported="true">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
for more clarity on code check this link. No campaign data found. Using Google Analytics v4
4> Specifically for GAV4(with my own exprience), its ok to see the error "No Campaign data found". try to run the code in verbose mode and you will see that GAV4 is making connections to its host.
GoogleAnalytics.getInstance(this).getLogger().setLogLevel(LogLevel.VERBOSE);
5> Do not turn on the dry_run, you will not see the data on Google Analytics. By default this is off.
6> finally, inside Google Analytics see under "Real-time" for live hits.
hope this helps.
I was having the same issue with an extra error of ClassNotFound sometimes.
First i suggest to see Nishant's response and here are a couple more thing to check if they solve your problem:
1) If you are having more than one BroadcastReceiver:
1.1) Ensure you don't! Keep only one and add the intent-filter to that one:
<service android:name="com.google.android.gms.analytics.CampaignTrackingService"/>
<receiver android:name="com.example.MyScheduleReceiver"
android:exported="true">
<intent-filter >
<action android:name="android.intent.action.ACTION_USER_PRESENT" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE"/>
<action android:name="android.intent.action.ACTION_SCREEN_OFF" />
<action android:name="android.intent.action.ACTION_SCREEN_ON" />
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
1.2) Then at end of the BroadcastReceiver send the intent to the right receiver:
#Override
public void onReceive(Context context, Intent intent) {
//Do your code for the other intents
new CampaignTrackingReceiver().onReceive(context, intent);
}
2) Calling the right Analytics version is also an issue when reading Google's tutorial because some links redirect you to older versions of the library all the time. If you are using v4 then:
2.1) Ensure not be including the libGoogleAnalyticsV2.jar
2.2) Double check that you are writing com.google.android.gms.analytics.CampaignTrackingService all the times and on all the imports.
3) When using the ADB to check if its working verify the previous points. On the above example, the right line to call the ADB will be:
adb shell am broadcast -a com.android.vending.INSTALL_REFERRER -n com.example/com.example.MyScheduleReceiver --es "referrer" "utm_source=testSource&utm_medium=testMedium&utm_term=testTerm&utm_content=testContent&utm_campaign=testCampaign"
For this make CustomReceiver and from that send intent to google CampaignTrackingReceiver in GoogleAnalyticsv4.
By this you will get CampaignFound in logs
public class CustomCampaignTrackingReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
new CampaignTrackingReceiver().onReceive(context, intent);
}
}
Install the apk file to you device.
adb install filename.apk
Type the following adb command:
..\sdk\platform-tools>adb shell am broadcast -a com.android.vending.INSTALL_REFERRER -n your.package.name/com.google.android.gms.analytics.CampaignTrackingReceiver --es "referrer" "utm_source=testSource"
Note that the command given in this link has a V3 Receiver.
Check logcat. The Campaign Found message should be there. Make sure the app is not running when the referrer is being sent. The app should be launched only after it is done.
Might be useful to someone... I was getting GAv4: Discarding hit. Missing tracking id parameter because instead of:
GoogleAnalytics.getInstance(context).newTracker(R.xml.app_tracker);
I've added
GoogleAnalytics.getInstance(context).newTracker(R.string.ga_trackingId);
Note the difference xml.app_tracker vs string.ga_trackingId!
Use xml.app_tracker configuration file!
As I checked in my last implementation. Maybe the log can be broken. I received "No campaign data found" in the logs, but I see real data in the web console.
I am using v4, and my manifest looks like this:
<receiver android:name="com.google.android.gms.analytics.CampaignTrackingReceiver" android:exported="true">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
<service android:name="com.google.android.gms.analytics.CampaignTrackingService" />
Good luck
I'm working with Mark Murphy's excellent Commonsware books - but it's a lot to digest. I built the 'FakePlayer' app (pretends to be an mp3 player). It contains a service. As a learning experience I tried to write a trivial app (has only a button) whose click handler does:
Intent i = new Intent();
i.setAction("com.example.cwfakeplayer.MyPlayerService");
Context context = getApplicationContext();
context.startService(i);
It worked fine - the service start ok. I noticed Eclipse complaining about no permission on the service, so I updated the service's manifest by adding 2 lines, android:permissions and android:exported:
<service
android:name="MyPlayerService"
android:permission="com.example.fakeplayer.permission.MY_PLAYER_PERMISSION"
android:exported="true"
<intent-filter>
<action android:name="com.example.fakeplayer.MyPlayerService"></action>
</intent-filter>
</service>
I reloaded the player app onto the device (I'm using a Galaxy S2) using 'debug' under eclipse. It seemed to work; the starter app caused a permission exception, which I expected.
I then added to the starter app's manifest (to give it the permission):
<manifest
...
<uses-sdk ....
....
<uses-permission android:name="com.example.fakeplayer.permission.MY_PLAYER_PERMISSION" />
I reloaded the starter app onto the device (using debug under Eclipse). Still get the permission error in the starter app.
I removed both apps from the device and reinstalled (using debug...), service app first, then starter. Still get perm error.
I am working my way through the 'how to use a remote service' section of Mr. Murphy's Advanced Android book, so I realized this is not the best way perhaps to work across apps.
I did a 'adb shell dumpsys package', located the starter app, and found it had 'permissionsFixed=false' and no 'grantedPermissions' section. I take this to mean the manifest change in the starter app did not manage to get the perm added to the app. But I have no idea why. As a learning experience, it's generated only confusion so far....
Any clues greatly appreciated! Thanks!
I updated the service's manifest by adding 2 lines, android:permissions and android:exported
Technically, android:exported="true" is superfluous, as having the <intent-filter> automatically makes the <service> be exported.
I removed both apps from the device and reinstalled (using debug...), service app first, then starter. Still get perm error.
You do not show where you ever declare the custom permission with the <permission> element. In practice, if you control both apps, put the same <permission> element in both manifests, so the order of installation of your two apps no longer matters.
Try replace this in your manifest
<service android:name="com.example.fakeplayer.MyPlayerService"></service>
instead of
<service
android:name="MyPlayerService"
android:permission="com.example.fakeplayer.permission.MY_PLAYER_PERMISSION"
android:exported="true"
<intent-filter>
<action android:name="com.example.fakeplayer.MyPlayerService"></action>
</intent-filter>
</service>
If this doesn't work, kindly post out your error.
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>