Cannot get last location although permissions are granted - java

I have the following class, that is extended by all my activities, where I want to save the last location using LocationServices.
Debugging it seems that permissions are granted, and I enter the onComplete method, but task.getResult() is always null. How is this possible?
public class MyAppCompatActivity extends AppCompatActivity {
private static final int LOCATION_REQUEST_CODE = 1000;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION},
LOCATION_REQUEST_CODE);
} else
setUserLocation();
}
#Override
public void onRequestPermissionsResult(int requestCode,
String[] permissions, int[] 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) {
setUserLocation();
}
return;
}
// other 'case' lines to check for other
// permissions this app might request.
}
}
#SuppressLint("MissingPermission")
private void setUserLocation() {
LocationServices.getFusedLocationProviderClient(this).getLastLocation().addOnCompleteListener(new OnCompleteListener<Location>() {
#Override
public void onComplete(#NonNull Task<Location> task) {
ROUserInfo user = UserManager.getROUserInfo();
if(user==null || task.getResult()==null)
return;
user.User._Position._Latitude=task.getResult().getLatitude();
user.User._Position._Longitude=task.getResult().getLongitude();
UserManager.updateUserOnServer(user);
}
});
}
}

Related

Send location via sms Button doesn't work - android studio

I tried to send my location via SMS, but the button doesn't work.
The button was working fine before I added the code of getting current location.
Can you please help me to fix that? I tried many solutions that I found in this website, but it doesn't work with me.
I am totally new to Android Studio, so I don't know how to write my code that it will work the way I want it.
private LocationManager locationManager;
private LocationListener locationListener;
String[] appPermissions = {
android.Manifest.permission.ACCESS_FINE_LOCATION,
android.Manifest.permission.SEND_SMS
};
private static final int PERMISSIONS_REQUEST_CODE = 123;
private static final int MY_PERMISSIONS_REQUEST_SEND_SMS = 0;
double x,y;
Button sendBtn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (checkAndRequestPermissons()) {
}
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
x = location.getAltitude() ;
y = location.getLongitude();
Log.d("Location", location.toString());
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
};
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.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;
}
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
sendBtn = (Button) findViewById(R.id.btnSendSMS);
sendBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
sendSMSMessage();
}
});
}
protected void sendSMSMessage() {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.SEND_SMS)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.SEND_SMS)) {
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.SEND_SMS},
MY_PERMISSIONS_REQUEST_SEND_SMS);
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode,String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_SEND_SMS: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage("+212xxxxx", null, "Je suis en danger, voici ma localisation : https://www.google.com/maps/search/?api=1&query=" + x + "," + y , null, null);
Toast.makeText(getApplicationContext(),
"SMS sent.", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(),
"SMS faild, please try again.", Toast.LENGTH_LONG).show();
return;
}
}
}
}
private boolean checkAndRequestPermissons() {
List<String> listPermissionsNeeded = new ArrayList<>();
for (String perm : appPermissions)
{
if (ContextCompat.checkSelfPermission(this,perm) != PackageManager.PERMISSION_GRANTED)
{
listPermissionsNeeded.add(perm);
}
}
if (!listPermissionsNeeded.isEmpty())
{
ActivityCompat.requestPermissions(this,listPermissionsNeeded.toArray(
new String[listPermissionsNeeded.size()]),PERMISSIONS_REQUEST_CODE
);
return false;
}
return true;
}

How to properly pause app until permission request is finished?

