Service stop working when turn on /of Wi-Fi many time, when I start service do counter 1,2,3 etc or any thing then turn on /of Wi-Fi many time the service stops working ,I have BroadcastReceiver class doing start service, no exceptions , error appear , only I sent one message to phone to start service..
This is the code inside BroadcastReceiver:
if(intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")) {
Intent recorderIntent = new Intent(context, Start2.class);
context.startService(recorderIntent);
}
This My Start2 Service:
public class Start2 extends Service {
private static final String TAG = Start2.class.getSimpleName();
int mStartMode;
#Override
public void onDestroy() {
Log.d(TAG, "Stop Service onDestroy");
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>() {
#Override
protected String doInBackground(Void... params) {
final Handler handler = new Handler(Looper.getMainLooper());
Runnable runnable = new Runnable() {
int i = 0 ;
#Override
public void run() {
try{
//do your code here
Log.d(TAG, "Start Service Repeat Time.. " + i);
i++;
}
catch (Exception e) {
// TODO: handle exception
}
finally{
//also call the same runnable to call it at regular interval
handler.postDelayed( this, 5000 );
}
}
};
handler.postDelayed(runnable, 1000 );
return null;
}
};
task.execute();
return mStartMode;
}
}
Related
I am trying to load an URL (API) after every 15 seconds in a service. Everything is working fine but when the app is killed URL is not called. I dont need any UI in my app. I just want it to work in background when the app is killed. I have been finding a solution for two days but nothing worked. Please help!
Here is my service code :
public class MyService extends Service {
Handler handler = new Handler();
Runnable runnable;
int delay = 15*1000;
String data ;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(final Intent intent, int flags, int startId) {
handler.postDelayed( runnable = new Runnable() {
public void run() {
data = (String) intent.getExtras().get("data");
Toast.makeText(MyService.this, ""+data, Toast.LENGTH_SHORT).show();
loadURL(data);
handler.postDelayed(runnable, delay);
}
}, delay);
return START_STICKY ;
}
#Override
public void onDestroy() {
handler.postDelayed( runnable = new Runnable() {
public void run() {
Toast.makeText(MyService.this, ""+data, Toast.LENGTH_SHORT).show();
loadURL(data);
handler.postDelayed(runnable, delay);
}
}, delay);
}
public void loadURL(String data){
try{
RequestFuture<JSONObject> requestFuture=RequestFuture.newFuture();
final String mURL = "http://192.168.1.12/att.php?emp_id=" + data + "&status=&submit=Insert";
JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST,
mURL,new JSONObject(),requestFuture,requestFuture);
MySingleton.getInstance(this).addToRequestQueue(request);
Toast.makeText(this, "Done", Toast.LENGTH_SHORT).show();
try {
JSONObject object= requestFuture.get(10, TimeUnit.SECONDS);
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e){
Toast.makeText(this, ""+e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
}
Here is my MainActivity.java where I am getting an intent as a userID :
public class MainActivity extends AppCompatActivity {
String data;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
data = getIntent().getStringExtra("ID");
Intent intent = new Intent(MainActivity.this, MyService.class);
intent.putExtra("data", data);
startService(intent);
}
}
You will have to turn that background service into a foreground service, because of the limitations called Background Execution Limits that started from android Oreo.
Please check out this link for more better understanding:
https://developer.android.com/about/versions/oreo/background
I am currently working on a video conferencing app, what I want to achieve is that when someone calls me and upon receiving their call I closed the app by swiping it from recent apps, and then I want to notify the caller by rejecting the call when the app is closed from recent apps
public class RecentAppService extends Service {
private static final String TAG = "RecentAppStatus";
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate()");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onStartCommand()");
return START_STICKY;
}
#Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
Log.i(TAG, "onTaskRemoved()....!!!!!!!!!!");
Boolean callactive= AppsharedPreference.getAppPrefrerence(this)
.readBooleanData("callingactive");
Log.i(TAG, "onTaskRemoved()....!!!!!!!!!! Callactive ::::"+callactive);
if(callactive){
NotificationManager nManager = ((NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE));
nManager.cancelAll();
rejectCall();
}
Intent restartService = new Intent(getApplicationContext(), this.getClass());
restartService.setPackage(getPackageName());
PendingIntent restartServicePI = PendingIntent.getService(
getApplicationContext(), 1, restartService,
PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmService = (AlarmManager)getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() +1000, restartServicePI);
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy()");
}
#Override
public void onLowMemory() {
super.onLowMemory();
Log.i(TAG, "onLowMemory()");
}
public void rejectCall(){
AsyncTaskRunner runner = new AsyncTaskRunner(this);
runner.execute();
}
}
I have added the above Sticky service to perform the tasks when someone closes my app from recent apps,i have also added the below code that contains Asynctask to the Service to perform the reject call function
class AsyncTaskRunner extends AsyncTask<String, String, String> {
private String resp;
private Context mcontext;
public AsyncTaskRunner(Context mContext) {
this.mcontext=mContext;
}
#Override
protected String doInBackground(String... params) {
publishProgress("Sleeping..."); // Calls onProgressUpdate()
try {
String mUserHash= AppsharedPreference.getAppPrefrerence(mcontext)
.readStringData("mUserHash");
String rejectApi= AppsharedPreference.getAppPrefrerence(mcontext)
.readStringData("rejectApi");
String apiToken= AppsharedPreference.getAppPrefrerence(mcontext)
.readStringData("apiToken");
String room= AppsharedPreference.getAppPrefrerence(mcontext)
.readStringData("room");
String callId= AppsharedPreference.getAppPrefrerence(mcontext)
.readStringData("callId");
ApiCallData apiCallData = new ApiCallData(rejectApi, apiToken, room, callId,mUserHash);
WebService.getWebservice().rejectCall(mcontext, apiCallData, new FutureCallback<String>() {
#Override
public void onCompleted(Exception e, String result) {
Log.i(TAG, "onTaskRemoved()....!!!!!!!!!! Result"+result);
}
});
} catch (Exception e) {
e.printStackTrace();
resp = e.getMessage();
}
return resp;
}
#Override
protected void onPostExecute(String result) {
Log.i(TAG, "onTaskRemoved()....!!!!!!!!!! Result"+result);
}
#Override
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(String... text) {
}
}
Everything works fine and the call gets disconnected correctly at the callerside when the application is not in foreground but when the app is open,then task is not achieved in Asynctask i.e, Asynctask stops when app is closed.. I am newbie to Android ,Thank you
You can use FirebaseJobDispatcher to perform some action even if app is closed.
to use FirebaseJobDispatcher first you need to create a Job , which will be something like this :-
FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(context));
Job myJob = dispatcher.newJobBuilder()
.setService(SyncJobScheduler.class)
.setTrigger(Trigger.executionWindow(0, 0))
.setTag("Set_your_unique_tag_here")
.setReplaceCurrent(false)
.build();
dispatcher.mustSchedule(myJob);
Put this above code where you want to start any task / perform any specific task
and then you can create your Scheduler class like this :-
public class SyncJobScheduler extends JobService {
#Override
public boolean onStartJob(final JobParameters job) {
new Thread(new Runnable() {
#Override
public void run() {
try {
if (("Set_your_unique_tag_here").equalsIgnoreCase(job.getTag())) {
//PERFORM YOUR TASK HERE_ WHICH YOU WANT TO RUN IN ASYNCTASK OR SERVICE
//IT WILL RUN EVEN IF APP IS IN BACKGROUND /CLOSED
}
} catch (Throwable ignored) {
}
}
}).start();
return false;
}
#Override
public boolean onStopJob(JobParameters job) {
return false;
}
}
i have a problem in my service, the service is runnig from MainActivity (i am doing test) and extends of service.
i want to use the service from foreground and background (when the app is closed) and i already have my first problem:
my service(have a counter that is displayed by LOG) is restarting when i close the app.
also i want to be able to use the service with the open app and close app, in other words to use both the Service Started and Link Service
public class MyService extends Service {
private Thread backgroundThread;
private boolean isRunning;
public MyService() {
Log.e("MyService","constructor");
}
#Override
public void onCreate() {
super.onCreate();
isRunning = false;
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public int onStartCommand(final Intent intent, int flags, int startId) {
Log.e("onStartCommand","Servicio Llamado");
if (!this.isRunning) {
Log.e("onStartCommand","hilo iniciandose");
this.backgroundThread = new Thread(myTask);
runTask();
}
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
super.onDestroy();
Log.e("onDestroy","servicio destuido");
}
private void runTask(){
this.isRunning = true;
this.backgroundThread.start();
}
private Runnable myTask = new Runnable() {
public void run() {
Log.e("myTask","hilo iniciado");
int i = 0;
do{
pauseService();
Log.e("myTask","hilo contador: "+i);
//Toast.makeText(getApplicationContext(),"CONTADOR = "+j, Toast.LENGTH_SHORT).show(); //no working :(
i++;
}while (i<10);
/*
//linea de detencion del servicio
//stopSelf();
isRunning=false;
backgroundThread.interrupt();
//backgroundThread = new Thread(myTask);
*/
Log.e("myTask","hilo cerrado");
}
};
private void pauseService(){
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
In main Activity
Intent intent = new Intent(MainActivity.this,MyService.class);
intent.putExtra("iteraciones",10);
startService(intent);
why because the service restarts when I close the application and how can I avoid it?
I start a Service from an activity that gets messages from service and shows in a Dialog. When I click back or Home button, app is killed. And app is not found in the multitasking area. I didn't write any code on onBackPressed(). How may I rectify this issue? Service Code.
public class BleepService extends Service{
String gotAlert;
Context context;
String drAlert=null;
public static boolean status = false;
public static final String TAG = BleepService.class.getSimpleName();
int counter = 0;
static final int UPDATE_INTERVAL = 5000;
private Timer timer = new Timer();
String resServer;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("SERVICE", "COMES TO THE ON STARTCOMMAND");
doRepeat();
//return super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
private void doRepeat() {
Log.i("SERVICE", "COMES TO THE DOREPEAT METHOD");
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
new GetStatus().execute();
}
}, 1000, UPDATE_INTERVAL);
}
class GetStatus extends AsyncTask<Void, Void, String>
{
#Override
protected String doInBackground(Void... params) {
ServiceHandler sh = new ServiceHandler();
resServer = sh.makeServiceCall(Urllist.urlGetPagerStatus, ServiceHandler.GET);
while(resServer.equals("1"))
{
status = true;
resServer = sh.makeServiceCall(Urllist.urlGetMsg, ServiceHandler.GET);
}
return resServer;
}
#Override
protected void onPostExecute(String result) {
Log.i("SERVICE", "COMES TO THE GetStatus AsyncTask Class");
super.onPostExecute(result);
if(!result.equals("0"))
{
Intent i = new Intent("com.bleep.DR_ALERT_MESSAGE");
i.putExtra("msg", result);
sendBroadcast(i);
}else{
Toast.makeText(getApplicationContext(), "No New Message", Toast.LENGTH_SHORT).show();
}
}
}
#Override
public void onDestroy() {
//timer.cancel();
//super.onDestroy();
/*if (timer != null){
timer.cancel();
}*/
}
}
Make sure your Service returns START_STICKY in its onStartCommand. This way OS will restart it if it ever gets killed.
It is legal for an app to be killed by the Android any time while the app is in the background.
However, OS very rarely kills Services. Are you sure you do not somehow kill it yourself, maybe, due to some bug?
I develop android app use GCM, i want to send heartbeat for every 5 minutes at once, i create it when service is run,these are my codes,
public class sendHeartbeat extends Service{
private Handler customHandler = new Handler();
private static final String TAG = "MyService";
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
Log.d(TAG, "onCreate");
}
#Override
public void onStart(Intent intent, int startId) {
Log.d(TAG, "onStart");
customHandler.postDelayed(updateTimerThread, 0);
}
#Override
public void onDestroy() {
Log.d(TAG, "onDestroy");
}
private Runnable updateTimerThread = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
new syncGetHeartbeat().execute();
Log.d("send hearbeat","send hearrrrrrrbeat");
customHandler.postDelayed(this, 260000);
}
};
class syncGetHeartbeat extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... unsued) {
try {
String varId="naengoland";
String url = "http://mydomain.com/gcmserver/getHeartbeat.php?id="+varId;
getRequestJSON(url);
return null;
} catch (Exception e) {
Log.e(e.getClass().getName(), "service get hertbeat "+ e.toString());
return null;
}
}
#Override
protected void onProgressUpdate(Void... unsued) {
}
#Override
protected void onPostExecute(String sResponse) {
}
}
public String getRequestJSON(String Url){
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(Url);
try{
client.execute(request);
}catch(Exception ex){
}
return null;
}
}
I successfully send the heartbeat for every 5 minutes, but the problem is my app running slowly and consume battery a lot, is there any way to send heartbeat beside doing my way?
i mean,the better method than my method.
Please help.
Using TimerTask provides better performance than using Thread (ref).. However TimerTask isn't good in handling multiple threads at the same time which isn't a concern in your case because you are doing one task repeatedly.
here is the code for Timer:
first initialize a Timer:
private Timer timer;
in onCreate:
timer = new Timer();
then within onStart:
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// TODO Auto-generated method stub
new syncGetHeartbeat().execute();
Log.d("send hearbeat","send hearrrrrrrbeat");
}
}, 0, 300000); //means start at 0 second and each 5 mins (300000 ms) run the task
I'm not sure if there is another solution that has better performance however this is absolutely better than running thread in a fixed rate.