Android创建/停止TimerTask

时间:2015-07-30 19:18:06

标签: android timertask

我有一个Android应用程序,它使用计时器任务每3分钟向数据库提交一次。即使用户最小化应用程序,也会假定计时器持续存在。如果我将焦点更改为另一个应用程序,然后更改回来一切正常,但如果我按下主页按钮然后按应用程序图标另一个计时器任务启动。任何人都可以解释原因吗?

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");
    }
}

继承我的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 个答案:

答案 0 :(得分:1)

因此,正如@Robert在评论中建议的那样,这是因为您的TimerTask实例与Activity实例相关联。当您启动另一个Activity实例时(通过点击启动器图标启动您的应用),会创建一个新的TimerTask实例。如果您需要TimerTask独立于活动,那么您需要Service

答案 1 :(得分:0)

当您重新启动应用程序时,MainActivity将通过onCreate和onStart,并在onStart中启动计时器。