• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

Apps NullPointerException: help is really appreciated!

Hi everyone,

I am new to programming with Android Studio and following two tutorials:
https://www.androidtutorialpoint.com/intermediate/android-map-app-showing-current-location-android/
https://www.androidtutorialpoint.co...ng-google-directions-google-maps-android-api/

I would like my app to find the current position of the user, and for the user to be able to draw a path between current position and destination. Then later, I would like the distance and time for the shortest route displayed and the app tracking the movement of the user (like runkeeper).

However, my app keeps crashing, so I checked my logcat and have the following error:
java.lang.NullPointerException: Attempt to read from field 'double com.google.android.gms.maps.model.LatLng.latitude' on a null object reference

I tried finding solutions online (also on StackOverflow) but can't figure it out, unfortunately. I have been stuck with this for a couple of days, so I really hope someone is able to help me out. I have attached two files: my full logcat and MapsActivity.java.

Thank you!!!
 

Attachments

Hi. Welcome to Android Forums.

Please read this, as it contains some useful information on debugging, and how to resolve null pointer problems

http://androidforums.com/threads/please-read-me-before-posting.987318/

If you still have problems, feel free to ask further questions, but could you please post your code like this


[code]
Your code here..
[/code]


And also attach the stack trace output from your Logcat view in the same manner.
 
Thank you for your reply and the kind words! Yes I apologize - I will post the code the right way from now. I saw it after I posted the thread :oops:.

I tried debugging but I am very new to Android Studio and I don't understand why or what the error means (also because I am following aforementioned tutorials). Hopefully somebody is able to point me in the right direction, so I can learn from it.

This is the stack trace output from my Logcat:

