Reputation: 109
I am learning Android Google API. I am creating an app to get the last location through Google Play Services. After trying many tutorials I am getting null in location. I am running application on my mobile which is API 23. I keep location and data setting on in my mobile. Below is my code.
Gradle dependencies:
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.google.android.gms:play-services:7.5.0'
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<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=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
MainActivity code
package com.lab.locationawareapp;
import android.location.Location;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.location.LocationServices;
public class MainActivity extends AppCompatActivity implements
ConnectionCallbacks, OnConnectionFailedListener {
protected static final String TAG = "MainActivity";
/**
* Provides the entry point to Google Play services.
*/
protected GoogleApiClient mGoogleApiClient;
/**
* Represents a geographical location.
*/
protected Location mLastLocation;
protected String mLatitudeLabel;
protected String mLongitudeLabel;
protected TextView mLatitudeText;
protected TextView mLongitudeText;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLatitudeLabel = getResources().getString(R.string.latitude_label);
mLongitudeLabel = getResources().getString(R.string.longitude_label);
mLatitudeText = (TextView) findViewById((R.id.latitude_text));
mLongitudeText = (TextView) findViewById((R.id.longitude_text));
buildGoogleApiClient();
}
/**
* Builds a GoogleApiClient. Uses the addApi() method to request the LocationServices API.
*/
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
@Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
@Override
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
/**
* Runs when a GoogleApiClient object successfully connects.
*/
@Override
public void onConnected(Bundle connectionHint) {
// Provides a simple way of getting a device's location and is well suited for
// applications that do not require a fine-grained location and that do not need location
// updates. Gets the best and most recent location currently available, which may be null
// in rare cases when a location is not available.
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mLastLocation != null) {
mLatitudeText.setText(String.format("%s: %f", mLatitudeLabel,
mLastLocation.getLatitude()));
mLongitudeText.setText(String.format("%s: %f", mLongitudeLabel,
mLastLocation.getLongitude()));
} else {
Toast.makeText(this, R.string.no_location_detected, Toast.LENGTH_LONG).show();
}
}
@Override
public void onConnectionFailed(ConnectionResult result) {
Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + result.getErrorCode());
}
@Override
public void onConnectionSuspended(int cause) {
Log.i(TAG, "Connection suspended");
mGoogleApiClient.connect();
}
}
Upvotes: 0
Views: 487
Reputation: 2127
try from this link which i was faced i put there some code also so you can try it Get Current Location 0 in marshmallow where below 23 API its give exact current Location using fused Location
check your Device in which you tested app it Have updated google Play services ?? if not then update it it should be match with your gradle play service version
Upvotes: 0
Reputation: 93561
getLastLocation will return null if the system doesn't have a location cached. Which is anytime that the location wasn't recently requested by another program. You either need to check it for null, or you need to request locations rather than get the last location (note that requesting location takes time and may never call your callback, if you can't get GPS lock and you want high accuracy).
Upvotes: 0
Reputation: 7070
With Android Marshmallow, you have to explicitly request permission from the user although you have specified those in Manifest file. So, you have to request for location permissions this way : First you create a request code for location
public static final int LOCATION_REQUEST_CODE = 1001; //Any number
And then check if already permission is granted or not, if not then the code will request for permission which will show a native popup asking to deny/allow the location permission
if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, LOCATION_REQUEST_CODE);
} else {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
}
The above code should be written before requesting any location preferably in onCreate()
of the activity. Then based on the action taken by the user on the popup , you'll get a callback where you can perform according to your requirement.
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case LOCATION_REQUEST_CODE: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED
&& (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
|| ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED)) {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
}
}
}
}
Also, wherever you are trying to fetch the location, you should check whether the location permission has been granted to your application or not and then fetch the location.
if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
}
You can request Manifest.permission.ACCESS_FINE_LOCATION
or Manifest.permission.ACCESS_COARSE_LOCATION
or both. It depends upon your requirement.
Upvotes: 2