0

我创建了一个 android 应用程序,其中有两个按钮开始停止。当单击开始按钮时,每 1 秒将当前纬度和经度值作为帖子发送到 usl 以插入远程 mysl 数据库。

在开始按钮中,我编写了一个用于发送纬度和经度的服务 MyService。
在 MyService 的 onStartCommand(..) 方法中,我编写了一个计时器,用于在 1 秒时发送纬度和经度。

但我得到以下异常

java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

谁能告诉我一些解决方案

我的代码如下所示

iLoadPage.java

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class iLoadPage extends Activity { 
    Button start,stop;
    boolean flag=true;
    double latin,longin,longitude,latitude;
    Activity activity;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.iloadpage);
        start = (Button) findViewById(R.id.startapp);
        stop = (Button) findViewById(R.id.stop);
        stop.setEnabled(false);

        start.setOnClickListener(new View.OnClickListener() {
            public void onClick(View arg0) {
                start.setEnabled(false);
                stop.setEnabled(true);
                String trackid= getIntent().getExtras().getString("trackid");
                MyService.setTrackid(trackid);
                startService(new Intent(getBaseContext(),MyService.class));
            }
        });

        stop.setOnClickListener(new View.OnClickListener() {
            public void onClick(View arg0) {
                start.setEnabled(true);
                stop.setEnabled(false);
                stopService(new Intent(getBaseContext(),MyService.class));
            }


        });
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    public double getLatin() {
        return latin;
    }

    public void setLatin(double latin) {
        this.latin = latin;
    }

    public double getLongin() {
        return longin;
    }

    public void setLongin(double longin) {
        this.longin = longin;
    }

    public double getLongitude() {
        return longitude;
    }

    public void setLongitude(double longitude) {
        this.longitude = longitude;
    }

    public double getLatitude() {
        return latitude;
    }

    public void setLatitude(double latitude) {
        this.latitude = latitude;
    }

}

我的服务.java

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ScheduledExecutorService;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import android.app.Service;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.IBinder;
import android.text.Html;
import android.widget.Toast;

public class MyService extends Service {
    public static String trackid;
    ScheduledExecutorService scheduler ;
    GPSTracker gps;
    boolean flag=false;
    DownloadFile ss;
    Handler handler = new Handler();

    double latin,longin,longitude,latitude;
    private final int  TEN_SECONDS = 3000;

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }
    String errors="notnull";
    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
        try
        {
         Toast.makeText(this, "Application Service Started!!!...", Toast.LENGTH_LONG).show();
              try {
                  TimerTask myTimerTask = new TimerTask() {

                        @Override
                        public void run() {
                             flag=true;
                             DownloadFile sd=new DownloadFile();
                             sd.execute("");
                        }                   };
                    Timer timer = new Timer();
                    timer.schedule(myTimerTask, 1000);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }catch(Exception e){
            e.printStackTrace();
            Toast.makeText(this, "Service Error->"+e, Toast.LENGTH_LONG).show();}
        return START_STICKY;
    }

    @Override
    public void onDestroy()
    {
        flag=false;
        super.onDestroy();
        Toast.makeText(this, "Application Service Stopped!!!...", Toast.LENGTH_LONG).show();
    }


    public double getLatin() {
        return latin;
    }

    public void setLatin(double latin) {
        this.latin = latin;
    }

    public double getLongin() {
        return longin;
    }

    public void setLongin(double longin) {
        this.longin = longin;
    }

    public static String getTrackid() {
        return trackid;
    }

    public static void setTrackid(String trackid) {
        CopyOfMyService.trackid = trackid;
    }



    String pass;
    private class DownloadFile extends AsyncTask<String, Integer, String>  {
        @Override
        protected String doInBackground(String... sUrl) {
            try {
                  gps = new GPSTracker(CopyOfMyService.this);
                  latin = gps.getLatitude();
                  longin = gps.getLongitude();
                  HttpClient httpclient = new DefaultHttpClient();
                  HttpPost httppost = new HttpPost("http://iloadlogistics.com.au/insert1.jsp");
                  String trackid= CopyOfMyService.getTrackid();
                  List<NameValuePair> namevaluepairs = new ArrayList<NameValuePair>(2);
                  namevaluepairs.add(new BasicNameValuePair("trackid",trackid));
                  namevaluepairs.add(new BasicNameValuePair("lat",""+latin));
                  namevaluepairs.add(new BasicNameValuePair("lon",""+longin));
                  httppost.setEntity(new UrlEncodedFormEntity(namevaluepairs));
                  HttpResponse response = httpclient.execute(httppost);
                  HttpEntity rp = response.getEntity();
                  String origresponseText =  EntityUtils.toString(rp);
                  String htmlTextStr = Html.fromHtml(origresponseText).toString();
                  pass=htmlTextStr.trim();
                  if(htmlTextStr.trim().equals("success"))
                  {

                  }else if(htmlTextStr.trim().equals("failure")){

                  }

                  } catch (Exception e) {
                      pass=""+e;
                      // TODO Auto-generated catch block
                      System.out.println("ERRRRRRRRRRRRRRRRRROR:"+e);
                    e.printStackTrace();

              } 

            return pass;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            if(flag)
                  {
                      Toast.makeText(getApplicationContext(), "Inserted!!!...", Toast.LENGTH_SHORT).show();
                  }
                  else
                  {
                      Toast.makeText(getApplicationContext(), "Asyntask is Destroying!!!...", Toast.LENGTH_LONG).show();
                      onDestroy();
                  }
        }

        @Override
        protected void onProgressUpdate(Integer... progress) {
            super.onProgressUpdate(progress);
        }
    }
}

