I want to get location data but first I have to get permission from the user. so i want to pause the app while the user grants or denies the permission
this is how I tried to do it:
MainActivity:
public class MainActivity extends AppCompatActivity {
private static final long LOCATION_REFRESH_TIME = 15000;
private static final float LOCATION_REFRESH_DISTANCE = 500;
public static final int LOCATION_PERMISSION_REQUEST_CODE = 1;
public Boolean locationPermissionResults=null;
double longitudeNetwork;
double latitudeNetwork;
TextView locationText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
locationText=findViewById(R.id.locationtext);
//getting the permission if its not granted
if(ActivityCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED
|| ActivityCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
locationText.setText("give permission1");
ActivityCompat.requestPermissions(MainActivity.this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION,
android.Manifest.permission.ACCESS_COARSE_LOCATION}, LOCATION_PERMISSION_REQUEST_CODE);
//resume if granted
}
else{
locationManager();
}
}
private final LocationListener mLocationListenerNetwork = new LocationListener() {
#Override
public void onLocationChanged(final Location location) {
latitudeNetwork = location.getLatitude();
longitudeNetwork = location.getLongitude();
locationText.setText(Double.toString(longitudeNetwork) + "//" + Double.toString(latitudeNetwork));
}
};
#SuppressLint("MissingPermission")
public void locationManager(){
LocationManager locationManagerNetwork = (LocationManager) getSystemService(LOCATION_SERVICE);
locationManagerNetwork.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, LOCATION_REFRESH_TIME,
LOCATION_REFRESH_DISTANCE, mLocationListenerNetwork);
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case LOCATION_PERMISSION_REQUEST_CODE: {
if (permissions[0].equals(Manifest.permission.ACCESS_COARSE_LOCATION)) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
locationManager();
} else{
locationText.setText("give permission2");
}
}
}
}
}
}
I have a problem with getting permission and handling the result. when the user denies the or grants the permission request the locationText shows give permission1 which means the moved over the first else in onCreate method and also the else in onRequestPermissionsResult.
why is this happening?
NOTE: in onRequestPermissionsResult I'm only checking for one of the permissions asked in onCreate because if one of them is granted the other one is granted too. can this be the problem?
You can't pause an app. Nor can you wait on the main thread. You need to reorganize your Activity so you don't need to do that- create an empty or waiting state that displays until that data is available.
i am using Fusedlocationprovider get my current location, Some times I get the current location currently ,but some times give wrong location ,but near the current location. what is the reason, I am new to android , help me to solve this problem.thank you.
This is the my code :
public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
private FusedLocationProviderApi locationProvider = LocationServices.FusedLocationApi;
private GoogleApiClient googleApiClient;
private LocationRequest locationRequest;
private double myLatitude;
private double myLongitude;
private static final int MY_PERMISSION_REQUEST_FINE_LOCATION = 101;
private static final int MY_PERMISSION_REQUEST_COARSE_LOCATION = 102;
private boolean permissionIsGranted = false;
String phonenumber;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Bundle extras = getIntent().getExtras();
if (extras != null) {
phonenumber = extras.getString("key11");
getIntent().removeExtra("key11");
}
googleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
locationRequest = new LocationRequest();
locationRequest.setInterval(10 * 1000);
locationRequest.setFastestInterval(15 * 1000);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
#Override
public void onConnected(Bundle bundle) {
requestLocationUpdates();
}
private void requestLocationUpdates() {
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.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSION_REQUEST_FINE_LOCATION);
} else {
permissionIsGranted = true;
}
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
#Override
public void onLocationChanged(Location location) {
myLatitude = location.getLatitude();
myLongitude = location.getLongitude();
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(phonenumber, null, "*-"+String.valueOf(myLatitude)+"#"+String.valueOf(myLongitude)+"#", null, null);
System.exit(0);
}
#Override
protected void onStart() {
super.onStart();
googleApiClient.connect();
}
#Override
protected void onResume() {
super.onResume();
if (permissionIsGranted) {
if (googleApiClient.isConnected()) {
requestLocationUpdates();
}
}
}
#Override
protected void onPause() {
super.onPause();
if (permissionIsGranted)
LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, this);
}
#Override
protected void onStop() {
super.onStop();
if (permissionIsGranted)
googleApiClient.disconnect();
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case MY_PERMISSION_REQUEST_FINE_LOCATION:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission granted
permissionIsGranted = true;
} else {
//permission denied
permissionIsGranted = false;
Toast.makeText(getApplicationContext(), "This app requires location permission to be granted", Toast.LENGTH_SHORT).show();
}
break;
case MY_PERMISSION_REQUEST_COARSE_LOCATION:
// do something for coarse location
break;
}
}
}
Please help me Android Pro Developers Solve my error!
I am creating an app which will get a user name from DB and print the ID and then on button click it will show the current GPS coordinates. I have implemented it but don't know why its not working.
Here is my Manifest file
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
Below is my MainActivity.java
public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
private static final String TAG = "MainActivity";
private TextView tv_lat;
private TextView tv_long;
private Button btn_loc;
private GoogleApiClient googleApiClient;
private Location location;
private LocationManager mLocationManager;
private LocationManager locationManager;
private LocationRequest locationRequest;
private LocationListener locationListener;
private long UPDATE_INTERVAL = 2 * 1000; /* 10 secs */
private long FASTEST_INTERVAL = 2000; /* 2 sec */
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_lat = (TextView)findViewById(R.id.tv_lat);
tv_long = (TextView)findViewById(R.id.tv_long);
btn_loc = (Button)findViewById(R.id.btn_loc);
// show location button click event
btn_loc.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
googleApiClient = new GoogleApiClient.Builder(MainActivity.this)
.addConnectionCallbacks(MainActivity.this)
.addOnConnectionFailedListener(MainActivity.this)
.addApi(LocationServices.API)
.build();
}
});
mLocationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
checkLocation(); //check whether location service is enable or not in your phone
}
#Override
public void onConnected(Bundle bundle) {
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;
}
startLocationUpdates();
location = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
if(location == null)
{
startLocationUpdates();
}
if (location != null)
{
}
else {
Toast.makeText(this, "Location not Detected", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "Connection Suspended");
googleApiClient.connect();
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.i(TAG, "Connection failed. Error: " + connectionResult.getErrorCode());
}
#Override
protected void onStart() {
super.onStart();
if (googleApiClient != null) {
googleApiClient.connect();
}
}
#Override
protected void onStop() {
super.onStop();
if (googleApiClient.isConnected()) {
googleApiClient.disconnect();
}
}
private void startLocationUpdates() {
// Create the location request
locationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY)
.setInterval(UPDATE_INTERVAL)
.setFastestInterval(FASTEST_INTERVAL);
// Request location updates
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;
}
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient,
locationRequest, this);
Log.d("reque", "--->>>>");
}
#Override
public void onLocationChanged(Location location) {
double lattitude = location.getLatitude();
double longitude = location.getLongitude();
String msg = "Updated Location: " +
Double.toString(lattitude) + " , " +
Double.toString(longitude);
tv_lat.setText("Latitude is " + lattitude );
tv_long.setText("Longitude is " + longitude);
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
// You can now create a LatLng Object for use with maps
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
}
private boolean checkLocation() {
if(!isLocationEnabled())
showAlert();
return isLocationEnabled();
}
private boolean isLocationEnabled() {
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) ||
locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
}
public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
private void showAlert() {
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)) {
final AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setTitle("Enable Location")
.setMessage("Your Locations Settings is set to 'Off'.\nPlease Enable Location to " +
"use this app")
.setPositiveButton("Location Settings", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
Intent myIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(myIntent);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
}
});
dialog.create().show();
}
}
else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION );
}
}
}
When i run my app on the my device, below result is shown
When i click on the get location coordinates nothing happens. Also no errors or warnings are shown in logcat.
Update 1
I have moved all the code outside from the button click event
googleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
googleApiClient.connect();
mLocationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
And then debugged it, and i got the below result.
I don't know why the coordinates are not showing :(
Any help would be highly appreciated.
When your device is over Android 6.0 Marshmallow, you have to check, that the location permission is allowed in the application settings. You can turn it manually in the settings on or you use the runtime permission library. I've found a very useful library for that: https://github.com/ParkSangGwon/TedPermission
go to mobile settings-->location settings
check whether your mobile GPS service is on or off
and turn on if it is off.
hope this helps.
I am working on accessing the user current location and have gone through this tutorial Current location and this tutorial Current Location. Everything seems fine but latitude and longitude are not coming up in the TextView field.
Here is my code
#Keep
public class edit_information extends Fragment implements AdapterView.OnItemSelectedListener, GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener, ResultCallback<LocationSettingsResult> {
protected final static String TAG = "EditInformation";
private static final int MY_PERMISSIONS_ACCESS_LOCATION = 1;
private RadioGroup radioGroup;
private RadioGroup musicRadioGroup;
private RadioGroup decorRadioGroup;
protected static final int REQUEST_CHECK_SETTINGS = 0x1;
//The desired interval for location updates
public static final long UPDATE_INTERVAL_IN_MILLISECONDS = 10000;
//The fastest rate for active location updates
public static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = UPDATE_INTERVAL_IN_MILLISECONDS / 2;
//Keys for storing activity state in bundle
protected static final String KEY_REQUESTING_LOCATION_UPDATES = "requesting-location-updates";
protected static final String KEY_LOCATION = "location";
protected static final String KEY_LAST_UPDATED_TIME_STRING = "last-updated-time-string";
/*
Provides entry point to Google play service
*/
protected GoogleApiClient mGoogleApiClient;
//Store parametrers for request to the FusedLocationProviderApi
protected LocationRequest mLocationRequest;
//location setting request
protected LocationSettingsRequest mLocationSettingsRequest;
protected Location mCurrentLocation;
//UI
protected TextView mLatitudeText;
protected TextView mLongitudeText;
protected Boolean mRequestingLocationUpdates;
protected String mLastUpdateTime;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.edit_information, container, false);
Spinner spinner = (Spinner) view.findViewById(R.id.spinner1);
Spinner spinner2 = (Spinner) view.findViewById(R.id.spinner2);
//Creating an array adapter using the string array and a default spinner layout
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(getContext(), R.array.hall_type, simple_spinner_item);
ArrayAdapter<CharSequence> adapter1 = ArrayAdapter.createFromResource(getContext(), R.array.hall_size, simple_spinner_item);
//Layout to choose the dropdown list
adapter.setDropDownViewResource(simple_spinner_dropdown_item);
adapter1.setDropDownViewResource(simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
spinner2.setAdapter(adapter1);
spinner.setOnItemSelectedListener(this);
spinner2.setOnItemSelectedListener(this);
radioGroup = (RadioGroup) view.findViewById(R.id.food_facility);
musicRadioGroup = (RadioGroup) view.findViewById(R.id.music_facility);
decorRadioGroup = (RadioGroup) view.findViewById(R.id.decor_facility);
mLatitudeText = (TextView) view.findViewById(R.id.myLatitude);
mLongitudeText = (TextView) view.findViewById(R.id.myLongitude);
mRequestingLocationUpdates = false;
mLastUpdateTime = "";
updateValuesFromBundle(savedInstanceState);
//Start the process of building GoogleApiClient, LocationRequest and LocationSettingRequest
buildGoogleApiClient();
createLocationRequest();
buildLocationSettingsRequest();
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(RadioGroup radioGroup, int checkedId) {
switch (checkedId) {
case R.id.yes:
Toast.makeText(getContext(), "Yes", Toast.LENGTH_SHORT).show();
break;
case R.id.may:
Toast.makeText(getContext(), "May be", Toast.LENGTH_SHORT).show();
break;
case R.id.no:
Toast.makeText(getContext(), "No", Toast.LENGTH_SHORT).show();
break;
}
}
});
musicRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
switch (i) {
case R.id.yesMusic:
Toast.makeText(getContext(), "Yes", Toast.LENGTH_SHORT).show();
break;
case R.id.mayMusic:
Toast.makeText(getContext(), "May be", Toast.LENGTH_SHORT).show();
break;
case R.id.noMusic:
Toast.makeText(getContext(), "No", Toast.LENGTH_SHORT).show();
break;
}
}
});
decorRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
switch (i) {
case R.id.yesDecor:
Toast.makeText(getContext(), "Yes", Toast.LENGTH_SHORT).show();
break;
case R.id.mayDecor:
Toast.makeText(getContext(), "May be", Toast.LENGTH_SHORT).show();
break;
case R.id.noDecor:
Toast.makeText(getContext(), "No", Toast.LENGTH_SHORT).show();
break;
}
}
});
return view;
}
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
Toast.makeText(adapterView.getContext(), "" + adapterView.getItemAtPosition(i).toString(), Toast.LENGTH_SHORT).show();
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
private void updateValuesFromBundle(Bundle savedInstanceState) {
if (savedInstanceState != null) {
// Update the value of mRequestingLocationUpdates from the Bundle, and make sure that
// the Start Updates and Stop Updates buttons are correctly enabled or disabled.
if (savedInstanceState.keySet().contains(KEY_REQUESTING_LOCATION_UPDATES)) {
mRequestingLocationUpdates = savedInstanceState.getBoolean(
KEY_REQUESTING_LOCATION_UPDATES);
}
// Update the value of mCurrentLocation from the Bundle and update the UI to show the
// correct latitude and longitude.
if (savedInstanceState.keySet().contains(KEY_LOCATION)) {
// Since KEY_LOCATION was found in the Bundle, we can be sure that mCurrentLocation
// is not null.
mCurrentLocation = savedInstanceState.getParcelable(KEY_LOCATION);
}
// Update the value of mLastUpdateTime from the Bundle and update the UI.
if (savedInstanceState.keySet().contains(KEY_LAST_UPDATED_TIME_STRING)) {
mLastUpdateTime = savedInstanceState.getString(KEY_LAST_UPDATED_TIME_STRING);
}
updateUI();
}
}
protected synchronized void buildGoogleApiClient() {
Log.i(TAG, "Building GoogleApiClient");
mGoogleApiClient = new GoogleApiClient.Builder(getContext())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
protected void buildLocationSettingsRequest() {
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(mLocationRequest);
mLocationSettingsRequest = builder.build();
}
protected void checkLocationSettings() {
PendingResult<LocationSettingsResult> result =
LocationServices.SettingsApi.checkLocationSettings(
mGoogleApiClient,
mLocationSettingsRequest
);
result.setResultCallback(this);
}
#Override
public void onResult(LocationSettingsResult locationSettingsResult) {
final Status status = locationSettingsResult.getStatus();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
Log.i(TAG, "All location settings are satisfied.");
startLocationUpdates();
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
Log.i(TAG, "Location settings are not satisfied. Show the user a dialog to" +
"upgrade location settings ");
try {
// Show the dialog by calling startResolutionForResult(), and check the result
// in onActivityResult().
status.startResolutionForResult(getActivity(), REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException e) {
Log.i(TAG, "PendingIntent unable to execute request.");
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
Log.i(TAG, "Location settings are inadequate, and cannot be fixed here. Dialog " +
"not created.");
break;
}
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
// Check for the integer request code originally supplied to startResolutionForResult().
case REQUEST_CHECK_SETTINGS:
switch (resultCode) {
case Activity.RESULT_OK:
Log.i(TAG, "User agreed to make required location settings changes.");
startLocationUpdates();
break;
case Activity.RESULT_CANCELED:
Log.i(TAG, "User chose not to make required location settings changes.");
break;
}
break;
}
}
public void startUpdatesButtonHandler(View view) {
checkLocationSettings();
}
public void stopUpdatesButtonHandler(View view) {
// It is a good practice to remove location requests when the activity is in a paused or
// stopped state. Doing so helps battery performance and is especially
// recommended in applications that request frequent location updates.
stopLocationUpdates();
}
protected void startLocationUpdates() {
if (ActivityCompat.checkSelfPermission(getContext(), android.Manifest.permission.ACCESS_FINE_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;
}
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient,
mLocationRequest,
this
).setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
mRequestingLocationUpdates = true;
}
});
}
private void updateUI() {
updateLocationUI();
}
private void updateLocationUI() {
if (mCurrentLocation != null) {
mLatitudeText.setText(String.valueOf(mCurrentLocation.getLatitude()));
mLongitudeText.setText(String.valueOf(mCurrentLocation.getLongitude()));
}
}
#Override
public void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
#Override
public void onResume() {
super.onResume();
// Within {#code onPause()}, we pause location updates, but leave the
// connection to GoogleApiClient intact. Here, we resume receiving
// location updates if the user has requested them.
if (mGoogleApiClient.isConnected() && mRequestingLocationUpdates) {
startLocationUpdates();
}
}
#Override
public void onPause() {
super.onPause();
// Stop location updates to save battery, but don't disconnect the GoogleApiClient object.
if (mGoogleApiClient.isConnected()) {
stopLocationUpdates();
}
}
protected void stopLocationUpdates() {
// It is a good practice to remove location requests when the activity is in a paused or
// stopped state. Doing so helps battery performance and is especially
// recommended in applications that request frequent location updates.
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient,
this
).setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
mRequestingLocationUpdates = false;
}
});
}
#Override
public void onStop() {
super.onStop();
mGoogleApiClient.disconnect();
}
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
public void onConnected(#Nullable Bundle bundle) {
Log.i(TAG, "Connected to GoogleApiClient");
// If the initial location was never previously requested, we use
// FusedLocationApi.getLastLocation() to get it. If it was previously requested, we store
// its value in the Bundle and check for it in onCreate(). We
// do not request it again unless the user specifically requests location updates by pressing
// the Start Updates button.
//
// Because we cache the value of the initial location in the Bundle, it means that if the
// user launches the activity,
// moves to a new location, and then changes the device orientation, the original location
// is displayed as the activity is re-created.
if (mCurrentLocation == null) {
if (ActivityCompat.checkSelfPermission(getContext(), android.Manifest.permission.ACCESS_FINE_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;
}
mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
updateLocationUI();
}
}
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_ACCESS_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
updateLocationUI();
// 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
}
}
#Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "Connection suspended");
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + connectionResult.getErrorCode());
}
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
public void onLocationChanged(Location location) {
mCurrentLocation = location;
mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
updateLocationUI();
}
/**
* Stores activity data in the Bundle.
*/
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putBoolean(KEY_REQUESTING_LOCATION_UPDATES, mRequestingLocationUpdates);
savedInstanceState.putParcelable(KEY_LOCATION, mCurrentLocation);
savedInstanceState.putString(KEY_LAST_UPDATED_TIME_STRING, mLastUpdateTime);
super.onSaveInstanceState(savedInstanceState);
}
}
These are permissions which I have added in manifest file
<uses-permission android:name = "android.permission.INTERNET" />
<uses-permission android:name = "android.permission.ACCESS_FINE_LOCATION" />
This is the xml code for latitude and longitude
<TextView
android:id="#+id/myLatitude"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="15sp"
android:textColor="#color/cordinates_color"
/>
<TextView
android:id="#+id/myLongitude"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="15sp"
android:textColor="#color/cordinates_color"
/>
I have added this line in build.gradle app level and sync the project compile 'com.google.android.gms:play-services:10.0.1'
I have been able to connect to GoogleApiClient but coordinates are not coming up. This is a glimpse of logcat
01-29 14:49:31.395 10560-10560/com.example.luke.xyz I/EditInformation: Building GoogleApiClient
01-29 14:49:31.675 10560-10560/com.example.luke.xyz D/ViewRootImpl: #1 mView = android.widget.LinearLayout{2782c80 V.E...... ......I. 0,0-0,0}
01-29 14:49:31.715 10560-10616/com.example.luke.xyz D/mali_winsys: new_window_surface returns 0x3000, [468x91]-format:1
01-29 14:49:31.755 10560-10560/com.example.luke.xyz I/EditInformation: Connected to GoogleApiClient
01-29 14:49:31.805 10560-10616/com.example.luke.xyz V/RenderScript: 0xdc179000 Launching thread(s), CPUs 8
I am testing it on Android Marshmallow. Still unable to figure it out.
Can you help me out ?
Thank you
Ask run time permissions like this:
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.ACCESS_COURSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.ACCESS_COURSE_LOCATION)) {
// Show an explanation 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.
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.ACCESS_COURSE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
// MY_PERMISSIONS_REQUEST_LOCATION is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}
Then:
#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! 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
}
}
more details you can find it out here: https://developer.android.com/training/permissions/requesting.html
Use both the location Permission - ACCESS_COARSE_LOCATION , ACCESS_FINE_LOCATION, same time use Double for LatLng:
#Override
public void onConnected(#Nullable Bundle connectionHint) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ActivityCompat.checkSelfPermission
(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&&
ActivityCompat.checkSelfPermission
(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
{
requestPermissions(new String[]{
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION
}, 1);
return;
}
}
else{
Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if(mLastLocation!=null){
mLatitudeText.setText(Double.parseDouble(mLastLocation.getLatitude()));
mLongitudeText.setText(Double.parseDouble(mLastLocation.getLongitude()));
}else {
Toast.makeText(getContext(),"LOcation is null",Toast.LENGTH_SHORT).show();
}
}
}
Handle requested Permission:
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case 1:
if (grantResults[0] != PackageManager.PERMISSION_GRANTED){
Toast.makeText(getContext(),"PERMISSION_GRANTED",Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(getContext(),"PERMISSION_GRANTED",Toast.LENGTH_SHORT).show();
}
break;
}
}
Go to Settings > Apps > Your_app, and in the Permissions tab, enable Location for instantly getting the output on Marshmallow.
Your coding is fine you just need to add few more permission to your manifest file
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.LOCATION_HARDWARE"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
Make sure your gps is enabled. Let me know if this fix your problem.
You are currently only asking for the last known location in onConnected. If there is no cached location, this will do nothing.
You should override onLocationChanged to receive the current location once your Google API client is connected. https://developer.android.com/training/location/receive-location-updates.html#callback
The GoogleApiClient.connect method is asynchronous. In the documentation I linked above, the request for location updates is made after the GoogleApiClient connects. You are making this request in onResume, but you are not guaranteed that the GoogleApiClient is connected until onConnected. Make the request in onConnected, as the example in the documentation shows.
I am trying to get the current location, the code works most of the times. But location updates fail to work in a tunnel, despite the fact that mobile reception presents.
I have tried and traced through the following two methods:
Location NetLocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
Location GPSLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
Neither seems to update in the tunnel. I have cross checked with a few other apps and noticed that location service is working correctly in google map.
Whole function is linked here
So is there anyways I could get correct location updates in a tunnel?
Google has this new API called fusedLocationAPI, you could probably try using that. Here's the sample code -
public class YourActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener {
private GoogleApiClient mGoogleApiClient;
private Location mLastLocation;
private static final int LOCATION_PERMISSION_CODE = 42;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash_screen);
initGoogleApiClient();
}
#Override
public void onConnected(#Nullable Bundle bundle) {
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}, LOCATION_PERMISSION_CODE);
} else {
getLastKnownLocation();
}
}
#Override
public void onConnectionSuspended(int i) {
mGoogleApiClient.connect();
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == LOCATION_PERMISSION_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
getLastKnownLocation();
} else {
startLocationActivity();
}
}
}
private void getLastKnownLocation() {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
}
private void initGoogleApiClient() {
if (mGoogleApiClient == null) {
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();
mGoogleApiClient.disconnect();
}
}
This is just a higher-level overview of what could be done. The code could be further customized by adding location update intervals and so on. You could refer this site - https://developer.android.com/training/location/retrieve-current.html for further info.