-1

Upon accessing the Maps Activity, it crashes. I've tried switching out the Activity with a generic Maps Activity which does work, and I've rolled back to a previous version that I know worked all to no avail.

This is the Android Java:

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.fragment.app.FragmentActivity;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Camera;
import android.location.Location;

import com.firebase.geofire.GeoFire;
import com.firebase.geofire.GeoLocation;
import com.google.android.gms.location.LocationListener;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApi;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.internal.GoogleApiAvailabilityCache;
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.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;

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

    private GoogleMap mMap;
    GoogleApiClient mGoogleApiClient;
    Location driverLastLocation;
    LocationRequest driverLocationRequest;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_driver_maps);
        // 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);

        Button buttonLogout = findViewById(R.id.buttonLogout);

        buttonLogout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                FirebaseAuth.getInstance().signOut();
                Intent intent = new Intent(DriverMapsActivity.this, MainActivity.class);
                startActivity(intent);
                finish();
                return;
            }
        });
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        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 onLocationChanged(Location location) {
        driverLastLocation = location;

        LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());

        mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
        mMap.animateCamera(CameraUpdateFactory.zoomTo(11));

        String userID = FirebaseAuth.getInstance().getCurrentUser().getUid();
        DatabaseReference ref = FirebaseDatabase.getInstance().getReference("driversClear");

        GeoFire geoFire = new GeoFire(ref);
        geoFire.setLocation(userID, new GeoLocation(location.getLatitude(), location.getLongitude()));
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {
        driverLocationRequest = new LocationRequest();
        driverLocationRequest.setInterval(1000);
        driverLocationRequest.setFastestInterval(2000);
        driverLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);

        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, driverLocationRequest, (com.google.android.gms.location.LocationListener) this);
    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    }

    @Override
    public void onStop(){
        super.onStop();

        String userID = FirebaseAuth.getInstance().getCurrentUser().getUid();
        DatabaseReference ref = FirebaseDatabase.getInstance().getReference("driversClear");

        GeoFire geoFire = new GeoFire(ref);
        geoFire.removeLocation(userID);
    }
}

I'm new to Android Dev so I'm not sure if it is particularly vital to debugging this kind of issue but here is the layout XML thing

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:map="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".DriverMapsActivity" >


    <Button
        android:id="@+id/buttonLogout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Logout" />

    <fragment
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    </FrameLayout>

and I'm not sure if I should share the AndroidManifest but I feel like it is important

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    <!--
         The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
         Google Maps Android API v2, but you must specify either coarse or fine
         location permissions for the 'MyLocation' functionality.
    -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION_LOCATION" />
    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme" >
        <activity android:name=".CustomerMapsActivity" >
        </activity>
        <activity android:name=".TestClass" />
        <!--
             The API key for Google Maps-based APIs is defined as a string resource.
             (See the file "res/values/google_maps_api.xml").
             Note that the API key is linked to the encryption key used to sign the APK.
             You need a different API key for each encryption key, including the release key that is used to
             sign the APK for publishing.
             You can define the keys for the debug and release targets in src/debug/ and src/release/.
        -->
        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="@string/google_maps_key" />

        <activity
            android:name=".DriverMapsActivity"
            android:label="@string/title_activity_driver_maps" />
        <activity android:name=".DriverLogin" />
        <activity android:name=".DriverRegistration" />
        <activity android:name=".CustomerLogin" />
        <activity android:name=".CustomerRegistration" />
        <activity android:name=".MainActivity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

Also if anyone can tell me why the built in debugger isn't notifying me of this error that would be appreciated (as in do I need to toggle a setting or install something extra?)

Thanks

riizwaan
  • 315
  • 1
  • 3
  • 6
  • What is error in logcat? – MMG May 17 '20 at 06:27
  • You tried to see in the Logcat if there is the error log of crash? – Sergio Donati May 17 '20 at 06:27
  • @MMG java.lang.SecurityException: my location requires permission ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION this is the error but I already have this permission in the manifest... – riizwaan May 17 '20 at 06:34
  • OK, see my answer – MMG May 17 '20 at 06:34
  • What is in error logcat? – MMG May 17 '20 at 06:43
  • 1
    @MMG Thank you for your interest in helping me, the solution was that the app is not granted permissions (I didn't code for the user to grant permissions). When I manually grant permissions in the app settings, it works. Thank you once again for your support! – riizwaan May 17 '20 at 06:48
  • Your welcome, so maybe my answer for this question helps you: https://stackoverflow.com/questions/61339719/how-to-ask-user-to-turn-on-location/61406934#61406934 – MMG May 17 '20 at 06:51

1 Answers1

-1

Can you check the 'Run' tab for error, instead of Logcat. If the app crashes as soon as it starts, logs may be present in 'Run' tab.

ACR
  • 317
  • 1
  • 8
  • OKAY! java.lang.SecurityException: my location requires permission ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION I already added permissions in the Manifest though, so I'm not sure why it is throwing this message... – riizwaan May 17 '20 at 06:32
  • Location permissions are dangerous permissions.They need runtime permission grants. If not given, securityexceptions are raised. You can refer this source to do so. https://medium.com/programming-lite/runtime-permissions-in-android-7496a5f3de55 – ACR May 17 '20 at 06:40
  • Thanks for the article! I need to grant permissions! I went in to the app settings and manually granted permissions and it worked! I need to look in to how to request permissions from user but this is the reason it wasn't working (I actually don't remember granting permissions yesterday so I'm not sure how it worked). Thank you for your kind support! – riizwaan May 17 '20 at 06:45
  • Glad I could help. – ACR May 17 '20 at 06:47