Code:
03-10 15:07:58.106 10685-10685/? E/Zygote: MountEmulatedStorage()
03-10 15:07:58.106 10685-10685/? E/Zygote: v2
03-10 15:07:58.106 10685-10685/? I/libpersona: KNOX_SDCARD checking this for 10263
03-10 15:07:58.106 10685-10685/? I/libpersona: KNOX_SDCARD not a persona
03-10 15:07:58.111 10685-10685/? I/SELinux: Function: selinux_compare_spd_ram, SPD-policy is existed. and_ver=SEPF_SM-G850F_5.0.2-1 ver=51
03-10 15:07:58.116 10685-10685/? I/SELinux: Function: selinux_compare_spd_ram , priority [1] , priority version is VE=SEPF_SM-G850F_5.0.2-1_0051
03-10 15:07:58.121 10685-10685/? E/SELinux: [DEBUG] get_category: variable seinfo: default sensitivity: NULL, cateogry: NULL
03-10 15:07:58.121 10685-10685/? I/art: Late-enabling -Xcheck:jni
03-10 15:07:58.171 10685-10685/? D/TimaKeyStoreProvider: TimaSignature is unavailable
03-10 15:07:58.171 10685-10685/? D/ActivityThread: Added TimaKeyStore provider
03-10 15:07:58.656 10685-10685/com.lemonkicks.trackmycab.trackmycab I/InstantRun: Starting Instant Run Server for com.lemonkicks.trackmycab.trackmycab
03-10 15:08:11.801 10685-10692/com.lemonkicks.trackmycab.trackmycab W/art: Suspending all threads took: 48.231ms
03-10 15:08:11.896 10685-10685/com.lemonkicks.trackmycab.trackmycab D/PhoneWindow: *FMB* installDecor mIsFloating : false
03-10 15:08:11.901 10685-10685/com.lemonkicks.trackmycab.trackmycab D/PhoneWindow: *FMB* installDecor flags : -2139029248
03-10 15:08:11.971 10685-10685/com.lemonkicks.trackmycab.trackmycab I/zzai: Making Creator dynamically
03-10 15:08:11.981 10685-10685/com.lemonkicks.trackmycab.trackmycab W/ResourcesManager: Asset path '/system/framework/com.android.media.remotedisplay.jar' does not exist or contains no resources.
03-10 15:08:11.981 10685-10685/com.lemonkicks.trackmycab.trackmycab W/ResourcesManager: Asset path '/system/framework/com.android.location.provider.jar' does not exist or contains no resources.
03-10 15:08:12.096 10685-10700/com.lemonkicks.trackmycab.trackmycab W/art: Suspending all threads took: 8.664ms
03-10 15:08:12.101 10685-10700/com.lemonkicks.trackmycab.trackmycab I/art: Background sticky concurrent mark sweep GC freed 1621(250KB) AllocSpace objects, 0(0B) LOS objects, 0% free, 9MB/9MB, paused 12.282ms total 45.824ms
03-10 15:08:12.256 10685-10685/com.lemonkicks.trackmycab.trackmycab I/art: DexFile_isDexOptNeeded failed to open oat file '/data/dalvik-cache/arm/data@data@com.google.android.gms@app_chimera@m@00000019@DynamiteModulesB_GmsCore_prodlmp_xhdpi_release.apk@classes.dex' for file location '/data/data/com.google.android.gms/app_chimera/m/00000019/DynamiteModulesB_GmsCore_prodlmp_xhdpi_release.apk': Failed to open oat filename for reading: No such file or directory
03-10 15:08:12.361 10685-10685/com.lemonkicks.trackmycab.trackmycab I/Google Maps Android API: Google Play services client version: 10298000
03-10 15:08:12.371 10685-10685/com.lemonkicks.trackmycab.trackmycab I/Google Maps Android API: Google Play services package version: 10298236
03-10 15:08:12.711 10685-10685/com.lemonkicks.trackmycab.trackmycab D/AbsListView: Get MotionRecognitionManager
03-10 15:08:12.781 10685-10685/com.lemonkicks.trackmycab.trackmycab W/System.err: mkdir failed: EEXIST (File exists) : /storage/emulated/0/Android/data/com.lemonkicks.trackmycab.trackmycab/cache/debug
03-10 15:08:12.781 10685-10685/com.lemonkicks.trackmycab.trackmycab W/System.err: mkdir failed: EEXIST (File exists) : /storage/emulated/0/Android/data/com.lemonkicks.trackmycab.trackmycab/cache
03-10 15:08:12.846 10685-10993/com.lemonkicks.trackmycab.trackmycab W/ActivityThread: ClassLoader.loadClass: The class loader returned by Thread.getContextClassLoader() may fail for processes that host multiple applications. You should explicitly specify a context class loader. For example: Thread.setContextClassLoader(getClass().getClassLoader());
03-10 15:08:12.856 10685-10993/com.lemonkicks.trackmycab.trackmycab I/System.out: (HTTPLog)-Static: isSBSettingEnabled false
03-10 15:08:12.856 10685-10993/com.lemonkicks.trackmycab.trackmycab I/System.out: (HTTPLog)-Static: isShipBuild true
03-10 15:08:12.856 10685-10993/com.lemonkicks.trackmycab.trackmycab I/System.out: (HTTPLog)-Thread-78199-269094671: SmartBonding Enabling is false, SHIP_BUILD is true, log to file is false, DBG is false
03-10 15:08:12.856 10685-10993/com.lemonkicks.trackmycab.trackmycab I/System.out: (HTTPLog)-Static: isSBSettingEnabled false
03-10 15:08:12.866 10685-10993/com.lemonkicks.trackmycab.trackmycab I/System.out: KnoxVpnUidStorageknoxVpnSupported API value returned is false
03-10 15:08:12.866 10685-10993/com.lemonkicks.trackmycab.trackmycab I/qtaguid: Tagging socket 88 with tag 3000110100000000{805310721,0} uid -1, pid: 10685, getuid(): 10263
03-10 15:08:12.981 10685-10685/com.lemonkicks.trackmycab.trackmycab D/onCreate: Google Play Services available. Continuing.
03-10 15:08:13.001 10685-11043/com.lemonkicks.trackmycab.trackmycab D/OpenGLRenderer: Render dirty regions requested: true
03-10 15:08:13.016 10685-10685/com.lemonkicks.trackmycab.trackmycab D/Atlas: Validating map...
03-10 15:08:13.106 10685-10685/com.lemonkicks.trackmycab.trackmycab W/Google Maps Android API: Deprecation notice: In a future release, indoor will no longer be supported on satellite, hybrid or terrain type maps. Even where indoor is not supported, isIndoorEnabled() will continue to return the value that has been set via setIndoorEnabled(), as it does now. By default, setIndoorEnabled is 'true'. The API release notes (https://developers.google.com/maps/documentation/android-api/releases) will let you know when indoor support becomes unavailable on those map types.
03-10 15:08:13.146 10685-10993/com.lemonkicks.trackmycab.trackmycab I/qtaguid: Untagging socket 88
03-10 15:08:13.201 10685-10685/com.lemonkicks.trackmycab.trackmycab D/PhoneWindow: *FMB* isFloatingMenuEnabled mFloatingMenuBtn : null
03-10 15:08:13.201 10685-10685/com.lemonkicks.trackmycab.trackmycab D/PhoneWindow: *FMB* isFloatingMenuEnabled return false
03-10 15:08:13.231 10685-11043/com.lemonkicks.trackmycab.trackmycab I/OpenGLRenderer: Initialized EGL, version 1.4
03-10 15:08:13.241 10685-11043/com.lemonkicks.trackmycab.trackmycab I/OpenGLRenderer: HWUI protection enabled for context ,  &this =0xaf230060 ,&mEglDisplay = 1 , &mEglConfig = -1356541004
03-10 15:08:13.256 10685-11043/com.lemonkicks.trackmycab.trackmycab D/OpenGLRenderer: Get maximum texture size. GL_MAX_TEXTURE_SIZE is 8192
03-10 15:08:13.256 10685-11043/com.lemonkicks.trackmycab.trackmycab D/OpenGLRenderer: Enabling debug mode 0
03-10 15:08:13.366 10685-10994/com.lemonkicks.trackmycab.trackmycab I/System.out: (HTTPLog)-Static: isSBSettingEnabled false
03-10 15:08:13.366 10685-10994/com.lemonkicks.trackmycab.trackmycab I/qtaguid: Tagging socket 88 with tag 3000110100000000{805310721,0} uid -1, pid: 10685, getuid(): 10263
03-10 15:08:13.366 10685-10994/com.lemonkicks.trackmycab.trackmycab I/qtaguid: Tagging socket 110 with tag 3000110100000000{805310721,0} uid -1, pid: 10685, getuid(): 10263
03-10 15:08:13.431 10685-10994/com.lemonkicks.trackmycab.trackmycab I/qtaguid: Untagging socket 88
03-10 15:08:13.541 10685-10685/com.lemonkicks.trackmycab.trackmycab I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy@29fe5dd6 time:400179999
03-10 15:08:14.286 10685-10692/com.lemonkicks.trackmycab.trackmycab W/art: Suspending all threads took: 23.903ms
03-10 15:08:14.291 10685-10995/com.lemonkicks.trackmycab.trackmycab I/System.out: (HTTPLog)-Static: isSBSettingEnabled false
03-10 15:08:14.296 10685-10995/com.lemonkicks.trackmycab.trackmycab I/qtaguid: Tagging socket 88 with tag 3000110100000000{805310721,0} uid -1, pid: 10685, getuid(): 10263
03-10 15:08:14.336 10685-10996/com.lemonkicks.trackmycab.trackmycab I/System.out: (HTTPLog)-Static: isSBSettingEnabled false
03-10 15:08:14.336 10685-10996/com.lemonkicks.trackmycab.trackmycab I/System.out: KnoxVpnUidStorageknoxVpnSupported API value returned is false
03-10 15:08:14.336 10685-10996/com.lemonkicks.trackmycab.trackmycab I/qtaguid: Tagging socket 118 with tag 3000110100000000{805310721,0} uid -1, pid: 10685, getuid(): 10263
03-10 15:08:14.341 10685-10993/com.lemonkicks.trackmycab.trackmycab I/System.out: (HTTPLog)-Static: isSBSettingEnabled false
03-10 15:08:14.341 10685-10993/com.lemonkicks.trackmycab.trackmycab I/System.out: KnoxVpnUidStorageknoxVpnSupported API value returned is false
03-10 15:08:14.341 10685-10993/com.lemonkicks.trackmycab.trackmycab I/qtaguid: Tagging socket 124 with tag 3000110100000000{805310721,0} uid -1, pid: 10685, getuid(): 10263
03-10 15:08:14.341 10685-10994/com.lemonkicks.trackmycab.trackmycab I/System.out: (HTTPLog)-Static: isSBSettingEnabled false
03-10 15:08:14.341 10685-10994/com.lemonkicks.trackmycab.trackmycab I/System.out: KnoxVpnUidStorageknoxVpnSupported API value returned is false
03-10 15:08:14.341 10685-10994/com.lemonkicks.trackmycab.trackmycab I/qtaguid: Tagging socket 125 with tag 3000110100000000{805310721,0} uid -1, pid: 10685, getuid(): 10263
03-10 15:08:14.346 10685-10995/com.lemonkicks.trackmycab.trackmycab I/qtaguid: Untagging socket 88
03-10 15:08:14.531 10685-10996/com.lemonkicks.trackmycab.trackmycab I/qtaguid: Untagging socket 118
03-10 15:08:14.531 10685-10993/com.lemonkicks.trackmycab.trackmycab I/qtaguid: Untagging socket 124
03-10 15:08:14.531 10685-10994/com.lemonkicks.trackmycab.trackmycab I/qtaguid: Untagging socket 125
03-10 15:08:14.951 10685-11040/com.lemonkicks.trackmycab.trackmycab W/DynamiteModule: Local module descriptor class for com.google.android.gms.googlecertificates not found.
03-10 15:08:14.986 10685-11040/com.lemonkicks.trackmycab.trackmycab I/DynamiteModule: Considering local module com.google.android.gms.googlecertificates:0 and remote module com.google.android.gms.googlecertificates:2
03-10 15:08:14.986 10685-11040/com.lemonkicks.trackmycab.trackmycab I/DynamiteModule: Selected remote version of com.google.android.gms.googlecertificates, version >= 2
03-10 15:08:15.016 10685-11040/com.lemonkicks.trackmycab.trackmycab I/art: DexFile_isDexOptNeeded failed to open oat file '/data/dalvik-cache/arm/data@data@com.google.android.gms@app_chimera@m@00000018@DynamiteModulesA_GmsCore_prodlmp_xhdpi_release.apk@classes.dex' for file location '/data/data/com.google.android.gms/app_chimera/m/00000018/DynamiteModulesA_GmsCore_prodlmp_xhdpi_release.apk': Failed to open oat filename for reading: No such file or directory
03-10 15:08:15.546 10685-10995/com.lemonkicks.trackmycab.trackmycab I/System.out: (HTTPLog)-Static: isSBSettingEnabled false
03-10 15:08:15.551 10685-10995/com.lemonkicks.trackmycab.trackmycab I/System.out: KnoxVpnUidStorageknoxVpnSupported API value returned is false
03-10 15:08:15.551 10685-10995/com.lemonkicks.trackmycab.trackmycab I/qtaguid: Tagging socket 128 with tag 3000110100000000{805310721,0} uid -1, pid: 10685, getuid(): 10263
03-10 15:08:16.306 10685-10995/com.lemonkicks.trackmycab.trackmycab I/qtaguid: Untagging socket 128
03-10 15:08:20.446 10685-10685/com.lemonkicks.trackmycab.trackmycab D/ViewRootImpl: ViewPostImeInputStage ACTION_DOWN
03-10 15:08:23.861 10685-10685/com.lemonkicks.trackmycab.trackmycab D/ViewRootImpl: ViewPostImeInputStage ACTION_DOWN
03-10 15:08:24.086 10685-10685/com.lemonkicks.trackmycab.trackmycab D/AndroidRuntime: Shutting down VM
03-10 15:08:24.091 10685-10685/com.lemonkicks.trackmycab.trackmycab E/AndroidRuntime: FATAL EXCEPTION: main
                                                                                      Process: com.lemonkicks.trackmycab.trackmycab, PID: 10685
                                                                                      java.lang.NullPointerException: Attempt to read from field 'double com.google.android.gms.maps.model.LatLng.latitude' on a null object reference
                                                                                          at com.lemonkicks.trackmycab.trackmycab.MapsActivity.build_retrofit_and_get_response(MapsActivity.java:251)
                                                                                          at com.lemonkicks.trackmycab.trackmycab.MapsActivity.access$100(MapsActivity.java:45)
                                                                                          at com.lemonkicks.trackmycab.trackmycab.MapsActivity$2.onClick(MapsActivity.java:153)
                                                                                          at android.view.View.performClick(View.java:5230)
                                                                                          at android.view.View$PerformClick.run(View.java:20999)
                                                                                          at android.os.Handler.handleCallback(Handler.java:739)
                                                                                          at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                          at android.os.Looper.loop(Looper.java:145)
                                                                                          at android.app.ActivityThread.main(ActivityThread.java:6117)
                                                                                          at java.lang.reflect.Method.invoke(Native Method)
                                                                                          at java.lang.reflect.Method.invoke(Method.java:372)
                                                                                          at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
                                                                                          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)


