Android Receivers not doing as expected - android

Well honestly, they aren't doing anything at all. Let me start by saying that I know that Android reworked receivers in 3.1, specifically boot control. I know that they made it so that ACTION_BOOT_COMPLETED cannot be used unless the application has been previously launched by the user. However, people have been successful in using them in current application, yet I am never hitting my receivers for my BOOT_COMPLETED or my SHUTDOWN.
Quick Edit - Please look at the bottom of this post for corrected Shutdown Receiver, I have gotten it to work and am now just stuck in my efforts to get BOOT_COMPLETED to work.
My manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.smashingboxes.speedblock"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="12"
android:targetSdkVersion="18" />
<!-- PERMISSIONS -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
...
<!-- RECEIVERS -->
<receiver android:name=".BootReceiver"
android:enabled="true" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver android:name=".ShutdownReceiver" >
<intent-filter>
<action android:name="android.intent.action.SHUTDOWN" />
</intent-filter>
</receiver>
Now my implemented receiver classes are fairly straight forward:
BOOT_COMPLETED Receiver (the one that isn't working)
public class BootReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context c, Intent i) {
Intent starterIntent = new Intent(c, LaunchActivity.class);
// Start the activity (by utilizing the passed context)
starterIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
c.getApplicationContext().startService(starterIntent);
}
}
I have tried different things based on what I have seen as far as solutions, such as altering my launching activity to include
/* May need this, as of 3.1 we can't call BOOT_COMPLETED until the app has been run successfully */
Intent intent = new Intent("com.smashingboxes.speedblock.intent");
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
this.sendBroadcast(intent);
or including this in my boot receiver intent-filter in my manifest
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
Nothing seems to work. When Logs are inserted into my receiver methods they are never hit. Apparently people are still using these two receivers fairly regularly, which is why I am having trouble understanding why neither of them work. Have I missed something with my registration or something?
--EDIT--
I have solved the problem with my shutdown receiver. First, I foolishly forgot the ACTION_ portion of the tag. Secondly, HTC has separate shutdown methods, in my case I needed to add an intent-filter to my Receiver request:
<receiver android:name=".ShutdownReceiver" >
<intent-filter>
<action android:name="android.intent.action.ACTION_SHUTDOWN" />
<action android:name="android.intent.action.QUICKBOOT_POWEROFF" />
</intent-filter>
</receiver>
Now my Shutdown Receiver works, still no luck on the Boot Completed Receiver though.

I found the answer and I think that it is actually important to note, as it seems like an issue others will run into at some point. My issue was that I was launching a "Launcher Activity" called just that, LauncherActivity. Basically, it acted as my gateway to start up services, receivers, and such when the application was launched. It is a very simple Activity class:
public class LaunchActivity extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
/* May need this, as of 3.1 we can't call BOOT_COMPLETED until the app has been run successfully */
Intent intent = new Intent("com.smashingboxes.speedapp.intent");
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
this.sendBroadcast(intent);
}
#Override
protected void onStart(){
super.onStart();
Intent serviceIntent = new Intent(this, MainService.class);
startService(serviceIntent);
// NOTE: It is VERY, VERY important that we DO NOT finish this activity.
// If we do, our BootReceiver will no longer receive its broadcast and
// we won't auto-start on boot
//finish();
}
}
Note that I was calling finish() on the LaunchActivity. The problem with this is that it seemed to tell Android that the application was in the stopped state, meaning that it won't allow the reception of the BOOT_COMPLETED broadcast, even though I had a number of services running in the background. The LauncherActivity MUST stay active throughout the entire life-cycle or the BOOT_COMPLETED receiver becomes useless. Something that I haven't really seen mentioned before, but again something I think is worth noting.

Related

Android App to start automatically on Boot Up

