5

I'm completely new to Android development, but I have worked with Java (and other programming languages) before.

I'm using Android Studio to develop my application and I've become stuck when following the developer tutorial on accessing Location information (http://developer.android.com/training/location/index.html). I understand that the Location services require the android.permission.ACCESS_COARSE_LOCATION and/or android.permission.ACCESS_FINE_LOCATION permissions but upon adding them to my ApplicationManifest my application still crashes with a SecurityException

java.lang.SecurityException: Client must have ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission to perform any location operations.

I've come across several other instances of people having trouble, but these have generally been the result of mis-placing (java.lang.SecurityException: Requires ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION permission), mis-spelling (ACCESS_FINE_LOCATION AndroidManifest Permissions Not Being Granted) or incorrect capitalization of the permission string.

Here is my ApplicationManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="scd.tt" >

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

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="23" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher_tt_v2"
        android:label="@string/app_name"
        android:theme="@style/TT_Theme">
        <activity
            android:name=".MainActivity"
            android:theme="@style/TT_Theme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".LoginActivity" android:theme="@style/TT_Theme.NoActionBar" />
        <activity android:name=".IndexActivity" />
    </application>

</manifest>

I've even tried to remove ACCESS_NETWORK_STATE and INTERNET to see if this would cause other SecurityExceptions as the application is required to communicate with an HTTP server (which it performs successfully) before it gets attempts to get Location information.

It seems as though modifications I make to the permissions on the AndroidManifest aren't being updated when I run the program. I've also tried to Clean and Rebuild the application using the Build menu.

UPDATE:

Here is the core of the Activity; I've removed some of the unrelated methods (such as onCreateOptionsMenu() and onBackPressed() as they have nothing to do with the Location)

package scd.tt;

import android.app.AlertDialog;
import android.app.Fragment;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Location;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;

import com.google.android.gms.common.ConnectionResult;
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 java.util.Map;

/**
 * Created by Liam on 08/09/2015
 */
public class IndexActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {

    private GoogleApiClient mGoogleApiClient;
    private LocationRequest mLocationRequest;
    private Location mLastLocation;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_index);
        if(debug) Log.d(TAG, "onCreate() called: savedInstanceState is " + (savedInstanceState == null ? "null" : "not null"));

        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(10000);
        mLocationRequest.setFastestInterval(1000);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
        buildGoogleApiClient();

        if (findViewById(R.id.index_fragment_container) != null) {
            if (savedInstanceState != null) return;

            Fragment index = new IndexFragment();
            index.setArguments(getIntent().getExtras());

            getFragmentManager().beginTransaction().add(R.id.index_fragment_container, index).commit();
        }
    }


    @Override
    protected void onStart() {
        super.onStart();
        mGoogleApiClient.connect();
    }

    @Override
    protected void onStop() {
        super.onStop();
        mGoogleApiClient.disconnect();
    }

    @Override
    public void onConnected(Bundle bundle) {
        if(debug) Log.d(TAG, "onConnected");
        mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
        startLocationUpdates();
    }

    @Override
    public void onConnectionSuspended(int i) {
        if(debug) Log.d(TAG, "Connection Suspended");
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        if(debug) Log.d(TAG, "Connection Failed");
    }

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

    protected synchronized void buildGoogleApiClient() {
        mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();
        if(debug) Log.d(TAG, "buildGoogleAPIClient()");
    }

    protected void startLocationUpdates() {
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
    }
}
Community
  • 1
  • 1
Liam Freke
  • 65
  • 1
  • 6
  • Are you running this program on an emulator? – Actiwitty Sep 11 '15 at 16:16
  • What code have you got in your activity so far? – fractalwrench Sep 11 '15 at 16:21
  • Yes, the application is being run in an emulator for testing. It is based on the Nexus 5 on an x86 platform using API / SDK version 23. – Liam Freke Sep 12 '15 at 19:48
  • Check these 2 links. The might help - 1. http://stackoverflow.com/questions/4745670/android-unable-to-get-the-gps-location-on-the-emulator 2. http://stackoverflow.com/questions/32224534/access-fine-location-permission-error-emulator-only – Techidiot Sep 12 '15 at 20:10
  • Also, there might be DNS issues with the emulator. Try this link - http://www.gitshah.com/2011/02/android-fixing-no-internet-connection.html – Techidiot Sep 12 '15 at 20:12
  • Ahah, that explains it! Permissions with a protection level of dangerous must be granted at runtime by prompting the user as of SDK 23 and can not be defined solely in the Manifest any more. This is omitted from the Android Tutorial which is likely due to the recent release of SDK 23. Information on this is provided here; http://developer.android.com/preview/features/runtime-permissions.html If you would like to submit an answer, @Bhush_Techidiot I'll accept it :) Thank you for your help – Liam Freke Sep 12 '15 at 20:59
  • Thanks. I will just put the 3 links. They deserve it more. I will get my fare as well :) Glad to help! – Techidiot Sep 12 '15 at 21:01
  • Check this for both emulator and real device using on al Android versions http://stackoverflow.com/a/38608800/2806800 – Ruslan Berozov Oct 13 '16 at 11:02

1 Answers1

1

Check these 3 links. They might help -

  1. Android - Unable to get the gps location on the emulator
  2. ACCESS_FINE_LOCATION permission error emulator only
  3. http://www.gitshah.com/2011/02/android-fixing-no-internet-connection.html

As quoted by you in comments -

Permissions with a protection level of dangerous must be granted at runtime by prompting the user as of SDK 23 and can not be defined solely in the Manifest any more.

Community
  • 1
  • 1
Techidiot
  • 1,921
  • 1
  • 15
  • 28