Code:
package com.lemonkicks.trackmycab.trackmycab;

import android.Manifest;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.location.Location;
import android.os.Build;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.lemonkicks.trackmycab.trackmycab.POJO.Example;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.Polyline;
import com.google.android.gms.maps.model.PolylineOptions;

import java.util.ArrayList;
import java.util.List;

import retrofit.Call;
import retrofit.Callback;
import retrofit.GsonConverterFactory;
import retrofit.Response;
import retrofit.Retrofit;

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback,
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener,
        LocationListener {

    private GoogleMap mMap;
    GoogleApiClient mGoogleApiClient;
    Location mLastLocation;
    Marker mCurrLocationMarker;
    LocationRequest mLocationRequest;
    LatLng origin;
    LatLng dest;
    ArrayList<LatLng> MarkerPoints;
    TextView ShowDistanceDuration;
    Polyline line;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);

        ShowDistanceDuration = (TextView) findViewById(R.id.show_distance_time);

        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            checkLocationPermission();
        }

        // Initializing
        MarkerPoints = new ArrayList<>();

        //show error dialog if Google Play Services not available
        if (!isGooglePlayServicesAvailable()) {
            Log.d("onCreate", "Google Play Services not available. Ending Test case.");
            finish();
        } else {
            Log.d("onCreate", "Google Play Services available. Continuing.");
        }

        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }

    /**
     * Manipulates the map once available.
     * This callback is triggered when the map is ready to be used.
     * This is where we can add markers or lines, add listeners or move the camera. In this case,
     * we just add a marker near Sydney, Australia.
     * If Google Play services is not installed on the device, the user will be prompted to install
     * it inside the SupportMapFragment. This method will only be triggered once the user has
     * installed Google Play services and returned to the app.
     */
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);

        // Setting onclick event listener for the map
        mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {

            @Override
            public void onMapClick(LatLng point) {

                // clearing map and generating new marker points if user clicks on map more than two times
                if (MarkerPoints.size() > 1) {
                    mMap.clear();
                    MarkerPoints.clear();
                    MarkerPoints = new ArrayList<>();
                    ShowDistanceDuration.setText("");
                }

                // Adding new item to the ArrayList
                MarkerPoints.add(point);

                // Creating MarkerOptions
                MarkerOptions options = new MarkerOptions();

                // Setting the position of the marker
                options.position(point);

                /**
                 * For the start location, the color of marker is GREEN and
                 * for the end location, the color of marker is RED.
                 */
                if (MarkerPoints.size() == 1) {
                    options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
                } else if (MarkerPoints.size() == 2) {
                    options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
                }


                // Add new marker to the Google Map Android API V2
                mMap.addMarker(options);

                // Checks, whether start and end locations are captured
                if (MarkerPoints.size() >= 2) {
                    origin = MarkerPoints.get(0);
                    dest = MarkerPoints.get(1);
                }

            }
        });

        Button btnDriving = (Button) findViewById(R.id.btnDriving);
        btnDriving.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                build_retrofit_and_get_response("driving");
            }
        });

        Button btnWalk = (Button) findViewById(R.id.btnWalk);
        btnWalk.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                build_retrofit_and_get_response("walking");
            }
        });

        //Initialize Google Play Services
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (ContextCompat.checkSelfPermission(this,
                    Manifest.permission.ACCESS_FINE_LOCATION)
                    == PackageManager.PERMISSION_GRANTED) {
                buildGoogleApiClient();
                mMap.setMyLocationEnabled(true);
            }
        } else {
            buildGoogleApiClient();
            mMap.setMyLocationEnabled(true);
        }
    }

    protected synchronized void buildGoogleApiClient() {
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
        mGoogleApiClient.connect();
    }

    @Override
    public void onConnected(Bundle bundle) {

        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(1000);
        mLocationRequest.setFastestInterval(1000);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
        }

    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onLocationChanged(Location location) {

        mLastLocation = location;
        if (mCurrLocationMarker != null) {
            mCurrLocationMarker.remove();
        }

        //Place current location marker
        LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
        MarkerOptions markerOptions = new MarkerOptions();
        markerOptions.position(latLng);
        markerOptions.title("Current Position");
        markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
        mCurrLocationMarker = mMap.addMarker(markerOptions);

        //move map camera
        mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
        mMap.animateCamera(CameraUpdateFactory.zoomTo(11));

        //stop location updates
        if (mGoogleApiClient != null) {
            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
        }

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {

    }

    private void build_retrofit_and_get_response(String type) {

        String url = "https://maps.googleapis.com/maps/";

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(url)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        RetrofitMaps service = retrofit.create(RetrofitMaps.class);

        Call<Example> call = service.getDistanceDuration("metric", origin.latitude + "," + origin.longitude,dest.latitude + "," + dest.longitude, type);

        call.enqueue(new Callback<Example>() {
            @Override
            public void onResponse(Response<Example> response, Retrofit retrofit) {

                try {
                    //Remove previous line from map
                    if (line != null) {
                        line.remove();
                    }
                    // This loop will go through all the results and add marker on each location.
                    for (int i = 0; i < response.body().getRoutes().size(); i++) {
                        String distance = response.body().getRoutes().get(i).getLegs().get(i).getDistance().getText();
                        String time = response.body().getRoutes().get(i).getLegs().get(i).getDuration().getText();
                        ShowDistanceDuration.setText("Distance:" + distance + ", Duration:" + time);
                        String encodedString = response.body().getRoutes().get(0).getOverviewPolyline().getPoints();
                        List<LatLng> list = decodePoly(encodedString);
                        line = mMap.addPolyline(new PolylineOptions()
                                .addAll(list)
                                .width(20)
                                .color(Color.RED)
                                .geodesic(true)
                        );
                    }
                } catch (Exception e) {
                    Log.d("onResponse", "There is an error");
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailure(Throwable t) {
                Log.d("onFailure", t.toString());
            }
        });

    }

    private List<LatLng> decodePoly(String encoded) {
        List<LatLng> poly = new ArrayList<LatLng>();
        int index = 0, len = encoded.length();
        int lat = 0, lng = 0;

        while (index < len) {
            int b, shift = 0, result = 0;
            do {
                b = encoded.charAt(index++) - 63;
                result |= (b & 0x1f) << shift;
                shift += 5;
            } while (b >= 0x20);
            int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
            lat += dlat;

            shift = 0;
            result = 0;
            do {
                b = encoded.charAt(index++) - 63;
                result |= (b & 0x1f) << shift;
                shift += 5;
            } while (b >= 0x20);
            int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
            lng += dlng;

            LatLng p = new LatLng( (((double) lat / 1E5)),
                    (((double) lng / 1E5) ));
            poly.add(p);
        }

        return poly;
    }

    // Checking if Google Play Services Available or not
    private boolean isGooglePlayServicesAvailable() {
        GoogleApiAvailability googleAPI = GoogleApiAvailability.getInstance();
        int result = googleAPI.isGooglePlayServicesAvailable(this);
        if(result != ConnectionResult.SUCCESS) {
            if(googleAPI.isUserResolvableError(result)) {
                googleAPI.getErrorDialog(this, result,
                        0).show();
            }
            return false;
        }
        return true;
    }


    public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
    public boolean checkLocationPermission(){
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {

            // Asking user if explanation is needed
            if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.ACCESS_FINE_LOCATION)) {

                // Show an explanation to the user *asynchronously* -- don't block
                // this thread waiting for the user's response! After the user
                // sees the explanation, try again to request the permission.

                //Prompt the user once explanation has been shown
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                        MY_PERMISSIONS_REQUEST_LOCATION);


            } else {
                // No explanation needed, we can request the permission.
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                        MY_PERMISSIONS_REQUEST_LOCATION);
            }
            return false;
        } else {
            return true;
        }
    }

}