I am trying to get my Android app to start automatically on boot up.
I have followed various examples and copied the code, but still, when I power up, the app does NOT start.
I am using a Galaxy Tab A7 Lite, running Android 11.
Any help gladly received.
Thank you.
Here is my code...
I have defined the receiver:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class StartOnBootupReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
Intent activityIntent = new Intent(context, MainActivity.class);
context.startActivity(activityIntent);
}
}
}
And in the AndroidManifest.xml file:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
and
<receiver android:name=".StartOnBootupReceiver"
android:exported="false"
>
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action..QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
Your code looks good and your receiver is most likely executing. However, it is crashing because of the call to startActivity(). Since Android 10, startActivity() can only be called if the application is already in the Foreground or if it meets one of the listed exceptions listed in the Android guide Restrictions on starting activities from the background.
As an aside, the value of the android:exported has no effect. The OS can still call receivers who have android:exported="false" and, in the case of exported="true", other application cannot send a broadcast with BOOT_COMPLETED or QUICKBOOT_COMPLETED because they are protected intent actions.
All your code is correct. However, if you look up android:exported="false" meaning you will find that:
The "exported" attribute describes whether or not someone else can be allowed to use it. So if you have "exported=false" on an Activity, no other app, or even the Android system itself, can launch it. Only you can do that, from inside your own application.
In your <receiver> statment, the android:exported="false" needs to be true.
That info borrowed from here and here.

Is rooted device required to start app on boot?

I have developed application to start app on boot, but it is working on rooted devices only some of code as below.
permission and receiver in AndroidManifest.xml file is given below.
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<receiver android:enabled="true" android:name="in.com.appname.StartAppAtBootReceiver"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter >
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>
below are the class to receive on boot.
public class StartAppAtBootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent myIntent = new Intent(context, MainActivity.class);
myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(myIntent);
}
}
my question is that this code will work with non rooted devices?
if yes then what is missing because same app is working with rooted devices.
This must work without root.
Else try to use a simple tutorial like: Android AutoStart App after boot
Differences:
Check which action occurs.
Use startService instead of startActivity
Another tip: Set permissions in top of manifest, and receiver in application-part.
This should work without root.
There are a couple of things to notice:
app must be started at least once before it can receive BOOT_COMPLETED
if app is force closed, it will lose it ability to receive BOOT_COMPLETED until next launch.
Also, permission should be at the root of manifest and not inside application:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.x.y" >
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
.
.
.
make sure you are not running in above situations.

How to start an application directly (without asking) at startup on Android 4.0

I want to start my application at startup in Android 4.0. To do that, I wrote some codes and these are completely the same with the #Ahmad's codes (in the answer). However, although I select my application as always, when tablet opens, it asks 'What do you prefer?' (Android's default launcher or my application). I don't want it to ask that question and it must start my application automatically.
Use the BOOT_COMPLETED Intent.
Broadcast Action: This is broadcast once, after the system has
finished booting. It can be used to perform application-specific
initialization, such as installing alarms. You must hold the
RECEIVE_BOOT_COMPLETED permission in order to receive this broadcast.
In your Manifest:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
Set up a Broadcastreceiver:
<receiver android:name="com.example.MyBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
This is how your BroadcastReceiver could look like:
public class MyBroadcastreceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, MyActivity.class);
startActivity(i);
}
}

Android Application not running at startup

