2015-04-05 3 views
13

Diese Frage bezieht sich direkt auf die gleiche vorherrschende stackoverflow Frage bei "Android: get current location of user without using gps or internet", wo die angenommene Antwort tatsächlich die Frage nicht beantwortet.Holen Sie sich den aktuellen Standortnamen des Benutzers ohne Verwendung von GPS oder Internet, aber mithilfe von Network_Provider in Android

Ich sollte in der Lage sein, den aktuellen Standortnamen (zB: Name der Stadt, Dorfname) des Geräts über Netzwerkanbieter nicht mit GPS oder Internet zu erhalten. Folgendes ist die akzeptierte Antwort in dieser Frage. (Die folgenden Code-Teile sollten in der onCreate() Verfahren einbezogen werden)

// Acquire a reference to the system Location Manager 
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE); 

// Define a listener that responds to location updates 
LocationListener locationListener = new LocationListener() { 
    public void onLocationChanged(Location location) { 
     // Called when a new location is found by the network location provider. 
     makeUseOfNewLocation(location); 
    } 

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

    public void onProviderEnabled(String provider) {} 

    public void onProviderDisabled(String provider) {} 
    }; 

// Register the listener with the Location Manager to receive location updates 
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener); 

ich den obigen Code in der verknüpften Antwort wie folgt festgelegt geändert, aber ohne Erfolg.

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    final TextView txtView = (TextView) findViewById(R.id.tv1); 
    txtView.setText("ayyo samitha"); 
    //// 

    // Acquire a reference to the system Location Manager 
    LocationManager locationManager; 
    locationManager= (LocationManager) this.getSystemService(Context.LOCATION_SERVICE); 

    // Define a listener that responds to location updates 
    LocationListener locationListener = new LocationListener() { 
     public void onLocationChanged(Location location) { 
      // Called when a new location is found by the network location provider. 
      makeUseOfNewLocation(location); 

     } 

     private void makeUseOfNewLocation(Location location) { 
      txtView.setText("sam came in"); 
      txtView.append(location.toString()); 
     } 

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

     public void onProviderEnabled(String provider) { 
      // makeUseOfNewLocation(location); 
     } 

     public void onProviderDisabled(String provider) {} 
    }; 

    // Register the listener with the Location Manager to receive location updates 
    if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) { 
     locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener); 
    } 

} 

Wie kann ich erreichen, was ich will, indem ich obigen Code oder eine andere Methode korrigiere? Beachten Sie, dass ich den Standortnamen erhalten möchte, nicht aber die Längen- und Breitengrade. Kann mir bitte jemand helfen?

+0

Ich bin nicht ganz klar von dem, was Sie fragen, können Sie genau beschreiben, was Sie zu erreichen versuchen, welche Art von Verhalten Sie versuchen, die erwartete Zeit zwischen Standort Updates, etc. – Kai

+0

Ich möchte nur aktuell zu bekommen Standort des Benutzers ohne Verwendung von GPS oder Internet. –

+0

@Kai Sind Sie klar, was das Problem ist? Ich habe am Ende auch eine kleine Bearbeitung in der Frage gemacht. –

Antwort

4

Was Sie hier beziehen (zeigt Ortsnamen auf älteren Handys) "Cell Broadcast" erfolgt (oder "CB"). Dies hat absolut nichts mit der Standort-API oder irgendwelchen Variationen dazu zu tun.

Cell Towers können Broadcast-Informationen senden, die von Geräten empfangen werden können (so etwas wie "one to many SMS"). Einige Betreiber haben Cell Broadcast verwendet, um den Namen des Standorts zu übertragen, an dem sich der Mobilfunkmast befindet. Einige Betreiber haben Cell Broadcast verwendet, um den Standort (lat/long) des Mobilfunkmastens zu übertragen. Einige Betreiber haben Cell Broadcast verwendet, um Werbeklischees zu versenden. Es gibt keine Standards für die Informationen, die in einer CB-Broadcast-Nachricht enthalten sind, und jeder Mobilfunkbetreiber kann wählen, ob er dies nutzt oder nicht.