I'm writing an app in which its only function is acting as a receiver for Bluetooth Low Energy. The app is useless if the user does not allow BLE. When the app is started for the first time, I want it to ask the user for Locations Permission (since Android requires it for BLE). I bring the permissions dialog up, but the rest of the app continues while the user is reading the dialog, starting BLEScanner and all that. I want the app to pause while the user is reading the dialog and deciding what to do. Here's my setup:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_CODE);
}
//More UI preparation stuff
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE: {
if (permissions[0].equals(Manifest.permission.ACCESS_COARSE_LOCATION)) {
if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
PermissionDialog newDialog = new PermissionDialog();
newDialog.show(getSupportFragmentManager(), "Request Location Permission");
}
}
}
}
Where "PermissionDialog" is a different class that uses an DialogFragment to explain why the app needs the permission and then closes/restarts the app. In this case, the rest of the app continues, attempting to do Bluetooth stuff while the user is still reading the permission dialog that has popped up! Naively, I thought I could use a synchronize lock to do it, as below, but in this case, the callback is never called:
private final Object initLock = new Object();
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_CODE);
}
Log.i("Lock", "At the lock!");
try {
synchronized (initLock) {
initLock.wait();
}
}
catch (InterruptedException e) {
//TODO find out what to do here
}
Log.i("Lock", "Past the lock!");
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE: {
if (permissions[0].equals(Manifest.permission.ACCESS_COARSE_LOCATION)) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
synchronized (initLock){
initLock.notify();
}
}
else{
PermissionDialog newDialog = new PermissionDialog();
newDialog.show(getSupportFragmentManager(), "Request Location Permission");
}
}
}
}
}
What's the proper way to do this? I have a few ideas, but they all balloon in scope. Do I need to make another class that inherits AppCompatActivity to do the permissions and I call it as a thread? But then how do I know where the onRequestPermissionResult callback will go? I'm at a loss.
Put the code inside your //More UI preparation stuff to a new method. After the permissions, say 'init()'
private void init(){
//More UI preparation stuff
}
Then inside onCreate, if permission is already granted, call init(); otherwise request permission.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_CODE);
} else {
init();
}
}
Now handle the user's response inside onRequestPermissionsResult - If user has granted, initialize the UI, otherwise block the feature and/or notify the user about the issue.
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE: {
if (permissions[0].equals(Manifest.permission.ACCESS_COARSE_LOCATION)) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
init();
} else{
PermissionDialog newDialog = new PermissionDialog();
newDialog.show(getSupportFragmentManager(), "Request Location Permission");
}
}
}
}
}
PS: For this same purpose, I have prepared a library which makes this process a lot easier. Have a look at my library.
You can use EasyPermissions and implement EasyPermissions.PermissionCallbacks to resolve it.
And add this annotation:#AfterPermissionGranted before the method you want to run
such as :
AfterPermissionGranted(PERMISSION_REQUESTCODE_BASE)
private void requestPerminssions(){
if(EasyPermissions.hasPermissions(this,PERMISSIONS)){
int hasCityData=config.getInt("isDataEmpty",0);
if(hasCityData==0){
new CountryInfoThread().execute();
}else {
new LocalPositionThread().execute();
}
}
}
I ended up using a private variable:
private boolean readyToStart = false;
In this way:
#Override
protected void onCreate(Bundle savedInstanceState) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_CODE);
}
else{
readyToStart = true;
}
}
#Override
protected void onResume() {
super.onResume();
if (readyToStart) {
startBluetooth();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[],
int[] grantResults) {
Log.i("Permission", "Callback made");
switch (requestCode) {
case REQUEST_CODE: {
if (permissions[0].equals(Manifest.permission.ACCESS_COARSE_LOCATION)) {
if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
PermissionDialog newDialog = new PermissionDialog();
newDialog.show(getSupportFragmentManager(), "Request Location Permission");
}
else{
startBluetooth();
}
}
}
}
}

Application Not Asking to get Permissions