Thank you!
 
It looks like your variables 'origin' and/or 'dest' have not been initialized i.e. their value is null.

So you should ask yourself, where do these variables get set to proper values. Looking at your code, there is a conditional block which does this

Code:
if (MarkerPoints.size() >= 2) {
                    origin = MarkerPoints.get(0);
                    dest = MarkerPoints.get(1);
                }

You can check that this code gets executed by setting a breakpoint at the 'if' line. In particular, what are the contents of Array MarkerPoints?
 
Thank you @aparkin and @LV426 for replying. I tried what you suggested, but I still find it quite difficult to understand and can't get it to work unfortunately.
Would you mind elaborating on the suggested solutions? I am sorry, still a noob.
 
I tried running my app in debug mode in console and got this. Guess I am not doing it right...

Code:
03/13 16:54:09: Launching app
$ adb shell am startservice com.lemonkicks.trackmycab.trackmycab/com.android.tools.fd.runtime.InstantRunService
$ adb shell am start -n "com.lemonkicks.trackmycab.trackmycab/com.lemonkicks.trackmycab.trackmycab.MapsActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -D
Connecting to com.lemonkicks.trackmycab.trackmycab
Connected to the target VM, address: 'localhost:8600', transport: 'socket'
 
I have posted part of my logcat in after debugging (this was after interacting with the app, putting another marker down and trying to click the driving mode button). The log from @aparkin has been set (onMapClickL origin and dest not set as number of marker points is 1) on the second line.