Da die meisten Betreiber diese Nachrichten nicht senden, ist es wahrscheinlich nicht sinnvoll, Zeit zu investieren, um sie empfangen und dekodieren zu können. Aber wenn Sie es versuchen möchten, können Sie eine BroadcastReceiver registrieren, die auf diese Intent Aktion reagiert: android.provider.Telephony.SMS_CB_RECEIVED. Weitere Informationen darüber, welche Daten in der Intent enthalten sind, finden Sie unter the documentation.

+0

Vielen Dank ... Das ist genau die Antwort, für die ich gekämpft habe ... 100% korrekt ... Entschuldigung, ich konnte die Antwort nicht akzeptieren, bevor ich die Bounty-Phase beendete, da ich es beim letzten Mal nicht überprüfen konnte moment .. –

+0

Lass mich wissen, wenn du Glück mit der Cell Broadcast hast .. –

+0

Ok, ich antworte nach dem Versuch ... –

1

Nach android docs LocationManager verwendet, ist nicht die aktuelle Recomended API (siehe reference):

The Google Play services location APIs are preferred over the 
Android framework location APIs (android.location) as a way of 
adding location awareness to your app. 

Um zu erfahren, wie Sie die Google-Services-Client-Bibliothek einzurichten, siehe Setup im Dienst Führungs Google Play.

import android.location.Location; 
    import android.os.Bundle; 
    import android.support.v7.app.ActionBarActivity; 
    import android.util.Log; 
    import android.view.Menu; 
    import android.view.MenuItem; 
    import android.widget.Toast; 

    import com.google.android.gms.common.ConnectionResult; 
    import com.google.android.gms.common.api.GoogleApiClient; 
    import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks; 
    import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener; 
    import com.google.android.gms.common.api.PendingResult; 
    import com.google.android.gms.common.api.ResultCallback; 
    import com.google.android.gms.common.api.Status; 
    import com.google.android.gms.location.FusedLocationProviderApi; 
    import com.google.android.gms.location.LocationListener; 
    import com.google.android.gms.location.LocationRequest; 
    import com.google.android.gms.location.LocationServices; 

    public class MainActivity extends ActionBarActivity 
      implements ConnectionCallbacks, OnConnectionFailedListener { 

     // .. 

     private GoogleApiClient mGoogleAPIClient; 

     @Override 
     protected void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      setContentView(R.layout.activity_main); 

      // create google api client object 
      mGoogleAPIClient = new GoogleApiClient.Builder(this) 
       .addApi(LocationServices.API) 
       .addConnectionCallbacks(this) 
       .addOnConnectionFailedListener(this) 
       .build(); 
     } 

     @Override 
     protected void onStart() { 
      super.onStart(); 

      mGoogleAPIClient.connect(); 
     } 

     @Override 
     protected void onStop() { 
      super.onStop(); 

      mGoogleAPIClient.disconnect(); 
     } 

     @Override 
     public void onConnectionFailed(ConnectionResult connectionResult) { 
      Toast.makeText(this, 
       "Could not connect to Google Play Services", 
       Toast.LENGTH_SHORT).show(); 

      finish(); 
     } 

     @Override 
     public void onConnected(Bundle bundle) { 
      Log.i(TAG, 
       "Successfuly connect to Google Play Services"); 

      // retrieve last location once connected 
      Location lastLocation = LocationServices.FusedLocationApi 
       .getLastLocation(mGoogleAPIClient); 

      if (lastLocation == null) { 
       // should request new one 
       // location should be enabled 
       Log.i(TAG, 
        "No location data previously acquired.. should request!"); 

       Toast.makeText(this, 
        "Requesting location data ..", 
        Toast.LENGTH_SHORT).show(); 

       LocationRequest locationRequest = LocationRequest.create(); 
       locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
       locationRequest.setInterval(5000); 

       PendingResult<Status> result = LocationServices.FusedLocationApi 
        .requestLocationUpdates(mGoogleAPIClient, 
         locationRequest, 
         new LocationListener() { 

        @Override 
        public void onLocationChanged(Location location) { 
         makeUseOfNewLocation(location); 
        } 
       }); 

       // TODO: use result to retrieve more info 

      } else { 
       makeUseOfNewLocation(lastLocation); 
      } 
     } 

     @Override 
     public void onConnectionSuspended(int i) { 
     } 

     private void makeUseOfNewLocation(Location location) { 
      // do your stuff here 
     } 

