Android Wear Location - java

I am making an Android Wear Watch Face and I need to show user current location.
I was followed tutorial on Dev site, but I can't get it to work. The code never goes to "onLocationChanged" listener.
Device is Huawei watch, and it is connected to mobile with WiFi and Location on.
Permissions are on (I have runtime permission request). Here is the code:
AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET"/>
build.gradle (Module.wear)
compile 'com.google.android.gms:play-services-location:8.4.0'
AnalogFaceService.java
googleApiClient = new GoogleApiClient.Builder(AnalogFaceService.this)
.addApi(LocationServices.API)
.addApi(Wearable.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
#Override
public void onConnected(#Nullable Bundle bundle)
{
LocationRequest locationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY)
.setInterval(TimeUnit.SECONDS.toMillis(2))
.setFastestInterval(TimeUnit.SECONDS.toMillis(2))
.setSmallestDisplacement(2);
if
(
(
ActivityCompat.checkSelfPermission(AnalogFaceService.this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED
) && (
ActivityCompat.checkSelfPermission(AnalogFaceService.this, Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED
)
) {
return;
}
LocationServices.FusedLocationApi
.requestLocationUpdates(googleApiClient, locationRequest, onLocationChangedListener)
.setResultCallback(locationCallback);
}
private final LocationListener onLocationChangedListener = new LocationListener()
{
#Override
public void onLocationChanged(Location location)
{
Log.v("LOCATION_TEST", location.getLatitude() + " :::: " + location.getLongitude());
getSunriseAndSunset(location);
addLocationEntry(location.getLatitude(), location.getLongitude());
}
};

The code from Dev site was not a problem.
Device was fresh factory reset and I didn't open Google Maps yet so the Watch couldn't get current location and because of that it didn't go into "onLocationChanged".

You have to call connect.
#Override
protected void onResume() {
super.onResume();
googleApiClient.connect();
...
}

Related

Android studio location permission listener

I am trying to ask for user location permission but I need to set some kind of listener to the user response otherwise, I cant get the user location and the app crashes due to null pointer exception.
This are the functions I am using to get and set the location
private void setLocation() {
if (ContextCompat.checkSelfPermission(getApplicationContext(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ) {
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, 44);
}
LocationManager locationManager;
locationManager = (LocationManager) getSystemService(ScoreActivity.this.LOCATION_SERVICE);
Location location = locationManager.getLastKnownLocation(locationManager.NETWORK_PROVIDER);
onLocationChanged(location);
}
#Override
public void onLocationChanged(#NonNull Location location) {
locationDetails=new LatLng(location.getLatitude(),location.getLongitude());
}

getLastKnowLocation return null

I was making an application, which has a MapView, in which I want to show a marker in the position obtained from the gps of the device when I press a button. The problem I have is that the first time I enter the mapview activity, the getLastKnowLocation returns null so it doesn't put the marker on the map, however if I go back to the MainActivity and then to the activity of the mapview ,I get a position and the marker is put on the map.
I do not know if I should use another method instead of getLastKnowLocation.
I put the code in which I have not yet implemented the GPS permission and the active GPS verification.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_incidencia_mapa);
bt_getgps=(Button)findViewById(R.id.bt_getgps);
bt_getgps.setOnClickListener(this);
mapView = (MapView) findViewById(R.id.map_incidencia);
if (mapView != null) {
mapView.onCreate(null);
mapView.onResume();
mapView.getMapAsync(this);
}
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
//SOLICITUD DE PERMISOS
return;
}
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, this);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 0, this);
Location location = locationManager.getLastKnownLocation(locationManager.GPS_PROVIDER);
if (location == null) {
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
}
if(location != null){
lat=location.getLatitude();
longi= location.getLongitude();
}
}
Onclick:
public void onClick(View view) {
if (lat != 0 && longi != 0) {
place = new LatLng(lat, longi);
marcador = new MarkerOptions();
marcador.position(place);
marcador.title("Zona del incidencia");
marcador.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_incidencia_mapa));
marcador.draggable(true);
gMap.setMinZoomPreference(5);
gMap.addMarker(marcador);
gMap.animateCamera(CameraUpdateFactory.newLatLngZoom(place, 17));
geocoder = new Geocoder(this, Locale.getDefault());
try {
direciones = geocoder.getFromLocation(lat, longi, 1);
} catch (IOException e) {
e.printStackTrace();
}
calle = direciones.get(0).getAddressLine(0);
Toast.makeText(this, direciones.get(0).getAddressLine(0), Toast.LENGTH_LONG).show();
bt_getgps.setText(direciones.get(0).getAddressLine(0));
} else {
Toast.makeText(this, "No hay longitud ni latitud", Toast.LENGTH_LONG).show();
}
}
Manifest:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
getLastKnowLocation returns null if no location was stored on the API before accessing (such reiniting the cellphone), you must waiit for locationManager.requestLocationUpdates to respond on the listener you added, there you will have a valid location.
getLastKnowLoation IF NOT NULL is a good starting point for a mapapplicaiton, but you should update trough requestLocationUpdates

