在设定的时间间隔内运行AsyncTask

时间:2013-08-02 20:33:16

标签: android timer android-asynctask intervals

我是Android的新手,所以这个问题可能很简单,但无论如何它仍然存在:

我正在创建一个Android应用程序,它将使用AsyncTask将用户的位置发送到远程数据库。现在,当您单击按钮时会发生这种情况,但我希望它能够以设定的间隔自动发生。

我试图制作一个处理程序和一个“scheduleAtFixedRate”,但它对我不起作用;可能只是因为我做错了。这是我的代码:

package com.paul.locations;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Timer;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

public class OptionsPage extends Activity implements OnClickListener {

private String lat="", lon="", current = "";
private Button  bUpdate, bGoogleMap, Confirm;
private EditText TimerInterval;
private TextView  Latit, Longit;
final Handler handler = new Handler();
private static final String TAG_SUCCESS = "success";
private static final String TAG_MESSAGE = "message";
private static final String UPDATE_INFO_URL = "http://192.168.1.16/locations/update_info.php";
 // Progress Dialog
private ProgressDialog pDialog;

// JSON parser class`enter code here`
JSONParser jsonParser = new JSONParser();

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.options);

    TimerInterval = (EditText) findViewById(R.id.etTimer);
    Longit = (TextView) findViewById(R.id.tvLon);
    Latit = (TextView) findViewById(R.id.tvLat);
    bUpdate = (Button)findViewById(R.id.bUpdate);
    bUpdate.setOnClickListener(this);
    bGoogleMap = (Button)findViewById(R.id.bGoogleMap);
    bGoogleMap.setOnClickListener(this);
    Confirm = (Button)findViewById(R.id.bConfirm);
    Confirm.setOnClickListener(this);


            //This is the new line for timer task
TimerTask task = new TimerTask(){
        @Override
        public void run(){
            new AttemptUpdate().execute();
        }

    };

    new Timer().scheduleAtFixedRate(task,0,5000);
}

@Override
public void onClick(View v) {
    // TODO Auto-generated method stub
    switch (v.getId()) {
    case R.id.bGoogleMap:
        Intent i = new Intent(OptionsPage.this, Location.class);
        finish();
        startActivity(i);
        break;
    case R.id.bUpdate:
        LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE); 
        android.location.Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        lon = Double.toString(location.getLongitude());
        lat = Double.toString(location.getLatitude());
        System.out.println(lon + ", " + lat);
        Calendar c = Calendar.getInstance();
        SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
        current = df.format(c.getTime());
        System.out.println(current);
        new AttemptUpdate().execute();
        break;
    case R.id.bConfirm:
        String Interval = TimerInterval.getText().toString();
        int I = Integer.parseInt(Interval);
        System.out.println(I);
        break;
    }
}

class AttemptUpdate extends AsyncTask<String, String, String> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(OptionsPage.this);
        pDialog.setMessage("Attempting to store your location...");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(true);
        pDialog.show();
    }

    @Override
    protected String doInBackground(final String... args) {
        // TODO Auto-generated method stub
        String success;
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(OptionsPage.this);
        String post_username = sp.getString("username", "anon");

        try {
            // Building Parameters
            List<NameValuePair> params1 = new ArrayList<NameValuePair>();
            params1.add(new BasicNameValuePair("username", post_username));
            params1.add(new BasicNameValuePair("lat", lat));
            params1.add(new BasicNameValuePair("lon", lon));
            params1.add(new BasicNameValuePair("time", current));

            Log.d("request!", "starting");

            //Posting user data to script 
            JSONObject json = jsonParser.makeHttpRequest(
                    UPDATE_INFO_URL, "POST", params1);

            // full json response
            Log.d("Store location attempt", json.toString());

            // json success element
            success = json.getString(TAG_SUCCESS);
            if(success.equals("SUCCESS")) {
                Log.d("Location Stored!", json.toString());    
                finish();
                return json.getString(TAG_MESSAGE);
            }else{
                Log.d("Storing Location Failure!", json.getString(TAG_MESSAGE));
                return json.getString(TAG_MESSAGE);
            } 
        } catch (JSONException e) {
            e.printStackTrace();
        }           
        return null;
    }

    protected void onPostExecute(String file_url) {
        // dismiss the dialog once product deleted
        pDialog.dismiss();
        if (file_url != null){
            Toast.makeText(OptionsPage.this, file_url, Toast.LENGTH_LONG).show();
        }
        Latit.setText("Latitude currently is: " + lat);
        Longit.setText("Longitude currently is: " + lon);
    }
}
}

在OnCreate方法中,您可以看到我尝试让计时器每5秒运行一次AttemptUpdate,但输入时会出现错误。任何帮助都将不胜感激!

添加计时器任务和计时器后,我运行了代码。应用程序崩溃了,我收到了以下logcat错误:

08-02 13:50:02.844: W/dalvikvm(29346): threadid=13: thread exiting with uncaught exception (group=0x41b11438)
08-02 13:50:02.854: E/AndroidRuntime(29346): FATAL EXCEPTION: Timer-0
08-02 13:50:02.854: E/AndroidRuntime(29346): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
08-02 13:50:02.854: E/AndroidRuntime(29346):    at android.os.Handler.<init>(Handler.java:121)
08-02 13:50:02.854: E/AndroidRuntime(29346):    at android.app.Dialog.<init>(Dialog.java:107)
08-02 13:50:02.854: E/AndroidRuntime(29346):    at android.app.AlertDialog.<init>(AlertDialog.java:114)
08-02 13:50:02.854: E/AndroidRuntime(29346):    at android.app.AlertDialog.<init>(AlertDialog.java:98)
08-02 13:50:02.854: E/AndroidRuntime(29346):    at android.app.ProgressDialog.<init>(ProgressDialog.java:77)
08-02 13:50:02.854: E/AndroidRuntime(29346):    at com.paul.locations.OptionsPage$AttemptUpdate.onPreExecute(OptionsPage.java:108)
08-02 13:50:02.854: E/AndroidRuntime(29346):    at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:586)
08-02 13:50:02.854: E/AndroidRuntime(29346):    at android.os.AsyncTask.execute(AsyncTask.java:534)
08-02 13:50:02.854: E/AndroidRuntime(29346):    at com.paul.locations.OptionsPage$1.run(OptionsPage.java:69)
08-02 13:50:02.854: E/AndroidRuntime(29346):    at java.util.Timer$TimerImpl.run(Timer.java:284)

2 个答案:

答案 0 :(得分:4)

你把asynctask放在计时器任务应该去的地方。看一下这个例子TimerTask not executing?

TimerTask task = new TimerTask(){
    @Override
    public void run(){
        new AttemptUpdate().execute();
    }

}

new Timer().scheduleAtFixedRate(task,0,5000);

答案 1 :(得分:4)

使用以下代码替换错误行:

new Timer().scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        new AttemptUpdate().execute();    
                    }
                });
            }
        }, 0, 5000);