为什么我的Gps位置没有更新?

时间:2011-09-08 23:18:52

标签: android service gps alarm

我试图每30分钟记录一次用户的gps信号。我正在使用警报并且正在调用该服务,但是当警报调用此函数时,它似乎似乎不更新gps位置,它使用之前的值。

这是我更新我的位置的代码,请注意,在底部,我为同一个功能设置了另一个警报,以便再次调用它。

package com.cellphone;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Calendar;

import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.AlarmManager;
import android.app.IntentService;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Looper;
import com.cellphone.astralweb.R;

public class UpdateLocation extends IntentService {
    public static final String id = "";

    public UpdateLocation() {
        super("UpdateLocation");
    }

    @Override
    protected void onHandleIntent(Intent intent) {

        SharedPreferences prefs = getSharedPreferences("Settings", 0);
        final String id = prefs.getString("ID", "");
        HttpParams httpParams = new BasicHttpParams();
        // 30seconds and it stops
        HttpConnectionParams.setConnectionTimeout(httpParams, 30000);
        HttpConnectionParams.setSoTimeout(httpParams, 30000);
        DefaultHttpClient httpclient = new DefaultHttpClient(httpParams);
        HttpPost httpost = new HttpPost(
                "http://iphone-radar.com/gps/gps_locations");

        JSONObject holder = new JSONObject();

        try {
            holder.put("id", id);
            LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
            Criteria criteria = new Criteria();
            criteria.setAccuracy(Criteria.ACCURACY_FINE);

            LocationListener loc_listener = new LocationListener() {

                @Override
                public void onStatusChanged(String provider, int status,
                        Bundle extras) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void onProviderEnabled(String provider) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void onProviderDisabled(String provider) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void onLocationChanged(Location location) {
                    // TODO Auto-generated method stub

                }
            };
            String bestProvider = locationManager.getBestProvider(criteria,
                    false);
            try {
                Looper.prepare();

                locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
                        loc_listener);
            } catch (Exception e) {
                e.printStackTrace();
            }
            Location location = locationManager
                    .getLastKnownLocation(bestProvider);
            Calendar c = Calendar.getInstance();
            SimpleDateFormat sdf = new SimpleDateFormat(
                    "hh:mmaa MM-dd-yyyy");
            holder.put("time", sdf.format(c.getTime()));
            holder.put("time_since_epoch",
                    System.currentTimeMillis() / 1000);
            try {
                holder.put("lat", location.getLatitude());
                holder.put("lon", location.getLongitude());
            } catch (NullPointerException e) {
                try {
                    holder.put("lat", -1.0);
                    holder.put("lon", -1.0);
                } catch (JSONException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
            }

            StringEntity se = new StringEntity(holder.toString());
            httpost.setEntity(se);
            httpost.setHeader("Accept", "application/json");
            httpost.setHeader("Content-type", "application/json");

            ResponseHandler responseHandler = new BasicResponseHandler();
            String response = httpclient.execute(httpost, responseHandler);
            org.json.JSONObject obj;
            obj = new org.json.JSONObject(response);
            SimpleDateFormat sdf2 = new SimpleDateFormat(
                    "yyyy-MM-dd hh:mm:ssaa");
            try {
                History.addHistory(sdf2.format(c.getTime()), "GPS",
                        "Latitude: " + location.getLatitude() + "\n"
                                + "Longitude: " + location.getLongitude());
            } catch (NullPointerException e) {
                History.addHistory(sdf2.format(c.getTime()), "GPS",
                        "Latitude: " + -1.0 + "\n" + "Longitude: " + -1.0);
            }
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
            Intent setAlarm = new Intent(UpdateLocation.this,
                    UpdateLocation.class);
            PendingIntent pendingIntent = PendingIntent.getService(
                    UpdateLocation.this, 0, setAlarm, 0);
            AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
            Calendar calendar = Calendar.getInstance();
            calendar.setTimeInMillis(System.currentTimeMillis());
            int UPDATE_TIME = prefs.getInt("Update_time", 30);
            calendar.add(Calendar.MINUTE, UPDATE_TIME);
            alarmManager.set(AlarmManager.RTC_WAKEUP,
                    calendar.getTimeInMillis(), pendingIntent);

        }
    }

这是我放在名为更新位置的按钮内的功能。此功能可以正常工作并正确更新位置。代码是一样的,所以我想知道它为什么不在服务中更新。

public class updateloc extends AsyncTask<Void, Void, Void> {

    protected void onPostExecute(String response) {
        if (response != null) {
            // check if this does anything later

        }
        progressDialog.dismiss();

    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        progressDialog = ProgressDialog.show(ImTracking.this, "",
                "Updating Data...");
    }