I have a basic Android application that is supposed to reboot the phone continuously a set number of times. In order to do this, I need the application to be started upon phone startup. In order to that, I essentially followed the instructions found here, adding the permissions to the manifest and creating a BroadcastReceiver class that starts the activity. Here is some of my relevant code:
public class StartMyServiceAtBootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
System.out.println("StartMyServiceAtBootReceiver called.");
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
// Intent activityIntent = new Intent("com.example.rebooter.MainActivity");
Intent activityIntent = new Intent(context,MainActivity.class);
activityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(activityIntent);
}
}
}
From the manifest file:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.rebooter"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/title_activity_main" >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</activity>
<service
android:name=".RebootManager"
android:label="Reboot Manager" >
<action android:name="com.example.rebooter.RebootManager" />
</service>
<receiver android:name=".StartMyServiceAtBootReceiver"
android:enabled="true"
android:exported="true"
android:label="StartMyServiceAtBootReceiver" >
<action android:name="android.intent.action.BOOT_COMPLETED" />
</receiver>
</application>
In the Eclipse emulator, the application appears to be working properly. That is, though my emulator isn't rooted and the phone doesn't execute the reboot commands correctly, I do see that, upon startup, the correct activity is started.
Now, when I'm trying it on a particular system running Android 4.0.4, everything in the application is working properly EXCEPT boot upon startup. Any ideas?
I tried to eliminate the possibility of any hardware problems (since I'm not using a commercially-released phone) by installing another application that boots upon startup and confirming that it does indeed boot upon startup, and it does indeed show up under running apps as a cached process after startup.
I would appreciate any help. Let me know if you need any additional information.
There are a number of issues here.
First, you neglected to post StartMyServiceAtBootReceiver, the component you are expecting to get control at boot time, so we cannot comment on whether there are any particular problems with it.
Second, unless something has explicitly executed one of your components (e.g., the user launched MainActivity from the home screen), StartMyServiceAtBootReceiver will never be invoked, on Android 3.1+. Make sure you run your activity before trying a reboot, and see if that helps.
Third, you implemented a constructor on StartupManager, which is a bad idea. Please move this logic to onCreate().
Fourth, your code will likely crash in that constructor, as getApplication() will not return a valid value at this point in the code, particularly since you failed to chain to the superclass' constructor. Again, moving this code to onCreate() will help here.
Fifth, starting an activity from onCreate() of a service (let alone its constructor) is very unusual and may not be appreciated by the user. Moreover, if that service is not doing anything else, you could just as easily start that activity from StartMyServiceAtBootReceiver and skip StartupManager entirely.
Sixth, you have <intent-filter> elements on your services, as if you are expecting third party developers to invoke those services. If that is the case, fine. If not, please remove the <intent-filter> elements and use explicit Intents within the rest of your app code to refer to them (e.g., new Intent(this, StartupManager.class)), for better security. Or, add android:exported="false" to those services, though that is automatic if you remove the <intent-filter> elements.

PACKAGE_ADDED BroadcastReceiver doesn't work

I have a broadcast receiver registered in Manifest:
<application ...>
<receiver android:name="com.some.pkg.NewAppReceiver" >
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED" />
</intent-filter>
</receiver>
</appcication>
And the receiver:
public class NewAppReceiver extends BroadcastReceiver {
private static final String TAG = "NewAppReceiver";
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "Intent: " + intent.getAction());
}
}
And nothing is received when I install APK manually or from the Android Market. Why?
Did you run the app that contains this broadcastReceiver before installing the other apps?
Starting at some API version, broadcastReceivers will not work till you execute the app. Put an activity and execute it.
Also , don't forget to add the following into the broadcastReceiver:
<data android:scheme="package" />
EDIT: On Android 8 and above, if your app targets API 27 or more, it will work partially, so you have to register to those events in code and not in manifest. Here's a list of intents that are still safe to use in manifest: https://developer.android.com/guide/components/broadcast-exceptions.html .
The rest should be used in code. More info here
Since android.intent.action.PACKAGE_ADDED is a System Intent (note that your own app will not receive it at its installation), your BroadcastReceiver will receive messages from sources outside your app. Thus, check you did NOT put: android:exported="false"
You also may need to add:
<data android:scheme="package" />
So, your BroadcastReceiver in your AndroidManifest.xml should look like this:
<application ...>
<receiver android:name=".NewAppReceiver" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED" />
<data android:scheme="package" />
</intent-filter>
</receiver>
</appcication>
If it still doesn't work, you may try to put an higher priority, such as: android:priority="1000"
Take a look at: http://developer.android.com/guide/topics/manifest/receiver-element.html
Registering receiver from manifest would not work from API 26(android 8). Because it had performance impact on older versions.
But we can register receiver from java code and receive updates of removed and added applications.
val intentFilter = IntentFilter()
intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED)
intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED)
intentFilter.addDataScheme("package")
registerReceiver(YourBroadcastReceiver(), intentFilter)
Are you trying to receive the intent in the application you are installing? The documentation for ACTION_PACKAGE_ADDED says:
Note that the newly installed package does not receive this broadcast.
Another possibility is that this intent might not be delivered to components registered via the manifest but only manually (as described in an answer by Mark Murphy to Stack Overflow question Can't receive broadcasts for PACKAGE intents).
If you try to receive some other package it must be worked.
(As #Savvas noted) If you try to receive your own package's addition you can't receive it. Even if your broadcast receiver has action.PACKAGE_ADDED, receiver's onReceive method isn't triggered.
In this case your best bet is saving this data. By using sharedPreferences, add a key something like "appIsWorkedBefore", and on your launcher Activity's onCreate method set this variable as "true". And you can make your works with respect to this Boolean.
This intent action is no longer available for applications.
This is a protected intent that can only be sent by the system.
https://developer.android.com/reference/android/content/Intent#ACTION_PACKAGE_ADDED

Categories

Resources