I am currently working on an app that uploads a file to my server. My app is designed to been started, used till task is done, and at the end the file upload will be initiated by pressing a button and the app has been used what it is there for. So a very linear approach: start, use till the end, file upload, done.
Now I would like to also send the file to my server if for some reason one decides not to use it till the end. So when the onStop() gets called.
After some research I decided to go with a unbound service that gets called in onStop() with startService(). Within that service there is while loop that is executed until the upload has been successful (serverResponseCode == 200) and sleeps after every unsuccessful attempt.
When the user starts using the stopped app again, thus calling onResume() I would like to cancel the file transfer as the user will upload the file at the end anyways by clicking the upload button in a different activty. So when I try to stop the service in onResume(), I receive the Toast that the service is stopped, but I see in my logcat that it is still running: try to connect to the server and sleeping.
What I have tried so far:
1) tried what was suggested on the the answers in:
automatically start up a service when the application is closed
2) Even when onStartCommand returns START_NOT_STICKY it happens.
HERE MY CODE:
Service Code:
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.Toast;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class UploadService extends Service {
private Looper mServiceLooper;
private ServiceHandler mServiceHandler;
private static final String TAG = "UploadService";
int serverResponseCode = 0;
String upLoadServerUri = null;
String uploadFilePath;
String uploadFileName;
// Handler that receives messages from the thread
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
//... have some Server connection parameters here
while (serverResponseCode != 200) {
// ... trying to upload a file to my server
if (serverResponseCode != 200) {
try {
Log.d(TAG, "Thread slepps");
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
stopSelf(msg.arg1);
}
}
private class DisplayToast implements Runnable {
String mText;
public DisplayToast(String text) {
mText = text;
}
public void run() {
Toast.makeText(UploadService.this, mText, Toast.LENGTH_SHORT).show();
}
}
@Override
public void onCreate() {
// Start up the thread running the service. Note that we create a
// separate thread because the service normally runs in the process's
// main thread, which we don't want to block. We also make it
// background priority so CPU-intensive work will not disrupt our UI.
HandlerThread thread = new HandlerThread("ServiceStartArguments", Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
// Get the HandlerThread's Looper and use it for our Handler
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
// For each start request, send a message to start a job and deliver the
// start ID so we know which request we're stopping when we finish the job
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
mServiceHandler.sendMessage(msg);
// If we get killed, after returning from here, restart
return START_STICKY;
}
@Override
public void onDestroy() {
Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
Activity that calls starts and stops the service:
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.LayerDrawable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.PopupMenu;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.RatingBar;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.SearchView;
import android.widget.SearchView.OnQueryTextListener;
import java.text.SimpleDateFormat;
import java.util.Date;
public class AppSelectionActivity extends AppCompatActivity implements View.OnClickListener, OnQueryTextListener {
private final static String TAG = "AppSelectionActivity";
private boolean leftOnIntent = false; // is set to true when starting one of my other activity with an intent, so that service will not be started
private Intent serviceIntent;
@Override
protected void onStop() {
Log.d(TAG,"onStop: app is stopped");
if (!leftOnIntent) {
serviceIntent = new Intent(AppSelectionActivity.this, UploadService.class);
startService(serviceIntent);
Log.d(TAG, "onStop: Intent is started");
}
super.onStop();
}
@Override
protected void onResume() {
super.onResume();
Log.d(TAG,"onResume: app is resumed");
stopService(new Intent(AppSelectionActivity.this, UploadService.class));
leftOnIntent = false;
}
@Override
protected void onDestroy() {
Log.d(TAG,"onDestroy: got called");
super.onDestroy();
}
}
Any suggestions how to stop the service and the file uploade correctly?