I'm using Fused Location API in my app ( getLatitude(), getLongitude(), getSpeed(), getElevation(), and distanceTo() ). It was working fine until I updated my phone (Moto X2 2014) to Marshmallow.
Now I don't receive speed in the location object in my app, rest methods are responding normally. However, if I run navigation on google maps in the background, I seem to receive speed inside my app as well.
Also, my app seems to work without any issues on Nexus 5X (Marshmallow) and other below API 23 phones.
What could be the problem? Has anyone faced something similar before?
On devices running Android 6.0 (API level 23) and higher, you need to validate the permission programmatically.
Youd could be something like this:
public class YourActivity extends AppCompatActivity implements
LocationListener, ActivityCompat.OnRequestPermissionsResultCallback{
private static final int REQUEST_LOCATION = 0;
private static final String[] PERMISSION_LOCATION = {Manifest.permission.ACCESS_FINE_LOCATION};
private LocationManager locManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_layout);
//Check if the Location permission is already available.
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
//Permission not granted.
requestLocationPermission();
} else {
//Permission granted.
initLocManager();
}
}
}
/**
* Requests the permission.
*/
private void requestLocationPermission() {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)) {
//Permission has been previously denied.
//Show message...
} else {
//Permission has not been granted yet. It is requested directly.
ActivityCompat.requestPermissions(this, PERMISSION_LOCATION, REQUEST_LOCATION);
}
}
/**
* Callback.
*/
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
if (requestCode == REQUEST_LOCATION) {
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//Permission granted.
initLocManager();
} else {
//Permission not granted.
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
public void initLocManager(){
//Sample code...
map.setMyLocationEnabled(true);
locManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
if(locManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) ||
locManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission("android.permission.ACCESS_FINE_LOCATION") == PackageManager.PERMISSION_GRANTED) {
locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}
}else{
locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}
} else{
Toast.makeText(this, "No location services", Toast.LENGTH_LONG).show();
}
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {}
#Override
public void onProviderEnabled(String provider) {}
#Override
public void onProviderDisabled(String provider) {}
#Override
public void onLocationChanged(Location location) {
map.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(),
location.getLongitude()), 16));
removeUpdatesLocListener();
}
private void removeUpdatesLocListener(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission("android.permission.ACCESS_FINE_LOCATION") == PackageManager.PERMISSION_GRANTED) {
if(locManager!=null)
locManager.removeUpdates(this);
}
}else{
if(locManager!=null)
locManager.removeUpdates(this);
}
}
#Override
protected void onStop() {
super.onStop();
removeUpdatesLocListener();
}
}
Good luck!
And if you need more information, look this
Related
I am trying to get runtime permissions on my app. However the app is not displaying the dialog to request the specific permission. The code below only works when the GPS is turned on on the phone manually.
I am running the app on Android 5.0.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_location = findViewById(R.id.get_location);
txt_latitude = findViewById(R.id.latitude);
txt_longitude = findViewById(R.id.longitude);
txt_timestamp = findViewById(R.id.timestamp);
btn_map = findViewById(R.id.map);
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
btn_location.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getLocation();
}
});
}
private void getLocation() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[] {
Manifest.permission.ACCESS_FINE_LOCATION
}, REQUEST_LOCATION_PERMISSION);
} else {
mFusedLocationClient.getLastLocation().addOnSuccessListener(new OnSuccessListener < Location > () {
#Override
public void onSuccess(Location location) {
if (location != null) {
mLastLocation = location;
txt_latitude.setText(getString(R.string.location_latitude, mLastLocation.getLatitude()));
txt_longitude.setText(getString(R.string.location_longitude, mLastLocation.getLongitude()));
txt_timestamp.setText(getString(R.string.timestamp, mLastLocation.getTime()));
} else {
txt_latitude.setText(R.string.no_latitude);
txt_longitude.setText(R.string.no_longitude);
txt_timestamp.setText(R.string.no_timestamp);
}
}
});
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if (requestCode == REQUEST_LOCATION_PERMISSION) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
getLocation();
} else {
Toast.makeText(this, R.string.location_permission_denied, Toast.LENGTH_SHORT).show();
}
}
}
}
Since you are run on Android 5.0 the Android runtime permission won't be shown. As runtime permission is only be shown starting from Android 6 (Marshmellow).
Please check the official documentation for the runtime permission details.
So I've been trying to learn more about Android GPS applications (specifically offline) and I've come to notice a LocationManager might be able to solve my issues. Problem is that it requires API 23 in order to function and I'd like to target API 19 devices for a specific reason. Is there any other way to manipulate the GPS function to get coordinates without internet access on a lower level API?
Please help!
#Edit: I've added a sample application that I made (and is working just fine - the only problem here is that it requires API 23 in order to run) This piece of code describes an application that displays decimal coordinates every 5 seconds.
button = (Button) findViewById(R.id.button);
textView = (TextView) findViewById(R.id.textView);
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
textView.append("\n "+ location.getLatitude() + " "+ location.getLongitude());
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
Intent intent = new Intent (Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
};
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{
Manifest.permission.ACCESS_FINE_LOCATION
}, 10 );
}
return;
}
else {
configureButton();
}
} //onCreate
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case 10:
if (grantResults.length>0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
configureButton();
return;
}
}
private void configureButton() {
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
locationManager.requestLocationUpdates("gps", 5000, 0, locationListener);
}
});
}
I am writing a code to get lastknownlocation from location manager and this prompted me to add runtime permissions.
Here is my code:
public class MainActivity extends AppCompatActivity implements LocationListener {
LocationManager locationManager;
String provider;
private final int MY_PERMISSIONS_REQUEST_CODE=1;
Location location;
Boolean isPermissionGranted=false;
#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);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION},MY_PERMISSIONS_REQUEST_CODE);
}
// return;
}
}
public void getlastknownposition()
{
}
#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) {
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode == MY_PERMISSIONS_REQUEST_CODE)
{
if(grantResults[0]==PackageManager.PERMISSION_GRANTED && grantResults[1]==PackageManager.PERMISSION_GRANTED){
Toast.makeText(MainActivity.this," granted "+grantResults[0]+"granted2"+grantResults[1], Toast.LENGTH_SHORT).show();
location = locationManager.getLastKnownLocation(provider);}
}
}
}
I am still getting an error "Call requires permission which may be rejected by user: code should explicitly check to see if permission is available (with checkPermission) or explicitly handle a potential SecurityException
in onRequestPermissionsResult on line location = locationManager.getLastKnownLocation(provider);
Put some braces around the second if in onPermissionsResult =)
if(requestCode == MY_PERMISSIONS_REQUEST_CODE){
if(grantResults[0]==PackageManager.PERMISSION_GRANTED && grantResults[1]==PackageManager.PERMISSION_GRANTED){
Toast.makeText(MainActivity.this," granted "+grantResults[0]+"granted2"+grantResults[1], Toast.LENGTH_SHORT).show();
location = locationManager.getLastKnownLocation(provider);
} else {
//TODO handle user saying NO! :)
}
}
Tip: if you request FINE_LOCATION you don't need COARSE, it already includes it.
Replace the line
location = locationManager.getLastKnownLocation(provider);
with
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED)
{
location = locationManager.getLastKnownLocation(provider);
}
Hello Everyone I am creating Navigation Application using Android Studio and getting this error while doing.
My Code Stops in if(ActivityCompat.checkSelfPermission) segment. Here i have toast statement. I have already provided COARSE_LOCATION, FINE_LOCATION and INTERNET permission in AndroidManifest file.
Following code given.
public class Second extends Activity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
//Declaring Class Objects
Location location;
LocationManager lm;
GoogleApiClient googleApiClient;
//Data type for storing value of Longitude and Latitude
private double fromLongitude;
private double fromLatitude;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second);
googleApiClient = new GoogleApiClient.Builder(this).addApi(LocationServices.API).addConnectionCallbacks(this).addOnConnectionFailedListener(this).build();
getLocation();
}
private void getLocation() {
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.
Toast.makeText(this,"Issue with permission",Toast.LENGTH_LONG).show();
return;
}
Location location = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
fromLatitude = location.getLatitude();
fromLongitude = location.getLongitude();
Toast.makeText(this,String.valueOf(fromLatitude)+" "+String.valueOf(fromLongitude),Toast.LENGTH_LONG).show();
}
//Starting Google API Client
#Override
protected void onStart() {
googleApiClient.connect();
super.onStart();
}
//Stopping Google API Client
#Override
protected void onStop() {
googleApiClient.disconnect();
super.onStop();
}
#Override
public void onConnected(Bundle bundle) {
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
}
This prints "Issue with Permission", that i have toast in if segment.
try
this
checkSelfPermission(Permission) to check is permission is granted already or not.
requestPermissions(String[] permissions, int requestCode) to request for permissions.
onRequestPermissionsResult(int permsRequestCode, String[] permissions, int[] grantResults) to check for results whether permission is granted or not.
Request Permission like this
private void askForPermission() {
int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.CAMERA);
if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {
if(!shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)) {
showMessageOKCancel("You need to allow access to Contacts",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
requestPermissions(new String[]{Manifest.permission.CAMERA},REQUEST_CODE_ASK_PERMISSIONS);
}
});
return;
}
requestPermissions(new String[] {Manifest.permission.CAMERA},
REQUEST_CODE_ASK_PERMISSIONS);
return;
}
}
Refer here to understand in detail https://coderzpassion.com/android-new-runtime-permissions/
i want to use GPS in my App. but when i tried to retrieve GPS readings as shown belwo in the code, Android studio gave me the belwo mentioned error
despit all the required permissions are added to manifest file
code:
LocationManager lm = (LocationManager) ctx.getSystemService(Context.LOCATION_SERVICE);
LocationListener ll = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
Log.w(TAG, "onLocationChanged");
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.w(TAG, "onStatusChanged");
}
#Override
public void onProviderEnabled(String provider) {
Log.w(TAG, "onProviderEnabled");
}
#Override
public void onProviderDisabled(String provider) {
Log.w(TAG, "onProviderDisabled");
}
};
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, ll);//error at this line
This is due to in Marshmallow (Android version 6.0) Users can choose to turn off permissions. Simply wrap this check to see if the permission is enabled before your location code.
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
}
You should also write in an else statement request code which will request the permission from the user if they haven't got it.
Here's a nice request permissions method:
public void requestPermissions(List<String> permissions, ActivityCompat.OnRequestPermissionsResultCallback onRequestPermissionsResultCallback) {
String[] params = permissions.toArray(new String[permissions.size()]);
requestPermissions(params, onRequestPermissionsResultCallback);
}
In your case you will have to pass it the Location permissions which you can get with this method:
private List<String> getRequiredLocationPermissions() {
String accessCoarsePermission = android.Manifest.permission.ACCESS_COARSE_LOCATION;
String accessFineLocationPermission = android.Manifest.permission.ACCESS_FINE_LOCATION;
int hasCoarsePermission = ContextCompat.checkSelfPermission(getActivity(), accessCoarsePermission);
int hasFineLocationPermission = ContextCompat.checkSelfPermission(getActivity(), accessFineLocationPermission);
List<String> permissions = new ArrayList<>();
if (hasCoarsePermission != PackageManager.PERMISSION_GRANTED) {
permissions.add(accessCoarsePermission);
}
if (hasFineLocationPermission != PackageManager.PERMISSION_GRANTED) {
permissions.add(accessFineLocationPermission);
}
return permissions;
}