Reputation: 117
I'm trying to make a simple Android GPS app that will read the user's current location.
In doing this, I need to request permissions. I've followed the tutorials on Google's own Android-pages.
My app starts up fine, it gets to the point where I need to start requesting permissions, then it doesn't work anymore.
I've put several "debug messages" in the app that prints text to textViews. It only gets to "1" in the onConnected() method.
Any clue what I'm doing wrong? Many thanks in advance!
Here is my Activity Java code
public class StartActivity extends AppCompatActivity implements ConnectionCallbacks, OnConnectionFailedListener {
private Location mLastLocation;
private boolean locationPermissionGoodToGo = false;
private final int MY_PERMISSION_ACCESS_FINE_LOCATION = 1;
// Google client to interact with Google API
private GoogleApiClient mGoogleApiClient;
// UI elements
private TextView mLatitudeText,mLongitudeText, mTextTest, mTextPerRes;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Create an instance of GoogleAPIClient.
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
mLatitudeText = (TextView) findViewById(R.id.mLatitudeText);
mLongitudeText = (TextView) findViewById(R.id.mLongitudeText);
mTextTest = (TextView) findViewById(R.id.textTest);
mTextPerRes = (TextView) findViewById(R.id.textPerRes);
LocationRequest mLocationRequest = createLocationRequest();
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(mLocationRequest);
PendingResult<LocationSettingsResult> result =
LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, //mGoogleClient
builder.build());
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
@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_start, 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);
}
protected void onStart() {
mGoogleApiClient.connect();
super.onStart();
}
protected void onStop() {
mGoogleApiClient.disconnect();
super.onStop();
}
public boolean refreshLocation(){
return false;
}
@Override
public void onConnected(Bundle bundle) {
mTextPerRes.setText("Permission getting ready");//DEBUG!!!
mTextTest.setText("1");//DEBUG!!!
if ( ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ) {
mTextTest.setText("1.5");//DEBUG!!!
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSION_ACCESS_FINE_LOCATION);
}
if(locationPermissionGoodToGo == true) {
//TODO: Kommer inte in här. Något fel med permissions! :(
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
mTextTest.setText("2");//DEBUG!!!
if (mLastLocation != null) {
mTextTest.setText("3");//DEBUG!!!
mLatitudeText.setText(String.valueOf(mLastLocation.getLatitude()));
mLongitudeText.setText(String.valueOf(mLastLocation.getLongitude()));
}
}
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
protected LocationRequest createLocationRequest() {
LocationRequest mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(10000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
return mLocationRequest;
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
mTextPerRes.setText("Permission wanted");//DEBUG!!!
switch (requestCode) {
case MY_PERMISSION_ACCESS_FINE_LOCATION: {
mTextPerRes.setText("Permission case right");//DEBUG!!!
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
mTextPerRes.setText("Permission granted");//DEBUG!!!
locationPermissionGoodToGo = true;
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
}
And here is my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="se.adrianhansson.gpsapp"
android:versionCode="1"
android:versionName="1.0">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="21" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<activity
android:name=".StartActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
My edited code, still does not work. Same result.
public class StartActivity extends AppCompatActivity implements ConnectionCallbacks, OnConnectionFailedListener {
private Location mLastLocation;
private boolean locationPermissionGoodToGo = false;
private final int MY_PERMISSION_ACCESS_FINE_LOCATION = 1;
// Google client to interact with Google API
private GoogleApiClient mGoogleApiClient;
// UI elements
private TextView mLatitudeText,mLongitudeText, mTextTest, mTextPerRes;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Create an instance of GoogleAPIClient.
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
mLatitudeText = (TextView) findViewById(R.id.mLatitudeText);
mLongitudeText = (TextView) findViewById(R.id.mLongitudeText);
mTextTest = (TextView) findViewById(R.id.textTest);
mTextPerRes = (TextView) findViewById(R.id.textPerRes);
LocationRequest mLocationRequest = createLocationRequest();
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(mLocationRequest);
PendingResult<LocationSettingsResult> result =
LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, //mGoogleClient
builder.build());
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
@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_start, 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);
}
protected void onStart() {
mGoogleApiClient.connect();
super.onStart();
}
protected void onStop() {
mGoogleApiClient.disconnect();
super.onStop();
}
public boolean refreshLocation(){
return false;
}
@Override
public void onConnected(Bundle bundle) {
mTextPerRes.setText("Permission getting ready");//DEBUG!!!
mTextTest.setText("1");//DEBUG!!!
if ( ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ) {
mTextTest.setText("1.5");//DEBUG!!!
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSION_ACCESS_FINE_LOCATION);
}
setCoordinates();
// original location of setCoordinates() code
}
public void setCoordinates(){
if(locationPermissionGoodToGo == true) {
//TODO: Kommer inte in här. Något fel med permissions! :(
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
mTextTest.setText("2");//DEBUG!!!
if (mLastLocation != null) {
mTextTest.setText("3");//DEBUG!!!
mLatitudeText.setText(String.valueOf(mLastLocation.getLatitude()));
mLongitudeText.setText(String.valueOf(mLastLocation.getLongitude()));
}
}
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
protected LocationRequest createLocationRequest() {
LocationRequest mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(10000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
return mLocationRequest;
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
mTextPerRes.setText("Permission wanted");//DEBUG!!!
switch (requestCode) {
case MY_PERMISSION_ACCESS_FINE_LOCATION: {
mTextPerRes.setText("Permission case right");//DEBUG!!!
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
mTextPerRes.setText("Permission granted");//DEBUG!!!
locationPermissionGoodToGo = true;
setCoordinates();
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
locationPermissionGoodToGo = false;
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
}
Upvotes: 0
Views: 981
Reputation: 1006604
requestPermissions()
is asynchronous. You are checking locationPermissionGoodToGo
immediately after calling it, which is much too early.
Move your code in the if(locationPermissionGoodToGo == true)
block into a separate method. If checkSelfPermission()
says that you have the permission, call that separate method right away. Otherwise, call it in onRequestPermissionResult()
, where you are setting locationPermissionGoodToGo
to true
.
Upvotes: 1