Не получать текущую лат долго

Я разрабатываю приложение, в котором я хочу получить широту и долготу при нажатии кнопки. Но он всегда показывает 0. Мой код такой, как показано ниже. AndroidGPSTrackingActivity.java

package com.example.gpstracking;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class AndroidGPSTrackingActivity extends Activity {

Button btnShowLocation;

// GPSTracker class
GPSTracker gps;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    btnShowLocation = (Button) findViewById(R.id.btnShowLocation);

    // show location button click event
    btnShowLocation.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View arg0) {        
            // create class object
            gps = new GPSTracker(AndroidGPSTrackingActivity.this);

            // check if GPS enabled     
            if(gps.canGetLocation()){

                double latitude = gps.getLatitude();
                double longitude = gps.getLongitude();

                // \n is for new line
                Toast.makeText(getApplicationContext(), "Your Location    is    - \nLat: " + latitude + "\nLong: " + longitude, Toast.LENGTH_SHORT).show(); 
            }else{
                // can't get location
                // GPS or Network is not enabled
                // Ask user to enable GPS/network in settings
                gps.showSettingsAlert();
            }

        }
    });
}

 }

И второй класс, как показано ниже.

GPSTracker.java

      package com.example.gpstracking;

      import android.app.AlertDialog;
      import android.app.Service;
      import android.content.Context;
      import android.content.DialogInterface;
      import android.content.Intent;
      import android.location.Location;
      import android.location.LocationListener;
      import android.location.LocationManager;
      import android.os.Bundle;
      import android.os.IBinder;
      import android.provider.Settings;
      import android.util.Log;
      import android.widget.Toast;

     public class GPSTracker extends Service implements LocationListener {

private final Context mContext;

// flag for GPS status
boolean isGPSEnabled = false;

// flag for network status
boolean isNetworkEnabled = false;

// flag for GPS status
boolean canGetLocation = false;

Location location; // location
double latitude = 37.422006; // latitude
double longitude = -122.084095; // longitude

// The minimum distance to change Updates in meters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters

// The minimum time between updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute

// Declaring a Location Manager
protected LocationManager locationManager;

public GPSTracker(Context context) {
    Log.i("*******", "Inside constructor");
    this.mContext = context;
    getLocation();
}

public Location getLocation() {
    try {
        Log.i("*******", "Inside get Location");
        locationManager = (LocationManager) mContext
                .getSystemService(LOCATION_SERVICE);

        // getting GPS status
        isGPSEnabled = locationManager
                .isProviderEnabled(LocationManager.GPS_PROVIDER);
        Log.i("*******", ""+isGPSEnabled);
        // getting network status
        isNetworkEnabled = locationManager
                .isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        Log.i("*******", ""+isNetworkEnabled);
        if (!isGPSEnabled && !isNetworkEnabled) {
            // no network provider is enabled
            Toast.makeText(getApplicationContext(), "GPS:"+isGPSEnabled+"NEtwork:"+isNetworkEnabled, Toast.LENGTH_LONG).show();
        } else {
            this.canGetLocation = true;
            if (isGPSEnabled) {
                Log.i("*********", "Inside isGPSEnabled");
                if (location == null) {
                    locationManager.requestLocationUpdates(
                            LocationManager.GPS_PROVIDER,
                            0,
                            0, this);
                    Log.d("GPS Enabled", "GPS Enabled");
                    if (locationManager != null) {
                        Log.i("*********", locationManager.toString());
                        location = locationManager
                                .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                        if (location != null) {
                            Log.i("*********", location.toString());
                            latitude = location.getLatitude();
                            longitude = location.getLongitude();
                            Log.i("*********", "Lat:"+latitude+"Long:"+longitude);
                        }Log.i("*********", location.toString());
                    }
                }
            }
            if (isNetworkEnabled) {
                Log.i("*********", "Inside isNetworkEnabled");
                locationManager.requestLocationUpdates(
                        LocationManager.NETWORK_PROVIDER,
                        0,
                        0, 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

        }

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

    return location;
}

/**
 * Stop using GPS listener
 * Calling this function will stop using GPS in your app
 * */
public void stopUsingGPS(){
    if(locationManager != null){
        locationManager.removeUpdates(GPSTracker.this);
    }       
}

/**
 * Function to get latitude
 * */
public double getLatitude(){
    if(location != null){
        latitude = location.getLatitude();
    }

    // return latitude
    return latitude;
}

/**
 * Function to get longitude
 * */
public double getLongitude(){
    if(location != null){
        longitude = location.getLongitude();
    }

    // return longitude
    return longitude;
}

/**
 * Function to check GPS/wifi enabled
 * @return boolean
 * */
public boolean canGetLocation() {
    return this.canGetLocation;
}

/**
 * Function to show settings alert dialog
 * On pressing Settings button will lauch Settings Options
 * */
public void showSettingsAlert(){
    AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);

    // Setting Dialog Title
    alertDialog.setTitle("GPS is settings");

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

    // On pressing Settings button
    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();
}

@Override
public void onLocationChanged(Location location) {
    Toast.makeText(getApplicationContext(), "Location Changed called", Toast.LENGTH_SHORT).show();
    latitude =location.getLatitude();
    longitude = location.getLongitude();
}

public void onProviderDisabled(String provider) {
}

public void onProviderEnabled(String provider) {
}


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

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

}

Я также добавил следующие разрешения в файл manifest.

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

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

Заранее спасибо..


person Rahil2952    schedule 06.11.2012    source источник
comment
Поставщик сетевого местоположения не очень точен для точности, вам следует использовать GPSProvider, который обычно занимает немного больше времени, чтобы найти местоположение, но имеет лучшее положение. Из вашего обновления я больше не понимаю вашу проблему.   -  person Gabriel Netto    schedule 06.11.2012


Ответы (3)


попробуй так...

LocationManager locManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE); 
                locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,1000L,500.0f, locationListener);
                Location location = locManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                if(location != null)                                
                {
                    double latitude = location.getLatitude();
                    double longitude = location.getLongitude();



                }  
