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.

Answer from user149408 on Stack Overflow
🌐
Microsoft Learn
learn.microsoft.com › en-us › windows › win32 › winsock › network-location-awareness-service-provider-nla--2
Network Location Awareness Service Provider (NLA) - Win32 apps | Microsoft Learn
January 7, 2021 - Personal computers running Microsoft Windows often have numerous network connections, such as multiple network interface cards (NIC) connected to different networks, or a physical network connection and a dial-up connection.
Discussions

How to provide your own LocationProvider on Android? - Stack Overflow
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. More on stackoverflow.com
🌐 stackoverflow.com
network programming - Source code for Android location provider packages - Stack Overflow
As for finding old versions of the network location provider, I would suggest a google search for NetworkLocationProvider.java. More on stackoverflow.com
🌐 stackoverflow.com
May 24, 2017
How do you make Android LocationManager use Cell network and not Wifi network? - Stack Overflow
Network location provider look ... But you can look at the implementation of NetworkProvider and see how to tweak your code. Codes are here: NetworkLocationProvider.... More on stackoverflow.com
🌐 stackoverflow.com
Activating Network Location Provider in the Android Emulator? - Stack Overflow
Is it possible to activate the network location provider on the android emulator? Maybe with a fake cellid? More on stackoverflow.com
🌐 stackoverflow.com
November 25, 2010
🌐
NXP
community.nxp.com › thread › 436381
NetworkLocationProvider - NXP Community
October 17, 2016 - As far as I know, NetworkLocationProvider has been phased out since android 1.5. However, there are many network location providers such as : com.google.Android.location.network.NetworkLocationService com.baidu.map.location.BaiduNetworkLocationService com.amap.android.location.NetworkLocat...
Top answer
1 of 4
13

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.

2 of 4
4

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.

🌐
Prog3
prog3.com › sbdm › blog › dailinqing1984 › article › details › 46358677
Network positioning service dailinqing1984 - NetworkLocationProvider blog Blog Channel - PROG3.COM
Network positioning service NetworkLocationProvider(107) APN (default, MMS, SUPL, dun, HIPRI access point type distinction)(99) Android 4.3 hidden function Ops App analysis(96) Mobile positioning service "ID Cell + RTT (cell recognition + round trip time)"(88) "OTDOA" (observed time difference of arrival) in mobile location service"(87) Comment ranking ·
Top answer
1 of 1
8

The package names are defined in /frameworks/base/core/res/res/values/config.xml:

<string-array name="config_locationProviderPackageNames" translatable="false">
    <!-- The standard AOSP fused location provider -->
    <item>com.android.location.fused</item>
</string-array>

And if you're looking for the source for the fused location provider itself, you can find that on grepcode here or googlesource here.

If you're looking for the network location provider, it seems the source code for that is no longer available. Quoting a message by Mike Lockwood from the Google android team:

The network location provider used to be in the open source, but has since been removed. We did this because we want the core android framework to be independent of any Google's services. We were also concerned that someone might ship a phone that uses network location without informing the user of its existence. Since it does communicate the user's location to our servers, we want to ensure that it is strictly an opt-in service and the users are made aware of our privacy guidelines. So now we only make NetworkLocation.apk available in binary form to partners that agree to follow our guidelines on how it is used.

As for finding old versions of the network location provider, I would suggest a google search for NetworkLocationProvider.java. I didn't see anything that looked particularly authoritative, but the first result was from netmite.com.

If you're specifically interested in the code that communicates with the Google Location Service backend, though, you should probably look at the LocationMasfClient class, which you can see here.

🌐
GitHub
github.com › microg › NetworkLocation › blob › master › NetworkLocation › src › internal › com › android › location › provider › LocationProvider.java
NetworkLocation/NetworkLocation/src/internal/com/android/location/provider/LocationProvider.java at master · microg/NetworkLocation
Deprecated! Use UnifiedNlp --- Geolocation using wlan and gsm cells. Data provided by Apple and opencellid.org - NetworkLocation/NetworkLocation/src/internal/com/android/location/provider/LocationProvider.java at master · microg/NetworkLocation
Author   microg
Find elsewhere
Top answer
1 of 3
1

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.

2 of 3
0

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.

Top answer
1 of 3
298

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

  1. Last Location: Use when you want to know current location once.
  2. Request Location using Listener: Use when application is on screen / frontend and require continues location.
  3. 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

--------------------------------------------------------

2 of 3
6

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

🌐
Android Developers
developer.android.com › api reference › locationprovider
LocationProvider | API reference | Android Developers
Skip to main content · English · Deutsch · Español – América Latina · Français · Indonesia · Polski · Português – Brasil · Tiếng Việt · 中文 – 简体
🌐
GitHub
github.com › rtreffer › LocalGSMLocationProvider
GitHub - rtreffer/LocalGSMLocationProvider: Local opencellid based location provider backend for UnifiedNlp
Local opencellid based location provider backend for UnifiedNlp - rtreffer/LocalGSMLocationProvider
Starred by 47 users
Forked by 10 users
Languages   Java 99.8% | Makefile 0.2% | Java 99.8% | Makefile 0.2%
Top answer
1 of 3
7

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

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;
}
🌐
GitHub
github.com › brave › brave-browser › issues › 10724
Support OS location service on macOS · Issue #10724 · brave/brave-browser
Upstream already has CoreLocationProvider. However, it doesn't work if Brave is not inserted in allowed list of Location Service. If Brave is not inserted, we should use NetworkLocationProvider as ...
Author   brave
🌐
XDA Forums
xdaforums.com › home › xiaomi › xiaomi mi 3 › mi 3 android development
[GUIDE] How to enable network location in Mi3/4 WCDMA | XDA Forums
December 17, 2014 - <string name="config_networkLocationProviderPackageName">com.amap.android.location</string> - Change that line into this one: Code: <string name="config_networkLocationProviderPackageName">@null</string> - Find this another line: Code: <string name="config_fusedLocationProviderPackageName">com.qualcomm.location</string> - Change that line into this one: Code: <string name="config_fusedLocationProviderPackageName">com.android.location.fused</string> 4.
Top answer
1 of 2
7

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

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.

🌐
GitHub
github.com › microg › NetworkLocation › issues › 4
Network Location Provider Documentation · Issue #4 · microg/NetworkLocation
February 5, 2014 - hi, i have some problems with the app which i would like to fix and would like to include an additional cell location provider. i wonder where i can get information about how it should work. can so...
Author   microg
🌐
Stack Overflow
stackoverflow.com › questions › 16811354 › android-network-provider-location
networking - Android NETWORK_PROVIDER location - Stack Overflow
I'm having little problem with getting my current location using NETWORK_PROVIDDER. My code looks like this: LocationManager lMgr = (LocationManager) context .getSystemService(Context.
🌐
Stack Overflow
stackoverflow.com › questions › 46000739 › cant-get-location-from-network-isproviderenabledlocationmanager-network-provid
android - can't get location from network isProviderEnabled(LocationManager.NETWORK_PROVIDER) always false - Stack Overflow
I am able to get location when GPS is on, but can't get location when it's off. I am trying to get the location from NETWORK_PROVIDER but it doesn't work. also tried using FusedLocationApi but it is