почему мое местоположение GPS не обновляется? - PullRequest
0 голосов
/ 09 сентября 2011

Я пытаюсь записывать сигнал GPS пользователя каждые 30 минут. Я использую сигналы тревоги, и служба вызывается, однако кажется, что когда эта функция вызывается сигналом тревоги, она не обновляет местоположение 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 голосов
/ 09 сентября 2011

Я думаю, что причина, по которой ваш AsyncTask отправляет только последнее местоположение, в том, что вы на самом деле не используете интерфейс LocationListener правильно или вообще не используете.

Я думаю, вам нужно поместить некоторый код в метод onLocationChangedсделать что-то с местоположением, например, поместить его в переменную члена вашей деятельности, чтобы вы могли с ней что-то делать.

Причина, по которой пользовательский интерфейс обновляется с помощью кнопки, на самом деле является лишь побочным эффектом наличиязарегистрировал слушателя (который фактически ничего не делает, когда слышит новое местоположение), что заставляет LocationManger идти вперед и обновлять lastKnownLocation, из которого ваша кнопка получает значение.Таким образом, глухой слушатель заставляет LocationManager запрашивать обновления и обновлять свой собственный lastKnown, на который полагается обработчик.

Причина, по которой это не работает в AsyncTask, заключается в том, что Задача запускается один раз, а затем умирает.Поэтому, когда вы регистрируете еще одного слушателя, у него никогда не будет возможности получить событие, потому что его родитель (задача) будет проходить до конца doInBackground, а затем умрет.Таким образом, он умирает, прежде чем он когда-либо получит событие изменения местоположения ... которое внутри вашей задачи на самом деле ничего бы не сделало (нет тела для метода onLocationChanged).закодируйте и немного переосмыслите свой дизайн.

Использование AsyncTask для обработки http-сообщения - хорошая идея, но иметь его и сам Activity в качестве слушателя не сработает.Особенно без реализации чего-либо полезного в событии onLocationChanged.

Подумайте о том, чтобы ваша активность была слушателем и у вас был член var для Location.В своем событии onLocationChanged клонируйте местоположение, полученное от события, на свой memeber var, а затем вы можете сначала обновить свой пользовательский интерфейс новым местоположением, а затем запустить задачу, чтобы отправить местоположение на ваш веб-сайт.

Вы можете по-прежнему иметь задачу, объявленную как Task<Void,Void,Void>, и просто получить доступ к переменной var вашей деятельности из задачи или, что более правильно, передать ее одному, объявленному как Task<Location,Void,Void>.

Кроме того, я думаю, что выВам нужно будет рассмотреть возможность проверки того, что задача уже запущена, прежде чем запускать новую, так как с помощью registerForLocationUpdates (provider, 0,0) вы получите их намного быстрее, чем ваш веб-сайт, вероятно, сможет их принять.особенно при тайм-ауте соединения 30 с.

Вы можете просто проверить, выполняется ли задача в настоящий момент, прежде чем начинать новую, или использовать логический член var в действии, которое устанавливается в true в onPreExecute иfalse в onPostExecute, затем просто проверьте это перед началом новой задачи.

Даже это может быть связано с веб-сайтом.Возможно, вы захотите создать структуру данных, которая будет содержать множество местоположений, а затем, как только вы накопите некоторое их количество, отправьте их все в одной партии на веб-сайт.

Надеюсь, что это поможет.

...