GPSTracker.java

public class GPSTracker extends Service implements LocationListener {

    private final Context mContext;
    boolean isGPSEnabled = false;
    boolean isNetworkEnabled = false;
    boolean canGetLocation = false;
    Location location; // location
    double latitude; // latitude
    double longitude; // longitude


    private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 5; // 10 meters

    private static final long MIN_TIME_BW_UPDATES = 1000; // 1 minute

    protected LocationManager locationManager;

    public GPSTracker(Context context) {
        this.mContext = context;
        getLocation();
    }

    public Location getLocation() {
        try {
            locationManager = (LocationManager) mContext
                    .getSystemService(LOCATION_SERVICE);

            // getting GPS status
            isGPSEnabled = locationManager
                    .isProviderEnabled(LocationManager.GPS_PROVIDER);

            // getting network status
            isNetworkEnabled = locationManager
                    .isProviderEnabled(LocationManager.NETWORK_PROVIDER);

            if (!isGPSEnabled && !isNetworkEnabled) {
                // no network provider is enabled
            } else {
                this.canGetLocation = true;
                if (isNetworkEnabled) {
                    locationManager.requestLocationUpdates(
                            LocationManager.NETWORK_PROVIDER,
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                    Log.d("Network", "Network");
                    if (locationManager != null) {
                        location = locationManager
                                .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                        if (location != null) {
                            latitude = location.getLatitude();
                            longitude = location.getLongitude();
                        }
                    }
                }
                // if GPS Enabled get lat/long using GPS Services
                if (isGPSEnabled) {
                    if (location == null) {
                        locationManager.requestLocationUpdates(
                                LocationManager.GPS_PROVIDER,
                                MIN_TIME_BW_UPDATES,
                                MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                        Log.d("GPS Enabled", "GPS Enabled");
                        if (locationManager != null) {
                            location = locationManager
                                    .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                            if (location != null) {
                                latitude = location.getLatitude();
                                longitude = location.getLongitude();
                            }
                        }
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return location;
    }

    public void stopUsingGPS(){
        if(locationManager != null){
            locationManager.removeUpdates(GPSTracker.this);
        }       
    }

    public double getLatitude(){
        if(location != null){
            latitude = location.getLatitude();
        }

        return latitude;
    }

    public double getLongitude(){
        if(location != null){
            longitude = location.getLongitude();
        }

        return longitude;
    }

    public boolean canGetLocation() {
        return this.canGetLocation;
    }

    public void showSettingsAlert(){
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);

        alertDialog.setTitle("GPS is settings");

        alertDialog.setMessage("GPS is not enabled. Do you want to go to settings menu?");

        alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog,int which) {
                Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                mContext.startActivity(intent);
            }
        });

        // on pressing cancel button
        alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
            dialog.cancel();
            }
        });

        // Showing Alert Message
        alertDialog.show();
    }


    public void onLocationChanged(Location location) {

    }


    public void onProviderDisabled(String provider) {
    }


    public void onProviderEnabled(String provider) {
    }


    public void onStatusChanged(String provider, int status, Bundle extras) {
    }


    public IBinder onBind(Intent arg0) {
        return null;
    }

}



UPDATION 2

我曾经调用方法scheduleSendLocation()而不是 Timer,该方法具有以下定义

Runnable r=new Runnable() {
        public void run() {
            flag=true;
            DownloadFile sd=new DownloadFile();
            sd.execute("");   
            handler.postDelayed(this, TEN_SECONDS);
        }
    };

    public void scheduleSendLocation() {
        handler.postDelayed(r, TEN_SECONDS);
    }
4

1 回答 1

0

I don't really see what you need this handler for, but I see at least 2 problems:

  • you call new Handler() in the UI thread which has no prepared looper
  • you create a handler without overriding handleMessage() (what does this handler do then?)

When you create a new Handler with the constructor that has no parameter, the handler is associated with the message queue of the current thread (calling new Handler()). It means the thread needs a looper. You can do it by calling Looper.prepare() before creating the handler.

However, you can't do it yet because new Handler() is called as a field initialization. You should move this call somewhere else, such as in onCreate() and then add Looper.prepare() before it.

于 2013-05-02T18:14:06.507 回答