I started my service properly, its working well. I write condition that if service is already running then it don't start service again. condition returns true values which shows that service is running. But whenever I force stop my application, or if any exception occurred, my service stops loading data at background and till showing that service is running. That's why service is not re-started.
Intent that I used to start service from activity :
this.startService(new Intent(MainMenu1.this, MovieService.class));
And My service class is :
public class MovieService extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TBD
Log.i("Movie Service : "," Created2");
new MovieDownloaderTask().execute();
return Service.START_FLAG_REDELIVERY;
//return Service.START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
Log.i("Movie Service : "," Created");
}
#Override
public void onDestroy() {
Log.d("Movie Service","onDestroy was Called!");
super.onDestroy();
}
#Override
public void onStart(Intent intent, int startid) {
Log.i("Movie Service : "," Started");
}
public class MovieDownloaderTask extends AsyncTask<Void, Void, Integer>
{
#Override
protected Integer doInBackground(Void... params) {
Log.i("Movie Service"," : Started2");
//Moviejson.createDB();
try
{
Moviejson.insert_Movie_Data();
}
catch(Exception e)
{
Log.e("Exception > ", "i m in doInBackground. Trying to stop Movie service.");
MovieService.this.stopSelf();
e.printStackTrace();
}
return 1;
}
#Override
protected void onPostExecute(Integer result) {
if (result == 1) {
if(MainMenu1.Movies_new_time==null)
{
MainMenu1.Movies_new_time=MainMenu1.sp.getMovies_Old_Date();
}
else
{
MainMenu1.sp.setMovies_Current_Date(MainMenu1.Movies_new_time);
}
MainMenu1.sp.setMovies_Current_Date(MainMenu1.Movies_new_time);
Log.i("Movie Date:", " : "+MainMenu1.Movies_new_time);
MovieService.this.stopSelf();
Log.i("Movie Service"," : Stoped");
super.onPostExecute(result);
}
}
}
}
In your onStartCommand(), replace
return Service.START_FLAG_REDELIVERY;
with
return Service.START_REDELIVER_INTENT
Related
I am very beginner in Android, I am creating android application, communication with Siemens PLC its working fine but if i click button only the data shown in android , I want to run this code in service I don't know how to add code(below) in service
protected String doInBackground(String... strings) {
try{
client.SetConnectionType(S7.S7_BASIC);
int res = client.ConnectTo("10.0.2.2",0,1);
if(res == 0)
{
byte[] data = new byte[4];
res = client.ReadArea(S7.S7AreaDB,1,0,2,data);
ret = "Values "+S7.GetWordAt(data,0);
}
else {
ret = "Err:"+S7Client.ErrorText(res);
}
client.Disconnect();
}
catch (Exception e)
{
ret= "Exe"+e.toString();
Thread.interrupted();
}
return "Executed";
}
Above code is working fine but this code added to service I create one service
public class MyService extends Service {
S7Client client = new S7Client();
String ret = "";
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
PlcReader task=new PlcReader();
task.execute("");
return START_NOT_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
public class PlcReader extends android.os.AsyncTask<String,Void,String>{
#Override
protected String doInBackground(String... strings) {
try{
client.SetConnectionType(S7.S7_BASIC);
int res = client.ConnectTo("10.0.2.2",0,1);
if(res == 0)
{
byte[] data = new byte[4];
client.ReadArea(S7.S7AreaDB,1,0,4,data);
ret = "Values "+S7.GetWordAt(data,0);
}
else {
ret = "Err:"+S7Client.ErrorText(res);
}
client.Disconnect();
}
catch (Exception e)
{
ret= "Exe"+e.toString();
Thread.interrupted();
}
return "Executed";
}
#Override
protected void onPostExecute(String s) {
Toast.makeText(getApplicationContext(),ret,Toast.LENGTH_LONG).show();
}
}
I added code with service but shows connection problem
See this example:-
public class ExtractService extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
AsyncTask task=new AsyncTask();
task.execute();
return START_NOT_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
public class AsyncTask extends android.os.AsyncTask<Void,Void,Void>{
#Override
protected Void doInBackground(Void... voids) {
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
}
}
}
You can call your AsyncTask from the method onStartCommand in the Service:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Let it continue running until it is stopped.
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
new MyAsyncTask().execute("stringParameter")
return START_STICKY;
}
A couple of tips:
I see that you return a String value from your AsyncTask, just avoid using
String result = new MyAsyncTask().execute("stringParameter").get()
As it will block your main thread (unless you start your async task in a different thread).
A more appropriate solution is to handle the result in the onPostExecute method in your AsyncTask (just override it)
Another thing to think about is that AsyncTask is deprecated in Android R, some good alternatives are the java.util.concurrent package and RxJava library
I need to use AsyncTask that called "Logout" when my app is killed by swiped. I used Service to handle this event but it doesn't work.
Added service tag in AndroidManifest.xml
<service
android:name=".MyService"
android:stopWithTask="false" />
My Service code
public class MyService extends Service {
PostClass post = new PostClass();
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("ClearFromRecentService", "Service Started");
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
new Logout().execute();
Log.d("ClearFromRecentService", "Service Destroyed");
}
#Override
public void onTaskRemoved(Intent rootIntent) {
Log.e("ClearFromRecentService", "END");
new Logout().execute();
stopSelf();
}
private class Logout extends AsyncTask<Void, Void, Void> {
JSONObject j;
ProgressDialog pDialog;
JSONObject jso;
String veri_string = "";
protected void onPreExecute() {
Log.e("MyService", "onPreExecute()");
}
protected Void doInBackground(Void... unused) {
Log.e("MyService", "doInBackground()");
return null;
}
protected void onPostExecute(Void unused) {
Log.e("MyService", "onPostExecute()");
}
}
}
I started this service in my first activity.
startService(new Intent(this, MyService.class));
is there any way to solve this problem ? Thanks..
Edit: i changed my AsyncTask code. i put some logs after the all lines. When i see my Logcat, "test1", "test2", "test3", "test4" are showing but "test5" and the others are not.
EDIT:
I test with my phone today, and Use IntentService in other process is working :
<service
android:name=".LogoutService"
android:process=":LogoutProcess"/>
<!-- LogoutService use a different process, So when MyService is destroyed can
start LogoutService -->
<service
android:name=".MyService"
android:enabled="true"
android:exported="false"
android:stopWithTask="false"/>
And the two services code:
public class MyService extends Service {
public static final String TAG = "MyService";
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
Log.e(TAG, "onCreate() called");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, "onStartCommand() called with: intent = [" + intent + "], flags = [" + flags + "], startId = [" + startId + "]");
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
Log.e(TAG, "onTaskRemoved() called with: rootIntent = [" + rootIntent + "]");
Intent logoutService = new Intent(this, LogoutService.class);
startService(logoutService);
this.stopSelf();
}
}
LogoutService.java code
public class LogoutService extends IntentService {
public static final String TAG = "LogoutService";
public LogoutService() {
super(TAG);
Log.e(TAG, "LogoutService() called");
}
#Override
protected void onHandleIntent(#Nullable Intent intent) {
Log.e(TAG, "onHandleIntent() called with: intent = [" + intent + "]");
// This is in the background thread, just call your logout logic:
try {
Log.e(TAG, "onHandleIntent: " );
HttpURLConnection connection = (HttpURLConnection) new URL("https://www.google.com").openConnection();
String result = readInputStreamToString(connection);
Log.e(TAG, "onHandleIntent() result = [" + result + "]");
} catch (IOException e) {
e.printStackTrace();
Log.e(TAG, "onHandleIntent: 111e" );
}
Log.e(TAG, "onHandleIntent: 111a" );
}
}
And the logcat:
03-07 10:04:05.969 8146-8146/org.goodev E/MyService: onCreate() called
03-07 10:04:05.969 8146-8146/org.goodev E/MyService: onStartCommand() called with: intent = [Intent { cmp=org.goodev/com.google.samples.gridtopager.MyService }], flags = [0], startId = [1]
03-07 10:04:10.940 8146-8146/org.goodev E/MyService: onTaskRemoved() called with: rootIntent = [Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=org.goodev/com.google.samples.gridtopager.MainActivity }]
03-07 10:04:10.952 1126-1848/? I/ActivityManager: Start proc 8287:org.goodev:LogoutProcess/u0a248 for service org.goodev/com.google.samples.gridtopager.LogoutService
03-07 10:04:11.016 8287-8287/? E/LogoutService: LogoutService() called
03-07 10:04:11.018 8287-8302/? E/LogoutService: onHandleIntent() called with: intent = [Intent { cmp=org.goodev/com.google.samples.gridtopager.LogoutService }]
03-07 10:04:11.018 8287-8302/? E/LogoutService: onHandleIntent:
03-07 10:04:12.154 8287-8302/org.goodev:LogoutProcess E/LogoutService: onHandleIntent() result = [<!doctype html><html lang="zh-HK"><head><meta content="width=device-width,minimum-scale=1.0" name="viewport"><meta content="telephone=no" name="format-detection"><meta content="address=no" name="format-detection">...orstr=#3f76d3,GradientType=0)}.gb_8a{display:none!import
03-07 10:04:12.154 8287-8302/org.goodev:LogoutProcess E/LogoutService: onHandleIntent: 111a
WARNING: Because the LogoutService is running in other process. So in your logcat do not select "Show only selected application" filter, you should use no filter and filter by tag "MyService|LogoutService".
Why not use IntentService:
#Override
protected void onDestroy() {
// On your main activity's onDestroy method
Intent logoutService = new Intent(this, LogoutService.class);
startService(logoutService);
super.onDestroy();
}
and
public class LogoutService extends IntentService {
public LogoutService() {
super("LogoutService");
}
#Override
protected void onHandleIntent(#Nullable Intent intent) {
// This is in the background thread, just call your logout logic:
List<NameValuePair> params = new ArrayList<>();
try {
veri_string = post.httpPost(cikisURL, "POST", params, 10000);
jso = new JSONObject(veri_string);
}
catch (JSONException e){
e.printStackTrace();
}
Log.e("Response: ", veri_string);
}
}
public class MyService extends Service {
PostClass post = new PostClass();
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("ClearFromRecentService", "Service Started");
return START_NOT_STICKY;
}
#Override
public void onDestroy() {
new Logout().execute();
Log.d("ClearFromRecentService", "Service Destroyed");
}
#Override
public void onTaskRemoved(Intent rootIntent) {
Log.e("ClearFromRecentService", "END");
new Logout().execute();
stopSelf();
}
private class Logout extends AsyncTask<Void, Void, Void> {
JSONObject j;
ProgressDialog pDialog;
JSONObject jso;
String veri_string = "";
protected void onPreExecute() {
}
protected Void doInBackground(Void... unused) {
List<NameValuePair> params = new ArrayList<>();
try {
veri_string = post.httpPost(cikisURL, "POST", params, 10000);
jso = new JSONObject(veri_string);
}
catch (JSONException e){
e.printStackTrace();
}
Log.e("Response: ", veri_string);
return null;
}
protected void onPostExecute(Void unused) {
try {
if(jso.has("data")) {
}
else {
}
pDialog.dismiss();
}
super.onDestroy();
catch (Exception e) {
e.printStackTrace();
}
}
}
}
Try this
I'm creating a service for my android application and I want it to run in onPostExecute on another activity.
below is CheckStatus.class (service class)
public class CheckStatus extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("service", "start");
loop();
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.e("service", "stop service");
}
private void loop(){
long endTime = System.currentTimeMillis()+5*1000;
while (System.currentTimeMillis()<endTime) {
synchronized (this) {
try {
wait(endTime - System.currentTimeMillis());
} catch (Exception e) {
}
}
}
Log.e("service", "Check status");
new CheckStatusTask().execute();
}
private class CheckStatusTask extends AsyncTask<String, Void, Void> {
char check_online;
#Override
protected Void doInBackground(String... params) {
//call url json POST method
try {
//Check return data status
} catch (Exception e) {
e.printStackTrace();
check_online = '2';
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
dialog.dismiss();
if (check_online == '1') {
Toast.makeText(getApplicationContext(), "online", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), "offline", Toast.LENGTH_LONG).show();
}
}
}
}
So I try to call the service on another activity
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
Intent check_status = new Intent(MainActivity.this,CheckStatus.class);
startService(check_status);
}
But this is not running.
How can I make it run (the service)?
Please add following in your manifest.xml
<service
android:name=".NameOfService">
</service>
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;
}
}
I am making AsynkTask within Service like this
public class MyService extends Service {
private final IBinder mBinder = new LocalBinder();
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.v("log_tag", "Service started");
ReceiveAsyncTask receiveATask = new ReceiveAsyncTask();
receiveATask.execute();
return super.onStartCommand(intent, flags, startId);
}
#Override
public IBinder onBind(Intent intent) {
Log.v("log_tag", "onBind");
return mBinder;
}
public class LocalBinder extends Binder {
MyService getService() {
return MyService.this;
}
}
class ReceiveAsyncTask extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... params) {
taskDummy();
return null;
}
#Override
protected void onPreExecute() {
Log.v("log_tag", "onPreExecute");
super.onPreExecute();
}
#Override
protected void onPostExecute(String result) {
Log.v("log_tag", "onPostExecute");
super.onPostExecute(result);
}
#Override
protected void onCancelled() {
Log.v("log_tag", "onPostExecute");
super.onCancelled();
}
}
private void taskDummy() {
while (true) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.v("log_tag", "taskDummy");
}
}
/** method for clients */
public int getRandomNumber() {
Log.v("log_tag", "inner Method called");
return 100;
}
}
when I am running the application it starting to print "taskDummy" every two second as expected, when I close application by prssing Back buttin still log printing continue as expected, but when I removed application from recent apps stack it stopped printing this should not happen I want my asynch task continue in this situation. even I can see my service is running from setting. please advise me.
You need to explicitly call of asyncTaskObject.cancel(true); in onDestroy of your Activity(Or your event whenever you want.)
And then rewrite your while loop logic , something like that:
// Create this variable is Your Asyantask class.
private boolean isRunning = true;
#Override
protected void onCancelled() {
isRunning = false;
}
#Override
protected String doInBackground(Void... params) {
while (isRunning ) {
// Your processing
}
return null;
}
It's a known bug: swiping the service out from recent apps destroys it.
Try following solution.