Code:
3-13 16:57:44.256 11183-11183/com.lemonkicks.trackmycab.trackmycab D/ViewRootImpl: ViewPostImeInputStage ACTION_DOWN
03-13 16:57:44.621 11183-11183/com.lemonkicks.trackmycab.trackmycab I/onMapClick: origin and dest not set as number of marker points is 1
03-13 16:58:02.046 11183-11183/com.lemonkicks.trackmycab.trackmycab D/ViewRootImpl: ViewPostImeInputStage ACTION_DOWN
03-13 16:58:02.266 11183-11183/com.lemonkicks.trackmycab.trackmycab D/AndroidRuntime: Shutting down VM
03-13 16:58:02.266 11183-11183/com.lemonkicks.trackmycab.trackmycab E/AndroidRuntime: FATAL EXCEPTION: main
                                                                                      Process: com.lemonkicks.trackmycab.trackmycab, PID: 11183
                                                                                      java.lang.NullPointerException: Attempt to read from field 'double com.google.android.gms.maps.model.LatLng.latitude' on a null object reference
                                                                                          at com.lemonkicks.trackmycab.trackmycab.MapsActivity.build_retrofit_and_get_response(MapsActivity.java:254)
                                                                                          at com.lemonkicks.trackmycab.trackmycab.MapsActivity.access$100(MapsActivity.java:45)
                                                                                          at com.lemonkicks.trackmycab.trackmycab.MapsActivity$2.onClick(MapsActivity.java:156)
                                                                                          at android.view.View.performClick(View.java:5230)
                                                                                          at android.view.View$PerformClick.run(View.java:20999)
                                                                                          at android.os.Handler.handleCallback(Handler.java:739)
                                                                                          at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                          at android.os.Looper.loop(Looper.java:145)
                                                                                          at android.app.ActivityThread.main(ActivityThread.java:6117)
                                                                                          at java.lang.reflect.Method.invoke(Native Method)
                                                                                          at java.lang.reflect.Method.invoke(Method.java:372)
                                                                                          at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
                                                                                          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
 