Ich habe den Code oben getestet und es funktioniert auch ohne Internetverbindung, aber es erfordert, dass Benutzer-Standort-Funktion aktivieren:

Sobald Sie Google-Services-Client-Bibliothek, um Ihre Anwendung verknüpft haben, können Sie Benutzer-Standort mit FusedLocationProviderApi erreichen auf dem Gerät. Außerdem muss der Benutzer die Standortverlaufsfunktion bereits in die Standortfunktion aktiviert haben.

Hoffe, dass dies Ihnen hilft.

+0

Danke dude, ich werde das testen. –

+0

Was ist mlocationProviderApi? Wie ich sehe, wird die Variable mlocationProviderApi nicht initialisiert. Und bitte erwähnen Sie die Importliste. –

+0

Entschuldigung, mein Fehler. Ich habe den Code bearbeitet, bitte schauen Sie nach. Als ich den Code zum ersten Mal implementierte, erstelle ich eine Attributinstanz von 'FusedLocationProviderApi', die ich ** mlocationProviderApi ** genannt habe, aber ich habe herausgefunden, dass ich direkt von' LocationServices.FusedLocationApi' auf eine Referenz von 'FusedLocationProviderApi' zugreifen kann. –

1

Das Problem ist, dass der Code, den Sie versucht haben, funktioniert, wahrscheinlich nicht so gut wie Sie es wollten. Zum Beispiel ist die Genauigkeit einer solchen Methode auf dem Samsung Galaxy S3 2000m, was bedeutet, dass die tatsächliche Position irgendwo innerhalb eines Kreises von 2 Kilometern Radius ist. Zusätzlich würde es wahrscheinlich eine ziemlich große Ortsänderung erfordern, bevor Ihre App über eine Standortänderung informiert wird, da die Fehlermarge so groß ist.

Ein GPS oder LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY (wenn Google Play Services verwendet wird) ist erforderlich, um einen relativ guten Standort zu erhalten. Dies erfordert jedoch android.permission.ACCESS_FINE_LOCATION, es sei denn, Sie benötigen nur eine Genauigkeit von km, ansonsten ist diese Erlaubnis ein Muss.

Beachten Sie, dass ich mit Google Play Services mit LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY Standortdaten so genau wie 10m ohne GPS aktivieren kann, so sollte dies noch Ihre Anforderung erfüllen.

Im Folgenden finden Sie ein vollständiges Beispiel:

AndroidManifest.xml

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

MainActivity.java

import android.app.Activity; 
import android.location.Location; 
import android.os.Bundle; 
import android.widget.TextView; 

import com.google.android.gms.common.ConnectionResult; 
import com.google.android.gms.common.api.GoogleApiClient; 
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks; 
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener; 
import com.google.android.gms.location.FusedLocationProviderApi; 
import com.google.android.gms.location.LocationRequest; 
import com.google.android.gms.location.LocationServices; 