Call requires permission which may be rejected by the user when trying to get the location

I looked on other questions, but was unable to find the anwer.
Anyway, I am trying to get the location of the device, and it just wont work. I am using Android 5.0 (API 21).
public class MainActivity extends AppCompatActivity implements LocationListener {
LocationManager locationManager;
String provider;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
provider = locationManager.getBestProvider(new Criteria(), false);
Location location = locationManager.getLastKnownLocation(provider);
}
#Override
public void onLocationChanged(Location location) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
}
The error is when in .getLastKnowLocation(). It says I should check for permissions, but I already added the permissions to the Android manifest.
uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
When I click the red light bulb, there is 'Add permission check' option, and when I click it, it ads this:
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
But when I run it, it always does the return; , like I don't have the permissions.
You need to enable run time permissions,
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION,Manifest.permission.ACCESS_FINE_LOCATION},1200);
If you only want your app to work up to API level 21, you can set targetSdkVersion 21 in your module level build.gradle file, which will make the error you're facing go away.
If/when you want to start targeting API level 23 or higher, you'll need to request permissions at runtime in addition to having them declared in your manifest.

Not able to get location with Service (LocationManager)

i am in real trouble here. Trying to get lat and lon with a background service every 3 sec but i am only able to get some data written when i click send lat and lon in extended controls of the emulator , so both phone and emulator are not working. Here is my code below, it would be awesome if someone could help me. Thanks!
Service
public class GPSService extends Service {
private static final String TAG = "GpsService";
private LocationListener locationListener;
private LocationManager locationManager;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
Intent i = new Intent("location_update");
i.putExtra("latExtra",location.getLatitude());
i.putExtra("lonExtra",location.getLongitude());
sendBroadcast(i);
Log.i(TAG, "onLocationChanged: extras lat lon"+location.getLatitude()+" "+location.getLongitude());
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
#Override
public void onProviderEnabled(String s) {
}
#Override
public void onProviderDisabled(String s) {
Log.i(TAG, "onProviderDisabled: DISABLED");
Intent i = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
};
locationManager =(LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
Criteria c = new Criteria();
String provider =locationManager.getBestProvider(c,true);
Log.i(TAG, "onCreate: bestProvider "+provider);
//noinspection MissingPermission
locationManager.requestLocationUpdates(provider,2000,0,locationListener);
}
#Override
public void onDestroy() {
super.onDestroy();
if (locationManager != null){
Log.i(TAG, "onDestroy: Location manager nije null i brisem");
//noinspection MissingPermission
locationManager.removeUpdates(locationListener);
}
}
}
MainActivity
private final String TAG = "Main";
...
BroadcastReceiver broadcastReciever;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//setStatusBarTranslucent(false);
if(!runtimePermisions()){
startLocationUpdate();}
...
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//stopService();
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
//REQUEST PERMISSION
Log.i(TAG, "onClick: NO PERMISION");
} else {
Log.i(TAG, "onClick: got permision");
}
...
}
public void startLocationUpdate(){
Intent i = new Intent(this,GPSService.class);
startService(i);
Log.i(TAG, "startLocationUpdate: Pokrenuo sam service");
}
#Override
protected void onResume() {
super.onResume();
if (broadcastReciever == null){
broadcastReciever = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
lat = (Double) intent.getExtras().get("latExtra");
lon = (Double) intent.getExtras().get("lonExtra");
Log.i(TAG, "onReceive: lat lon "+lat+" "+lon);
}
};
}
registerReceiver(broadcastReciever,new IntentFilter("location_update"));
}
#Override
protected void onDestroy() {
super.onDestroy();
if (broadcastReciever!=null){
unregisterReceiver(broadcastReciever);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 100) {
if (grantResults [0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED){
startLocationUpdate();
}else{
runtimePermisions();}
}
}
private boolean runtimePermisions() {
if (Build.VERSION.SDK_INT >= 23 &&ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION)!= PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_COARSE_LOCATION)!= PackageManager.PERMISSION_GRANTED){
requestPermissions(new String[]{
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
},100);
return true;
}
return false;
}
MANIFEST
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.digiart.yoweather">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<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">
<activity
android:name=".MainActivity"
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>
<activity android:name=".SettingsActivity"
android:theme="#style/SettingsTheme"></activity>
<service android:name=".Gps.GPSService"/>
</application>
</manifest>
Again... Any help would be great! THANKS :D
As K. Sopheak said, it can take a while to get the location. From the documentation:
It may take a while to receive the first location update. If an immediate location is required, applications may use the getLastKnownLocation(String) method.
So, you could try getting the last known location using getLastKnownLocation(String) when the service is started and, assuming it exists, broadcast it in the same way you would a location update. Bear in mind, though, that the last known location could be out of date. Depending on what you're using the location for this may or may not be acceptable.
Also, as an aside, a couple of thoughts:
You said 3 seconds, but the code uses 2,000 milliseconds - was that just a typo?
The frequency of location updates is a minimum time - you are not guaranteed to get updates that often. As per the documentation:
The location update interval can be controlled using the minTime parameter. The elapsed time between location updates will never be less than minTime, although it can be more depending on the Location Provider implementation and the update interval requested by other applications.
Is there any particular reason you need location updates at such a high frequency? Obtaining a location can be battery intensive, particularly given that you are requesting FINE as well as COARSE location permissions, so requesting it so frequently could place an enormous drain on device battery life. This is particularly so given that the code is running in a service and will therefore continue to run even when the application is in the background or the user is in an activity which does not require location data. Again, from the documentation:
Choosing a sensible value for minTime is important to conserve battery life. Each location update requires power from GPS, WIFI, Cell and other radios. Select a minTime value as high as possible while still providing a reasonable user experience. If your application is not in the foreground and showing location to the user then your application should avoid using an active provider (such as NETWORK_PROVIDER or GPS_PROVIDER), but if you insist then select a minTime of 5 * 60 * 1000 (5 minutes) or greater. If your application is in the foreground and showing location to the user then it is appropriate to select a faster update interval.
Google recommends using the Google Play services location APIs instead of the Android framework location APIs:
The Google Play services location APIs are preferred over the Android framework location APIs (android.location) as a way of adding location awareness to your app. If you are currently using the Android framework location APIs, you are strongly encouraged to switch to the Google Play services location APIs as soon as possible.

