android run class in service with new thread - java

i just use service to make something like chathead and this is my result
but only i have two problem
first some time my service killed i notice that's on weak device so how can i prevent it from killed in same time the facebook messenger never killed
second my class animation not smooth i think i must run the class on new thread
xxx = new classanimation (mContext);
i tried this
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
xxx = new classanimation (mContext);
}
});
but i see it same no different
and this is my service code
public class MyCustomService extends Service {
private volatile HandlerThread mHandlerThread;
private ServiceHandler mServiceHandler;
private static Context mContext;
Handler mHandler;
IBinder mBinder = new LocalBinder();
public static Socket client;
public classanimation xxx;
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public class LocalBinder extends Binder {
public MyCustomService getServerInstance() {
return MyCustomService.this;
}
}
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
// Define how to handle any incoming messages here
#Override
public void handleMessage(Message message) {
// ...
// When needed, stop the service with
// stopSelf();
}
}
public void onCreate() {
super.onCreate();
this.mContext = this;
xxx= new classanimation(mContext); //class i run it but its not smooth
mHandler = new Handler(Looper.getMainLooper());
// An Android handler thread internally operates on a looper.
mHandlerThread = new HandlerThread("MyCustomService.HandlerThread");
mHandlerThread.start();
// An Android service handler is a handler running on a specific background thread.
mServiceHandler = new ServiceHandler(mHandlerThread.getLooper());
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Send empty message to background thread
mServiceHandler.sendEmptyMessageDelayed(0, 500);
// or run code in background
mServiceHandler.post(new Runnable() {
#Override
public void run() {
// Do something here in background!
SessionManager session = new SessionManager(mContext);
// If desired, stop the service
//stopSelf();
}
});
// Keep service around "sticky"
return START_STICKY;
}
#Override
public void onDestroy() {
// Cleanup service before destruction
mHandlerThread.quit();
}
}

To ensure that your service is never killed, you can make your service a foreground service by using a notifiaction. This means that there will always be a notification icon when the service is running, but it will never be killed. For example :
Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text), System.currentTimeMillis());
Intent notificationIntent = new Intent(this, ExampleActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(this, getText(R.string.notification_title), getText(R.string.notification_message), pendingIntent);
startForeground(ONGOING_NOTIFICATION_ID, notification);

You can't prevent from killing,Yes but you can minimize probability of killing by starting service in different process than your app process.

Related

How to gracefully shut down all activities and close all running threads in an Android app?

At the moment, in each one of my activities I have this method:
private void registerReceiverClose(){
Activity activity = this;
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("CLOSE_ALL");
broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
activity.finish();
}
};
registerReceiver(broadcastReceiver, intentFilter);
}
and this one as well:
#Override
protected void onDestroy() {
unregisterReceiver(broadcastReceiver);
super.onDestroy();
}
They're triggered by the following logout button:
Button logout = findViewById(R.id.logout_button);
logout.setOnClickListener(click -> {
Intent intent = new Intent("CLOSE_ALL");
this.sendBroadcast(intent);
});
One thing that I'm sure is not closing in the right way, is that I have this code:
private static final ScheduledExecutorService pollingScheduledExecutor = Executors.newSingleThreadScheduledExecutor();
private static final Object lock = new Object();
private static ScheduledFuture<?> currentRunningTask;
public void longPoll() {
synchronized (lock) {
if (currentRunningTask != null) {
currentRunningTask.cancel(true);
}
try {
currentRunningTask = pollingScheduledExecutor.scheduleAtFixedRate(this, 0, 3, TimeUnit.SECONDS);
} catch (Exception ignored) {
}
}
}
public void request() {
Thread requestThread = new Thread(this);
requestThread.start();
}
which continues to issue requests even after I think I should be logged out, which causes errors on the server.
How can I make sure all the threads stop gracefully and the application closes down in the right way?
You could wrapthe polling code inside of a Service. This service can then be stopped using
Intent intent = new Intent(MainActivity.this, MyService.class);
stopService(intent);
Inside of the service, you can override onDestroy() to clean resources up.

