2015-07-30 3 views
0

У меня есть приложение для Android, которое делает представления в базе данных каждые 3 минуты, используя задачу таймера. Таймер, как предполагается, сохраняется, даже если пользователь минимизирует приложение. Если я сфокусирую фокус на другое приложение, а затем изменим все, то все будет работать правильно, но если я нажму кнопку «Домой», а затем нажмите кнопку «Приложение», начнется другая задача таймера. Может ли кто-нибудь объяснить, почему?Создание/остановка Android TimerTask

package temp; 

import android.app.Activity; 
import android.content.Context; 
import android.content.Intent; 
import android.location.Location; 
import android.net.ConnectivityManager; 
import android.net.NetworkInfo; 
import android.net.Uri; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.View; 
import android.widget.Button; 
import android.widget.ImageButton; 
import android.widget.TextView; 
import android.widget.Toast; 
import android.location.Geocoder; 

import com.google.android.gms.common.ConnectionResult; 
import com.google.android.gms.common.GooglePlayServicesUtil; 
import com.google.android.gms.common.api.GoogleApiClient; 
import com.google.android.gms.common.api.PendingResult; 
import com.google.android.gms.common.api.Status; 
import com.google.android.gms.location.LocationListener; 
import com.google.android.gms.location.LocationRequest; 
import com.google.android.gms.location.LocationServices; 

import java.text.DateFormat; 
import java.util.Date; 
import java.util.Locale; 

