Eclipse Location Based Service (ELBS)


ELBS:   SOLD       




The LocationManager API seems overkill for a simple use case. The app I'm working on isn't really a location app per se, but it needs to get the user's location to display a list of nearby businesses. It doesn't need to worry about whether the user is moving or anything like that.

Here's what I want to do:

  1. Show users a list of nearby locations.
  2. Preload the user's location so that when I need it in ActivityX, it will be available.
  3. I don't really care about accuracy or frequency of updates. Just grabbing one location is enough as long as it's not too far away. Maybe if I wanted to get fancy I'd update the location every few minutes, but that's not a huge priority.
  4. Works for any device as long as it has GPS or Network Location provider.

Here's what I did:

  1. First I check what providers are enabled. Some may be disabled on the device, some may be disabled in the app manifest.
  2. If there is a provider available, I start a location listener and a timer runs out. It's 20 seconds in my example, probably not enough for GPS so you can zoom in.
  3. If I get an update from the location listener I use the provided value. I stopped the listener and timer.
  4. If I don't get an update and the timer elapses I have to use the last known value.
  5. I took the last known values ​​from the available providers and chose the latest one from them.

This is the class I use,

LocationResult locationResult = new LocationResult(){
    @Override
    public void gotLocation(Location location){
        //Got the location!
    }
};
MyLocation myLocation = new MyLocation();
myLocation.getLocation(this, locationResult);

This is my Location class,

import java.util.Timer;
import java.util.TimerTask;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;

public class MyLocation {
    Timer timer1;
    LocationManager lm;
    LocationResult locationResult;
    boolean gps_enabled=false;
    boolean network_enabled=false;

    public boolean getLocation(Context context, LocationResult result)
    {
        //I use LocationResult callback class to pass location value from MyLocation to user code.
        locationResult=result;
        if(lm==null)
            lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);

        //exceptions will be thrown if provider is not permitted.
        try{gps_enabled=lm.isProviderEnabled(LocationManager.GPS_PROVIDER);}catch(Exception ex){}
        try{network_enabled=lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);}catch(Exception ex){}

        //don't start listeners if no provider is enabled
        if(!gps_enabled && !network_enabled)
            return false;

        if(gps_enabled)
            lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps);
        if(network_enabled)
            lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork);
        timer1=new Timer();
        timer1.schedule(new GetLastLocation(), 20000);
        return true;
    }

    LocationListener locationListenerGps = new LocationListener() {
        public void onLocationChanged(Location location) {
            timer1.cancel();
            locationResult.gotLocation(location);
            lm.removeUpdates(this);
            lm.removeUpdates(locationListenerNetwork);
        }
        public void onProviderDisabled(String provider) {}
        public void onProviderEnabled(String provider) {}
        public void onStatusChanged(String provider, int status, Bundle extras) {}
    };

    LocationListener locationListenerNetwork = new LocationListener() {
        public void onLocationChanged(Location location) {
            timer1.cancel();
            locationResult.gotLocation(location);
            lm.removeUpdates(this);
            lm.removeUpdates(locationListenerGps);
        }
        public void onProviderDisabled(String provider) {}
        public void onProviderEnabled(String provider) {}
        public void onStatusChanged(String provider, int status, Bundle extras) {}
    };

    class GetLastLocation extends TimerTask {
        @Override
        public void run() {
             lm.removeUpdates(locationListenerGps);
             lm.removeUpdates(locationListenerNetwork);

             Location net_loc=null, gps_loc=null;
             if(gps_enabled)
                 gps_loc=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
             if(network_enabled)
                 net_loc=lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

             //if there are both values use the latest one
             if(gps_loc!=null && net_loc!=null){
                 if(gps_loc.getTime()>net_loc.getTime())
                     locationResult.gotLocation(gps_loc);
                 else
                     locationResult.gotLocation(net_loc);
                 return;
             }

             if(gps_loc!=null){
                 locationResult.gotLocation(gps_loc);
                 return;
             }
             if(net_loc!=null){
                 locationResult.gotLocation(net_loc);
                 return;
             }
             locationResult.gotLocation(null);
        }
    }

    public static abstract class LocationResult{
        public abstract void gotLocation(Location location);
    }
}

Someone may also want to modify my logic. For example, if you get an update from the Network provider do not stop the listener but continue waiting. GPS provides more accurate data so it is worth waiting. If the timer passes and you get an update from the Network but not from GPS, then you can use the value provided from the Network.

One more approach is to use LocationClient 

But it requires Google Play Services apk to be installed on the user's device.

implementation 'com.google.android.gms:play-services-location:7.0.0'

Use this to get the location,

if (mGoogleApiClient == null) {
    mGoogleApiClient = new GoogleApiClient.Builder(this)
        .addConnectionCallbacks(this)
        .addOnConnectionFailedListener(this)
        .addApi(LocationServices.API)
        .build();
}
if (mGoogleApiClient != null) {
    mGoogleApiClient.connect();
}

Display the data while the connection is in progress,

public class MainActivity extends ActionBarActivity implements
        ConnectionCallbacks, OnConnectionFailedListener {
    ...
    @Override
    public void onConnected(Bundle connectionHint) {
        mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
                mGoogleApiClient);
        if (mLastLocation != null) {
            mLatitudeText.setText(String.valueOf(mLastLocation.getLatitude()));
            mLongitudeText.setText(String.valueOf(mLastLocation.getLongitude()));
        }
    }
}

This Way Is More Precise In Getting User Geolocation

Hi Dev, the story is that I want to get the location of my application users, more precisely, I really need a reliable service to get the user's location precisely.

Unfortunately, I didn't know what to do, especially since I was still a newbie at that time.

Thanks to the masters on stackoverflow who have helped me a lot, here is a summary of their reviews.

First, I have to use LocationManager to get the coordinate points consisting of latitude and longitude. Then GeoCoder to get the location name and other information (this is called Reverse Geocoding), more about this you can read in the following documentation.

This code example will help you understand how to implement it, of course you also have to pay attention to what is explained in the link above.

import java.util.List;
import java.util.Locale;

import android.app.Activity;
import android.content.Context;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.TextView;

public class GeoSample extends Activity
{

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

        LocationManager locationManager;
        String context = Context.LOCATION_SERVICE;
        locationManager = (LocationManager) getSystemService(context);

        Criteria crta = new Criteria();
        crta.setAccuracy(Criteria.ACCURACY_FINE);
        crta.setAltitudeRequired(false);
        crta.setBearingRequired(false);
        crta.setCostAllowed(true);
        crta.setPowerRequirement(Criteria.POWER_LOW);
        String provider = locationManager.getBestProvider(crta, true);

        // String provider = LocationManager.GPS_PROVIDER;
        Location location = locationManager.getLastKnownLocation(provider);
        updateWithNewLocation(location);

        locationManager.requestLocationUpdates(provider, 1000, 0,
                locationListener);
    }

    private final LocationListener locationListener = new LocationListener()
    {

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

        @Override
        public void onProviderDisabled(String provider)
        {
            updateWithNewLocation(null);
        }

        @Override
        public void onProviderEnabled(String provider)
        {
        }

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

    };

    private void updateWithNewLocation(Location location)
    {
        String latLong;
        TextView myLocation;
        myLocation = (TextView) findViewById(R.id.myLocation);

        String addressString = "no address found";

        if (location != null)
        {
            double lat = location.getLatitude();
            double lon = location.getLongitude();
            latLong = "Lat:" + lat + "\nLong:" + lon;

            double lattitude = location.getLatitude();
            double longitude = location.getLongitude();

            Geocoder gc = new Geocoder(this, Locale.getDefault());
            try
            {
                List<Address> addresses = gc.getFromLocation(lattitude,
                        longitude, 1);
                StringBuilder sb = new StringBuilder();
                if (addresses.size() > 0)
                {
                    Address address = (Address) addresses.get(0);
                    sb.append(address.getAddressLine(0)).append("\n");
                    sb.append(address.getLocality()).append("\n");
                    sb.append(address.getPostalCode()).append("\n");
                    sb.append(address.getCountryName());
                }
                addressString = sb.toString();
            } catch (Exception e)
            {
            }
        } else
        {
            latLong = " NO Location Found ";
        }
        myLocation.setText("your Current Position is :\n" + latLong + "\n "
                + addressString);
    }
}

You also need to remember that the GPS Provider will provide precise information (provided that the surrounding environment is far from obstacles & interventions. Activating the GPS Provider will of course consume more battery power.

I think that's all the summary, hope it helps & good luck!

Android Studio Get Current Position Latitude & Longitude

Starting from my thesis project, I tried various ways to get longitude & latitude data from real devices. Long story short, I got the best practice of the Java code.

Actually, to test whether the code works or not, we can also do it with an Android emulator, it doesn't have to use a real device, just input the longitude & latitude data manually.

Another alternative if you are too lazy to travel to do a unit test using a real device, you can also use the fake GPS application on the Playstore, there you can do it by dragging & dropping check points on the fake GPS map.

First

Add permission in manifest.xml

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

This code is very simple, effective and easy to understand. This code produces the best data latitude and longitude of the current position, starting with the initialization of the satellite that can be captured, then the satellite used. In addition, location determination can also be done by collaboration between PROVIDERS (GPS or NETWORK), so you can set it using GPS mode, Network Provider, or using both.

Let's say in this case I want to display the current location in a TextView, so here is the sample code.

package com.bundet.sig;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.Menu;
import android.widget.TextView;
//don't implents LocationListner if you wants only latitude and longitude
//only at a time

public class MainActivity extends Activity implements LocationListener{
LocationManager locationManager;
TextView tvLatitude, tvLongitude;
String provider;
Location location;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    tvLongitude=(TextView)findViewById(R.id.lng);
    tvLatitude=(TextView)findViewById(R.id.lat);

    locationManager =(LocationManager)this.getSystemService(Context.LOCATION_SERVICE);
    Criteria c=new Criteria();
    //if we pass false than
    //it will check first satellite location than Internet and than Sim Network
    provider=locationManager.getBestProvider(c, false);
    location=locationManager.getLastKnownLocation(provider);
    if(location!=null)
    {
        double lng=location.getLongitude();
        double lat=location.getLatitude();
        tvLongitude.setText(""+lng);
        tvLatitude.setText(""+lat);
    }
    else
    {
        tvLongitude.setText("No Provider");
        tvLatitude.setText("No Provider");
    }
}
 //The below methods can be removed if you don't want location on move
@Override
public void onLocationChanged(Location arg0)
{
    double lng =location.getLongitude();
    double lat=location.getLatitude();
    tvLongitude.setText(""+lng);
    tvLatitude.setText(""+lat);
}
@Override
public void onProviderDisabled(String arg0) {
}
@Override
public void onProviderEnabled(String arg0) {
}
@Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
 }
}

Good luck!

Creating Android GPS & Location Based Service Application Using Eclipse

In this section, you will learn about

  • GPS on android
  • Google Maps 
  • Map, Marker and GPS

Current and future technology trends include mobile technology with its LBS feature. With LBS, we can search for a location very easily, search for friends' positions, publish our own location, search for road routes or others.

A gadget, say Android, can get its location from GPS, Network Location Provider, or both. Cell-id (Simcard) and wifi are examples of Network Location Providers.

Determining location using Android is easy but difficult, because the more accurate a location is, the more wasteful the battery is. The following are things that are obstacles to determining location

1. Multitude of location sources 

GPS, simcard and wifi can be combined to get accurate location, but the effect falls on the battery.

2. User migration 

As a user moves, the application will also refresh the location repeatedly.

3. Accuracy 

Accuracy of a location's position is inconsistent. A position 10 minutes ago may be more accurate than a recent position.

Okay, to quickly become an Android expert, now is the time to create an application to determine Latitude and Longitude. The scenario is we create an application that can capture changes in longitude and latitude values. Every time a change occurs, the new latitude and longitude values ​​are displayed via Toast and TextView. We can send the location to the emulator using DDMS. DDMS is discussed in more depth in section xx. The final result looks like figure 14.1.


Figure 14.1. Sending Location to the emulator. (a) DDMS section, (b) Emulator

1. Create a new project

| Project name    | PengenalanGPS     |
|-----------------|-------------------|
| Build Target    | Android 2.2       |
| Aplication name | Pengenalan GPS    |
| Package name    | Com.gps.sederhana |
| Create Activity | Lokasiku          |
| Min SDK version | 8                 |

2. Add a few lines of code to Strings.xml

1: <?xml version="1.0" encoding="utf-8"?>
2: <resources>
3: <string name="hello">Lokasiku!</string>
4: <string name="app_name">pengenalan GPS</string>
5: <string name="latText">Latitude :</string>
6: <string name="lonText">Longitude :</string>
7: </resources>

3. Create a main.xml view like the following

1: <?xml version="1.0" encoding="utf-8"?>
2: <LinearLayout
3: xmlns:android="http://schemas.android.com/apk/res/android"
4: android:orientation="vertical"
5: android:layout_width="fill_parent"
6: android:layout_height="fill_parent">
7: <TextView android:id="@+id/textView1"
8: android:layout_width="wrap_content"
9: android:layout_height="wrap_content"
10: android:textStyle="bold"
11: android:text="@string/lonText"></TextView>
12: <TextView android:text="unknown"
13: android:id="@+id/longitutdeTxt"
14: android:layout_width="wrap_content"
15: android:layout_height="wrap_content"></TextView>
16: <TextView android:id="@+id/textView3"
17: android:layout_width="wrap_content"
18: android:layout_height="wrap_content"
19: android:textStyle="bold"
20: android:text="@string/latText"></TextView>
21: <TextView android:text="unknown"
22: android:id="@+id/latitudeTxt"
23: android:layout_width="wrap_content"
24: android:layout_height="wrap_content"></TextView>
25: </LinearLayout>

4. Now we go to the MyLocation.java activity, add the following code.

1: package com.gps.sederhana;
2:
3: import android.app.Activity;
4: import android.content.Context;
5: import android.location.Location;
6: import android.location.LocationListener;
7: import android.location.LocationManager;
8: import android.os.Bundle;
9: import android.widget.TextView;
10: import android.widget.Toast;
11:
12: public class Lokasiku extends Activity {
13: private LocationManager lm;
14: private LocationListener locListener;
15: private TextView latTxt,lonTxt;
16:
17: /** Called when the activity is first created. */
18: @Override
19: public void onCreate(Bundle savedInstanceState) {
20: super.onCreate(savedInstanceState);
21: setContentView(R.layout.main);
22:
23: latTxt = (TextView) findViewById(R.id.latitudeTxt);
24: lonTxt = (TextView) findViewById(R.id.longitutdeTxt);
25: lm = (LocationManager)
26: getSystemService(Context.LOCATION_SERVICE);
27: locListener = new MyLocationListener();
28: lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0,
29: 200, locListener);
30: }
31:
32: private class MyLocationListener implements LocationListener
{
33: @Override
34: public void onLocationChanged(Location loc) {
35: if (loc != null) {
36: latTxt.setText(String.valueOf(loc.getLatitude()));
37: lonTxt.setText(String.valueOf(loc.getLongitude()));
38: Toast.makeText(getBaseContext(),
39: "Location Changed : Lat " + loc.getLatitude() +
40: "lgt: "+loc.getLongitude(), Toast.LENGTH_SHORT).show();
41: }
42: }
43: @Override
44: public void onProviderDisabled(String arg0) {}
45: @Override
46: public void onProviderEnabled(String arg0) {}
47: @Override
48: public void onStatusChanged(String provider, int status,
49: Bundle extras){}
50: }
51: }

5. Finally, add user.permission to access GPS into the Manifest.

1: <?xml version="1.0" encoding="utf-8"?>
2: <manifest
xmlns:android="http://schemas.android.com/apk/res/android"
3: package="com.gps.sederhana" android:versionCode="1"
4: android:versionName="1.0">
5: <application android:icon="@drawable/icon"
6: android:label="@string/app_name">
7: <activity android:name=".Lokasiku"
8: android:label="@string/app_name">
9: <intent-filter>
10: <action android:name="android.intent.action.MAIN" />
11: <category
12: android:name="android.intent.category.LAUNCHER" />
13: </intent-filter>
14: </activity>
15: </application>
16: <uses-sdk android:minSdkVersion="8" />
17: <uses-permission
18: android:name="android.permission.ACCESS_FINE_LOCATION">
19: </uses-permission>
20: <uses-permission
21: android:name="android.permission.ACCESS_COARSE_LOCATION">
22: </uses-permission>
23: <uses-permission
24: android:name="android.permission.INTERNET">
25: </uses-permission>
26: </manifest>

Please run it, while switching to the DDMS view.

Program Explanation

We start from the Manifest, here are the details of the 3 newly added permissions.

| ACCESS_COARSE_LOCATION | Izin untuk menentukan lokasi dari cell-id, wifi |
|------------------------|-------------------------------------------------|
| ACCESS_FINE_LOCATION   | Izin untuk menentukan lokasi dari GPS           |
| INTERNET               | Izin untuk mengakses internet                   |

Without adding the above permissions, the application you create will not fail to determine the location.

Next, look again at the MyLocation.java activity, we use 2 new classes, namely the LocationListener class and the LocationManager class. The LocationManager class acts as the application's gateway to access the location service on Android. This service allows applications to update their positions periodically. Note line 54, The first parameter in requestLocationUpdates() is the type of system used to determine the location, in this case we use GPS. If you want to determine the location based on wifi, replace GPS_PROVIDER with NETWORK_PROVIDER. The next parameter is the minimum time the application updates, while the 3rd parameter is the minimum distance. If the minimum time is filled in 60000 (ms) then the application will update every 6 seconds. In this project, the distance is filled in with the number 200 (m) then the application will update every time it moves more than 200m. The last parameter is the LocatinListener which will capture every location update process.

When a location change occurs or when the location update process is taking place, the application sends a signal which is then captured by the LocationListener class. In this class, there are 4 methods with the following details:

  • onLocationChanged(), executed when a location change occurs
  • onProviderDisabled(), executed when the provider is inactive 
  • onProviderEnabled(), called when the provider is active 
  • onStatusChanged(), called when there is a status change on the provider such as OUT_OF_SERVICE, AVAILABLE, or TEMPORARILY_UNAVAILABLE.

Post a Comment

Previous Next

نموذج الاتصال