There's some information here -

https://developer.android.com/studio/debug/index.html

If the output you show is from the debug window, then I think your app has been launched in debug mode, and is running.

Ok, so next question is, do you understand what a breakpoint is? If not, let me explain: Basically Android Studio allows you to stop the execution of your app at virtually any point in the code. Why would you want to do this? Well it's very useful in situations like the one you have, where for some reason, variables aren't getting set to the values you expect, causing logic errors.
To set a breakpoint, click in the left margin of a line, and you'll see a red dot. When the execution of your code reaches this point, the application stops. You then have the capability of examining the values of variables, and stepping through the code, line by line to see where it goes.
So for instance, if you're expecting your app to execute a certain method, or reach a certain place in your code, you could place at breakpoint at these lines, and see what happens.
So have a go, see if you can set a breakpoint and watch as the app stops at that line. Experiment with the debug features offered by Android Studio.
 
The map is set up so that the first time the user clicks on the map sets the "origin" marker point, and the second time the user clicks the map it sets the "dest" marker point (any subsequent map clicks result in the marker points being cleared).

If you have clicked the map twice you should see a green marker for the origin and a red marker for the destination.

Have you definitely clicked *exactly twice* on the map to set these 2 marker points before you click on the "driving" button? From your logs it seems you may have only clicked once. It's also possible you may have clicked 3 times which would be equivalent to clicking once (please see my comments on subsequent clicks clearing the marker points).