public class MainActivity extends Activity implements 
     com.google.android.gms.location.LocationListener, ConnectionCallbacks, 
     OnConnectionFailedListener { 
    private final FusedLocationProviderApi fusedLocationProviderApi = LocationServices.FusedLocationApi; 
    private GoogleApiClient mGoogleAPIClient; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     mGoogleAPIClient = new GoogleApiClient.Builder(this) 
       .addApi(LocationServices.API).addConnectionCallbacks(this) 
       .addOnConnectionFailedListener(this).build(); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 

     mGoogleAPIClient.connect(); 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 

     if (mGoogleAPIClient != null) { 
     mGoogleAPIClient.disconnect(); 
     } 
    } 

    @Override 
    public void onConnected(Bundle arg0) { 
     final LocationRequest locationRequest = LocationRequest.create(); 
     locationRequest 
       .setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY); 
     locationRequest.setInterval(30 * 1000); 
     locationRequest.setFastestInterval(5 * 1000); 
     fusedLocationProviderApi.requestLocationUpdates(mGoogleAPIClient, 
       locationRequest, this); 
    } 

    @Override 
    public void onConnectionSuspended(int arg0) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void onConnectionFailed(ConnectionResult arg0) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void onLocationChanged(Location location) { 
     // the location is no more than 10 min old, and with reasonable 
     // accurarcy (50m), done 
     if (System.currentTimeMillis() < location.getTime() + 10 * 60 * 1000 
       && location.getAccuracy() < 50) { 
      mGoogleAPIClient.disconnect(); 
      mGoogleAPIClient = null; 
      ((TextView) findViewById(R.id.test)).setText(location.toString()); 
     } 
    } 
} 
+0

Funktioniert das gut ohne Internet? –

+0

Ja, Sie können GPS und jede Internetverbindung ausschalten und versuchen Sie es selbst – Kai

+0

, aber das kann mir nicht den Namen des Standortes (z. B. London). Dies gibt nur Breitengrade und Längengrade. Ich habe auch versucht, Geocoder zu verwenden, aber es braucht Internet. –

0

diesen Code versuchen ..

import android.app.Service; 
import android.content.Context; 
import android.content.Intent; 
import android.location.Location; 
import android.location.LocationListener; 
import android.location.LocationManager; 
import android.os.Bundle; 
import android.os.IBinder; 

public class AppLocationService extends Service implements LocationListener   { 

protected LocationManager locationManager; 
Location location; 

private static final long MIN_DISTANCE_FOR_UPDATE = 10; 
private static final long MIN_TIME_FOR_UPDATE = 1000 * 60 * 2; 

public AppLocationService(Context context) { 
    locationManager = (LocationManager) context 
      .getSystemService(LOCATION_SERVICE); 
} 

public Location getLocation(String provider) { 
    if (locationManager.isProviderEnabled(provider)) { 
     locationManager.requestLocationUpdates(provider, 
       MIN_TIME_FOR_UPDATE, MIN_DISTANCE_FOR_UPDATE, this); 
     if (locationManager != null) { 
      location = locationManager.getLastKnownLocation(provider); 
      return location; 
     } 
    } 
    return null; 
} 

@Override 
public void onLocationChanged(Location location) { 
} 

@Override 
public void onProviderDisabled(String provider) { 
} 

@Override 
public void onProviderEnabled(String provider) { 
} 

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

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

}

und nächste Klasse ist

import android.app.Activity; 
import android.app.AlertDialog; 
import android.content.DialogInterface; 
import android.content.Intent; 
import android.location.Location; 
import android.location.LocationManager; 
import android.os.Bundle; 
import android.provider.Settings; 
import android.view.Menu; 
import android.view.View; 
import android.widget.Button; 
import android.widget.Toast; 

public class AndroidLocationActivity extends Activity { 

Button btnGPSShowLocation; 
Button btnNWShowLocation; 

AppLocationService appLocationService; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    appLocationService = new AppLocationService(
      AndroidLocationActivity.this); 