How to keep alive a service, after starting, until the application be closed or killed in Android?

I am developing android application, so I am starting a service with alarm:
public void scheduleLocationCheckerAlarm() {
Intent intent = new Intent(getApplicationContext(), LocationCheckerReceiver.class);
final PendingIntent pIntent = PendingIntent.getBroadcast(this, LocationCheckerReceiver.REQUEST_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
long firstMillis = System.currentTimeMillis();
AlarmManager alarm = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
alarm.setInexactRepeating(AlarmManager.RTC_WAKEUP, firstMillis, 600000, pIntent);
}
LocationCheckerReceiver:
public class LocationCheckerReceiver extends BroadcastReceiver {
public static final int REQUEST_CODE = 12345;
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, LocationNotificator.class);
context.startService(i);
}
Service:
public class LocationNotificator extends Service {
public LocationNotificator() {
}
#Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("Location checker", "Service running");
//My code is here
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d("Location checker", "Service destroyed");
}
So I want this service to be checking for something every 1 minute and to be running all the time, even when the application is closed by the user.
You must call startForeground(FOREGROUND_ID, buildForegroundNotification(filename)); in order to ensure that your service running continuously. Also, this will post a notification from your app to show the user about the service state. Please follow the reference.
Here is the code :
public class LocationNotificator extends Service {
private static int FOREGROUND_ID=1338;
public LocationNotificator() {
}
#Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("Location checker", "Service running");
//My code is here
startForeground(FOREGROUND_ID,
buildForegroundNotification(filename));
stopForeground(true);
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d("Location checker", "Service destroyed");
}
private Notification buildForegroundNotification(String filename) {
NotificationCompat.Builder b=new NotificationCompat.Builder(this);
b.setOngoing(true);
b.setContentTitle("Some Title")
.setContentText("some File name")
.setSmallIcon(android.R.drawable.stat_sys_download)
.setTicker("downloading");
return(b.build());
}
You need to read this first. https://developer.android.com/guide/components/services.html
In a nutshell, start your service as a foreground service so there's lesser chance of Android killing your service. As a foreground service, you need to display an on-going notification in the status bar.
There's no direct way of making sure your service is never killed by the Android system. A workaround is to send a broadcast in onDestroy() of your service, and have a Receiver in your Android application start the service upon receiving the broadcast.
By the way, it seems that your service is sending location updates periodically to your backend server. This might be better implemented using Firebase Job Dispatcher library or Evernote's Android-Job library.

Can I Make A Background Service That runs at certain intervals of time even after closing the Application

I am Referring this Application https://github.com/hzitoun/android-camera2-secret-picture-taker.
In this Application there are two classes(APictureCapturingService.java & PictureCapturingServiceImpl.java) that takes pictures without preview can these two classes be converted to Background Service that runs always never dies.
Is this possible to have camera capturing process as a background service if yes how to proceed?
I don't know how you are taking picture in your activity but i can guide you to run your app in background even your close your app and you can able to run your camera code in every second..
public class SampleService extends Service {
public SampleService() {
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return null;
}
#Override
public int onStartCommand(final Intent inten, int flags, int startId) {
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
#Override
public void run() {
// Make use your method here..
}
});
}
}, 5000, 2000);
return super.onStartCommand(inten, flags, startId);
}
#Override
public void onCreate() {
super.onCreate();
}}
And you need to start the service form activity..
startService(new Intent(this, SampleService.class));
I have used this for monitoring the foreground app it will work..

This is the correct way to repeat method every x second in service?

