问题
Good day.I have horrible situation.I am creating an location share logic within session.I keep that session on server on the mysql.When android hits on that activity,i insert accordingly user information.When android leaves the activity ofcourse i delete that column so the session is abandoned for opposite side.All is great until one issue.Android does not provide an callback for app being swiped from recents,meanging app was killed completelly.I have found an work around there.I am using an service and starting service as soon as it reaches my desired activity.In service i have simple thing called onTaskRemoved() which notifies me as soon as the app was killed by swiping it from recents.All good until the point where i want to call to my server in order to remove the column.The call will not just get through,i will never receive any response there,but in onDestroy() everything working as expected.Actually here is the code
@Override
public void onTaskRemoved(Intent rootIntent) {
destroySession();
super.onTaskRemoved(rootIntent);
}
private void destroySession() {
Log.d("Fsafasfsafasfas", "destroySession: " + opponentId + " my user id" + sharedHelper.getUserId());
Call<ResponseBody> locationCall = Retrofit.getInstance().getInkService().requestFriendLocation(sharedHelper.getUserId(), opponentId, "", "", Constants.LOCATION_REQUEST_TYPE_DELETE);
locationCall.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response == null) {
destroySession();
return;
}
if (response.body() == null) {
destroySession();
return;
}
try {
String responseBody = response.body().string();
Log.d("Fsafasfsafasfas", "onResponse: " + responseBody);
JSONObject jsonObject = new JSONObject(responseBody);
boolean success = jsonObject.optBoolean("success");
if (success) {
stopSelf();
} else {
destroySession();
}
} catch (IOException e) {
stopSelf();
e.printStackTrace();
} catch (JSONException e) {
stopSelf();
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
destroySession();
}
});
}
The call will never get through i guess as the only log which is printed,is the id's logs and nothing more..Anyone have a clue whats going on?and how can i handle this situation?
回答1:
/**
* Created by Parag on 01/05/2017.
*/
public class AppService extends android.app.Service {
public static final String TAG=AppService.class.getName();
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Bundle bundle=intent.getExtras();
if(bundle!=null){
final String logout=bundle.getString("logout");
final String driverLoginId=bundle.getString("driverLoginId");
if(logout!=null&&driverLoginId!=null){
Toast.makeText(this, "logging out", Toast.LENGTH_SHORT).show();
Log.e(TAG,"Logging out");
Log.e(TAG,"Inside driverLogout "+driverLoginId);
Call<LogoutResponse> call = RestHandler.getApiService().driverLogout(driverLoginId);
call.enqueue(new Callback<LogoutResponse>() {
@Override
public void onResponse(Call<LogoutResponse> call, Response<LogoutResponse> response) {
//close the service on receiving response from API
Log.e("Response : ",response.body().getStatus()+"");
AppService.this.stopSelf();
}
@Override
public void onFailure(Call<LogoutResponse> call, Throwable t) {
//close the service on receiving response from API
AppService.this.stopSelf();
}
});
}else{
//Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
Log.e(TAG,"DriverLoginId : "+driverLoginId);
Log.e(TAG,"Logout : "+logout);
}
}else{
//Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
Log.e(TAG,"Service Start");
}
return super.onStartCommand(intent,flags,startId);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onTaskRemoved(Intent rootIntent) {
Log.e(TAG,"Service Stop");
UserLocalStore userLocalStore=new UserLocalStore(AppService.this);
Log.e("USER DATA :",userLocalStore.fetchUserData().toString());
Intent restartServiceTask = new Intent(getApplicationContext(),this.getClass());
restartServiceTask.setPackage(getPackageName());
restartServiceTask.putExtra("logout","true");
restartServiceTask.putExtra("driverLoginId",userLocalStore.fetchUserData().getUserId());
PendingIntent restartPendingIntent =PendingIntent.getService(getApplicationContext(), 1,restartServiceTask, PendingIntent.FLAG_ONE_SHOT);
AlarmManager myAlarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
myAlarmService.set(
AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + 1000,
restartPendingIntent);
super.onTaskRemoved(rootIntent);
}
}
I was also facing the same issue of not being able to make any API calls from onTaskRemoved method. So, I also researched a lot but found no solution. So, I finally got an idea of restarting the web service with some extras placed inside the intent. In this manner you can differentiate when the service is restarted to execute your API call.
来源:https://stackoverflow.com/questions/38999142/android-ontaskremoved-call-to-webservice