In my Android application I want to run a Service without opening/running my application. For that I have extended BroadcastReciever class. But this BroadcastReceiver class is not being called from AndroidManifest.xml on BOOT_COMPLETE. So please tell what is the problem in my code? Or is there any other way to run a Service without opening my application? I have checked the control flow of my code and whole the code is working perfectly, the problem is that BroadcastReceiver is not being called.
Part of AndroidManifest.xml file:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<service android:name=".HelloService"
android:exported="false"/>
<receiver android:name=".MyBroadcastreceiver" android:enabled="true" android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
MyBroadcastreceiver.java class
package com.example.abc.project1;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class MyBroadcastreceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
/*this is not being called*/
Intent startServiceIntent = new Intent(context, HelloService.class);
context.startService(startServiceIntent);
}
}
Remove android:exported="false" from the <receiver>. That says you do not want anyone (other than yourself) sending a broadcast to this receiver. As a result, your receiver will be ignored by the system.
Beyond that, you also need an activity and to have run that activity before trying to reboot the device. You may already have that, but I thought that I would mention it for completeness.
Related
I have an android service that runs when i open my app, now I want my android service to run at boot time. I tried the bellow code, but the service is not running automatically when i reboot my device. I cannot see it running as a service on my phone! Is there something wrong in my code?
I added these permissions to the manifest:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.RECEIVE_HEADSET_PLUG"/>
Here's my receiver in the manifest:
<receiver android:name="org.qtproject.example.MyBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.RECEIVE_BOOT_COMPLETED"/>
<action android:name="android.intent.action.RECEIVE_HEADSET_PLUG"/>
</intent-filter>
</receiver>
And here's MyBroadcastReceiver.java:
import android.os.Bundle;
import org.qtproject.qt5.android.bindings.QtActivity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent startServiceIntent = new Intent(context, org.qtproject.example.MyCustomAppService.class);
context.startService(startServiceIntent);
}
}
replace
<action android:name="android.intent.action.RECEIVE_BOOT_COMPLETED"/>
with
<action android:name="android.intent.action.BOOT_COMPLETED"/>
in the manifest
ok so I had 2 problems in my code:
1)Thanks to #kajay, i had to change my action line as he described,
to be:
<action android:name="android.intent.action.BOOT_COMPLETED"/> in the manifest.
2) I was missing defining the package in the MyBroadcastReceiver.java. So, the class couldn't find the startServiceIntent. Of course qt doesn't give any errors or warnings with many java problems.
So, in my case i had to add this to the MyBroadcastReceiver.java :
package org.qtproject.example;
I had to do both of the above steps to fix my problem!
P.S Sometimes the service takes around 45 secs or more to start after booting!
Can't I retrieve it again using Request ID?
like using:
pendingIntent = PendingIntent.getBroadcast(this, RequestID, intent, PendingIntent.FLAG_UPDATE_CURRENT);
PS: I have all pendingExtra's in PendingIntent, else I have to fetch from database again!
Yes, all PendingIntents will be deleted after you reboot. But you can recreate them when the phone is booted up. This tutorial here does a pretty good job of explaining how to deal with bootup listeners.
Define a class DeviceBootReceiver as follows, which will run your code (creating PendingIntents, or whatever else you want) when the device has been booted.:
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class DeviceBootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
// Do your thing in here
}
}
}
And don't forget to (a) get permission and (b) declare this receiver in your AndroidManifest.xml:
<application ...>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
...
<receiver android:name=".DeviceBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
</application>
Does all Pending Intent is deleted after boot in android?
Yes. They are only held in RAM, in a core OS process.
Can't I retrieve it again using Request ID?
Not after a reboot.
In my app, I have a Broadcast Receiver for catching the message sent to my phone
<receiver
android:name="com.qmobile.ows.SMS_Receiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
If I start app with activity GUI, the BroadCast Receiver works normally.
I want to start my application without activity and do not show icon app, so I remove this code below from my activity
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
And after that, Broadcast Receiver do not work.
Please help me solve this problem.
This is because Android OS does not allow BroadcastReceiver to receive some important broadcast(android.provider.Telephony.SMS_RECEIVED must be one of it) if the appĀ“s process is not alive.It was designed to against the evil apps. If you have an activity running,your process is alive and so your receiver is allowed to receive the broadcast.
I think you can make a transparent activity and use startService to start a service in background,then finish the activity.As your service is running ,your process is alive,so the Android OS will let you to receive the broadcast.
For Android 3.1 and higher,
You have to launch one of your activities before any manifest-registered BroadcastReceiver will work.
See developer docs specifically the section -
Launch controls on stopped applications for android-3.1
If you are testing Broadcast receiver without an Activity then you should edit your run configuration.
When the Edit configuration dialog appears, select the Do not launch Activity option so that the activity is installed but not launched and click on the Run button
This will launch the application without activity.
This could help you:
Creating and Sending the Broadcast Intent
Having created the framework for the SendBroadcast application, it is now time to implement the code to send the broadcast intent. This involves implementing the broadcastIntent() method specified previously as the onClick target of the Button view in the user interface. Locate and double click on the SendBroadcastActivity.java file and modify it to add the code to create and send the broadcast intent. Once modified, the source code for this class should read as follows:
package com.ebookfrenzy.sendbroadcast;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.content.Intent;
import android.view.View;
public class SendBroadcastActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_send_broadcast);
}
public void broadcastIntent(View view)
{
Intent intent = new Intent();
intent.setAction("com.ebookfrenzy.sendbroadcast");
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
sendBroadcast(intent);
}
.
.
.
}
Creating the Broadcast Receiver
In order to create the broadcast receiver, a new class needs to be created which subclasses the BroadcastReceiver superclass. Create a new project with the application name set to BroadcastReceiver and the company domain name set to com.ebookfrenzy, this time selecting the Add No Activity option before clicking on Finish.
Within the Project tool window, navigate to app -> java and right click on the package name. From the resulting menu, select the New -> Other -> Broadcast Receiver menu option, name the class MyReceiver and make sure the Exported and Enabled options are selected.
Once created, Android Studio will automatically load the new MyReceiver.java class file into the editor where it should read as follows:
package com.ebookfrenzy.broadcastreceiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class MyReceiver extends BroadcastReceiver {
public MyReceiver() {
}
#Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
// an Intent broadcast.
throw new UnsupportedOperationException("Not yet implemented");
}
}
As can be seen in the code, Android Studio has generated a template for the new class and generated a stub for the onReceive() method. A number of changes now need to be made to the class to implement the required behavior. Remaining in the MyReceiver.java file, therefore, modify the code so that it reads as follows:
package com.ebookfrenzy.broadcastreceiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class MyReceiver extends BroadcastReceiver {
public MyReceiver() {
}
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Broadcast Intent Detected.",
Toast.LENGTH_LONG).show();
}
}
The code for the broadcast receiver is now complete.
Configuring a Broadcast Receiver in the Manifest File
In common with other Android projects, BroadcastReceiver has associated with it a manifest file named AndroidManifest.xml.
This file needs to publicize the presence of the broadcast receiver and must include an intent filter to specify the broadcast intents in which the receiver is interested. When the BroadcastReceiver class was created in the previous section, Android Studio automatically added a <receiver> element to the manifest file. All that remains, therefore, is to add an <intent-filter> element within the <receiver> declaration appropriately configured for the custom action string:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ebookfrenzy.broadcastreceiver.broadcastreceiver" >
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true" >
<intent-filter>
<action
android:name="com.ebookfrenzy.sendbroadcast" >
</action>
</intent-filter>
</receiver>
</application>
</manifest>
With the manifest file completed, the broadcast example is ready to be tested.
add DEFAULT category in your intent filter
<category android:name="android.intent.category.DEFAULT" />
Ok. Here's what worked for me. I created a launcher activity. Removed the call to setContentView(R.layout.activity_main)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
finish();
}
I have an intent service in my application. When my application starts up it successfully runs the service class and it works nicely (storing data obtained from bluetooth in a sqlite database). The intent service is just for my app and will not be used by other apps.
However, when the application has been inactive for a long while, the service sometimes stops running. I want my service to carry on running reliably--that's why I created a service. I also want the service to start up by itself when the phone boots up (which it does not do).
When I go to settings -> applications -> running services my service is not listed there.
Here is the relevant part of my manifest file:
<service android:enabled="true" android:name=".MyHxMService" android:exported="false">
<intent-filter>
<action
android:name="org.xxxxx.MyHxMService" />
</intent-filter>
</service>
<receiver android:name="MyStartupIntentReceiver">
<intent-filter>
<action
android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.HOME" />
</intent-filter>
</receiver>
</application>
Here is my intent service class declaration:
public class MyHxMService extends IntentService {
Here is my MyStartupIntentReceiver:
package com.NewApp;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class MyStartupIntentReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Intent serviceIntent = new Intent();
serviceIntent.setAction("org.xxxxx.MyHxMService");
context.startService(serviceIntent);
}
}
Start MyHxMService Service as
#Override
public void onReceive(Context context, Intent intent) {
Intent serviceIntent = new Intent(context,org.xxxxx.MyHxMService.class);
context.startService(serviceIntent);
}
Termination of service : IntentService is designed to be like an AsyncTask, it stops as soon as its work is done. If you need other behavior, consider extending the Service class itself. Also, returning START_STICKY from onStartCommand() in Service class tells android to keep it alive unless explicitly stopped.
Start Up at Boot: You have already setup the BOOT_COMPLETED IntentReciever, just create the Intent with proper Context and Component Class as shown in other answer.
Does every device send the BOOT_COMPLETED? I want to start an Activity on Boot Completed.
I put the following in the Manifest:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<receiver android:name=".BootFinished">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
Created the following class (receiver):
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.widget.Toast;
public class BootFinished extends BroadcastReceiver {
#Override
public void onReceive(Context mContext, Intent intent) {
if(intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
//do something like start an activity or service
}
try {
PackageManager pm = mContext.getPackageManager();
Intent launch = pm.getLaunchIntentForPackage("com.example.afterboot");
mContext.startActivity(launch);
} catch (Exception e) {
Toast.makeText(mContext, e.getMessage(), Toast.LENGTH_SHORT);
}
}
}
Am I missing something? Thanks!
Add full path and secondly add permission in your receiver.
<receiver android:name="com.example.BootFinished"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
As a starting point, try putting the full path of your receiver in the manifest.
The possible reasons why broadcast reciever events could fail:
Receiver not declared in AndroidManifest.xml
Declare the receiver in the Manifest-file:
Receiver in the Manifest xml is misspelled
Android-System is case sensitive. So check your spelling and path is correct in the AndroidMainfest.xml
AVD running for a long time
Reset your avd/device
4.Also if your app is in moved to sdcard.Say you have registered for android.intent.action.BOOT_COMPLETED,the boot event is triggered even before the mediascanner scans the sdcard.
and all the devices which run android sends BOOT_COMPLETE :P
Check again and try :)
all the best :)