I write a method on service to run every x seconds. But there are some problems.
What I did is
public class noti extends Service {
Context mcont;
private Handler myhandler ;
private long RETRY_TIME = 15000;
private long START_TIME = 2000;
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public void onStart(Intent intent, int startId) {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
mcont=this;
myhandler= new Handler();
myhandler.postDelayed(myRunnable, START_TIME);
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
super.onDestroy();
try {
myhandler.removeCallbacks(myRunnable);
} catch (Exception e) {
// TODO: handle exception
}
}
private Runnable myRunnable = new Runnable() {
public void run() {
try {
new get_notifyalert_service(mcont).execute("") ;
} catch (Exception e) {
// TODO: handle exception
}
myhandler.postDelayed(myRunnable, RETRY_TIME);
}
};
}
this is the right way?
on the phone when I check the settings->apps->running-apps it says sometimes restarting and it took long time
thanks in advance
I see two problems in your solution:
First: Your commands will indeed be activated periodically, but they will do so on the main thread. In many cases, maybe most, you want your periodical processing to run on a separate thread.
if that is what you want, a timer will be a better option:
t = new Timer();
task = new TimerTask() {
#Override
public void run() {
// do periodical action <-------------
}
};
t.scheduleAtFixedRate(task, 0, 1000);
Second: your service will, sooner or later, be reclaimed by Android, stopping the periodical
processing.
For many apps this is not a real problem. You do not really want your background logic running all the time.
If that is not the case for you, declare your service as a foreground service (i.e. guaranteed not to be killed by Android):
Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),
System.currentTimeMillis());
Intent notificationIntent = new Intent(this, ExampleActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(this, getText(R.string.notification_title),
getText(R.string.notification_message), pendingIntent);
startForeground(ONGOING_NOTIFICATION_ID, notification);
..Or, at minimum, set it to be sticky:
public class StickyService extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return Service.START_NOT_STICKY;
}
}

Android service won't start - in manifest... but nothing?

UPDATE:
After adding the suggested methodes (doBindService() and doUnbindService()) along with calls to no avail) From here suggested by #Nick Campion
I've been trying for a while to get this service running but nothing seems to be working - I know I'm probably missing a semicolon or something :)
The program calls startNotificationService(), then the Log shows the log message... and the app continues to run without the Service showing up. I can't find the Service in Advance Task Killer. HELP!!!
XML (In Manifest) :
<service
android:icon="#drawable/icon"
android:label="Smart Spdate Service"
android:name="notifyService">
<intent-filter
android:label="FULL_PATH_NAME_HERE.updateService">
</intent-filter>
</service>
Service Call
Log.v("NOTICE", "Notification Service was not found running - starting");
//startService(new Intent(this, notifyService.class));
startService(new Intent(notifyService.class.getName()));
//startService(new Intent(TweetCollectorService.class.getName()));
/* FROM GOOGLE */
void doBindService() {
// Establish a connection with the service. We use an explicit
// class name because we want a specific service implementation that
// we know will be running in our own process (and thus won't be
// supporting component replacement by other applications).
this.bindService(new Intent(this, updateService.class), mConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
}
void doUnbindService() {
if (mIsBound) {
// Detach our existing connection.
unbindService(mConnection);
mIsBound = false;
}
}
/* END OF GOOGLE CODE */
#Override
public void onDestroy() {
web.close();
doUnbindService(); // Added to `onDestroy` - suggested by Google page
super.onDestroy();
Log.v("NOTICE", "PROGRAM TERMINATED");
}
updateService.java
public class updateService extends Service {
private String TAG = "SERVICE";
public static final int INTERVAL = 60000;
private Timer timer = new Timer();
private static updateService Pointer;
public updateService() {
Pointer = updateService.this;
}
public static class LocalBinder extends Binder {
static updateService getService() {
return Pointer;
}
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy() {
if (timer != null) {
timer.cancel();
}
super.onDestroy();
}
#Override
public void onStart(Intent intent, int startId) {
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
doStuff();
}
}, 0, INTERVAL);
super.onStart(intent, startId);
}
public void doStuff() {
Log.v(TAG, "doStuff");
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
private final IBinder mBinder = new LocalBinder();
}
I don't see anywhere where your client binds to your service. Take a look at the local service example.. The reason for using the bind pattern even though you call startService is because the startService call is asynchronous. You need to make an additional call to bind the service to make sure you get a call back once the startup is complete.
I've found that a really great example of a service client and service are available in the NPR Open Source App for you to learn from!

Categories

Resources