Yes, origin and dest only get set when 2 MarkerPoints have been selected.
This can be confirmed for sure, if a breakpoint is set in that conditional block of code I highlighted in post #4
 
Thanks so much for your patience!

Yes, the red marker is my own current position and if I tap the screen once for destination, a green marker is added. After that, when I click the driving mode or walking mode button, the app crashes.
I
set a breakpoint at the line Call<Example> call = service.getDistanceDuration("metric", origin.latitude + "," + origin.longitude,dest.latitude + "," + dest.longitude, type); and at variables it says:

Code:
origin.longitude=java.lang.NullPointerException
origin.latitude=java.lang.NullPointerException
origin=null
dest.latitude=java.lang.NullPointerException
dest.longitude=java.lang.NullPointerException
dest=null

I just don't know how/where/with what to set correct value to the origin and dest?
 
I set a breakpoint at

Code:
if (MarkerPoints.size() >= 2) {
    origin = MarkerPoints.get(0);
    dest = MarkerPoints.get(1);
    Log.i("onMapClick", "origin and dest now set.");
} else {
    Log.i("onMapClick", "origin and dest not set as number of marker points is " + MarkerPoints.size());
}

and was not able to get the second marker (green one) as tapped my screen.
 
You're re-creating the MarkerPoints array if MarkerPoints.size() > 1. That means two selected points will clear it. That's not what you want, I don't think.
So maybe this

