I have a project which is only a service and it has no activity and user interface. I want to start my application background service when phone boot completely. but I never receive the "BOOT_COMPLETED" Message from OS. these are my code:
Manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.droid.arghaman.location_tracker">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<receiver android:name=".BootBroadcastReceiver"
android:enabled="true"
android:exported="false"
android:label="StartServiceAtBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"></action>
<category android:name="android.intent.category.DEFAULT"></category>
</intent-filter>
</receiver>
</application>
<service android:name=".mySevice"></service>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses-permission>
</manifest>
Broadcast Receiver:
public class BootBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("boot Received", intent.getAction());
Intent serviceLuncher = new Intent(context, myService.class);
context.startService(serviceLuncher);
}
}
myService:
public class LocationNotifierService extends Service {
Timer timer ;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate(){
timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
Toast.makeText(getBaseContext(),"Location",Toast.LENGTH_SHORT).show();
}
},3000);
}
#Override
public void onDestroy(){
}
#Override
public int onStartCommand(Intent intent, int flagId, int startId){
return START_STICKY;
}
}
but I never get "boot Received" log.
is there any mistake and is there any way to debug my program?
I Recommend that my project must have only this Service and it cannot have any UI.
I never receive the "BOOT_COMPLETED" Message from OS
Partly, that is because you do not have a <receiver> set up to receive android.intent.action.BOOT_COMPLETED broadcasts.
Partly, that is because your app will not receive broadcasts until something on the device uses an explicit Intent to start one of your components. The way your app is set up — without an activity that the user can run — it is unlikely that any app will do this, and so your code will never run.
Also, please bear in mind that Android O has changes designed specifically to prevent background services from running for very long and to limit your ability to get background location updates (which your location_tracker name suggests that you want to add in the future). You may wish to reconsider whether writing this app the way that you are is a wise course.
try this in your manifest
<receiver android:name=".BootBroadcastReceiver"
android:enabled="true"
android:exported="false"
android:label="StartServiceAtBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
Related
I'm building a simple reminder application that will remind you of your events.
I've just used "Alarm Manager" with "Broadcast Receiver " to trigger my service at a certain time in the future. The purpose of the service is to vibrate the device when the notification arrives. Notification is working fine but, the Service isn't working as expected. I know that I can simply put the code for vibration inside the "Broadcast Receiver" but NEED TO KNOW ABOUT THE SERVICE. Don't know what's wrong with my code help me out guys, THANKS in advance.
Broadcast Receiver as follows:
public class NotificationSetter extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("AlarmTriggered", "Alarm is triggered to start background service");
Intent serviceVibes = new Intent(context,BackgroundService.class);
context.startService(serviceVibes);
Toast.makeText(context, String.valueOf(Build.VERSION.SDK_INT), Toast.LENGTH_SHORT).show();
//creating the Notification
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "Notify");
builder.setSmallIcon(R.drawable.reminder);
builder.setContentTitle("Reminding of your event");
builder.setContentText("Time to play Cricket");
builder.setAutoCancel(true);
NotificationManagerCompat compat = NotificationManagerCompat.from(context);
compat.notify(3000, builder.build());
}
}
My service class:
public class BackgroundService extends Service {
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("ServiceStarted", "Service is started using NotificationSetter");
Vibrator vibes = (Vibrator) getSystemService(VIBRATOR_SERVICE);
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
vibes.vibrate(VibrationEffect.createOneShot(2000,200));
}else {
vibes.vibrate(2000);
}
Toast.makeText(getApplicationContext(), String.valueOf(Build.VERSION.SDK_INT), Toast.LENGTH_SHORT).show();
return START_STICKY;
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
The Manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.remindme">
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:name="com.example.remindme.MyContext"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".StopAlarm"></activity>
<activity android:name=".GetEvent" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="com.example.remindme.BackgroundService"
android:enabled="true"
android:exported="true">
</service>
<receiver android:name=".NotificationSetter"
android:enabled="true"
android:exported="true"/>
</application>
</manifest>
According to documentation, since Android 8.0 afterwards, an app cannot start a foreground service unless in a few conditions:
https://developer.android.com/about/versions/oreo/background
Check if your service is triggered when you have your app in foreground, meaning that your app has a visible Activity to user. If it works in this condition, then it means your problem lies in background execution limits introduced in Android 8.0. So to make your service work, you can start it as a foreground service by calling this line of code:
ContextCompat.startForegroundService(context, new Intent(context, YourBackgroundService.class));
A foreground service needs a notification to be shown at status bar. You can either grab an instance of your alarm notification and use it as the foreground service notification or create a new notification.
I need an app which will run always in the background and apps will start while phone is turn on. Please help me with example code.
I already tried several code but it run on background while pressing button after start the apps
You need to receive BOOT_COMPLETED of the phone, then start the service.
Follow the following steps
Step 1: create your service
public class myService extends Service{
public myService(){}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
}
Step 2: Create your boot receiver
public class BootReceiver extends BroadcastReceiver {
public void onReceive(final Context context, Intent intent) {
Intent i = new Intent(context, RemindersService.class);
context.startService(i);
}
}
Step 3: add them to manifest inside application
<service
android:name=".services.RemindersService"
android:enabled="true"
android:exported="true" />
<receiver
android:name=".services.BootReceiver"
android:enabled="true"
android:exported="true">
<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>
Step 4: add permission in manifest
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
Thats it. Happy coding.
Please note that in android Oreo, you will want to start service as foreground
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(i);
}
I am trying to start an activity when am restart my phone then its open app or show me toast when booting is complete
class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equalsIgnoreCase(Intent.ACTION_BOOT_COMPLETED)) {
Intent serviceIntent = new Intent(context, MyIntentService.class);
context.startService(serviceIntent);
}
}
}
this is my Broadcaste receiver Code
class MyIntentService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
// do something when the service is created
}
}
This is my service Code.
Manifest
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses-permission>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service android:name=".MyIntentService"></service>
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
am trying lots of diffrent code but no one work for me so can anyone help me to correct this code
Your BroadcastReceiver will never get called because you have this in the manifest entry for it:
android:exported="false"
Remove that.
NOTE: You also need to make sure that your app is started at least once manually after installing it on the phone. Otherwise your BroadcastReceiver will NOT get the BOOT_COMPLETE Intent.
NOTE: Also, using Toast as a debugging aid isn't a very good idea. You should write messages to the logcat and use that to determine if your Service is getting started, etc. Toast is not reliable as a debugging tool.
Add this in BroadcastReceiver class
public void onReceive(Context context, Intent intent) {
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
Intent pushIntent = new Intent(context, SyncData.class);
context.startService(pushIntent);
Log.e("BroadCast Received", "ON BOOT COMPLETE");
}
}
and remove this two lines android:enabled="true"
android:exported="false"
Im trying to track how many times the "SCREEN_ON" is triggered without the user starting the app. The app itself shows a single activity with some charts and info nothing more. I created a small test but i think it's not the correct way because it's draining my battery.
I got a broadcast receiver "BOOT_COMPLETED" that starts a sticky IntentService that is registering the "SCREEN_ON" broadcast receiver with a never ending loop to catch to broadcast's (the battery drain problem).
Is it possible that i can listen on the "SCREEN_ON" broadcast without a Service?
Jur
Manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:name=".Application"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme"
android:hardwareAccelerated="true">
<activity
android:name=".activities.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:enabled="true" android:name=".services.ScreenOnService" />
<receiver android:name=".broadcast.receivers.AutoStartReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver android:name=".broadcast.receivers.ScreenOnReceiver">
<intent-filter>
<action android:name="android.intent.action.SCREEN_ON" />
</intent-filter>
</receiver>
</application>
AutoStartReceiver
public class AutoStartReceiver extends BroadcastReceiver
{
public void onReceive(Context aContext, Intent anIntent)
{
Log.i("[AutoStartReceiver]", "onReceive");
aContext.startService(new Intent(aContext, ScreenOnService.class));
}
}
ScreenOnReceiver
public class ScreenOnReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
Log.i("[ScreenOnReceiver]", "onReceive");
}
}
ScreenOnService
public class ScreenOnService extends IntentService
{
private ScreenOnReceiver theReceiver;
public ScreenOnService()
{
super(ScreenOnService.class.getName());
theReceiver = new ScreenOnReceiver();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.v("[ScreenOnService]", "onStartCommand");
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
#Override
protected void onHandleIntent(Intent intent)
{
Log.i("[ScreenOnService]", "onHandleIntent");
registerReceiver(theReceiver, new IntentFilter(Intent.ACTION_SCREEN_ON));
while(true);
}
#Override
public void onDestroy()
{
Log.i("[ScreenOnService]", "onDestroy");
unregisterReceiver(theReceiver);
super.onDestroy();
}
}
Do you have any particular reason for using an IntentService as opposed to a regular started Service?
You should be able to achieve this using a regular started Service. Register the receiver as part of onStartCommand.
Something like this:
public class MyService extends Service {
private ScreenOnReceiver mReceiver;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (mReceiver == null) {
mReceiver = new ScreenOnReceiver();
registerReceiver(mReceiver, new IntentFilter(Intent.ACTION_SCREEN_ON));
}
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
// remember to unregister receiver in onDestroy...
}
This way you avoid busy looping. IntentService is designed to be a short lived service performing a background operation. Your usage does not fit the purpose of IntentService.
I got a broadcast receiver "BOOT_COMPLETED" that starts a sticky IntentService that is registering the "SCREEN_ON" broadcast receiver with a never ending loop to catch to broadcast's (the battery drain problem)
This is completely inappropriate for an IntentService. Your problem is that an IntentService shuts down after onHandleIntent() returns, forcing you into this busy-wait.
Instead, use a regular Service.
Is it possible that i can listen on the "SCREEN_ON" broadcast without a Service?
AFAIK, ACTION_SCREEN_ON still cannot be registered for in the manifest, so, yes, you need a Service. But you need a Service, not an IntentService.
I got a broadcast receiver "BOOT_COMPLETED" that starts a sticky
IntentService that is registering the "SCREEN_ON" broadcast receiver
with a never ending loop to catch to broadcast's (the battery drain
problem).
This is not correct. The intent service is not design for long running operation.Actually It is no longer remain running after onHandleIntent().
If you want to listen constantly up to device is turn on then service will sure help you to listen each every trigger.
public class ScreenOnService extends Service
{
...........
}
I want to do something when a headset is plugged in when my app is running in the background. (if possible I want to do it with a broadcast receiver)
I tried the code below:
--ReceiveBroadcast--
package com.example.openmusiconheadsetconnect;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class ReceiveBroadcast extends BroadcastReceiver {
public ReceiveBroadcast() {
}
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"Received!",Toast.LENGTH_LONG).show();
}
}
--Manifest--
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.openmusiconheadsetconnect" >
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<receiver
android:name=".ReceiveBroadcast"
android:enabled="true"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.HEADSET_PLUG" />
</intent-filter>
</receiver>
</application>
</manifest>
Thank you!
Your code is correct, but as far as I know, you cannot put the HEADSET_PLUG filter on the manifest.
Instead, create a receiver in its own class, and make it listen for USER_PRESENT (screen unlocked) or BOOT_COMPLETED in the manifest:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<receiver android:name="classes.myReceiver" >
<intent-filter>
<action android:name="android.intent.action.USER_PRESENT" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
When triggered by such events, your receiver should start the service:
public class myReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context ctx, Intent intent) {
Intent service = new Intent(ctx, VoiceLaunchService.class);
if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)||intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
ctx.startService(service);
}
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
ctx.stopService(service);
}
}
The service will now register the receiver that will be listening to the HEADSET_PLUG intent, in its onCreate method:
#Override
public void onCreate() {
super.onCreate();
speechReconRx=new SpeechReconControlReceiver(this);//"this" will allow you to call service's methods from the receiver
registerReceiver(speechReconRx, new IntentFilter(Intent.HEADSET_PLUG));
}
It's is a hassle, but you'll need it if you don't want to use an activity.
It is google's fault for not letting us put PLUG receivers in the manifest! Finally make the Broadcast that will take action when the headset is plugged in.
public class SpeechReconControlReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context ctx, Intent intent) {
Log.e("joshcsr","HEADSET PLUGGED!");
if(intent.getStringExtra("command")!=null){
c=intent.getStringExtra("command");
}
//run some methods from the service
if (c.equals("resume")) {
sService.resume();
}
if (c.equals("pause")) {
sService.pause();
}
if (c.equals("stop")) {
sService.stop();
}
}
}
To wrap, up you will need:
*A receiver for the BOOT/Screen unlock events.
*A Service to hold everything that will run on the background and to register your headset listening broadcast.
*And a receiver for the headset Plug, that will take action and call methods hosted in the service.
I've did this yesterday, and it works from Jelly bean to Lollipop ...and perhaps even older versions. Cheers.
First you'll need permission to start app in background after boot is completed.
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
and also specify this in your broadcast receiver,
<receiver android:name=".YourBroadcastReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
Then create a service that run your application in background, and inside the service use AudioManager.isWiredHeadsetOn() to check if the headset is plugged in. And if so, do the task you want.
while(AudioManager.isWiredHeadsetOn()){
//your task goes here
}
Also add the permission in manifest
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />