0

I am a beginner in Android development. I have to develop an Android app for GPS location estimates using distributed location estimation algorithm. It uses the neighbouring nodes' location information and calculates the current GPS location. I got to know through the android location documentation http://developer.android.com/reference/android/location/package-summary.html that Google Location Services API is recommended. I have gone through quite a few posts here But still in a haze. Any inputs are welcome.

MainActivity.java

package com.example.sxn8837.locationapi;



import android.app.Activity;
import android.location.Location;
import android.location.LocationListener;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;

import static com.example.sxn8837.locationapi.R.*;
import static com.example.sxn8837.locationapi.R.layout.activity_main;
import static com.google.android.gms.location.LocationServices.*;

public class MainActivity extends Activity implements
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener,LocationListener {

    private static final String TAG = MainActivity.class.getSimpleName();
    private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 1000;
    private Location mLastLocation;
    private GoogleApiClient mGoogleApiClient;
    private boolean mRequestLocationUpdates = false ;
    private LocationRequest mLocationRequest;
    private static int UPDATE_INTERVAL = 10000;
    private static int FASTEST_INTERVAL = 5000;
    private static int DISPLACEMENT = 10;




    private TextView lbLocation;
    private Button btnStartLocationUpdates = (Button) findViewById(id.buttonLocationUpdates);
    private Button btnShowLocation = (Button) findViewById(id.buttonShowLocation);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(activity_main);
        lbLocation = (TextView) findViewById(id.lblLocation);
        if(checkPlayServices()){
         buildGoogleApiClient();
         createLocationRequest();
        }

        btnShowLocation.setOnClickListener(new View.OnClickListener (){

            public void onClick(View v){

                displayLocation();

            }
        });

        btnStartLocationUpdates.setOnClickListener(new View.OnClickListener(){

            public void onClick( View v){

                togglePeriodLocationUpdates();
            }

        });
    }

    protected void onStart(){
        super.onStart();
        if(mGoogleApiClient != null){
            mGoogleApiClient.connect();
        }
    }

    protected void onResume(){
        super.onResume();
        checkPlayServices();
        if(mGoogleApiClient.isConnected() && mRequestLocationUpdates ){
            startLocationUpdates();
        }
    }

    protected void onStop(){
        super.onStop();
        if(mGoogleApiClient.isConnected()  ){
            mGoogleApiClient.disconnect();
        }

    }

    protected void onPause(){
        super.onPause();
        stopLocationUpdates();
    }

    private void displayLocation(){

        mLastLocation = FusedLocationApi.getLastLocation(mGoogleApiClient);
        if(mLastLocation !=  null){
            double latitude = mLastLocation.getLatitude();
            double longitude = mLastLocation.getLongitude();
            lbLocation.setText(latitude + "," +longitude);
        }
        else {
            lbLocation.setText("Couldn't get Location Updates");
        }
    }

    private void togglePeriodLocationUpdates(){
        if(!mRequestLocationUpdates) {
            btnStartLocationUpdates.setText(getString(string.btn_stop_location_update));

            mRequestLocationUpdates = true;

            startLocationUpdates();
        }

        else {

            btnStartLocationUpdates.setText(getString(string.btn_stop_location_update));

            mRequestLocationUpdates = false ;

            stopLocationUpdates();


        }
    }

    protected synchronized void buildGoogleApiClient(){

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

    protected void createLocationRequest(){
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(UPDATE_INTERVAL);
        mLocationRequest.setInterval(FASTEST_INTERVAL);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
    }

    private boolean checkPlayServices(){
        int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);

        if(resultCode != ConnectionResult.SUCCESS){

            if(GooglePlayServicesUtil.isUserRecoverableError(resultCode)){
           GooglePlayServicesUtil.getErrorDialog(resultCode,this,PLAY_SERVICES_RESOLUTION_REQUEST).show();

            }else{

                Toast.makeText(getApplicationContext(),"This Device is not supported", Toast.LENGTH_LONG).show();
                finish();
            }
         return false ;
        }

        return true;
    }

    protected void startLocationUpdates(){
        FusedLocationApi.requestLocationUpdates(mGoogleApiClient,mLocationRequest, (com.google.android.gms.location.LocationListener) this);
    }

    protected void stopLocationUpdates (){
        final PendingResult<Status> statusPendingResult = FusedLocationApi.removeLocationUpdates(mGoogleApiClient, (com.google.android.gms.location.LocationListener) this);


    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onConnected(Bundle bundle) {

        displayLocation();

        if(mRequestLocationUpdates){
            startLocationUpdates();
        }
    }

    @Override
    public void onConnectionSuspended(int i) {
     mGoogleApiClient.connect();
    }

    @Override
    public void onLocationChanged(Location location) {

        mLastLocation = location ;

        Toast.makeText(getApplicationContext(),"Location Changed",Toast.LENGTH_SHORT).show();
        displayLocation();

    }

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

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
       Log.i(TAG, "Connection Failed:" + connectionResult.getErrorCode());
    }
}

content_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    android:layout_gravity="center_horizontal"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:showIn="@layout/activity_main" tools:context=".MainActivity">

    <TextView android:text="@string/lbl_you_are_at"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize = "25sp"
        android:textStyle = "bold"/>

    <TextView
        android:id="@+id/lblLocation"
        android:padding="15dp"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:textSize = "16sp"
        android:textStyle = "bold"/>

    <Button
        android:id="@+id/buttonShowLocation"
        android:padding="20dp"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:layout_marginTop="40dp"
        android:paddingLeft="20dp"
        android:paddingRight="20dp"
        android:text = "@string/btn_get_location"
        android:textSize = "16sp"
        android:textStyle = "bold"/>
    >

    <Button
        android:id="@+id/buttonLocationUpdates"
        android:padding="20dp"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:layout_marginTop="60dp"
        android:background="@color/common_signin_btn_default_background"
        android:paddingLeft="20dp"
        android:paddingRight="20dp"
        android:text = "@string/btn_start_location_update"
        android:textSize = "16sp"
        android:textStyle = "bold"/>
        >

</LinearLayout>

Androidmanifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.sxn8837.locationapi" >
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar" >

        <meta-data
            android:name = "com.google.android.gms.version"
            android:value = "@integer/google_play_services_version"
            />
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

logcat

11-09 20:18:13.352 3645-3645/? D/dalvikvm: Not late-enabling CheckJNI (already on)
11-09 20:18:15.012 3645-3645/com.example.sxn8837.locationapi I/dalvikvm: Could not find method android.content.res.TypedArray.getChangingConfigurations, referenced from method android.support.v7.internal.widget.TintTypedArray.getChangingConfigurations
11-09 20:18:15.022 3645-3645/com.example.sxn8837.locationapi W/dalvikvm: VFY: unable to resolve virtual method 511: Landroid/content/res/TypedArray;.getChangingConfigurations ()I
11-09 20:18:15.022 3645-3645/com.example.sxn8837.locationapi D/dalvikvm: VFY: replacing opcode 0x6e at 0x0002
11-09 20:18:15.032 3645-3645/com.example.sxn8837.locationapi I/dalvikvm: Could not find method android.content.res.TypedArray.getType, referenced from method android.support.v7.internal.widget.TintTypedArray.getType
11-09 20:18:15.032 3645-3645/com.example.sxn8837.locationapi W/dalvikvm: VFY: unable to resolve virtual method 533: Landroid/content/res/TypedArray;.getType (I)I
11-09 20:18:15.032 3645-3645/com.example.sxn8837.locationapi D/dalvikvm: VFY: replacing opcode 0x6e at 0x0002
11-09 20:18:15.312 3645-3645/com.example.sxn8837.locationapi I/dalvikvm: Could not find method android.content.pm.PackageManager.getPackageInstaller, referenced from method com.google.android.gms.common.GooglePlayServicesUtil.zzh
11-09 20:18:15.312 3645-3645/com.example.sxn8837.locationapi W/dalvikvm: VFY: unable to resolve virtual method 438: Landroid/content/pm/PackageManager;.getPackageInstaller ()Landroid/content/pm/PackageInstaller;
11-09 20:18:15.312 3645-3645/com.example.sxn8837.locationapi D/dalvikvm: VFY: replacing opcode 0x6e at 0x000b
11-09 20:18:15.332 3645-3645/com.example.sxn8837.locationapi W/GooglePlayServicesUtil: Google Play services is missing.
11-09 20:18:15.502 3645-3645/com.example.sxn8837.locationapi D/dalvikvm: GC_FOR_ALLOC freed 158K, 11% free 3301K/3692K, paused 83ms, total 86ms
11-09 20:18:16.002 3645-3645/com.example.sxn8837.locationapi D/dalvikvm: GC_FOR_ALLOC freed 3K, 11% free 3451K/3848K, paused 23ms, total 23ms
11-09 20:18:16.022 3645-3645/com.example.sxn8837.locationapi I/dalvikvm-heap: Grow heap (frag case) to 5.278MB for 1764376-byte allocation
11-09 20:18:16.052 3645-3654/com.example.sxn8837.locationapi D/dalvikvm: GC_FOR_ALLOC freed <1K, 8% free 5174K/5572K, paused 29ms, total 29ms
11-09 20:18:16.282 3645-3645/com.example.sxn8837.locationapi W/GooglePlayServicesUtil: Google Play services is missing.
11-09 20:18:16.332 3645-3645/com.example.sxn8837.locationapi D/AndroidRuntime: Shutting down VM
11-09 20:18:16.332 3645-3645/com.example.sxn8837.locationapi W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0xb1adbba8)
11-09 20:18:16.342 3645-3645/com.example.sxn8837.locationapi E/AndroidRuntime: FATAL EXCEPTION: main
11-09 20:18:16.342 3645-3645/com.example.sxn8837.locationapi E/AndroidRuntime: Process: com.example.sxn8837.locationapi, PID: 3645
11-09 20:18:16.342 3645-3645/com.example.sxn8837.locationapi E/AndroidRuntime: java.lang.RuntimeException: Unable to resume activity {com.example.sxn8837.locationapi/com.example.sxn8837.locationapi.MainActivity}: java.lang.NullPointerException
11-09 20:18:16.342 3645-3645/com.example.sxn8837.locationapi E/AndroidRuntime:     at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2774)
11-09 20:18:16.342 3645-3645/com.example.sxn8837.locationapi E/AndroidRuntime:     at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2803)
11-09 20:18:16.342 3645-3645/com.example.sxn8837.locationapi E/AndroidRuntime:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2238)
11-09 20:18:16.342 3645-3645/com.example.sxn8837.locationapi E/AndroidRuntime:     at android.app.ActivityThread.access$800(ActivityThread.java:135)
11-09 20:18:16.342 3645-3645/com.example.sxn8837.locationapi E/AndroidRuntime:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
11-09 20:18:16.342 3645-3645/com.example.sxn8837.locationapi E/AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:102)
11-09 20:18:16.342 3645-3645/com.example.sxn8837.locationapi E/AndroidRuntime:     at android.os.Looper.loop(Looper.java:136)
11-09 20:18:16.342 3645-3645/com.example.sxn8837.locationapi E/AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:5001)
11-09 20:18:16.342 3645-3645/com.example.sxn8837.locationapi E/AndroidRuntime:     at java.lang.reflect.Method.invokeNative(Native Method)
11-09 20:18:16.342 3645-3645/com.example.sxn8837.locationapi E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Method.java:515)
11-09 20:18:16.342 3645-3645/com.example.sxn8837.locationapi E/AndroidRuntime:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
11-09 20:18:16.342 3645-3645/com.example.sxn8837.locationapi E/AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
11-09 20:18:16.342 3645-3645/com.example.sxn8837.locationapi E/AndroidRuntime:     at dalvik.system.NativeStart.main(Native Method)
11-09 20:18:16.342 3645-3645/com.example.sxn8837.locationapi E/AndroidRuntime:  Caused by: java.lang.NullPointerException
11-09 20:18:16.342 3645-3645/com.example.sxn8837.locationapi E/AndroidRuntime:     at com.example.sxn8837.locationapi.MainActivity.onResume(MainActivity.java:86)
11-09 20:18:16.342 3645-3645/com.example.sxn8837.locationapi E/AndroidRuntime:     at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1192)
11-09 20:18:16.342 3645-3645/com.example.sxn8837.locationapi E/AndroidRuntime:     at android.app.Activity.performResume(Activity.java:5310)
11-09 20:18:16.342 3645-3645/com.example.sxn8837.locationapi E/AndroidRuntime:     at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2764)
11-09 20:18:16.342 3645-3645/com.example.sxn8837.locationapi E/AndroidRuntime:     at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2803)
11-09 20:18:16.342 3645-3645/com.example.sxn8837.locationapi E/AndroidRuntime:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2238)
11-09 20:18:16.342 3645-3645/com.example.sxn8837.locationapi E/AndroidRuntime:     at android.app.ActivityThread.access$800(ActivityThread.java:135)
11-09 20:18:16.342 3645-3645/com.example.sxn8837.locationapi E/AndroidRuntime:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
11-09 20:18:16.342 3645-3645/com.example.sxn8837.locationapi E/AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:102)
11-09 20:18:16.342 3645-3645/com.example.sxn8837.locationapi E/AndroidRuntime:     at android.os.Looper.loop(Looper.java:136)
11-09 20:18:16.342 3645-3645/com.example.sxn8837.locationapi E/AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:5001)
11-09 20:18:16.342 3645-3645/com.example.sxn8837.locationapi E/AndroidRuntime:     at java.lang.reflect.Method.invokeNative(Native Method)
11-09 20:18:16.342 3645-3645/com.example.sxn8837.locationapi E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Method.java:515)
11-09 20:18:16.342 3645-3645/com.example.sxn8837.locationapi E/AndroidRuntime:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
11-09 20:18:16.342 3645-3645/com.example.sxn8837.locationapi E/AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
11-09 20:18:16.342 3645-3645/com.example.sxn8837.locationapi E/AndroidRuntime:     at dalvik.system.NativeStart.main(Native Method)

 

MayorJay
  • 89
  • 7
Ice_Queen
  • 319
  • 2
  • 5
  • 19

2 Answers2

1

You can use Google’s fused location API for Android.

The Fused Location Provider intelligently manages the underlying location technology and gives us the best location according to our needs.

WHY USE :

We could choose one of the location providers (network or GPS) and request location updates or set up proximity alert. But there were two main issues with this approach:

  1. In case we need to define precise location, we had to switch between network and GPS location providers (as GPS doesn’t work indoors).
  2. Proximity alerts were used to notify a user about proximity to a location, and this took its toll on the battery life.

ADVANTAGE OF USING THIS API

  1. Simple APIs: Lets us specify high-level needs like “high accuracy” or “low power”, instead of having to worry about location providers.
  2. Immediately available: Gives our apps immediate access to the best, most recent location.
  3. Power-efficiency: Minimizes out app’s use of power. Based on all incoming location requests and available sensors, fused location provider chooses the most efficient way to meet those needs.
  4. Versatility: Meets a wide range of needs, from foreground uses that need highly accurate location to background uses that need periodic location updates with negligible power impact.
Er.Rohit Sharma
  • 696
  • 5
  • 21
  • Thanks for the Suggestion ! Will try that out ! – Ice_Queen Oct 20 '15 at 13:28
  • @ Er.Rohit Sharma I will be working over the weekend on retrieving the GPS coordinates using the APIs I just had another query I am not sure if I have to make an another thread for the same.I need a database to store the GPS coordinates retrieved via the APIs . I did go through various threads some suggest SQLite , MySQL with spatial extensions/plugins and some PostGIS.I need to develop a simple app so a lightweight db would do.Any inputs are welcome ? – Ice_Queen Oct 22 '15 at 21:48
  • If you want to store the location on the device(locally) in some database, then you can use SQLite . But if you want to store only location and no other data in a database, then using database connectivity is not the best choice. Then you should used 'Shared Preferences'. Its very easy to implement and very reliable to store such kind of small data in device. Storing and retrieving data from shared preferences is also fast as compare to SQLite. – Er.Rohit Sharma Oct 23 '15 at 05:47
  • Thank you so much.Will try all of that over the next couple of days.And post about how it went over the next week.I will check this answer as solved then.You have been of great help. – Ice_Queen Oct 23 '15 at 13:33
  • I tried the following program by referring a few tutorials online videos and so forth The code runs without any errors and on the emulator it displays unfortunately locationApi stopped.LocationApi is the name of my android project. I am here with attaching the MainActivity.java code – Shravya 54 mins ago – Ice_Queen Nov 01 '15 at 20:31
  • Please refer to this post : http://stackoverflow.com/questions/16810628/solved-android-unable-to-instantiate-activity-componentinfo – Er.Rohit Sharma Nov 02 '15 at 05:43
  • Thanks for the suggestion.But I am still not able to figure out the similarities with the problem in that post and mine.If you could elaborate what exactly I should be doing would be more helpful. – Ice_Queen Nov 08 '15 at 21:22
  • In that post it has ClassNotFoundException error and mine is Null Pointer Exception.Sorry but if you could shed more light that would be great. – Ice_Queen Nov 08 '15 at 21:29
  • Any inputs guyz it's been a while.Sorry to be pestering you.Need to get done with this as soon as I can . :-) – Ice_Queen Nov 09 '15 at 18:40
  • Have You gone through the fused location api documentation?? – Er.Rohit Sharma Nov 10 '15 at 04:16
  • Thanks for the reply.I did refer it and some of the other video references too.Here is the link I referred https://developers.google.com/android/reference/com/google/android/gms/location/FusedLocationProviderApi. But it just gives us a list of methods and what they do ? I noticed in my stack trace too that Google Play Services is missing . I have installed the package from the SDK Manager but when I googled go to know maybe I should set it to a lower version.Can you let me where I might be going wrong.Your inputs are welcome.Sorry about that. – Ice_Queen Nov 10 '15 at 16:40
  • This API ( FusedLocationProviderApi) has been deprecated; use FusedLocationProviderClient instead: https://developers.google.com/android/reference/com/google/android/gms/location/FusedLocationProviderClient – ONE May 11 '19 at 21:15
0

The Google Location Services API, part of Google Play Services, provides a more powerful, high-level framework that automatically handles location providers, user movement, and location accuracy. It also handles location update scheduling based on power consumption parameters you provide. In most cases, you'll get better battery performance, as well as more appropriate accuracy, by using the Location Services API.

http://developer.android.com/guide/topics/location/strategies.html