person Mehul Ranpara    schedule 06.11.2012

Когда вы создаете свой прослушиватель местоположения, это займет некоторое время, прежде чем фактически получить местоположение, вы можете изменить создание своего класса gpsTracker из onClick или, по крайней мере, сохранить экземпляр, который вы создаете при первом щелчке, пока вы не уничтожите его, возможно, после получения location, поэтому вы не создаете его каждый раз, вызывая создание прослушивателя другого местоположения.

Вы можете использовать обработчик для передачи сообщения в свою деятельность после получения местоположения.

Ваш обработчик может выглядеть примерно так: Создайте общедоступный обработчик своей активности.

public Handler handler;

Затем добавьте это в свой метод onCreate.

handler = new Handler(new Handler.Callback() {

        @Override
        public boolean handleMessage(Message msg) {
            // TODO Auto-generated method stub
            if(msg.what == 0){
                //do the methods that require knowing your location you location
                return true;
            }
            return false;
        }
    });

И ваш класс GPSTracker вы добавляете это к своему onLocationChanged:

Message msg = new Message();
msg.what = 0;
((AndroidGPSTrackingActivity)mContext).handler.sendMessage(msg);

Вы можете прочитать об обработчиках здесь.

person Gabriel Netto    schedule 06.11.2012
comment
@ Габриэль Нетто Я не задерживаюсь долго даже через 10 минут. - person Rahil2952; 06.11.2012
comment
вам может понадобиться добавить locationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, this);, но пока вы подключены к Wi-Fi и GPS активен или у вас есть активное подключение для передачи данных, вы все равно должны получить местоположение через некоторое время. - person Gabriel Netto; 06.11.2012
comment
Я использую это в своем коде внутри, если условие isGPSEnabled. - person Rahil2952; 06.11.2012

Большинство устройств не будут получать GPS быстро, когда вы звоните LocationListener. Итак, что я сделал, так это попытался получить его в AsyncTask с условием latitude and longitude !=0. Если это условие выполняется успешно, мы получаем и широту, и долготу. После этого вы можете делать все, что захотите.

Это код в асинхронной задаче

public class GPSLocation extends AsyncTask<Void, Void, Void>
    {  
        boolean running =true;
                @Override
                protected void onPreExecute()
                {  
                    super.onPreExecute(); 
                    progressDialog = new ProgressDialog(RoadMaintenanceActivity.this);
                    progressDialog.setOnCancelListener(new DialogInterface.OnCancelListener(){
                          public void onCancel(DialogInterface dialog) {
                              getgps.cancel(true);  
                          }
                    });
                    LocationManager mlocManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE); 
                    LocationListener mlocListener = new MyLocationListener();  
                    mlocManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, mlocListener);    
                    progressDialog.setCancelable(true);
                    progressDialog.setMessage("Getting GPS Location...");
                    progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
                    progressDialog.setProgress(1);
                    progressDialog.show();

                } 

                @Override 
                protected void onProgressUpdate(Void... values) {
                    super.onProgressUpdate(values);
                    // Things to be done while execution of long running operation is in progress. For example updating ProgessDialog
                 }

                @Override 
                protected void onPostExecute(Void result)
                {  
                        progressDialog.cancel(); 
                }

                @Override
                protected Void doInBackground(Void... params) {  
                    boolean isDataSubmitted = false; 
                 while(!isDataSubmitted)
                        {   
                            if(longitude !=0 && latitude!=0) 
                            {
                                    //Do your operation here 
                                isDataSubmitted = true;
                            } 
                    }

                    return null;    
                } 
     } 

Он должен работать.

person vinothp    schedule 06.11.2012
comment
Если он не изменит это на свой собственный класс Activity, ему понадобится способ сообщить своей активности, что он получил местоположение. И вы пропустили метод, который закроет диалоговое окно прогресса. - person Gabriel Netto; 06.11.2012
comment
@GabrielNetto Да, я согласен с вами, если ему нужно получить уведомление, он может использовать обработчик. Но если широта должна перейти к следующему процессу его приложения, асинхронная задача будет полезна. Прогресс Закрытие диалога будет работать, если он нажмет кнопку «Назад». Вы можете увидеть этот метод в OnPreExecute. - person vinothp; 06.11.2012
comment
Мне это нужно, чтобы продолжить, я согласен с вами. В диалоговом окне его следует закрыть после успешного определения местоположения. - person Gabriel Netto; 06.11.2012
comment
Да onPostexecute() его уволят. Потому что пост-выполнение произойдет, когда процесс завершится. - person vinothp; 06.11.2012
comment
Только что увидел, что ты сделал на doInBackground довольно хакерским. Я бы использовал метод onLocationChanged для того, что вы использовали для AsycnTask, если какое-то время для этого. Проверьте мой ответ и просто представьте, что вы закрываете диалоговое окно в методе onLocationChanged и создаете его в onClick, предполагая, что вы находитесь в том же классе. - person Gabriel Netto; 06.11.2012