I am using SDK-23, and every time I run the application, my SecurityException gets thrown and the error from the debugger reads as so:
java.lang.SecurityException: "gps" location provider requires
ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission.
This seems like a simple mistake, however, my manifest file is completely correct. Here it is, and here is my MapActivity code as well:
package com.buahbatu.salesmonitoring;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
final static String TAG = "MainActivity";
SwitchCompat switchTracked;
MyService service;
private GoogleMap googleMap;
Context mContext;
private TextView textAddress;
/* Google Fused Location Service */
public static GoogleApiClient mGoogleApiClient;
public static LocationRequest mLocationRequest;
public static GoogleApiClient.ConnectionCallbacks connectionCallbacks;
public static GoogleApiClient.OnConnectionFailedListener onConnectionFailedListener;
public final static int REQUEST_LOCATION = 199;
public final static int REQUEST_CONNECTION = 11;
public final static int NOTIFICATION_ID = 2;
private static final String[] INITIAL_PERMS={
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.READ_CONTACTS
};
private static final String[] LOCATION_PERMS={
Manifest.permission.ACCESS_FINE_LOCATION
};
boolean checkPermission() {
String location_fine = "android.permission.ACCESS_FINE_LOCATION";
String location_coarse = "android.permission.ACCESS_COARSE_LOCATION";
int permission_fine = mContext.checkCallingOrSelfPermission(location_fine);
int permission_coarse = mContext.checkCallingOrSelfPermission(location_coarse);
return permission_fine == PackageManager.PERMISSION_GRANTED && permission_coarse == PackageManager.PERMISSION_GRANTED;
}
public void startTracking(Activity activity) {
if (checkPermission()) {
Log.i(TAG, "startTracking");
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, (com.google.android.gms.location.LocationListener) this);
} else {
int permissionCheck = ContextCompat.checkSelfPermission(activity,
Manifest.permission.ACCESS_FINE_LOCATION);
}
}
#Override
protected void onDestroy() {
super.onDestroy();
try {
service.setUpdateView(null);
initilizeMap();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
checkLoggedStatus();
setSupportActionBar((Toolbar) findViewById(R.id.top_toolbar));
((TextView) findViewById(R.id.username_text)).setText(AppConfig.getUserName(this));
switchTracked = (SwitchCompat) findViewById(R.id.tracked_switch);
switchTracked.setOnCheckedChangeListener(onCheckedChangeListener);
switchTracked.setChecked(AppConfig.getOnTracked(this));
findViewById(R.id.test_but).setOnClickListener(this);
textAddress = (TextView) findViewById(R.id.txtAddress);
}
CompoundButton.OnCheckedChangeListener onCheckedChangeListener = new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (!isChecked) {
switchTracked.setText(R.string.untracked);
service.stopTracking();
AppConfig.saveOnTracked(MainActivity.this, false);
} else {
switchTracked.setText(R.string.tracked);
service = AcaciaX.createService(getApplicationContext(), MyService.class);
service.startTracking(MainActivity.this);
service.setUpdateView((TextView) findViewById(R.id.location_text));
AppConfig.saveOnTracked(MainActivity.this, true);
}
}
};
void checkLoggedStatus() {
if (!AppConfig.getLoginStatus(this)) {
moveToLogin();
}
}
void moveToLogin() {
Intent move = new Intent(this, LoginActivity.class);
startActivity(move);
finish();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.d(TAG, Integer.toString(resultCode));
//final LocationSettingsStates states = LocationSettingsStates.fromIntent(data);
switch (requestCode) {
case ServiceImpl.REQUEST_CONNECTION:
switch (resultCode) {
case Activity.RESULT_OK: {
switchTracked.setChecked(true);
break;
}
case Activity.RESULT_CANCELED: {
Toast.makeText(this, "Location not enabled, user cancelled.", Toast.LENGTH_LONG).show();
break;
}
default: {
break;
}
}
break;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_logout) {
AppConfig.saveLoginStatus(this, false);
AppConfig.storeAccount(this, "", "");
switchTracked.setChecked(false);
moveToLogin();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onClick(View v) {
NetHelper.login(MainActivity.this, "Tester", "pasu", new PostWebTask.HttpConnectionEvent() {
#Override
public void preEvent() {
}
#Override
public void postEvent(String... result) {
}
});
}
private void initilizeMap() {
if (googleMap == null) {
googleMap = ((MapFragment) getFragmentManager().findFragmentById(
R.id.map)).getMap();
setUpMap();
// check if map is created successfully or not
if (googleMap == null) {
Toast.makeText(getApplicationContext(),
"Sorry! unable to create maps", Toast.LENGTH_SHORT)
.show();
}
if (googleMap != null) {
//setUpMap();
}
}
}
#Override
protected void onResume() {
super.onResume();
initilizeMap();
//googleMap.setMyLocationEnabled(true);
setUpMap();
}
public void setUpMap() {
if(checkPermission()) {
googleMap.setMyLocationEnabled(true);
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
String provider = locationManager.getBestProvider(criteria, true);
Location location = locationManager.getLastKnownLocation(provider);
CameraUpdate center = CameraUpdateFactory.newLatLng(new LatLng(location.getLatitude(), location.getLongitude()));
CameraUpdate zoom = CameraUpdateFactory.zoomTo(15);
googleMap.moveCamera(center);
googleMap.animateCamera(zoom);
Geocoder geocoder;
List<Address> addresses;
geocoder = new Geocoder(this, Locale.getDefault());
try {
addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
if (addresses != null) {
String address = addresses.get(0).getAddressLine(0);
String city = addresses.get(0).getLocality();
String state = addresses.get(0).getAdminArea();
String country = addresses.get(0).getCountryName();
String postalCode = addresses.get(0).getPostalCode();
String knowName = addresses.get(0).getFeatureName();
String addressfull = address + " " + city + " " + state + " " + country + " " + postalCode + " " + knowName;
Intent intent = new Intent();
intent.putExtra("addressfull", addressfull);
textAddress.setText(addressfull);
}
} catch (IOException e) {
e.printStackTrace();
}
}else{
requestPermissions(INITIAL_PERMS, 2);
}
}
}
If you are targeting Android M, you need to ask users permission to access device GPS. Here is a not so clean code, but might help u a little bit. A better way to do it would be to create your own permission manager class to handle requests and a alertDialog ativity.
Whats happening below is
1) You are checking if permissions are granted.
2) If not, you are checking if the permissions have been denied previously, In that case, you are showing a rationale, to explain to the user why you need the permissions.
3) You show the request permission popup using ActivityCompat.
4) If user declines, show a snackbar with a view button to take the user to the app info screen, whenever u need to access the GPS but notice that permissions are not granted.
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_COARSE_LOCATION)) {
showRationale();
} else {
// do request the permission
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 8);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ){
//Start your code
} else {
//Show snackbar
}
}
}
private void showRationale(){
String strDeleteMessage = getResources().getString(R.string.rationale_message11) ;
final View dialogView = LayoutInflater.from(this.getActivity()).inflate(R.layout.dialog_fragment, null);
final AlertDialog storageRationaleAlert = new AlertDialog.Builder(this.getActivity()).create();
storageRationaleAlert.setView(dialogView, 0, 0, 0, 0);
storageRationaleAlert.setCanceledOnTouchOutside(false);
TextView mDialogTitle = (TextView) dialogView.findViewById(R.id.dialog_title);
TextView mDialogDetails = (TextView) dialogView.findViewById(R.id.dialog_details);
mDialogDetails.setVisibility(View.VISIBLE);
Button mCancelButton = (Button) dialogView.findViewById(R.id.cancel_btn);
Button mOkButton = (Button) dialogView.findViewById(R.id.ok_btn);
mOkButton.setText(getString(R.string.dialog_continue));
mDialogDetails.setText(Html.fromHtml(strDeleteMessage));
final Activity activity = this.getActivity();
mOkButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
storageRationaleAlert.dismiss();
//Ask for GPS permission
}
});
mCancelButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
storageRationaleAlert.dismiss();
//Show permission snackbar
}
});
storageRationaleAlert.show();
}
This is my code that works for me:
private void askForGeoPermissions(boolean _askGeo) throws InterruptedException {
if (_askGeo) {
for (int i = 0; i < 5; i++)
{
if (!String.valueOf(latitude).equals("0.0")) {
break;
}
new SdkTrackingLocationUtils().checkGeolocationPermissions(this.context, getCurrentActivity());
TimeUnit.SECONDS.sleep(2);
}
}
}
protected void checkGeolocationPermissions(Context context, Activity activity)
{
try
{
if (ContextCompat.checkSelfPermission(activity, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
&& ContextCompat.checkSelfPermission(activity, android.Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED)
{
getLocation(context);
}
else
{
ActivityCompat.requestPermissions(activity, new String[] {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION }, 1);
}
}
catch (Exception e)
{
Log.e("SDK_TRACKING_ERROR", e.getMessage());
}
}
#SuppressLint("MissingPermission")
protected Location getLocation(Context context)
{
try
{
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
// getting network status
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (isGPSEnabled == false && isNetworkEnabled == false)
{
Log.e("SDK_TRACKING_ERROR", "No network provider is enabled");
}
else
{
this.canGetLocation = true;
if (isNetworkEnabled)
{
location = null;
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("Network", "Network");
if (locationManager != null)
{
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null)
{
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
// if GPS Enabled get lat/long using GPS Services
if (isGPSEnabled)
{
location = null;
if (location == null)
{
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("GPS Enabled", "GPS Enabled");
if (locationManager != null)
{
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null)
{
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
return location;
}
Related
Iam creating an app in which I have to show user current location on map.
SO for this firstly the problem I was facing was when user login in the app if his location is turned off I asked for the permission for turn on the location and even after user give me the permission I still get null lat long in my get location function and I get the location after user restart the app. Iam getting permission in splash so for this restart issue what I have done is in splash Iam restarting the activity in onActivityResult like this :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
displayLocationSettingsRequest();
}
private void displayLocationSettingsRequest() {
GoogleApiClient googleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API).build();
googleApiClient.connect();
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(10000);
locationRequest.setFastestInterval(10000 / 2);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(locationRequest);
builder.setAlwaysShow(true);
PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
#Override
public void onResult(LocationSettingsResult result) {
final Status status = result.getStatus();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
startActivity(new Intent(getApplicationContext(), LoginActivity.class));
finish();
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
try {
status.startResolutionForResult(SplashActivity.this, 7);
} catch (IntentSender.SendIntentException e) {
Toast.makeText(SplashActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
Toast.makeText(SplashActivity.this, "Location settings are inadequate, and cannot be fixed here. Dialog not created.", Toast.LENGTH_SHORT).show();
break;
}
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 7 && resultCode == RESULT_OK && data != null) {
finish();
overridePendingTransition(0, 0);
startActivity(getIntent());
overridePendingTransition(0, 0);
Toast.makeText(this, "entering", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "To continue please give permission for location", Toast.LENGTH_LONG).show();
displayLocationSettingsRequest();
}
}
#Override
protected void onRestart() {
super.onRestart();
if (ConnectivityReceiver.isNetworkConnected(this)) {
displayLocationSettingsRequest();
} else {
HelperClass.openAlertDialog(SplashActivity.this, Constants.alert, Constants.No_Internet_Msg, Constants.try_again, Constants.Dialog_cancel, this);
}
}
}
this method worked for some time but after 1 day Iam still getting the same issue and now I'm getting an extra edge case that if app is over wifi and I get the dialog to give location permission then every time I will get the same dialog even after restarting the app and giving permission and this issue will resolve after I turn my mobile data on run the app on mobile data one time and then get back to wifi again.
This is my Location class :
public class LocationUtil implements LocationListener {
private final Context mContext;
// flag for GPS status
private boolean isGPSEnabled = false;
// flag for network status
private boolean isNetworkEnabled = false;
// flag for GPS status
private boolean canGetLocation = false;
private Location location; // location
private double latitude; // latitude
private double longitude; // longitude
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
private static final long MIN_TIME_BW_UPDATES = 1000 * 60; // 1 minute
private android.location.LocationManager locationManager;
public LocationUtil() {
this.mContext = null;
}
public LocationUtil(Context context) {
this.mContext = context;
getLocation();
}
public Location getLocation() {
try {
locationManager = (android.location.LocationManager) mContext.getSystemService(LOCATION_SERVICE);
if (locationManager != null) {
isGPSEnabled = locationManager.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER);
}
if (locationManager != null) {
isNetworkEnabled = locationManager.isProviderEnabled(android.location.LocationManager.NETWORK_PROVIDER);
}
if (isGPSEnabled || isNetworkEnabled) {
this.canGetLocation = true;
if (isNetworkEnabled) {
if (ActivityCompat.checkSelfPermission(this.mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this.mContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
}
locationManager.requestLocationUpdates(android.location.LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("Network", "Network");
if (locationManager != null) {
location = locationManager.getLastKnownLocation(android.location.LocationManager.NETWORK_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude() ;
}
}
}
if (isGPSEnabled) {
if (location == null) {
if (locationManager != null) {
locationManager.requestLocationUpdates(android.location.LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
}
if (locationManager != null) {
location = locationManager.getLastKnownLocation(android.location.LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude() ;
longitude = location.getLongitude() ;
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
stopUsingGPS();
return location;
}
private void stopUsingGPS() {
if (locationManager != null) {
locationManager.removeUpdates(LocationUtil.this);
}
}
public double getLatitude() {
if (location != null) {
latitude = location.getLatitude();
}
return latitude;
}
public double getLongitude() {
if (location != null) {
longitude = location.getLongitude();
}
return longitude;
}
public boolean canGetLocation() {
return this.canGetLocation;
}
#Override
public void onLocationChanged(Location location) {
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude() ;
}
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
public static boolean getLocationMode(Context context) {
try {
return Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE) == 3;
} catch (Settings.SettingNotFoundException e) {
e.printStackTrace();
}
return false;
}
}
And here in my MainActivity Iam getting location :
protected void setupLocation() {
if (locManager == null)
locManager = new LocationUtil(MainActivity.this);
if (locManager.getLocation() != null) {
locationHelper = new LocationHelper(locManager.getLocation().getLatitude(), locManager.getLocation().getLongitude());
latitude = locationHelper.getLatitude();
longitude = locationHelper.getLongitude();
} else {
Toast.makeText(getApplicationContext(), "Please accept location improvement dialog or restart the application!", Toast.LENGTH_LONG).show();
startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
}
}
NOTE : Iam getting the lat long but the issue is coming in permission if before running the app location is off and I turn on the app it will give me null and I have to restart the app .
Hi in the below code am setting current location to my application.If it is turn on the location by manually it was showing current location.
If am not turn it on it was showing nothing in my map.
But i want to display the permission to turn on location and have written the code but it is not working .
can any one please help to resolve this issue.
MapsActivity.java:
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
private static final int LOCATION_REQUESTOR = 101;
#Bind(R.id.back)
TextView mBack;
#Bind(R.id.location)
TextView mLocation;
#Bind(R.id.toolBar)
Toolbar mToolBar;
#Bind(R.id.map_address)
TextView mMapAddress;
#Bind(R.id.latitude)
EditText mLatitude;
#Bind(R.id.longitude)
EditText mLongitude;
#Bind(R.id.setLocation)
Button mSetLocation;
private Location mLastLocation;
private GoogleMap mMap;
Marker mCurrLocationMarker;
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
private SharedPreferences mPref;
private SolarBLEPacket mSolarController = new SolarBLEPacket();
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
ButterKnife.bind(this);
mPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
final SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
#Override
public void onConnected(#Nullable Bundle bundle) {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(1000);
mLocationRequest.setFastestInterval(1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
#Override
public void onLocationChanged(Location location) {
mLastLocation = location;
if (mCurrLocationMarker != null) {
mCurrLocationMarker.remove();
}
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("Current Position");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
mCurrLocationMarker = mMap.addMarker(markerOptions);
//move map camera
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng,11));
mLongitude.setText(latLng.longitude + "");
mLatitude.setText(latLng.latitude + "");
}
#Override
public void onMapReady(GoogleMap googleMap)
{
mMap=googleMap;
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
//Initialize Google Play Services
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
//Location Permission already granted
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
} else {
//Request Location Permission
checkLocationPermission();
}
}
else {
buildGoogleApiClient();
mMap.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 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.
new AlertDialog.Builder(this)
.setTitle(R.string.title_location_permission)
.setMessage(R.string.text_location_permission)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
//Prompt the user once explanation has been shown
ActivityCompat.requestPermissions(MapsActivity.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
}
})
.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);
}
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! Do the
// location-related task you need to do.
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
//Request location updates:
//.requestLocationUpdates(provider, 400, 1, this);
}
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
}
}
#OnClick(R.id.setLocation)
public void onClick() {
Intent intent = new Intent();
String longtitude = mLongitude.getText().toString();
if (!TextUtils.isEmpty(longtitude)) {
intent.putExtra(Constants.LONGITUDE, longtitude);
} else {
Toast.makeText(this, R.string.please_enter_longitude, Toast.LENGTH_SHORT).show();
return;
}
String latitude = mLatitude.getText().toString();
if (!TextUtils.isEmpty(latitude)) {
intent.putExtra(Constants.LATITUDE, latitude);
} else {
Toast.makeText(this, R.string.please_enter_latitude, Toast.LENGTH_SHORT).show();
return;
}
String latCommand = mSolarController.generatePacket("lat " +latitude,"00");
String longitudeCmd = mSolarController.generatePacket("lon "+longtitude,"00");
mPref.edit().putString(Constants.LAT_COMMAND,latCommand).commit();
mPref.edit().putString(Constants.LONG_COMMAND,longitudeCmd).commit();
mPref.edit().putString(Constants.LAST_LATITUDE,latitude).commit();
mPref.edit().putString(Constants.LAST_LONGITUDE,latitude).commit();
setResult(RESULT_OK, intent);
finish();
}
#OnClick({R.id.back, R.id.location})
public void onClick(View view) {
switch (view.getId()) {
case R.id.back:
setResult(RESULT_OK, new Intent());
finish();
break;
case R.id.location:
Intent intent = new Intent();
String longtitude = mLongitude.getText().toString();
if (!TextUtils.isEmpty(longtitude)) {
intent.putExtra(Constants.LONGITUDE, longtitude);
} else {
Toast.makeText(this, R.string.please_enter_longitude, Toast.LENGTH_SHORT).show();
return;
}
String latitude = mLatitude.getText().toString();
if (!TextUtils.isEmpty(latitude)) {
intent.putExtra(Constants.LATITUDE, latitude);
} else {
Toast.makeText(this, R.string.please_enter_latitude, Toast.LENGTH_SHORT).show();
return;
}
Float lat = Float.parseFloat(latitude);
if (lat > 90 || lat < -90) {
Toast.makeText(this, R.string.longitude_alert, Toast.LENGTH_SHORT).show();
return;
}
float lan = Float.parseFloat(longtitude);
if (lan > 180 || lan < -180) {
Toast.makeText(this, R.string.latitude_alert, Toast.LENGTH_SHORT).show();
return;
}
String latCommand = mSolarController.generatePacket("lat "+latitude,"00");
String longitudeCmd = mSolarController.generatePacket("long "+longtitude,"00");
mPref.edit().putString(Constants.LAT_COMMAND,latCommand).commit();
mPref.edit().putString(Constants.LONG_COMMAND,longitudeCmd).commit();
mPref.edit().putString(Constants.LAST_LATITUDE,latitude).commit();
mPref.edit().putString(Constants.LAST_LONGITUDE,latitude).commit();
setResult(RESULT_OK, intent);
finish();
break;
}
}
}
You are just checking the permission, You need to check whether is location is enable of the device or not.
LocationManager lm = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
boolean gps_enabled = false;
boolean network_enabled = false;
try {
gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
} catch(Exception ex) {}
try {
network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
} catch(Exception ex) {}
if(!gps_enabled && !network_enabled) {
// notify user
AlertDialog.Builder dialog = new AlertDialog.Builder(context);
dialog.setMessage(context.getResources().getString(R.string.gps_network_not_enabled));
dialog.setPositiveButton(context.getResources().getString(R.string.open_location_settings), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
// TODO Auto-generated method stub
Intent myIntent = new Intent( Settings.ACTION_LOCATION_SOURCE_SETTINGS);
context.startActivity(myIntent);
//get gps
}
});
dialog.setNegativeButton(context.getString(R.string.Cancel), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
// TODO Auto-generated method stub
}
});
dialog.show();
}
I am trying to get current location using FusedLocationAPI in my application. It works just fine in both android API>23 and <23. The issue is in case of GPS is not enabled, the app prompts the user to enable the GPS and after that the location returns null. But while restarting the app, it works just fine. In case of GPS not being turned OFF, the app just works fine. Is there any way that the app can wait for the GPS to be enabled before getting the location? below I am posting my code. Please have a look.
Inside onCreate():
manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
statusOfGPS = manager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (!statusOfGPS) {
displayPromptForEnablingGPS(this);
}
Log.d("permipart", "before");
if(CheckingPermissionIsEnabledOrNot())
{
Toast.makeText(MainActivity.this, "All Permissions Granted Successfully", Toast.LENGTH_LONG).show();
}
else {
RequestMultiplePermission();
}
if(Build.VERSION.SDK_INT<= 23)
{
buildGoogleApiClient();
if (!mGoogleApiClient.isConnected()) {
mGoogleApiClient.connect();
}
}
Log.d("permipart", "out");
Other methods:
#Override
public void onLocationChanged(Location location) {
Log.d("onconnectedlocchange","called");
if (location != null) {
lat = location.getLatitude();
lon = location.getLongitude();
if (!String.valueOf(lat).equals("0.0"))
{
latitudeVal = location.getLatitude();
longitudeVal = location.getLongitude();
Log.e("Lat and Lng", String.valueOf(latitudeVal) + longitudeVal);
}
}
}
#Override
public void onConnected(#Nullable Bundle bundle) {
if(CheckingPermissionIsEnabledOrNot())
{
Toast.makeText(MainActivity.this, "All Permissions Granted Successfully", Toast.LENGTH_LONG).show();
}
// If, If permission is not enabled then else condition will execute.
else {
//Calling method to enable permission.
RequestMultiplePermission();
}
Log.d("onconnected","called");
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
// Update location every second
if (ActivityCompat.checkSelfPermission(this, ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
}
else
{
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
if (mLastLocation != null) {
lat = mLastLocation.getLatitude();
lon = mLastLocation.getLongitude();
if (!String.valueOf(lat).equals("0.0")){
latitudeVal = mLastLocation.getLatitude();
longitudeVal = mLastLocation.getLongitude();
Log.e("Lat and Lng", String.valueOf(latitudeVal)+ longitudeVal);
}
}
}
}
#Override
public void onConnectionSuspended(int i) {
}
synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
public void displayPromptForEnablingGPS(final Activity activity) {
final android.support.v7.app.AlertDialog.Builder builder = new android.support.v7.app.AlertDialog.Builder(activity);
final String action = Settings.ACTION_LOCATION_SOURCE_SETTINGS;
final String message = "Do you want open GPS setting?";
builder.setMessage(message)
.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface d, int id) {
activity.startActivity(new Intent(action));
d.dismiss();
}
})
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface d, int id) {
d.cancel();
}
});
builder.create().show();
}
String[] permissions = new String[]{ACCESS_FINE_LOCATION,
ACCESS_COARSE_LOCATION, READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE };
//Permission function starts from here
private void RequestMultiplePermission() {
// Creating String Array with Permissions.
Log.d("permipart", "RequestMultiplePermission");
ActivityCompat.requestPermissions(MainActivity.this, new String[]
{
READ_EXTERNAL_STORAGE,
WRITE_EXTERNAL_STORAGE,
ACCESS_FINE_LOCATION,
ACCESS_COARSE_LOCATION
}, RequestPermissionCode);
}
private boolean checkPermission() {
int result;
List<String> listPermissionsNeeded = new ArrayList<>();
for (String p:permissions) {
result = ContextCompat.checkSelfPermission(this,p);
if (result != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(p);
}
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]),10 );
Log.d("permissionissue","no");
return false;
}
Log.d("permissionissue","yes");
return true;
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
Log.d("permipart", "onRequestPermissionsResult");
switch (requestCode) {
case RequestPermissionCode:
if (grantResults.length > 0) {
boolean CameraPermission = grantResults[0] == PackageManager.PERMISSION_GRANTED;
boolean RecordAudioPermission = grantResults[1] == PackageManager.PERMISSION_GRANTED;
boolean SendSMSPermission = grantResults[2] == PackageManager.PERMISSION_GRANTED;
boolean GetAccountsPermission = grantResults[3] == PackageManager.PERMISSION_GRANTED;
if (CameraPermission && RecordAudioPermission && SendSMSPermission && GetAccountsPermission) {
Log.d("permipart", "done");
buildGoogleApiClient();
Toast.makeText(MainActivity.this, "Permission Granted", Toast.LENGTH_LONG).show();
if (!mGoogleApiClient.isConnected()) {
mGoogleApiClient.connect();
}
}
else {
Toast.makeText(MainActivity.this,"Permission Denied",Toast.LENGTH_LONG).show();
}
}
break;
}
}
/**
* Checking permission is enabled or not using function starts from here.
*
*/
public boolean CheckingPermissionIsEnabledOrNot() {
int FirstPermissionResult = ContextCompat.checkSelfPermission(getApplicationContext(), READ_EXTERNAL_STORAGE);
int SecondPermissionResult = ContextCompat.checkSelfPermission(getApplicationContext(), WRITE_EXTERNAL_STORAGE);
int ThirdPermissionResult = ContextCompat.checkSelfPermission(getApplicationContext(), ACCESS_FINE_LOCATION);
int ForthPermissionResult = ContextCompat.checkSelfPermission(getApplicationContext(), ACCESS_COARSE_LOCATION);
return FirstPermissionResult == PackageManager.PERMISSION_GRANTED &&
SecondPermissionResult == PackageManager.PERMISSION_GRANTED &&
ThirdPermissionResult == PackageManager.PERMISSION_GRANTED &&
ForthPermissionResult == PackageManager.PERMISSION_GRANTED ;
}
You need to recieve the broadcast of the GPS status something like this:
public class GpsLocationReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().matches("android.location.PROVIDERS_CHANGED")) {
// here you can get the location or start a service to get it.
// example
// Intent getLocationService = new Intent(context,YourService.class);
// context.startService(getLocationService);
}
}
}
update
according to comment below
use this in your code
manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if(manager.isProviderEnabled( LocationManager.GPS_PROVIDER)){
// it is enabled
}else{
// it is not
}
Use my code, it will ask the user to turn on GPS if it is turned off. It will never return you anything until GPS turned on.
Note: you have to get location permission before using it for marshmallow and above mobiles.
Try this:
#SuppressWarnings("MissingPermission")
public class LocationFinder implements LocationListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
public static final String TAG = "LocationFinder";
private static final String BROADCAST_GPS_REQ = "LocationFinder.GPS_REQ";
private static final String KEY_GPS_REQ = "key.gps.req";
private static final int GPS_REQUEST = 2301;
private Activity activity;
private FinderType finderType;
private GoogleApiClient googleApiClient;
private LocationRequest locationRequest;
private long updateInterval;
private long fastestInterval;
private GpsRequestListener gpsRequestListener;
private LocationUpdateListener locationUpdateListener;
public LocationFinder(Activity activity, FinderType finderType) {
this.activity = activity;
this.finderType = finderType;
}
private void connectGoogleApiClient() {
googleApiClient = new GoogleApiClient.Builder(activity)
.addApi(LocationServices.API).addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
googleApiClient.connect();
}
private void createLocationRequest() {
locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(updateInterval);
locationRequest.setFastestInterval(fastestInterval);
}
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
int intExtra = intent.getIntExtra(KEY_GPS_REQ, 0);
switch (intExtra) {
case Activity.RESULT_OK:
try {
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, LocationFinder.this);
} catch (Exception e) {
e.printStackTrace();
}
gpsRequestListener.gpsTurnedOn();
break;
case Activity.RESULT_CANCELED:
gpsRequestListener.gpsNotTurnedOn();
}
}
};
public void gpsRequestCallback(GpsRequestListener gpsRequestListener) {
this.gpsRequestListener = gpsRequestListener;
LocalBroadcastManager.getInstance(activity).registerReceiver(receiver, new IntentFilter(BROADCAST_GPS_REQ));
}
public void config(long updateInterval, long fastestInterval) {
this.updateInterval = updateInterval;
this.fastestInterval = fastestInterval;
}
public void find(LocationUpdateListener listener) {
this.locationUpdateListener = listener;
createLocationRequest();
connectGoogleApiClient();
}
private void find() {
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest);
builder.setAlwaysShow(true);
PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
#Override
public void onResult(#NonNull LocationSettingsResult locationSettingsResult) {
Status status = locationSettingsResult.getStatus();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, LocationFinder.this);
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
try {
status.startResolutionForResult(activity, GPS_REQUEST);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
Log.d(TAG, "No GPS Hardware");
break;
}
}
});
}
public void stopFinder() {
if (googleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, this);
googleApiClient.disconnect();
}
try {
activity.unregisterReceiver(receiver);
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onConnected(#Nullable Bundle bundle) {
Log.d(TAG, "GoogleApiClient: Connected");
find();
}
#Override
public void onConnectionSuspended(int i) {
Log.d(TAG, "GoogleApiClient: onConnectionSuspended");
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Log.d(TAG, "GoogleApiClient: onConnectionFailed");
}
#Override
public void onLocationChanged(Location location) {
if (finderType != FinderType.TRACK)
stopFinder();
locationUpdateListener.onLocationUpdate(new LatLng(location.getLatitude(), location.getLongitude()));
}
public void setGpsRequestListener(GpsRequestListener gpsRequestListener) {
this.gpsRequestListener = gpsRequestListener;
}
public static void onRequestResult(Activity activity, int requestCode, int resultCode) {
if (requestCode == GPS_REQUEST) {
Intent intent = new Intent(BROADCAST_GPS_REQ);
intent.putExtra(KEY_GPS_REQ, resultCode);
LocalBroadcastManager.getInstance(activity).sendBroadcast(intent);
}
}
public enum FinderType {
// It will update the current GPS location once.
GPS,
//It will update the user location continuously.
TRACK
}
public interface LocationUpdateListener {
void onLocationUpdate(LatLng latLng);
}
public interface GpsRequestListener {
void gpsTurnedOn();
void gpsNotTurnedOn();
}
}
To get location update initialize the class like this:
public class MyActivity extends AppCompatActivity implements
LocationFinder.GpsRequestListener,
LocationFinder.LocationUpdateListener {
private LocationFinder locationUpdater;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
locationUpdater = new LocationFinder(this, LocationFinder.FinderType.TRACK);
driverLocationUpdater.gpsRequestCallback(this);
driverLocationUpdater.config(5000, 5000);
driverLocationUpdater.find(this);
}
#Override
protected void onDestroy(){
super.onDestroy()
driverLocationUpdater.stopFinder();
}
#Override
public void onLocationUpdate(LatLng latLng) {
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
LocationFinder.onRequestResult(this, requestCode, resultCode);
}
}
In my app I want to fetch Latitude, Longitude and current Location name and pass this value in the database. The app is running perfectly in Tab. But in case of other device getLastKnownLocation() returns null. For this reason I am facing nullpointerexception.
private Location getLastKnownLocation() {
locationmanager = (LocationManager) getApplicationContext().getSystemService(LOCATION_SERVICE);
List<String> providers = locationmanager.getProviders(true);
Location bestLocation = null;
for (String provider : providers) {
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 null;
}
Location l = locationmanager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
if (l == null) {
continue;
}
if (bestLocation == null || l.getAccuracy() < bestLocation.getAccuracy()) {
// Found best last known location: %s", l);
bestLocation = l;
}
}
return bestLocation;
}
Please help me to solve this. I know this issue is asked before. But I have tried most of them. Still I am facing the nullpointerexception in the same place(while fetching lat long value).
10-13 15:54:12.825 16095-16095/com.example.ivdisplays.vehereapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.ivdisplays.vehereapp, PID: 16095
java.lang.NullPointerException
at com.example.ivdisplays.vehereapp.MainActivity$1.onClick(MainActivity.java:117)
at android.view.View.performClick(View.java:4463)
at android.view.View$PerformClick.run(View.java:18792)
at android.os.Handler.handleCallback(Handler.java:808)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5344)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:676)
at dalvik.system.NativeStart.main(Native Method)
public class MainActivity extends AppCompatActivity implements NetworkCallback,
LocationListener {
private EditText empIdTxt;
private EditText passwordTxt;
private TextView tv_lat;
private TextView tv_long;
private TextView tv_place;
private Button loginBtn;
private Button logoutBtn;
LocationManager locationmanager;
GPSTracker gps;
String cityName = "";
Context context;
static String loginDate;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
empIdTxt = (EditText) findViewById(R.id.et_loginId);
passwordTxt = (EditText) findViewById(R.id.et_loginPass);
loginBtn = (Button) findViewById(R.id.bt_login);
logoutBtn= (Button) findViewById(R.id.bt_logout);
empIdTxt.addTextChangedListener(new MyTextWatcher(empIdTxt));
passwordTxt.addTextChangedListener(new MyTextWatcher(passwordTxt));
empIdTxt.setText("vinay");
passwordTxt.setText("qwerty");
context=MainActivity.this;
final Location location = getLastKnownLocation();
if (location != null) {
onLocationChanged(location);
} else {
Toast.makeText(getApplicationContext(), "location not found", Toast.LENGTH_LONG).show();
System.out.println("Output of Location is:" + getLastKnownLocation());
}
loginDate = AlertDialogManager.todayDate();
loginBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!validateEmpID()) {
return;
}
if (!validatePassword()) {
return;
}
LoginApi api = new LoginApi(context, (NetworkCallback) context);
System.out.println("Output of LoginAPI:" +"username" +empIdTxt.getText().toString()
+"password"+passwordTxt.getText().toString()+"Lat"+location.getLatitude()+"Long"+location.getLongitude()
+"Date"+loginDate+"Locality"+new GPSTracker(MainActivity.this).getLocality(location));
api.processLogin(empIdTxt.getText().toString(), passwordTxt.getText().toString(),
location.getLatitude()+"",location.getLongitude()+"",loginDate,
new GPSTracker(MainActivity.this).getLocality(location),"123456");
loginBtn.setVisibility(View.GONE);
logoutBtn.setVisibility(View.VISIBLE);
}
});
logoutBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
LogoutApi api = new LogoutApi(context, (NetworkCallback) context);
System.out.println("Output of LogoutAPI:" +"userid " +AppDelegate.getInstance().uid
+"Lat"+location.getLatitude()+"Long"+location.getLongitude()
+"Date"+AlertDialogManager.todayDate()+"Locality"+new GPSTracker(MainActivity.this).getLocality(location));
api.processLogout(AppDelegate.getInstance().uid,
location.getLatitude()+"",location.getLongitude()+"",AlertDialogManager.todayDate(),
new GPSTracker(MainActivity.this).getLocality(location),"123456","");
logoutBtn.setVisibility(View.GONE);
loginBtn.setVisibility(View.VISIBLE);
}
});
}
private Location getLastKnownLocation() {
locationmanager = (LocationManager) getApplicationContext().getSystemService(LOCATION_SERVICE);
List<String> providers = locationmanager.getProviders(true);
Location bestLocation = null;
for (String provider : providers) {
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 null;
}
Location l = locationmanager.getLastKnownLocation(provider);
if (l == null) {
continue;
}
if (bestLocation == null || l.getAccuracy() < bestLocation.getAccuracy()) {
// Found best last known location: %s", l);
bestLocation = l;
}
}
return bestLocation;
}
private void requestFocus(View view) {
if (view.requestFocus()) {
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
}
}
private boolean validateEmpID() {
if (empIdTxt.getText().toString().trim().isEmpty()) {
empIdTxt.setError(ErrorUtil.USERNAME_ERROR);
requestFocus(empIdTxt);
return false;
}
return true;
}
private boolean validatePassword() {
if (passwordTxt.getText().toString().trim().isEmpty()) {
passwordTxt.setError(ErrorUtil.PASSWORD_ERROR);
requestFocus(passwordTxt);
return false;
}
return true;
}
private class MyTextWatcher implements TextWatcher {
private View view;
private MyTextWatcher(View view) {
this.view = view;
}
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
public void afterTextChanged(Editable editable) {
switch (view.getId()) {
case R.id.et_loginId:
validateEmpID();
break;
case R.id.et_loginPass:
validatePassword();
break;
}
}
}
#Override
public void updateScreen(String data, String tag) {
if (tag.compareTo(ApiUtil.TAG_LOGIN) == 0) {
try {
System.out.println("Login Response"+data);
JSONObject mainObj = new JSONObject(data);
AppDelegate ctrl = AppDelegate.getInstance();
if (!mainObj.isNull("user_id")) {
ctrl.uid = mainObj.getString("user_id");
}
if (!mainObj.isNull("error")) {
Toast.makeText(MainActivity.this,"Login Fails",Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this,"Login Success",Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
Toast.makeText(MainActivity.this,"Seems there is an issue please try again later",Toast.LENGTH_SHORT).show();
}
}
if (tag.compareTo(ApiUtil.TAG_LOGOUT) == 0) {
try {
System.out.println("Logout Response"+data);
JSONObject mainObj = new JSONObject(data);
AppDelegate ctrl = AppDelegate.getInstance();
if (!mainObj.isNull("message")) {
Toast.makeText(MainActivity.this,"Logout Success",Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this,"Logout Fails",Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
Toast.makeText(MainActivity.this,"Seems there is an issue please try again later",Toast.LENGTH_SHORT).show();
}
}
}
#Override
public void onLocationChanged(Location location) {
double latitude,longitude;
tv_lat = (TextView) findViewById(R.id.tv_lat);
tv_long = (TextView) findViewById(R.id.tv_long);
tv_place = (TextView) findViewById(R.id.tv_place);
latitude=location.getLatitude();
longitude=location.getLongitude();
tv_lat.setText("Latitude : "+latitude);
tv_long.setText("Longitude : "+ longitude);
// create class object
gps = new GPSTracker(MainActivity.this);
// check if GPS enabled
if (gps.canGetLocation()) {
Geocoder geocoder = new Geocoder(MainActivity.this, Locale.getDefault());
List<Address> addresses;
try {
addresses = geocoder.getFromLocation(latitude,
longitude, 1);
System.out.println("Output of Address" + addresses);
cityName = addresses.get(0).getAddressLine(0);
System.out.println("Cityname is" + cityName);
tv_place.setText("Place : "+cityName);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
gps.showSettingsAlert();
}
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
#Override
public void onProviderEnabled(String s) {
}
#Override
public void onProviderDisabled(String s) {
}
}
I think the problem is about checking permissions and && != operands. Handle it more carefully.
Try this:
private Location getLastKnownLocation() {
locationmanager = (LocationManager) getApplicationContext().getSystemService(LOCATION_SERVICE);
boolean permissionsActivated = canAll();
if (!permissionsActivated)
return null;
List<String> providers = locationmanager.getProviders(true);
Location bestLocation = null;
for (String provider : providers) {
Location l = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);// this may lead to 'null' value if not permissions
if (l == null) {
continue;
}
if (bestLocation == null || l.getAccuracy() < bestLocation.getAccuracy()) {
// Found best last known location: %s", l);
bestLocation = l;
}
}
return bestLocation;
}
private boolean canAll() {
// TODO Auto-generated method stub
return (canAccessLocation() && canCoarseLocation());
}
private boolean canAccessLocation() {
return hasPermission(android.Manifest.permission.ACCESS_FINE_LOCATION);
}
private boolean canCoarseLocation() {
return hasPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION);
}
#SuppressLint("NewApi")
private boolean hasPermission(String perm) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return (PackageManager.PERMISSION_GRANTED == checkSelfPermission(perm));
} else {
return true;
}
}
Do not forget:
getLastKnownLocation may return a null value if the application has not detected any location.
You can use GoogleApiClient's fused location provider for fetching location. You need to add a dependency in your gradle file. i.e
compile 'com.google.android.gms:play-services-location:9.6.1'
Add fine_location permission needed in manifest
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
It is a Dangerous Permission you need to ask permission at runtime like this.
Code Snippet
public class DashboardActivity extends AppCompatActivity implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener,
ResultCallback<LocationSettingsResult> {
private GoogleApiClient googleApiClient;
private GoogleApiAvailability apiAvailability;
private static final long MIN_TIME_BW_UPDATES = 10000;
private static final long FAST_TIME_BW_UPDATES = 3000;
private final static int REQUEST_CHECK_SETTINGS = 100;
private static final long EXPIRATION_DURATION = 3600000;
protected LocationRequest mLocationRequest;
protected LocationSettingsRequest mLocationSettingsRequest;
private Location location;
private LatLng latLng = new LatLng(0, 0);
private double latitude;
private double longitude;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dashboard);
init();
}
private void init() {
apiAvailability = GoogleApiAvailability.getInstance();
if (googleApiAvaibility()) {
buildGoogleApiClient();
displayLocation();
}
}
protected void createLocationRequest() {
mLocationRequest = LocationRequest.create();
mLocationRequest.setInterval(MIN_TIME_BW_UPDATES);
mLocationRequest.setFastestInterval(FAST_TIME_BW_UPDATES);
mLocationRequest.setSmallestDisplacement(10);
mLocationRequest.setExpirationDuration(EXPIRATION_DURATION);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(mLocationRequest);
builder.setAlwaysShow(true);
mLocationSettingsRequest = builder.build();
}
protected synchronized void buildGoogleApiClient() {
googleApiClient = new GoogleApiClient.Builder(getApplicationContext())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
private boolean googleApiAvaibility() {
int resultCode = apiAvailability.isGooglePlayServicesAvailable(this);
switch (resultCode) {
case ConnectionResult.SUCCESS:
return true;
case ConnectionResult.API_UNAVAILABLE:
Dialog dialog = apiAvailability.getErrorDialog(this, ConnectionResult.API_UNAVAILABLE, 200,
new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
//finish();
}
});
dialog.show();
break;
case ConnectionResult.SERVICE_MISSING:
Dialog dialog1 = apiAvailability.getErrorDialog(this, ConnectionResult.SERVICE_MISSING, 201,
new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
//finish();
}
});
dialog1.show();
break;
}
return false;
}
#Override
public void onLocationChanged(Location location) {
latLng = new LatLng(location.getLatitude(), location.getLongitude());
//here you will get new latitude and longitude if location is changed
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQUEST_CHECK_SETTINGS:
switch (resultCode) {
case Activity.RESULT_OK:
displayLocation();
break;
case Activity.RESULT_CANCELED:
//finish();
Toast.makeText(getActivity(), "Please enable location. Otherwise you can not use this application", Toast.LENGTH_LONG).show();
break;
}
break;
default:
break;
}
}
#Override
public void onConnected(#Nullable Bundle bundle) {
createLocationRequest();
checkLocationSettings();
}
#Override
public void onConnectionSuspended(int i) {
googleApiClient.connect();
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
googleApiClient.connect();
}
#Override
public void onResult(#NonNull LocationSettingsResult result) {
Status status = result.getStatus();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
displayLocation();
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
try {
status.startResolutionForResult(this, REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException e) {
Log.e("Exception", e.toString());
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
//showDialog(this,"You have choose never for Location!");
break;
default:
break;
}
}
protected void checkLocationSettings() {
PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.
checkLocationSettings(googleApiClient, mLocationSettingsRequest);
result.setResultCallback(this);
}
private void displayLocation() {
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 250);
} else {
location = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
if (location != null) {
latLng = new LatLng(location.getLatitude(), location.getLongitude());
latitude = location.getLatitude();
longitude = location.getLongitude();
//print latitude longitude here
} else {
if (googleApiAvaibility()) {
buildGoogleApiClient();
googleApiClient.connect();
if (googleApiClient.isConnected()) {
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, mLocationRequest, this);
}
}
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (permissions[0].equals(Manifest.permission.ACCESS_FINE_LOCATION)) {
if (location != null) {
displayLocation();
} else {
//googleApiClient.connect();
if (googleApiAvaibility()) {
buildGoogleApiClient();
googleApiClient.connect();
}
}
}
}
}
}
You can also check this sample
i am trying to get IMEI no of mobile device.And getting error on if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) getApplicationContext(),
Manifest.permission.READ_PHONE_STATE)) method override. And also want to know can we access IMEI no in a service class.thanks
this is my service class code.
public class LocationService extends Service implements LocationListener {
private static String url_insert_location = "http://localhost/testing/insert.php";
public static String LOG = "Log";
JSONParser jsonParser = new JSONParser();
private final Context mContext;
boolean isGPSEnabled = false;
boolean isNetworkEnabled = false;
boolean canGetLocation = false;
Location location; // location
double latitude; // latitude
double longitude; // longitude
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 0; // 0 meters
private static final int MY_PERMISSIONS_REQUEST_READ_PHONE_STATE = 0;
private static final long MIN_TIME_BW_UPDATES = 1000; // 1 second
protected LocationManager locationManager;
public LocationService(Context context) {
this.mContext = context;
}
public LocationService() {
super();
mContext = LocationService.this;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
String currentDateandTime = sdf.format(new Date());
Toast.makeText(this,( "latitude" + latitude +"longitude" + longitude + currentDateandTime), Toast.LENGTH_LONG).show();
Log.i(LOG, "Service started");
Log.i("asd", "This is sparta");
Log.i("a",currentDateandTime);
loadIMEI();
new SendToServer().execute(Double.toString(getLocation().getLongitude()), Double.toString(getLocation().getLatitude()));
return START_STICKY;
}
#Override
public void onCreate() {
super.onCreate();
Log.i(LOG, "Service created");
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i(LOG, "Service destroyed");
}
class SendToServer extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... la) {
try {
Log.i("string", la[0]);
String longi = la[0];
String lati = la[1];
// Building Parameters
Log.d("value", lati);
Log.d("value", longi);
ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("longitude", longi));
params.add(new BasicNameValuePair("latitude", lati));
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url_insert_location);
HttpResponse httpresponse = httpclient.execute(httppost);
} catch (Exception e) {
Log.i("error", e.toString());
}
return "call";
}
}
public void loadIMEI() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE)
!= PackageManager.PERMISSION_GRANTED) {
requestReadPhoneStatePermission();
} else {
doPermissionGrantedStuffs();
}
}
private void requestReadPhoneStatePermission() {
if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) getApplicationContext(),
Manifest.permission.READ_PHONE_STATE)) {
new AlertDialog.Builder(this)
.setTitle("Permission Request")
.setMessage("permission_read_phone_state_rationale")
.setCancelable(false)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
//re-request
ActivityCompat.requestPermissions((Activity) getApplicationContext(),
new String[]{Manifest.permission.READ_PHONE_STATE},
MY_PERMISSIONS_REQUEST_READ_PHONE_STATE);
}
})
.setIcon(R.drawable.ic_cast_on_light)
.show();
} else {
ActivityCompat.requestPermissions((Activity) getApplicationContext(), new String[]{Manifest.permission.READ_PHONE_STATE},
MY_PERMISSIONS_REQUEST_READ_PHONE_STATE);
}
}
/**
* Callback received when a permissions request has been completed.
*/
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
if (requestCode == MY_PERMISSIONS_REQUEST_READ_PHONE_STATE) {
// Received permission result for READ_PHONE_STATE permission.est.");
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// READ_PHONE_STATE permission has been granted, proceed with displaying IMEI Number
//alertAlert(getString(R.string.permision_available_read_phone_state));
doPermissionGrantedStuffs();
} else {
alertAlert("permission not granted");
}
}
}
private void alertAlert(String msg) {
new AlertDialog.Builder(this)
.setTitle("Permission Request")
.setMessage(msg)
.setCancelable(false)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// do somthing here
}
})
.setIcon(R.drawable.ic_plusone_medium_off_client)
.show();
}
public void doPermissionGrantedStuffs() {
//Have an object of TelephonyManager
TelephonyManager tm =(TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
//Get IMEI Number of Phone //////////////// for this example i only need the IMEI
String IMEINumber=tm.getDeviceId();
}
public Location getLocation() {
try {
locationManager = (LocationManager) mContext
.getSystemService(LOCATION_SERVICE);
// getting GPS status
isGPSEnabled = locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
// getting network status
isNetworkEnabled = locationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled) {
// no network provider is enabled
} else {
this.canGetLocation = true;
if (isNetworkEnabled) {
//updates will be send according to these arguments
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("Network", "Network");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
// if GPS Enabled get lat/long using GPS Services
if (isGPSEnabled) {
if (location == null) {
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 null;
}
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("GPS Enabled", "GPS Enabled");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return location;
}
#Override
public void onLocationChanged(Location location) {
SendToServer().execute(Double.toString(getLocation().getLongitude()),Double.toString(getLocation().getLatitude()));
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras){
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
You cannot cast ApplicationContext to Activity since it is not an Activity. I suppose that constructing the service with an Activity instance would cause memory leaks, so I suggest you ask for the permission somewhere else, for example in the activity that starts the Service.