Android LocationListener onLocationChanged() is never called

I'm developing a Android app and I'm still green in this area.
In my app I'm using the FusedLocationApi to get both the last know location and make Location update requests and I got a problem where, even with both Location and WiFi activated on Android Studio emulator and Samsung Galaxy S5, I never got the LocationListener's onLocationChanged() called.
Here is my code:
package com.trackit.app.locationupdatetest;
import android.content.pm.PackageManager;
import android.location.Location;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
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.Toast;
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 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;
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
private static final String TAG = MapsActivity.class.getSimpleName();
public static final String STARTING_POSITION = "Rio de Janeiro"; //Application's default position
public static final int MY_PERMISSIONS_REQUEST_FINE_LOCATION = 1; //Fine location permission
private GoogleMap mMap;
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
private MapsActivity mActivity;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
(findViewById(R.id.Location)).setEnabled(false);
(findViewById(R.id.StreetView)).setEnabled(false);
// 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);
if (mGoogleApiClient == null)
buildGoogleAPIClient();
//Create and configure a Location Request object to used while looking for location updates
if(mLocationRequest == null)
buildLocationRequest();
mActivity = this;
}
private synchronized void buildGoogleAPIClient() {
//Configuring the Google API client before connect
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
private synchronized void buildLocationRequest() {
mLocationRequest = LocationRequest.create()
.setInterval(10000)
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setFastestInterval(1000)
.setSmallestDisplacement(1);
}
#Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
/**
* This method is called when the Activity is no longer visible to the user.
*/
#Override
protected void onStop() {
if(mGoogleApiClient.isConnected())
mGoogleApiClient.disconnect();
super.onStop();
}
/**
* This callback is triggered when the map is ready to be used.
*/
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// Add a marker in Sydney and move the camera
LatLng sydney = new LatLng(-34, 151);
mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
}
public void buttonPressed(View buttonPressed){
displayUserLocation();
}
#Override
public void onConnected(#Nullable Bundle bundle) {
(findViewById(R.id.Location)).setEnabled(true);
(findViewById(R.id.StreetView)).setEnabled(true);
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Log.e(TAG,"onConnectionFailed:"+connectionResult.getErrorCode()+","+connectionResult.getErrorMessage());
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String permissions[], #NonNull
int[] grantResults) {
//Process the user permission's response
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_FINE_LOCATION:
processLocationPermissionResult(grantResults);
break;
default:
}
}
public void processLocationPermissionResult(#NonNull int grantResults[]) {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED)
displayLocation();
else {} // permission denied, boo! Disable the functionality that depends on this permission.
}
public void displayUserLocation(){
//Verify if the app have permission to access user's location
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.
ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.
permission.ACCESS_FINE_LOCATION)) {
//Asks the permission to access the user's location
Toast.makeText(this, "This app needs to access your location. " +
"Allow the app to access it?", Toast.LENGTH_LONG).show();
} else {
ActivityCompat.requestPermissions(this,
new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
MapsActivity.MY_PERMISSIONS_REQUEST_FINE_LOCATION);
}
} else displayLocation(); //If the permission was granted
}
public void displayLocation() throws SecurityException{
Location lastLocation = LocationServices.FusedLocationApi.
getLastLocation(mGoogleApiClient);
if(lastLocation != null) {
Log.e(TAG, "!!!!!!");
LatLng position = new LatLng(lastLocation.getLatitude(), lastLocation.
getLongitude());
mMap.addMarker(new MarkerOptions().position(position).title("Marker in " +
MapsActivity.STARTING_POSITION));
mMap.moveCamera(CameraUpdateFactory.newLatLng(position));
} else{
Log.e(TAG, "??????");
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
mLocationRequest, this);
}
}
#Override
public void onLocationChanged(Location location) {
if(location.getAccuracy() < 10 && location.getSpeed() < 55.55555555555556){
Log.e(TAG, "onLocationChanged() started");
LatLng position = new LatLng(location.getLatitude(), location.getLongitude());
mMap.addMarker(new MarkerOptions().position(position).title("Marker in " +
MapsActivity.STARTING_POSITION));
mMap.moveCamera(CameraUpdateFactory.newLatLng(position));
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
Log.e(TAG, "onLocationChanged() terminated");
}
/*else{
//Continue listening for a more accurate location
}*/
}
}
Below are both my AndroidManifest.xml and my gradle:
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.trackit.app.locationupdatetest">
<!--
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.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-feature
android:glEsVersion="0x00020000"
android:required="true"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<!--
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=".MapsActivity"
android:label="#string/title_activity_maps">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 24
buildToolsVersion "24.0.1"
defaultConfig {
applicationId "com.trackit.app.locationupdatetest"
minSdkVersion 21
targetSdkVersion 24
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:24.2.0'
compile 'com.google.android.gms:play-services:9.4.0'
}
I'v searched a lot this week but I've got no helpful answer yet =s
These are some of the threads I've searched (I don't want to look like a lazy guy, because I'm not, I'm just stuck)
onLocationChanged does not get called using fusedLocationAPI.requestLocationUpdates
Unable to get location updates
onLocationChanged not called on some devices
on locaton changed never gets called in android google client api
onLocationChanged isn't being called
Can someone point my errors? =S
I'll venture this answer... if it's helpful, great... if not, sorry...
I have a similar Activity that uses the FusedLocationprovider.
I'm no expert, and can't say WHY yours is not working, but mine is working, and I've noticed the following differences:
YOUR CODE:
private synchronized void buildGoogleAPIClient() {
//Configuring the Google API client before connect
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
private synchronized void buildLocationRequest() {
mLocationRequest = LocationRequest.create()
.setInterval(10000)
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setFastestInterval(1000)
.setSmallestDisplacement(1);
}
MY CODE:
protected synchronized void buildGoogleApiClient() {
this.mGoogleApiClient = new GoogleApiClient.Builder(this).
addConnectionCallbacks(this).
addOnConnectionFailedListener(this).
addApi(LocationServices.API).build();
createLocationRequest();
}
protected void createLocationRequest() {
this.mLocationRequest = new LocationRequest();
this.mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
this.mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
this.mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
Differences:
1) You put:
if(mLocationRequest == null)
buildLocationRequest();
in your onCreate method. Is this necessary? Wouldn't mLocationRequest always be null in onCreate()?
2) Your methods are private, mine protected
3) your createLocationrequest() is labeled as 'synchronized' ... could is be not working because of this?
4) you use the setSmallestDisplacement() method. I have seen posts that say this method doesn't work properly and results in onLocationChanged() not being called.
5) You instantiate your LocationRequest with: 'LocationRequest.create()' and not "new LocationRequest()' could this be the problem?
Does this help?
Here is an alternate answer.
There is one line of code that is vital in order for onlocationChanged to ever be called:
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
mLocationRequest, this);
And in your case, this code resides very deeply in your code with many conditions needing to be met for this to be reached:
Conditions you require:
security exception not thrown
last location == null
(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
!(ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)
button pushed
I would consider putting MORE LOGS in your code in order to determine that these conditions are in fact being met... trace backwards from:
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
mLocationRequest, this);
PS - I see you're using the Android N permission model. I have yet to put my toes in that water due to the confusion it seems to create... I just set my target SDK = 22. :)

Categories

Resources