For development and testing purposes you can implement a mock location provider. You need to enable "Allow mock locations" in developer options in order for applications to see locations from that provider.
For a code example, look at GPX Playback:
https://github.com/johncarpenter/Android-GPX-Mock-Location-Provider
The code for registering the location provider starts in line 203 of file
android/src/com/twolinessoftware/android/PlaybackService.java.
If you want a "real" location provider (e.g. to deploy your functionality as part of an end-user application), some sources say it cannot be done unless that provider is in a package signed with the system key, so you'd have to build your own ROM from source, sign it with your key, sign your location provider with the same key and install both on your phone.
However, Android at some point introduced "unbundled" location providers. Apparently they needed that in order to move their own NetworkLocationProvider from the Android core into the Google Apps package.
I haven't seen an unbundled location provider working in practice yet and I'm not aware of any open-source code using it, but it looks like recent version of Android have support for "aftermarket" location providers.
Source code for the respective library is at
https://github.com/CyanogenMod/android_frameworks_base/tree/cm-10.1/location/lib
A location provider would have to extend com.android.location.provider.LocationProviderBase.
Classes and methods are documented in the code.
Edit: Looking at
https://github.com/android/platform_frameworks_base/blob/master/core/res/AndroidManifest.xml
starting at line 607, it looks like the protection level for the INSTALL_LOCATION_PROVIDER permission is signatureOrSystem. This means that any app which uses this feature (i.e. installs a location provider, not necessarily the locaion provider itself) would either need to be signed with the same key as the platform (which would require you to build your entire Android system from source) or be installed as a system application (which might work on rooted devices).
There is some code at
https://github.com/microg/NetworkLocation
which seems to implement a LocationProvider. I haven't looked at it in detail (yet) or built it, so I cannot say if it works and what is requierd for it. But maybe it provides some pointers.
How to provide your own LocationProvider on Android? - Stack Overflow
network programming - Source code for Android location provider packages - Stack Overflow
How do you make Android LocationManager use Cell network and not Wifi network? - Stack Overflow
Activating Network Location Provider in the Android Emulator? - Stack Overflow
Videos
For development and testing purposes you can implement a mock location provider. You need to enable "Allow mock locations" in developer options in order for applications to see locations from that provider.
For a code example, look at GPX Playback:
https://github.com/johncarpenter/Android-GPX-Mock-Location-Provider
The code for registering the location provider starts in line 203 of file
android/src/com/twolinessoftware/android/PlaybackService.java.
If you want a "real" location provider (e.g. to deploy your functionality as part of an end-user application), some sources say it cannot be done unless that provider is in a package signed with the system key, so you'd have to build your own ROM from source, sign it with your key, sign your location provider with the same key and install both on your phone.
However, Android at some point introduced "unbundled" location providers. Apparently they needed that in order to move their own NetworkLocationProvider from the Android core into the Google Apps package.
I haven't seen an unbundled location provider working in practice yet and I'm not aware of any open-source code using it, but it looks like recent version of Android have support for "aftermarket" location providers.
Source code for the respective library is at
https://github.com/CyanogenMod/android_frameworks_base/tree/cm-10.1/location/lib
A location provider would have to extend com.android.location.provider.LocationProviderBase.
Classes and methods are documented in the code.
Edit: Looking at
https://github.com/android/platform_frameworks_base/blob/master/core/res/AndroidManifest.xml
starting at line 607, it looks like the protection level for the INSTALL_LOCATION_PROVIDER permission is signatureOrSystem. This means that any app which uses this feature (i.e. installs a location provider, not necessarily the locaion provider itself) would either need to be signed with the same key as the platform (which would require you to build your entire Android system from source) or be installed as a system application (which might work on rooted devices).
There is some code at
https://github.com/microg/NetworkLocation
which seems to implement a LocationProvider. I haven't looked at it in detail (yet) or built it, so I cannot say if it works and what is requierd for it. But maybe it provides some pointers.
It cannot be done.
The problem is that only OEMs are allowed to install a new location provider. A third-party developer cannot grant to his/her application the permission required to install a new location provider (android.permission.INSTALL_LOCATION_PROVIDER).
See the answer of Dianne Hackborn (Android framework engineer) in this thread:
https://groups.google.com/d/topic/android-developers/OvCcdvO6jZY/discussion
To install a new location provider, you should develop a whole new firmware (like http://www.cyanogenmod.com/ ), insert your new location provider in this firmware and install all of this stuff o the user's phone.
See this SO thread, as well: Why are these permissions being refused?
All of this because of security concerns.
I don't believe you can.
Network location provider look at the wifi state and cell state, discard one if too old, or send them both over to the Google Location Server (GLS) via MASF server. What's done there is magic. But you can look at the implementation of NetworkProvider and see how to tweak your code. Codes are here: NetworkLocationProvider.
If you just want the cell ID, check out Telephony Manager. Add a PhoneStateListener there.
Check out this section in the Android Dev Guide: Requesting Location Updates. Basically, you need to register a listener to get location updates, and then you tell Android that you want to get those updates with the network location provider.
// 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);
You should then be able to get the last known location with getLastKnownLocation() and/or use the onLocationChanged() in the LocationListener.
I believe that what you want to achieve is not possible at the moment. You cannot put mock location data to the emulator's network location provider.
"Providing mock location data is injected as GPS location data, so you must request location updates from GPS_PROVIDER in order for mock location data to work." (Quote from Android, Documentation, Providing Mock Location Data)
The closest thing I can come up with would be to to create a "Test Provider" from the Location Manager
public void addTestProvider (String name, boolean requiresNetwork, boolean requiresSatellite, boolean requiresCell, boolean hasMonetaryCost, boolean supportsAltitude, boolean supportsSpeed, boolean supportsBearing, int powerRequirement, int accuracy)
and set the arguments requiresNetwork, requiresCell and requiresSatellite accordingly. Then you can from put fake locations to that provider:
public void setTestProviderLocation (String provider, Location loc)
That's close to but not exactly what you asked for.
do you need to send location info to the emulator? if you wanna do this, yo can send location to the emulator throug the adb console and the geo command http://developer.android.com/guide/developing/tools/emulator.html#geo
i don't know if its possible to send fake cellid, but its possible with gps coordinates, if your application listen to any gps provider
There are 3 location providers in Android.
They are:
gps –> (GPS, AGPS): Name of the GPS location provider. This provider determines location using satellites. Depending on conditions, this provider may take a while to return a location fix. Requires the permission android.permission.ACCESS_FINE_LOCATION.
network –> (AGPS, CellID, WiFi MACID): Name of the network location provider. This provider determines location based on availability of cell tower and WiFi access points. Results are retrieved by means of a network lookup. Requires either of the permissions android.permission.ACCESS_COARSE_LOCATION or android.permission.ACCESS_FINE_LOCATION.
passive –> (CellID, WiFi MACID): A special location provider for receiving locations without actually initiating a location fix. This provider can be used to passively receive location updates when other applications or services request them without actually requesting the locations yourself. This provider will return locations generated by other providers. Requires the permission android.permission.ACCESS_FINE_LOCATION, although if the GPS is not enabled this provider might only return coarse fixes. This is what Android calls these location providers, however, the underlying technologies to make this stuff work is mapped to the specific set of hardware and telco provided capabilities (network service).
The best way is to use the “network” or “passive” provider first, and then fallback on “gps”, and depending on the task, switch between providers. This covers all cases, and provides a lowest common denominator service (in the worst case) and great service (in the best case).

Article Reference : Android Location Providers - gps, network, passive By Nazmul Idris
Code Reference : https://stackoverflow.com/a/3145655/28557
-----------------------Update-----------------------
Now Android have Fused location provider
The Fused Location Provider intelligently manages the underlying location technology and gives you the best location according to your needs. It simplifies ways for apps to get the user’s current location with improved accuracy and lower power usage
Fused location provider provide three ways to fetch location
- Last Location: Use when you want to know current location once.
- Request Location using Listener: Use when application is on screen / frontend and require continues location.
- Request Location using Pending Intent: Use when application in background and require continues location.
References :
Official site : http://developer.android.com/google/play-services/location.html
Fused location provider example: GIT : https://github.com/kpbird/fused-location-provider-example
http://blog.lemberg.co.uk/fused-location-provider
--------------------------------------------------------
GPS is generally more accurate than network but sometimes GPS is not available, therefore you might need to switch between the two.
A good start might be to look at the android dev site. They had a section dedicated to determining user location and it has all the code samples you need.
http://developer.android.com/guide/topics/location/obtaining-user-location.html
Attached below some nice network util functions I've been using across my apps, all works like a charm! and for location polling, definitely -> https://github.com/commonsguy/cwac-locpoll
hope this helps...
public static boolean checkInternetConnection(Context context) {
ConnectivityManager conMgr = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
// ARE WE CONNECTED TO THE NET?
if (conMgr.getActiveNetworkInfo() != null
&& conMgr.getActiveNetworkInfo().isAvailable()
&& conMgr.getActiveNetworkInfo().isConnected()) {
return true;
} else {
Log.w(TAG, "Internet Connection NOT Present");
return false;
}
}
public static boolean isConnAvailAndNotRoaming(Context context) {
ConnectivityManager conMgr = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (conMgr.getActiveNetworkInfo() != null
&& conMgr.getActiveNetworkInfo().isAvailable()
&& conMgr.getActiveNetworkInfo().isConnected()) {
if(!conMgr.getActiveNetworkInfo().isRoaming())
return true;
else
return false;
} else {
Log.w(TAG, "Internet Connection NOT Present");
return false;
}
}
public static boolean isRoaming(Context context) {
ConnectivityManager conMgr = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
return (conMgr.getActiveNetworkInfo()!=null && conMgr.getActiveNetworkInfo().isRoaming());
}
You can also try like this:
public boolean isDataConnectionAvailable(Context context){
ConnectivityManager connectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = connectivityManager.getActiveNetworkInfo();
if(info == null)
return false;
return connectivityManager.getActiveNetworkInfo().isConnected();
}
public boolean isGpsEnabled(LocationManager manager){
if ( !manager.isProviderEnabled( LocationManager.GPS_PROVIDER ) ) {
return false;
}
return true;
}
public boolean isLocationByNetworkEnabled(LocationManager manager){
if ( !manager.isProviderEnabled( LocationManager.NETWORK_PROVIDER ) ) {
return false;
}
return true;
}
Probably you were disabling the main menu's Wi-Fi connection on the drop down options instead of disabling the "Use wireless networks" under Settings-Location Services.
Bear in mind that Wi-Fi != Use Wireless Networks.
When you use
locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
it is cheking the "User Wireless Networks" option.
I had the same problem, many alike questions were posted at StackOverflow and only one answer had this information. Took me a whole afternoon. Hope you got it! :)
In new Android 4.3 (API level 18 and above) and devices using that, there's an advanced WiFi setting: "Scan always available". If its checkbox is checked, the device is able to scan for WLAN & location even if WiFi is switched off, and therefore will most likely enter the second if statement. To get this fixed programmatically, you could add build version check (and probably some other settings checks) to the if statement. (And you should define how you would want it to work in that case.) The easy manual workaround is of course to disable the setting: e.g. in Nexus 7: Settings->WiFi->Advanced-> uncheck "Scanning always available".
You are definitely trying to do this the hard way. Here are some snippets from a new app I am working on. It uses Criteria to get all providers capable of returning a fine level of accuracy without a cost.
If no providers are enabled a dialog is displayed that prompts the user to turn on their location settings. If the user hits ok an Intent is actually fired that sends them to the settings on their phone. If there are providers enabled the app takes the most recent last known location from any of the enabled providers. For my app I just need to know what general area the user is in and it's likely that the last known location is from their home area.
If providers are enabled the loop also requests location updates as quickly as possible. This is ideal for my app but you can change this to conserve battery my modifying the arguments to the requestLocationUpdates method.
The optimization that this code has that the examples on the Android app don't really show is that all of the enabled providers are started simultaneously. All of the providers will return separate updates on to the onLocationChanged method. In my app I remove the location listener after one of the providers returns a location with a good enough accuracy.
Start Location Updates:
void getCurrentLocation() {
List<String> providers = locationManager.getProviders(criteria, true);
if (providers != null) {
Location newestLocation = null;
for (String provider : providers) {
Location location = locationManager.getLastKnownLocation(provider);
if (location != null) {
if (newestLocation == null) {
newestLocation = location;
} else {
if (location.getTime() > newestLocation.getTime()) {
newestLocation = location;
}
}
locationManager.requestLocationUpdates(provider, 0, 0, this);
}
}
} else {
LocationDialogFragment dialog = new LocationDialogFragment();
dialog.show(getSupportFragmentManager(),
LocationDialogFragment.class.getName());
}
}
Receive Location Update:
@Override
public void onLocationChanged(Location location) {
float bestAccuracy = -1f;
if (location.getAccuracy() != 0.0f
&& (location.getAccuracy() < bestAccuracy) || bestAccuracy == -1f) {
if (location.getAccuracy() < Const.MIN_ACCURACY) {
locationManager.removeUpdates(this);
}
}
bestAccuracy = location.getAccuracy();
}
Location Settings Dialog:
public class LocationDialogFragment extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage(R.string.location_dialog_message)
.setPositiveButton(R.string.location_dialog_positive_button,
new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent settingsIntent = new Intent(
Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(settingsIntent);
}
})
.setNegativeButton(R.string.location_dialog_negative_button,
new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(getActivity(),
R.string.no_location_message, Toast.LENGTH_LONG)
.show();
}
});
return builder.create();
}
}
Thread.sleep() in production code is a serious code smell IMHO. If you find you're having to do that, you're probably doing something that's not supposed to work that way. In this case, I think it's the source of your problem -- you're not letting Android go back to process this thread's message queue to dispatch any location updates it finds. I suspect an IntentService is just not going to work for your scenario.