I have been searching in the entire web understanding why my background service is not working. When I close the application the service is killed without being called back from the Brodcast Receiver. This guide : https://www.quora.com/How-do-I-keep-an-app-running-in-the-background-in-MIUI shows three different methods and none of them is working for me. I'm sure that the application is perfectly working because it works fine with the emulator, same API 24, and it worked with a huawei aswell, again same API.
XML
<service
android:name="com.arvi.neverendingbackgroundservice.SensorService"
android:enabled="true"
android:exported="true"
android:stopWithTask="false">
</service>
<receiver
android:name="com.arvi.neverendingbackgroundservice.SensorRestartBroadcastReceiver"
android:enabled="true"
android:exported="true"
android:label="RestartServiceWhenStopped">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.QUICKBOOT_POWERON"/>
</intent-filter>
</receiver>
Service
public class SensorService extends Service {
private Context ctx;
TimerCounter tc;
private int counter = 0;
private static final String TAG = SensorService.class.getSimpleName();
public SensorService() {
}
public SensorService(Context applicationContext) {
super();
ctx = applicationContext;
Log.i(TAG, "SensorService class");
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate()");
tc = new TimerCounter();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
Log.i(TAG, "onStartCommand()");
tc.startTimer(counter);
return START_STICKY;
}
#Override
public void onDestroy() {
Log.i(TAG, "serviceOnDestroy()");
super.onDestroy();
Intent broadcastIntent = new Intent(getApplicationContext(),SensorRestartBroadcastReceiver.class);
sendBroadcast(broadcastIntent);
tc.stopTimerTask();
}
#Override
public void onTaskRemoved(Intent rootIntent) {
Log.i(TAG, "serviceonTaskRemoved()");
// workaround for kitkat: set an alarm service to trigger service again
Intent intent = new Intent(getApplicationContext(), SensorService.class);
PendingIntent pendingIntent = PendingIntent.getService(this, 1, intent, PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, SystemClock.elapsedRealtime() + 5000, pendingIntent);
super.onTaskRemoved(rootIntent);
}
#Override
public void onLowMemory() {
super.onLowMemory();
Log.i(TAG, "onLowMemory()");
}
}
Related
I want to run my android application always in background like whatsapp,truecaller i have used all things but when device is reboot the application is stop running in background for that i have used broadcast receiver to listen boot. here is my code.
My Service
public class Myservice extends Service {
File file;
private static String fileName = null;
private MediaRecorder recorder = null;
boolean mStartRecording = true;
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy() {
super.onDestroy();
Intent intent = new Intent("RestartService");
}
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public int onStartCommand(final Intent intent, int flags, int startId) {
onTaskRemoved(intent);
file = new File(Environment.getExternalStorageDirectory(), "pranay");
if (!file.exists()) {
boolean mkdir = file.mkdirs();
if (!mkdir) {
Toast.makeText(this, "Fialed", Toast.LENGTH_SHORT).show();
}
}
fileName = Environment.getExternalStorageDirectory().getAbsolutePath() + "/pranay/" + UUID.randomUUID().toString() + "sample.mp3";
Log.i("msg", "running");
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent =
PendingIntent.getActivity(this, 0, notificationIntent, 0);
String channel = "pranay";
NotificationChannel notificationChannel = new NotificationChannel("id", channel, NotificationManager.IMPORTANCE_NONE);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.createNotificationChannel(notificationChannel);
Notification notification = new NotificationCompat.Builder(this, "id")
.setContentTitle("sa")
.setContentText("ssa")
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentIntent(pendingIntent)
.build();
startForeground(1, notification);
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setOutputFile(fileName);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
TelephonyManager manager1 = (TelephonyManager) getApplicationContext().getSystemService(getApplicationContext().TELEPHONY_SERVICE);
manager1.listen(new PhoneStateListener() {
#Override
public void onCallStateChanged(int state, String phoneNumber) {
super.onCallStateChanged(state, phoneNumber);
if (TelephonyManager.EXTRA_STATE_IDLE.equals(intent.getStringExtra(TelephonyManager.EXTRA_STATE))) {
cleanup();
} else if (TelephonyManager.CALL_STATE_OFFHOOK == state) {
try {
recorder.prepare();
} catch (IOException e) {
Log.e("msg", "prepare() failed");
}
recorder.start();
mStartRecording = true;
}
}
}, PhoneStateListener.LISTEN_CALL_STATE);
return super.onStartCommand(intent,flags,startId);
}
private void startForeground(Notification notification, String id) {
startForeground(notification, id);
}
private void cleanup(){
if(recorder!=null)
{
try {
recorder.stop();
}catch (Exception e){
Log.e("msg",String.valueOf(e.getMessage()));
}finally {
recorder.release();
recorder=null;
}
stopSelf();
mStartRecording = false;
}
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onTaskRemoved(Intent rootIntent) {
Intent restartServiceIntent = new Intent(getApplicationContext(),this.getClass());
restartServiceIntent.setPackage(getPackageName());
startService(restartServiceIntent);
super.onTaskRemoved(rootIntent);
}
}
Broad cast receiver
public class Receiver extends BroadcastReceiver {
static final String ACTION = "android.intent.action.BOOT_COMPLETED";
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
Toast.makeText(context,"Booted",Toast.LENGTH_SHORT).show();
Intent serviceIntent = new Intent(context, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startService(serviceIntent);
}
}
Manifest
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<receiver android:name=".Receiver"
android:enabled="true"
android:exported="true"
>
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE"/>
<action android:name="RestartService"/>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<category android:name="android.intent.category.DEFAULT"/>
<action android:name="android.intent.action.QUICKBOOT_POWERON"/>
<action android:name="android.intent.action.REBOOT"/>
</intent-filter>
</receiver>
<service android:name=".Myservice"/>
I am using android 10 and pie is it working on this versions?
You can use JobService android.intent.action.BOOT_COMPLETED this method is not worked on latest version of Android.
JobService
public MyJobService extends JobService {
private Handler myHandler = new Handler(new Handler.Callback() {
#Override
public boolean handler(Message msg) {
Log.e("TAG", "Does it run after reboot? ");
return true;
}
});
#Override
public boolean onStartJob(JobParameters params) {
myHandler.sendMessage(Message.obtain(myHandler, 1, params));
return true;
}
#Override
public boolean onStopJob(JobParameters params) {
myHandler.removeMessages(1);
}
}
MainActivity
MainActivity extends AppCompatActivity {
#Override
protected void onCreate(#Nullable Bundle saveInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout);
ComponentName serviceComponent = new ComponentName(this,MyJobService.class);
JobInfo.Builder builder = new JobInfo.Builder(0, serviceComponent);
builder.setMinimumLatency(1 * 1000);
builder.setOverrideDeadline(5 * 1000);
builder.setPersisted(true);
JobScheduler jobScheduler = (JobScheduler) getSystemService(this.JOB_SCHEDULER_SERVICE);
jobScheduler.schedule(builder.build());
}
}
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="you.package.name">
<application
..............
>
<service
android:name=".your.package.MyJobService"
android:permission="android.permission.BIND_JOB_SERVICE" />
</mainfest>
I am trying to register a FileObserver inside of a service to monitor whenever a new photo has been saved to "/DCIM/Camera/".
So far I have tried everything I could find online. In my opinion it should already work...
i do request permissions in the manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<service android:name=".FileWatcherService"
android:enabled="true"
android:exported="false"/>
<!-- Declaring broadcast receiver for BOOT_COMPLETED event. -->
<receiver android:name=".StartupReceiver" android:enabled="true" android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
my observer:
public class FileWatcherService extends Service {
static String PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + "/DCIM/Camera/";
private static String TAG = "FileWatcher";
public static FileObserver fileObserver = new FileObserver(PATH, CREATE) {
#Override
public void onEvent(int i, #Nullable String s) {
Log.d(TAG, "eventttttt"); //never triggered
}
};
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
Log.d(TAG, "onDestroy: service destroyed");
}
#Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate: service created");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
int res = super.onStartCommand(intent, flags, startId);
fileObserver.startWatching();
Log.d(TAG,"Service started!");
return Service.START_STICKY;
}
public static void start(Context ctx) {
Intent i = new Intent(ctx, FileWatcherService.class);
ctx.startService(i);
}
}
The main activity:
public class MainActivity extends AppCompatActivity {
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(grantResults[0]== PackageManager.PERMISSION_GRANTED){
Log.v(".","Permission: "+permissions[0]+ "was "+grantResults[0]);
FileWatcherService.start(getApplicationContext());
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
}
}
What am I missing? The service starts just fine.
Thanks for your help.
For locally confirming your changes, go to Settings->App info->Your app->Permissions and enable 'Storage' permissions.
Close your app completely (remove from tasks too) and then check if your code works.
What looks to be actually missing is requesting user for access to external storage.
Reference: https://developer.android.com/training/permissions/requesting
I need to create a service that allow my application to work also when I close it, I’ve tried with STICKY_SERVICE but it doesn’t work... if anyone can decribe me how I can do this please answer this question.
It works with android 7.1 and it doesn’t with other versions
Here is my code...
public class SensorService extends Service {
public int counter=0;
public SensorService(Context applicationContext) {
super();
Log.i("HERE", "here I am!");
}
public SensorService() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
startTimer();
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i("EXIT", "ondestroy!");
stoptimertask();
Intent broadcastIntent = new Intent("RestartSensor");
sendBroadcast(broadcastIntent);
}
private Timer timer;
private TimerTask timerTask;
long oldTime=0;
public void startTimer() {
//set a new Timer
timer = new Timer();
//initialize the TimerTask's job
initializeTimerTask();
//schedule the timer, to wake up every 1 second
timer.schedule(timerTask, 1000, 1000); //
}
/**
* it sets the timer to print the counter every x seconds
*/
public void initializeTimerTask() {
timerTask = new TimerTask() {
public void run() {
Log.i("in timer", "in timer ++++ "+ (counter++));
}
};
}
/**
* not needed
*/
public void stoptimertask() {
//stop the timer, if it's not already null
if (timer != null) {
timer.cancel();
timer = null;
}
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
This is my service Restarter...
public class SensorRestarterBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i(SensorRestarterBroadcastReceiver.class.getSimpleName(), "Service Stops");
context.startService(new Intent(context, SensorService.class));
}
}
And the mainClass
public class MainActivity extends AppCompatActivity {
Intent mServiceIntent;
private SensorService mSensorService;
Context ctx;
public Context getCtx() {
return ctx;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ctx = this;
setContentView(R.layout.activity_main);
mSensorService = new SensorService(getCtx());
mServiceIntent = new Intent(getCtx(), mSensorService.getClass());
if (!isMyServiceRunning(mSensorService.getClass())) {
startService(mServiceIntent);
}
}
private boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
Log.i ("isMyServiceRunning?", true+"");
return true;
}
}
Log.i ("isMyServiceRunning?", false+"");
return false;
}
#Override
protected void onDestroy() {
stopService(mServiceIntent);
Log.i("MAINACT", "onDestroy!");
super.onDestroy();
}
}
This restartthe service correctly but after 3/4 seconds it die.
I've added this to my manifest
<service
android:name=".SensorService"
android:enabled="true" >
</service>
<receiver
android:name=".SensorRestarterBroadcastReceiver"
android:enabled="true"
android:exported="true"
android:label="RestartServiceWhenStopped">
<intent-filter>
<action android:name="RestartSensor"/>
</intent-filter>
</receiver>
Add the following code to your sensor service and edit as per your need. You need to bind the sticky service to a notification to keep the service alive and start in the foreground.
#Override
public void onCreate() {
super.onCreate();
Intent notifIntent = new Intent(this, SensorService.class);
PendingIntent pi = PendingIntent.getActivity(this, 0, notifIntent, 0);
Notification notification = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.smslogo_100x100)
.setColor(ContextCompat.getColor(this, R.color.colorAccent))
.setContentTitle(getResources().getString(R.string.app_name))
.setContentText("Running")
.setContentIntent(pi)
.build();
startForeground(101010, notification);
}
This will rectify the issue you are facing and the service will run forever.
This code isn't working for me it should make notification every 2 sec the app runs with no errors and then after 2 sec keeps giving me messages you're app has stopped working.
I added these codes:
AndroidManifest.xml
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<service android:name="NotificationService" android:exported="false"/>
<receiver android:name="BootReceiver">
<intent-filter>
<action android:name="com.company.app"/>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
MainActivity.java
startActivity(new Intent(this,NotificationService.class));
NotificationService.java
public class NotificationService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
mTimer=new Timer();
mTimer.schedule(timerTask,2000,2*1000);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
try {
}catch (Exception e){
e.printStackTrace();
}
return super.onStartCommand(intent, flags, startId);
}
private Timer mTimer;
TimerTask timerTask=new TimerTask() {
#Override
public void run() {
Log.e("log","Running");
notifiy();
}
};
#Override
public void onDestroy() {
try {
mTimer.cancel();
timerTask.cancel();
}catch (Exception e){
e.printStackTrace();
}
Intent intent=new Intent("com.company.app");
intent.putExtra("your value","torestore");
sendBroadcast(intent);
}
public void notifiy(){
IntentFilter intentFilter=new IntentFilter();
intentFilter.addAction("RSSPullService");
Intent mIntent=new Intent(Intent.ACTION_VIEW, Uri.parse(""));
PendingIntent pendingIntent=PendingIntent.getActivity(getBaseContext(),0,mIntent,Intent.FLAG_ACTIVITY_NEW_TASK);
Context context=getApplicationContext();
Notification.Builder builder=new Notification.Builder(context)
.setContentTitle("T")
.setContentText("M")
.setContentIntent(pendingIntent)
.setDefaults(Notification.DEFAULT_SOUND)
.setAutoCancel(true)
;//.setSmallIcon();
Notification notification=builder.build();
NotificationManager notificationManager=(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(1,notification);
}
}
BootReceiver.java
public class BootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("Service stops","ohhhhhhh");
context.startService(new Intent(context,NotificationService.class));
}
}
I'm new at Android,
so please excuse my low experience.
I need this service to check if BroadcastReceiver is running or not every period of time.
If it's running then I want it to do nothing, but if not running I want it to run it.
In this code the service run the receiver every 20 sec, but it didn't check if receiver running or not, so every 20 sec I will get new receiver and the running receiver.
Any idea to solve this problem please?
Receiver.java
public class Receiver extends BroadcastReceiver
{
int numberr =0;
private static final String TAG = "RestartServiceReceiver";
#Override
public void onReceive(Context context, Intent intent) {
int delay = 0;
int period = 10000;
Timer basic_timer = new Timer();
basic_timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
Log.e("view", ""+numberr );
numberr++;
}
}, delay, period);
}
}
Service1.java
public class Service1 extends Service {
public Service1() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
int delay = 0;
int period =20000;
Timer basic_timer = new Timer();
basic_timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
sendBroadcast(new Intent("run"));
}
}, delay, period);
return Service.START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public void onCreate() {
Toast.makeText(this, "Service was Created", Toast.LENGTH_LONG).show();
}
#Override
public void onStart(Intent intent, int startId) {
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
}
#Override
public void onDestroy() {
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
}
I think u just forget to register the receiver in menifest.
try to add this beside service in menifest~
<receiver android:name=".Receiver">
<intent-filter>
<action android:name="run" />
</intent-filter>
</receiver>
<service ...
ps. make sure your service has been started . or try to call this in your activity
startService(new Intent(this, Service1.class));