public class MainActivity extends Activity implements LocationListener, 
     GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener{ 

    private Button bLogout, bWebsite; 
    private ImageButton bLogData; 
    private TextView etLabel; 
    private UserLocalStore userLocalStore; 
    private String mLastUpdateTime; 
    private LocationRequest mLocationRequest; 
    private GoogleApiClient mGoogleApiClient; 
    private static final String TAG = "MainActivity"; 
    private static final long INTERVAL = 1000 * 15; 
    private static final long FATEST_INTERVAL = 1000 * 30; 
    private Geocoder geocoder; 
    AddressOps addressOps; 
    TimerUpdate timerUpdate; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     Log.e(TAG, "On Create . . . . ."); 

     if(!isGooglePlayServicesAvailable()){ 
      startActivity(new Intent(MainActivity.this, login.class)); 
      finish(); 
      Toast.makeText(getApplicationContext(), "Please update GooglePlay Servies to use this Application", Toast.LENGTH_LONG).show(); 
     }else { 
      mGoogleApiClient = new GoogleApiClient.Builder(this) 
        .addApi(LocationServices.API) 
        .addConnectionCallbacks(this) 
        .addOnConnectionFailedListener(this) 
        .build(); 

      createLocationRequest(); 
      userLocalStore = new UserLocalStore(this); 
      this.geocoder = new Geocoder(MainActivity.this, Locale.getDefault()); 
      addressOps = new AddressOps(this.geocoder); 

//   if(this.timerUpdate == null && authenticate() == true) { 
//    this.timerUpdate = new TimerUpdate(this, addressOps); 
//    timerUpdate.startTimer(); 
//   } 

      etLabel = (TextView) findViewById(R.id.etEmailLabel); 
      bLogout = (Button) findViewById(R.id.bLogout); 
      bLogData = (ImageButton) findViewById(R.id.DataLog); 
      bWebsite = (Button) findViewById(R.id.website); 

      bLogData.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View arg0) { 
        String pressStatus = "3"; 
        timerUpdate.update(pressStatus); 
       } 
      }); 

      bLogout.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View arg0) { 
        userLocalStore.clearuserData(); 
        userLocalStore.setUserLoggedIn(false); 
        timerUpdate.stopTimerTask(); 
        startActivity(new Intent(MainActivity.this, login.class)); 
        finish(); 
       } 
      }); 

      bWebsite.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View arg0) { 
        Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://temp.com")); 
        startActivity(browserIntent); 
       } 
      }); 
     } 
    } 

    private void displayUserDetails(){ 
     User user = userLocalStore.getLoggedInUser(); 
     String userdisplay = "Logged in as: " + user.username; 
     etLabel.setText(userdisplay); 
    } 

    private boolean authenticate(){ 
     return userLocalStore.getUserLoggedIn(); 
    } 

    private boolean isNetworkAvailable() { 
     ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); 
     NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo(); 
     Log.e(TAG, "Network Check"); 
     return activeNetworkInfo != null && activeNetworkInfo.isConnected(); 
    } 

    private boolean isGooglePlayServicesAvailable() { 
     int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this); 
     if (ConnectionResult.SUCCESS == status) { 
      return true; 
     } else { 
      GooglePlayServicesUtil.getErrorDialog(status, this, 0).show(); 
      return false; 
     } 
    } 

    protected void createLocationRequest(){ 
     mLocationRequest = new LocationRequest(); 
     mLocationRequest.setInterval(INTERVAL); 
     mLocationRequest.setFastestInterval(FATEST_INTERVAL); 
     mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
    } 

    @Override 
    public void onConnected(Bundle bundle) { 
     Log.e(TAG, "onConnected: Connected - " + mGoogleApiClient.isConnected()); 
     startLocationUpdates(); 
    } 

    protected void startLocationUpdates() { 
     PendingResult<Status> pendingResult = LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); 
     Log.e(TAG, "Location update started "); 
    } 

    @Override 
    public void onConnectionSuspended(int i) { 
     stopLocationUpdates(); 
     Log.e(TAG, "On Connection Suspended " + mGoogleApiClient.isConnected()); 
     Toast.makeText(getApplicationContext(), "No Network Connection", Toast.LENGTH_LONG).show(); 
    } 

    @Override 
    public void onConnectionFailed(ConnectionResult connectionResult) { 
     Log.e(TAG, "Connection failed " + connectionResult.toString()); 
     stopLocationUpdates(); 
     Log.e(TAG, "onConnectionFailed " + mGoogleApiClient.isConnected()); 
     Toast.makeText(getApplicationContext(), "No Network Connection", Toast.LENGTH_LONG).show(); 
    } 

    @Override 
    public void onLocationChanged(Location location) { 
     Log.e(TAG, "Firing onLocationChanged........."); 
     if(this.timerUpdate != null) { 
      timerUpdate.location = location; 
     }else{ 
      Log.e(TAG, "Timer is null"); 
     } 
     mLastUpdateTime = DateFormat.getTimeInstance().format(new Date()); 
    } 

    protected void stopLocationUpdates() { 
     LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this); 
     Log.e(TAG, "Location update stopped"); 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     Log.e(TAG, "MainActivity Paused"); 
    } 

    @Override 
    public void onResume() { 
     super.onResume(); 
     Log.e(TAG, "MainActivity Resumed"); 
     if (mGoogleApiClient.isConnected()) { 
      if(!isGooglePlayServicesAvailable()){ 
       startActivity(new Intent(MainActivity.this, login.class)); 
       Toast.makeText(getApplicationContext(), "Please update GooglePlay Servies to use this Application", Toast.LENGTH_LONG).show(); 
       finish(); 
      } 
     } 
    } 

    @Override 
    public void onStart() { 
     super.onStart(); 

     if(authenticate() == true){ 
      displayUserDetails(); 
      if(this.timerUpdate == null) { 
       this.timerUpdate = new TimerUpdate(this, addressOps); 
       Log.e(TAG, "Timer created"); 
       timerUpdate.startTimer(); 
      } 
     }else{ 
      startActivity(new Intent(MainActivity.this, login.class)); 
      finish(); 
     } 

     mGoogleApiClient.connect(); 
     Log.e(TAG, "MainActivity Started, GoogleApi Connection: " + mGoogleApiClient.isConnected()); 
    } 

    @Override 
    public void onStop() { 
     super.onStop(); 
     Log.e(TAG, "MainActivity Stopped"); 
    } 
} 

Heres мой TimerTask класс

package temp; 

import android.content.Context; 
import android.location.Location; 
import android.net.ConnectivityManager; 
import android.net.NetworkInfo; 
import android.os.Handler; 
import android.util.Log; 
import android.widget.Toast; 

