13

This question is directly related to the same prevailing stackoverflow question at "Android: get current location of user without using gps or internet" where the accepted answer is actually not answering the question.

I should be able to get the current location name (eg:city name, village name) of the device via network provider not with GPS or internet. Following is the accepted answer in that question. (The following code parts should be included in the onCreate() method)

// 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); 

I changed the above code given in the linked answer as following but no success.

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); } } 

How to accomplish what I want by correcting above code or any other method? Note that I want to get the location name, but not the longitudes and latitudes. Can somebody please help me.

8
  • I am not entirely clear of what you are asking, can you describe exactly what you are trying to accomplish, what kind of behavior you are trying to get, the expected time between location updates, etc Commented May 2, 2015 at 1:47
  • I just want to get current location of user without using gps or internet. Commented May 2, 2015 at 3:39
  • @Kai Are you clear what the problem is? I did a small edit in the question at the end too. Commented May 3, 2015 at 12:01
  • 1
    The problem is that the code you tried does work, probably just not as well as you wished. For example, the accuracy such a method provides on Samsung Galaxy S3 is 2000m, meaning my actual position is anywhere within a circle of 2 kilometers radius. Additional it would probably take quite a large change in location before your app would be informed of a location change since the margin of error is so big. The answer provided by Ruben would give you better result many times, though you do have to change the priority to LocationRequest.PRIORITY_LOW_ENERGY to satisfy your no GPS requirement. Commented May 3, 2015 at 12:21
  • @Kai I want to get the location without a location change occur. That is my objective. It means that I want to get the fresh current location when I start the app while my phone location is never changed. If my objective cannot be fulfilled by above code, how to change it to do it. Commented May 3, 2015 at 12:31

6 Answers 6

4
+25

What you are referring to here (showing location name on older phones) is done using "Cell Broadcast" (or "CB"). This has absolutely nothing to do with the Location API or any variations on that.

Cell towers can send out broadcast information that can be received by devices (something like "one to many SMS"). Some operators have used Cell Broadcast to broadcast the name of the location where the cell tower is. Some operators have used Cell Broadcast to broadcast the location (lat/long) of the cell tower. Some operators have used Cell Broadcast to send advertising tickers. There are no standards for the information contained in a CB broadcast message and each mobile operator can choose to use this or not.

Since most operators do not send these messages, it probably doesn't make sense to invest any time in trying to receive and decode them. But if you want to try, you can register a BroadcastReceiver listening for this Intent action: android.provider.Telephony.SMS_CB_RECEIVED. See the documentation for more details about what data is contained in the Intent.

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks a lot... This is exactly the answer I was struggling for... 100% correct... Sorry I couldn't accept the answer before ending the bounty period as I couldn't check at the last moment..
Let me know if you have any luck with the Cell Broadcast.
I tried to get cell broadcast messages. But could not find a correct way. Can u mention a way if u know please.
Do you know if your operator is sending cell broadcasts? Have you confirmed this?
Yes, I confirmed it. When I turn on cell broadcast messages in my phone those messages are received with location names.
|
1

The problem is that the code you tried does work, probably just not as well as you wished. For example, the accuracy such a method provides on Samsung Galaxy S3 is 2000m, meaning the actual position is anywhere within a circle of 2 kilometers radius. Additional it would probably take quite a large change in location before your app would be informed of a location change since the margin of error is so big.

A GPS or LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY (if Google Play Services is used) is required to get a reasonably good location. This does require android.permission.ACCESS_FINE_LOCATION, however unless you only require km level accuracy, otherwise this permission is a must.

Finally note that using Google Play Services with LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY I can get location data as accurate as 10m without turning on GPS, so this should still satisfy your requirement.

Below is a complete example:

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()); } } } 

5 Comments

yes, you can turn off GPS and any internet connection and try it for yourself
but this cannot give me the location name (eg. London). This only gives latitudes and longitudes.. I tried also using geocoder, but it does need internet.
I think u have seen a most primitive phone such as "nokia 1110" shows the location name from the signal tower.(without internet or gps) I want to get that data. But as I see this approach cannot get it as Location class no method to get the location name
You've mentioned nothing about getting the location name which is entirely separate from the location info itself. That cannot be done without internet connection.
Sorry, I didn't thought I should mention that. [I will edit the question.] But I don't think that it is impossible as most primitive phones such as "nokia 1110" shows the location name by default from the signal tower.(without internet or gps). So if such a simple phone could do that, I guess android too could do that.
1

According to android docs using LocationManager is not the current recomended API (see 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. 

To learn how to set up the Google Services client library, see Setup in the Google Play services guide.

Once you have linked Google Services client library to your app you can achieve user location using FusedLocationProviderApi:

 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 } 

I have tested the code above and it works without internet connection but it requires that user enable location feature on device. Also it requires that the user have already enabled Location History feature into location feature.

Hope that this helps you.

7 Comments

what is mLocationProviderApi ? As I see mLocationProviderApi variable is not initialized. And pls mention the imports list.
Sorry, my mistake. I edited the code, please take a look. When I first implemented the code I create an attribute instance of FusedLocationProviderApi that I called mLocationProviderApi, but I found out that I can access a reference of FusedLocationProviderApi directly from LocationServices.FusedLocationApi.
Thanks, What do u mean by "enable location feature on device"? I guess this doesn't mean I should turn on gps.
Ok, This run without error but this cannot give me the location name (eg. London). This only gives latitudes and logitudes.. OMG,,,!!!
I think u have seen a most primitive phone such as "nokia 1110" shows the location name from the signal tower.(without internet or gps) I want to get that data. But as I see this approach cannot get it as Location class no method to get the location name
|
1

You can try getting a country level accuracy using the Locale object or using the Telephony service. No internet or GPS required.

Getting country code from Locale:

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

Getting country code from Android's Telephony service:

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(); 

Better code samples and discussion here.

1 Comment

But I need a city level accuracy.
0

Good luck with this. It's called geocoder. Or more specifically reverse geocoding to turn coordinates into a human readable output. I'm fairly sure the one google provides is a pay service but you get a bunch free. So plan on caching the results and using your cached results when ever possible.

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?

3 Comments

Like what tower device connected to?
Yes. Any way the name of area the tower is located..!!
:( It looks like proprietary information the area the tower is located in. I couldn't find anything. I think your best bet is to cache known locations on the device. Your app has to have a little bit of data connection in it...
0

try this code..

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; } } 

and next class is

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; } } 

and this user permission given At Manifest File

<!-- 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" /> 

4 Comments

also you change your XML File ..when Require. Thanks & Regards
yes you get this lat long. on this lat long to get the address
you get the address from to lat and long ?
I can get the address by lat long but that needs internet.. I cant use internet for the whole process.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.