I have this code to get the following permissions (READ_PHONE_STATE, READ_CONTACTS, WRITE_CONTACTS):
int permissionCheck = ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_PHONE_STATE);
int permissionCheck1 = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS);
int permissionCheck2 = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_CONTACTS);
if (permissionCheck != PackageManager.PERMISSION_GRANTED && permissionCheck1 != PackageManager.PERMISSION_GRANTED && permissionCheck2 != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.READ_PHONE_STATE}, 1);
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS}, 2);
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_CONTACTS}, 3);
} else {
TelephonyManager tMgr = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
mPhoneNumber = tMgr.getLine1Number();
}
I know I don't have these permissions because I get an error like so:
java.lang.SecurityException: Permission Denial: opening provider com.android.providers.contacts.ContactsProvider2 from ProcessRecord{95e4cb4 30797:com.example.ortel.tagnet/u0a217} (pid=30797, uid=10217) requires android.permission.READ_CONTACTS or android.permission.WRITE_CONTACTS
Also: It is not requesting my permission to get access to READ_CONTACTS and WRITE_CONTACTS.
Whats the issue?
You are using && instead of ||. As it stands, you will not ask for any runtime permissions if you hold just one of the three.
Also, you are calling requestPermissions() three times. Call it once, with whichever permissions you need. new String[] creates a string array, and it can hold all three of your desired permission names.
If you have 10 permissions, will you extend your code by 20 more lines. Noooo!
You have 2 ways
Follow correct way to ask permission. I am posting my code snippet, copy this code in your Base Activity class.
Or you use RxPermissions. If you are new to Android.
Here is my code snippet.
String[] permissions = {Manifest.permission.READ_PHONE_STATE, Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS};
getBulkPermissions(permissions, new RequestPermissionAction() {
#Override
public void permissionDenied() {
// TODO: 5/27/2018 handle permission deny
}
#Override
public void permissionGranted() {
// TODO: 5/27/2018 you code do further operations
}
});
Can it be more simpler?
Now you will put this code Base Activity class and use anywhere you need. Or put in your current class if you don't need it at any other place.
RequestPermissionAction onPermissionCallBack;
private final static int REQUEST_BULK_PERMISSION = 3006;
private boolean checkBulkPermissions(String[] permissions) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
for (String permission : permissions) {
if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
} else {
return true;
}
}
public void getBulkPermissions(String[] permissions, RequestPermissionAction onPermissionCallBack) {
this.onPermissionCallBack = onPermissionCallBack;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!checkBulkPermissions(permissions)) {
requestPermissions(permissions, REQUEST_BULK_PERMISSION);
return;
}
}
if (onPermissionCallBack != null)
onPermissionCallBack.permissionGranted();
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (onPermissionCallBack != null)
onPermissionCallBack.permissionGranted();
} else if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_DENIED) {
if (onPermissionCallBack != null)
onPermissionCallBack.permissionDenied();
}
}
public interface RequestPermissionAction {
void permissionDenied();
void permissionGranted();
}

Java Android requestPermissions after click button

This is how I request permissions :
private boolean checkAndRequestPermissions() {
int permissionSendMessage = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);
int locationPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
int cameraPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);
int phoneStatePermission = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE);
List<String> listPermissionsNeeded = new ArrayList<>();
if (locationPermission != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION);
}
if (permissionSendMessage != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.READ_EXTERNAL_STORAGE);
}
if (cameraPermission != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.CAMERA);
}
if (phoneStatePermission != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.READ_PHONE_STATE);
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), REQUEST_ID_MULTIPLE_PERMISSIONS);
return false;
}
return true;
}
I call this method after click button :
#OnClick(R.id.email_sign_in_button)
void loginButton() {
if(checkAndRequestPermissions()) {
attemptLogin();
}
}
But when a user confirm all permissions have to click one more time button. What I have to do that user do not click a button ?
You need to override the activity's onRequestPermissionsResult method, it will be called when the user accepts/rejects permissions. You can find more details HERE
Here is an example specific to your case:
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
if(requestCode == REQUEST_ID_MULTIPLE_PERMISSIONS && grantResults.length == listPermissionsNeeded.size()){
boolean allGranted = true;
for(int grantedResult : grantedResults){
if(grantedResult != PackageManager.PERMISSION_GRANTED){
allGranted = false;
}
}
if(allGranted){
attemptLogin();
}
}
}
Use RxPermissions: No need to again click on button after allow permissions
gradle
compile 'com.tbruyelle.rxpermissions:rxpermissions:0.7.0#aar'
compile 'com.jakewharton.rxbinding:rxbinding:0.4.0'
code
RxPermissions.getInstance(this)
.request(REQUEST_PERMISSIONS)
.subscribe(new Action1<Boolean>() {
#Override
public void call(Boolean granted) {
if (granted) {
attemptLogin();
}
}
});
You can listen for the onRequestPermissionsResult in your Activity/Fragment.
As statet in the Documentation, you can implement this to check if the user has granted the requested permissions:
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
// 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.
} 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
}
}
Remember to alter the switch/case according to your needs. If the user has granted all permissions, just call attemptLogin() once again.