import java.util.Timer; 
import java.util.TimerTask; 

public class TimerUpdate { 
    private Timer timer; 
    private TimerTask timertask; 
    public boolean timerScheduled = false; 
    private final Handler handler = new Handler(); 
    private static final String TAG = "UpdateTimer"; 
    AddressOps addressOps; 
    private Context mainContext; 
    private UserLocalStore userLocalStore; 
    public Location location; 

    public TimerUpdate(Context context, AddressOps ops){ 
     initializeTimerTask(); 
     this.mainContext = context; 
     this.addressOps = ops; 
     userLocalStore = new UserLocalStore(context); 
    } 

    private void initializeTimerTask(){ 
     timertask = new TimerTask() { 
      public void run(){ 
       handler.post(new Runnable(){ 
        public void run(){ 
         Log.e(TAG, "TimerTask Ran"); 
         String status = "5"; 
         update(status); 
        } 
       }); 
      } 
     }; 
    } 

    public void startTimer(){ 
     timer = new Timer(); 
     timer.schedule(timertask, 1000 * 30, 1000 * 60 * 3); 
     timerScheduled = true; 
     Log.e(TAG, "Start Schedule created"); 
    } 

    public void stopTimerTask(){ 
     if (timer != null){ 
      timer.cancel(); 
      timer = null; 
      Log.e(TAG, "Timer Stopped"); 
     } 
    } 

    public void update(String status) { 
     Log.e(TAG, "Update initiated ............."); 
     if (location != null) { 
      double lat = location.getLatitude(); 
      double lng = location.getLongitude(); 

      if(isNetworkAvailable()){ 
       String address = addressOps.getAddressString(lng, lat); 
       if(address != null) { 
        User user = userLocalStore.getLoggedInUser(); 
        ServerRequest request = new ServerRequest(this.mainContext); 
        request.storeLocationInBackground(lat, lng, user.username, address, status); 
        Toast.makeText(this.mainContext, "Longitude: " + lng + "\nLatitude: " 
          + lat + "\nAddress: " + address, Toast.LENGTH_SHORT).show(); 
       }else{ 
        Toast.makeText(this.mainContext, "Unable to retrieve Address", Toast.LENGTH_SHORT).show(); 
       } 
      }else{ 
       Toast.makeText(this.mainContext, "No Network Connection" + "\nLatitude: " + lat 
         + "\nLongitude: " + lng, Toast.LENGTH_LONG).show(); 
      } 

     } else { 
      Log.e(TAG, "There is no current Location Data in Update"); 
      Toast.makeText(this.mainContext, "There is no current Location Data ....", Toast.LENGTH_SHORT).show(); 
     } 
    } 

    private boolean isNetworkAvailable() { 
     ConnectivityManager connectivityManager = (ConnectivityManager)mainContext.getSystemService(Context.CONNECTIVITY_SERVICE); 
     NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo(); 
     Log.e(TAG, "Network Check"); 
     return activeNetworkInfo != null && activeNetworkInfo.isConnected(); 
    } 
} 
+2

Приложение для Android должно выполнять только задачи на переднем плане. Если вы хотите сделать что-то в фоновом режиме, выполните службу в сочетании с CountDownTimer. – Robert

ответ

1

Так что, как @Robert предложил в комментариях, это происходит потому, что ваш TimerTask экземпляр привязан к экземпляру Activity. Когда вы запускаете другой экземпляр Activity (путем запуска приложения, нажав значок запуска), создается новый экземпляр TimerTask. Если вам нужно, чтобы ваш TimerTask был независим от деятельности, вам понадобится Service.

+0

У меня было ощущение, что это так, но я не был уверен. Я попытался проверить его, поставив нулевую проверку, но я сделал это неправильно. Спасибо, что подтвердили! – Walorn

+1

Добро пожаловать, рад, что смогу помочь. – Egor

0

Когда вы перезагружаете приложение, MainActivity проходит через onCreate и onStart, а в onStart вы запускаете таймер.

Смежные вопросы