    @Override
    protected Void doInBackground(Void... arg0) {
        SharedPreferences prefs = getSharedPreferences("Settings", 0);
        final String id = prefs.getString("ID", "");
        HttpParams httpParams = new BasicHttpParams();
        // 30seconds and it stops
        HttpConnectionParams.setConnectionTimeout(httpParams, 30000);
        HttpConnectionParams.setSoTimeout(httpParams, 30000);
        DefaultHttpClient httpclient = new DefaultHttpClient(httpParams);
        HttpPost httpost = new HttpPost(
                "http://iphone-radar.com/gps/gps_locations");

        JSONObject holder = new JSONObject();

        try {
            holder.put("id", id);
            LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
            Criteria criteria = new Criteria();
            criteria.setAccuracy(Criteria.ACCURACY_FINE);

            LocationListener loc_listener = new LocationListener() {

                @Override
                public void onStatusChanged(String provider, int status,
                        Bundle extras) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void onProviderEnabled(String provider) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void onProviderDisabled(String provider) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void onLocationChanged(Location location) {
                    // TODO Auto-generated method stub

                }
            };
            String bestProvider = locationManager.getBestProvider(criteria,
                    false);
            try {
                Looper.prepare();

                locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
                        loc_listener);
            } catch (Exception e) {
                e.printStackTrace();
            }
            Location location = locationManager
                    .getLastKnownLocation(bestProvider);
            Calendar c = Calendar.getInstance();
            SimpleDateFormat sdf = new SimpleDateFormat(
                    "hh:mmaa MM-dd-yyyy");
            holder.put("time", sdf.format(c.getTime()));
            holder.put("time_since_epoch",
                    System.currentTimeMillis() / 1000);
            try {
                holder.put("lat", location.getLatitude());
                holder.put("lon", location.getLongitude());
            } catch (NullPointerException e) {
                try {
                    holder.put("lat", -1.0);
                    holder.put("lon", -1.0);
                } catch (JSONException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
            }

            StringEntity se = new StringEntity(holder.toString());
            httpost.setEntity(se);
            httpost.setHeader("Accept", "application/json");
            httpost.setHeader("Content-type", "application/json");

            ResponseHandler responseHandler = new BasicResponseHandler();
            String response = httpclient.execute(httpost, responseHandler);
            org.json.JSONObject obj;
            obj = new org.json.JSONObject(response);
            SimpleDateFormat sdf2 = new SimpleDateFormat(
                    "yyyy-MM-dd hh:mm:ssaa");
            try {
                History.addHistory(sdf2.format(c.getTime()), "GPS",
                        "Latitude: " + location.getLatitude() + "\n"
                                + "Longitude: " + location.getLongitude());
            } catch (NullPointerException e) {
                History.addHistory(sdf2.format(c.getTime()), "GPS",
                        "Latitude: " + -1.0 + "\n" + "Longitude: " + -1.0);
            }
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        progressDialog.dismiss();
        return null;
    }

}

由于

1 个答案:

答案 0 :(得分:0)

我认为你的AsyncTask只发送最后一个位置的原因是因为你没有正确使用LocationListener接口,或者实际上根本没有。

我认为您需要在onLocationChanged方法中添加一些代码来对该位置执行某些操作,例如可能将其放入您的活动的成员var中,这样您就可以使用它。

UI通过按钮更新的原因实际上只是注册一个监听器的副作用(当它听到一个新位置时实际上没有任何东西)导致LocationManger继续并更新lastKnownLocation,你的按钮他们从中获取价值。因此,聋人监听器会导致LocationManager轮询更新,并更新它自己的lastKnown,单击处理程序依赖它。

这在AsyncTask中不起作用的原因是任务运行一次然后死掉。因此,当你注册另一个监听器时,它将永远不会有机会获得一个事件,因为它的父(任务)将一直运行到doInBackground的末尾然后死掉。所以,它在它获得位置更改事件之前就已经死了......在你的任务内部实际上不会做任何事情(没有onLocationChanged方法的主体)。

我认为您需要退回原型代码并重新考虑您的设计。

使用AsyncTask来处理http帖子是一个好主意,但拥有它并且Activity本身是一个监听器是行不通的。特别是在onLocationChanged事件中没有实现有用的东西。

考虑让您的Activity成为侦听器,并为Location设置成员var。在onLocationChanged事件中,将您从事件中获得的位置克隆到memeber var,然后您可以先使用新位置更新UI,然后开始将任务发送到您的网站。

您可以继续将任务声明为Task<Void,Void,Void>,只需从任务中访问活动的成员var,或者更正确地将其传递给声明为Task<Location,Void,Void>的成员。

此外,我认为你需要考虑检查一个任务当前是否已经在运行,然后再开始新任务,就像registerForLocationUpdates(provider,0,0)一样,你将比你的网站更快地获得它们。可能能够接收它们,特别是连接时超时30秒。

您可以在开始新任务之前测试任务当前是否正在运行,或者在onPreExecute中设置为true的活动中使用布尔成员var,在onPostExecute中使用false,然后在开始新任务之前检查

即使这可能是对网站的喋喋不休。您可能想要创建一个数据结构来容纳许多位置,然后,一旦您累积了一些数量,就可以将它们全部一批地发送到网站。

希望有所帮助。