setMyLocationEnabled() error on Android 6

I'm trying to make that when I load my map activity, a "my location" button will appear. This is my code, and the button which makes my activity to zoom in to my current location isn't appearing. What do I need to change in my code to make it work?
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private static final String FIREBASE_URL="https://********.firebaseio.com/";
private Firebase firebaseRef;
private LocationManager locationManager;
private GoogleMap mMap;
SupportMapFragment mapFrag;
boolean bPermissionGranted;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps2);
Firebase.setAndroidContext(this);
firebaseRef = new Firebase(FIREBASE_URL);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
bPermissionGranted = checkLocationPermission();
}
// 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);
}
private void setUpMapIfNeeded() {
if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
if (mMap != null) {
CameraUpdate center = CameraUpdateFactory.newLatLng(new LatLng(32.065483, 34.824550));
CameraUpdate zoom = CameraUpdateFactory.zoomTo(10);
mMap.moveCamera(center);
mMap.animateCamera(zoom);
}
}
}
public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
public boolean checkLocationPermission(){
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)) {
// Show an expanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
// TODO: Prompt with explanation!
//Prompt the user once explanation has been shown
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
}
return false;
} else {
return true;
}
}
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay!
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
mMap.setMyLocationEnabled(true);
}
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show();
}
return;
}
}
}
#Override
public void onMapReady(final GoogleMap googleMap) {
mMap=googleMap;
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (bPermissionGranted) {
//User has previously accepted this permission
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
mMap.setMyLocationEnabled(true);
}
}
}
else {
//Not in api-23, no need to prompt
mMap.setMyLocationEnabled(true);
}
firebaseRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot child : dataSnapshot.child("users").getChildren()) {
String rightLocation = child.child("location_right").getValue().toString();
String leftLocation = child.child("location_left").getValue().toString();
double location_left = Double.parseDouble(leftLocation);
double location_right = Double.parseDouble(rightLocation);
String party_title = child.child("party/party_title").getValue().toString();
LatLng cod = new LatLng(location_left, location_right);
googleMap.addMarker(new MarkerOptions().position(cod).title(party_title));
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
}
}
This is a simplified version of my other answer that also requests location updates .
The key is just to make sure that the user has granted you permission before you make the call to setMyLocationEnabled().
It's also possible that the user has not accepted the permission prompt by the time onMapReady() is called (most likely on first launch of the app), therefore there's another call to setMyLocationEnabled() in the onRequestPermissionsResult() callback in the case that the user accepted the permission.
First, ensure that you have the permissions in your AndroidManifest.xml (outside of the application tag):
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Here is a full Activity class that will work for you:
public class MapLocationActivity extends AppCompatActivity
implements OnMapReadyCallback {
GoogleMap mGoogleMap;
SupportMapFragment mapFrag;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
checkLocationPermission();
}
mapFrag = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFrag.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
mGoogleMap = googleMap;
mGoogleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//User has previously accepted this permission
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
mGoogleMap.setMyLocationEnabled(true);
}
} else {
//Not in api-23, no need to prompt
mGoogleMap.setMyLocationEnabled(true);
}
}
public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
public boolean checkLocationPermission() {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)) {
// Show an expanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
// TODO: Prompt with explanation!
//Prompt the user once explanation has been shown
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
}
return false;
} else {
return true;
}
}
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay!
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
mGoogleMap.setMyLocationEnabled(true);
}
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show();
}
return;
}
}
}
}
If you revoke the permission:
It will prompt again:
You are using the same condition in if and else both blocks.
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED)
So, if your above condition is not true then how will be the same condition gets true in your else block. That's the reason
mMap.setMyLocationEnabled(true); never gets executed because your condition is false.
I guess what you want to do in else block is to request for permissions if it is not there. So it will change like this -
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
mMap.setMyLocationEnabled(true);
} else{
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, <request_code>);
}
And implement onRequestPermissionsResult callback
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case <request_code>:
if (grantResults.length <= 0 || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
mMap.setMyLocationEnabled(true);
}
break;
}
}
Please write N instead of M after Build.VERSION_CODES.
In this line in your code:
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
it worked for me

Categories

Resources