Code:
if (MarkerPoints.size() > 1) {
                    mMap.clear();
                    MarkerPoints.clear();
                    MarkerPoints = new ArrayList<>();
                    ShowDistanceDuration.setText("");
                }

Should be this -

Code:
if (MarkerPoints.size() > 2) {

                    mMap.clear();

                    MarkerPoints.clear();

                    MarkerPoints = new ArrayList<>();

                    ShowDistanceDuration.setText("");

                }
 
Yes, you are right. The app starts with a purple marker at my current postition. I tap the screen and the green one appears. If I tap the screen AGAIN and a red one appears. If I tap a fourth time all markers except the green one dissappear. I think this is indeed where the problem lies.
 
I tried @LV426 suggestion, but unfortunately the app still crashes, so I don't think this is the problem. Really appreciate the help though! But it seems something is off with the marker. The marker with my current position should be the starting point, another tap on the screen should make the destination marker appear and a tap on either the driving or walking button should show the distance and route.
 
I believe there is something not right with my code for the user's current position (purple marker) and the two markers (red and green) between which a route should be drawn. I just can't figure out what to change?
 
@aparkin - thanks for your reply. I tried debugging with the breakpoints you have provided but I get a lot of info back and don't see onFailure anywhere? My goal is to use the current position of the user as the starting point or starting marker for drawing a path. The user should tap the screen for a destination,marker. Between current position and destination marker the route should appear (with distance and time). Eventually I want to make the app so the user can enter an address as well and - like Runkeeper - the current position moves as the user moves. Hope I'm explaining it clearly.
 
So when the code breakpointed in your onResponse() method. Did you step through it line by line to see what happened? Did the service return any routes for you?
 
Does the code step into the for loop? (This is important!)
If not, there were no driving routes returned between the two points you selected.
 
Back
Top Bottom