    btnGPSShowLocation = (Button) findViewById(R.id.btnGPSShowLocation); 
    btnGPSShowLocation.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View arg0) { 

      Location gpsLocation = appLocationService 
        .getLocation(LocationManager.GPS_PROVIDER); 

      if (gpsLocation != null) { 
       double latitude = gpsLocation.getLatitude(); 
       double longitude = gpsLocation.getLongitude(); 
       Toast.makeText(
         getApplicationContext(), 
         "Mobile Location (GPS): \nLatitude: " + latitude 
           + "\nLongitude: " + longitude, 
         Toast.LENGTH_LONG).show(); 
      } else { 
       showSettingsAlert("GPS"); 
      } 

     } 
    }); 

    btnNWShowLocation = (Button) findViewById(R.id.btnNWShowLocation); 
    btnNWShowLocation.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View arg0) { 

      Location nwLocation = appLocationService 
        .getLocation(LocationManager.NETWORK_PROVIDER); 

      if (nwLocation != null) { 
       double latitude = nwLocation.getLatitude(); 
       double longitude = nwLocation.getLongitude(); 
       Toast.makeText(
         getApplicationContext(), 
         "Mobile Location (NW): \nLatitude: " + latitude 
           + "\nLongitude: " + longitude, 
         Toast.LENGTH_LONG).show(); 
      } else { 
       showSettingsAlert("NETWORK"); 
      } 

     } 
    }); 

} 

public void showSettingsAlert(String provider) { 
    AlertDialog.Builder alertDialog = new AlertDialog.Builder(
      AndroidLocationActivity.this); 

    alertDialog.setTitle(provider + " SETTINGS"); 

    alertDialog 
      .setMessage(provider + " is not enabled! 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); 
        AndroidLocationActivity.this.startActivity(intent); 
       } 
      }); 

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

    alertDialog.show(); 
} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    getMenuInflater().inflate(R.menu.main, menu); 
    return true; 
} 

} und diese Erlaubnis Benutzer

gegeben
<!-- to get location using GPS --> 
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 

<!-- to get location using NetworkProvider --> 
<uses-permission android:name="android.permission.INTERNET" /> 
+0

ändern Sie auch Ihre XML-Datei ..when Require.Danke und Grüße –

+0

Ich sehe das auch nicht geben NAME .. !!! Dies gibt auch nur lat und lang. –

+0

Ja, Sie bekommen diesen Lat lang. auf diesem lat lange um die Adresse –

0

Viel Glück damit. Es heißt Geocoder. Oder genauer Rückwärtskodierung, um Koordinaten in eine vom Menschen lesbare Ausgabe zu verwandeln. Ich bin mir ziemlich sicher, dass das, das Google anbietet, ein Bezahldienst ist, aber Sie erhalten ein Bündel frei. Planen Sie also das Zwischenspeichern der Ergebnisse und die Verwendung Ihrer zwischengespeicherten Ergebnisse, wann immer dies möglich ist.

List<Address> list = geoCoder.getFromLocation(location 
      .getLatitude(), location.getLongitude(), 1); 
    if (list != null & list.size() > 0) { 
     Address address = list.get(0); 
     result = address.getLocality(); 
     return result; 

https://developer.android.com/training/location/display-address.html

How to get city name from latitude and longitude coordinates in Google Maps?

+0

Das braucht Internet .. !!! Also das ist nicht das, was ich will –

+0

Wie mit welchem ​​Turm Gerät verbunden? – danny117

+0

Ja. Wie auch immer der Name des Bereichs der Turm ist .. !! –

1

Sie können versuchen, eine länderspezifische Genauigkeit mithilfe des Locale-Objekts oder mithilfe des Telefoniedienstes zu erhalten. Kein Internet oder GPS erforderlich.

Erster Ländercode von Gebietsschema:

String locale = context.getResources().getConfiguration().locale.getCountry(); 

Erster Ländercode von Android Telefonie-Dienst:

TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE); 
// Will work on all networks. Only provide the SIM card's country 
String countryCode = tm.getSimCountryIso(); 

// Might not work well on CDMA networks. Will provide the country code 
// for the country the device is currently in. 
String currentCountryCode = tm.getNetworkCountryIso(); 

Bessere Codebeispiele und Diskussion here.

+1

Aber ich brauche eine Genauigkeit auf Stadtebene. –

Verwandte Themen