Places API android not showing on specific device - android

I'm trying to create a location based notification for an app I'm working on. I get a location using Google Places API and create a location based notification like so:
//used to get places
private void showPlaces() {
try {
PlacePicker.IntentBuilder builder = new PlacePicker.IntentBuilder();
startActivityForResult(builder.build(getActivity()), PLACE_PICKER_REQUEST);
} catch (GooglePlayServicesRepairableException | GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
}
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PLACE_PICKER_REQUEST && resultCode == Activity.RESULT_OK) {
displayPlace(PlacePicker.getPlace(getContext(), data));
}
}
private void displayPlace(Place place)
{
if (place == null)
return;
double latitude = place.getLatLng().latitude;
double longitude = place.getLatLng().longitude;
if (ingredient_list.size() > 0)
{
System.out.println("Display Place:");
if (ActivityCompat.checkSelfPermission(getContext(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getContext(), android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(getActivity(), new String[]{ android.Manifest.permission.ACCESS_FINE_LOCATION}, 1);
ActivityCompat.requestPermissions(getActivity(), new String[]{ android.Manifest.permission.ACCESS_COARSE_LOCATION}, 1);
return;
}
System.out.println("Display Place:");
initGoogleAPIClient();
createGeofences(latitude, longitude);
Toast.makeText(getContext(),"Added Notification!",Toast.LENGTH_SHORT).show();
}
}
public void initGoogleAPIClient()
{
mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
.addApi(LocationServices.API)
.addConnectionCallbacks(connectionAddListener)
.addOnConnectionFailedListener(connectionFailedListener)
.build();
mGoogleApiClient.connect();
}
private GoogleApiClient.ConnectionCallbacks connectionAddListener = new GoogleApiClient.ConnectionCallbacks()
{
#Override
public void onConnected(Bundle bundle)
{
System.out.println("onConnected");
try{
LocationServices.GeofencingApi.addGeofences(
mGoogleApiClient,
getGeofencingRequest(),
getGeofencePendingIntent()
).setResultCallback(new ResultCallback<Status>()
{
#Override
public void onResult(Status status)
{
if (status.isSuccess())
{
System.out.println("Saving Geofence");
}
else
{
System.out.println("Registering geofence failed: " + status.getStatusMessage() + " : " + status.getStatusCode());
}
}
});
}
catch (SecurityException securityException)
{
// Catch exception generated if the app does not use ACCESS_FINE_LOCATION permission.
System.out.println("Error " + securityException);
}
}
#Override
public void onConnectionSuspended(int i)
{
System.out.println("onConnectionSuspended");
}
};
private GoogleApiClient.OnConnectionFailedListener connectionFailedListener =
new GoogleApiClient.OnConnectionFailedListener() {
#Override
public void onConnectionFailed(ConnectionResult connectionResult)
{
System.out.println("onConnectionFailed");
}
};
public void createGeofences(double latitude, double longitude)
{
String id = UUID.randomUUID().toString();
Geofence fence = new Geofence.Builder()
.setRequestId(id)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT)
.setCircularRegion(latitude, longitude, 200)
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.build();
mGeofenceList.add(fence);
}
private GeofencingRequest getGeofencingRequest()
{
GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);
builder.addGeofences(mGeofenceList);
return builder.build();
}
private PendingIntent getGeofencePendingIntent()
{
// Reuse the PendingIntent if we already have it.
if (mGeofencePendingIntent != null)
{
return mGeofencePendingIntent;
}
Intent intent = new Intent(getActivity(), GeofenceTransitionsIntentService.class);
intent.putExtra("extra", title_string);
intent.putStringArrayListExtra("extra2", ingredient_list);
return PendingIntent.getService(getActivity(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
This seems to work fine on every device I tested on except for a user testing on a Nexus 5 6.0.1 who reports that when he launches a notification request, the map shows briefly and then disappears immediately after that. I initially thought that this might have something to do with the permission so I asked him to manually turn on his location permission in the app settings but he got the same result. Does anyone have a clue as to whats going on here? I can't seem to figure out why it works on multiple other devices even on the same firmware but it's not showing up for him.

Related

Android Geofence works after phone restart

I am adding multiple geofence to one app.(Max 100 allowed according to documentation.) I was getting callbacks of geofence then it stopped.
Geofence works smoothly only when I restart phone. After few minutes it stops working again.
public class GeoFenceHelper implements IGeoFenceListener, GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private Context context;
private GeofencingClient mGeoFencingClient;
private PendingIntent geoFencePendingIntent;
private String TAG = GeoFenceHelper.class.getSimpleName();
private GoogleApiClient mGoogleApiClient;
private Location mLastLocation;
Location tempLocation = new Location("");
/**
* The list of geoFences used in this sample.
*/
private ArrayList<Geofence> mGeoFenceList;
private List<GeoFenceModel> geoFenceEntries;
private ArrayList<String> removeGeoFenceList = new ArrayList<>();
public GeoFenceHelper(Context context) {
this.context = context;
mGeoFenceList = new ArrayList<>();
mGeoFencingClient = LocationServices.getGeofencingClient(context);
}
public void registerGeoFence(List<GeoFenceModel> geoFenceEntries) {
mGeoFenceList.clear();
this.geoFenceEntries = geoFenceEntries;
if (DatabaseManager.getInstance(context).getGeoFenceLocationCount() <= Constants.MAX_GEOFENCE_ENTRY_COUNT) {
addGeoFences(geoFenceEntries);
} else {
buildGoogleApiClient();
}
}
private void addGeoFences(List<GeoFenceModel> geoFenceEntries) {
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
for (GeoFenceModel geoFenceEntry : geoFenceEntries) {
if(geoFenceEntry.getId()==Constants.DESTINATION_REACHED_ID) {
removeGeoFenceList.clear();
removeGeoFenceList.add(""+geoFenceEntry.getId());
unregisterGeoFence(removeGeoFenceList);
}
Geofence geoFence = new Geofence.Builder()
.setRequestId(String.valueOf(geoFenceEntry.getId()))
.setExpirationDuration(geoFenceEntry.getExpireDuration())
.setCircularRegion(
geoFenceEntry.getLatitude(),
geoFenceEntry.getLongitude(),
geoFenceEntry.getRadius()
)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT)
.build();
CustomLogger.logE("GEOGENCE", "Geo Fence lat = " + geoFenceEntry.getLatitude() + " log = " + geoFenceEntry.getLongitude() + "Radius = " + geoFenceEntry.getRadius()+" Expiry "+geoFenceEntry.getExpireDate());
mGeoFenceList.add(geoFence);
}
mGeoFencingClient.addGeofences(getGeoFencingRequest(mGeoFenceList), getGeoFencePendingIntent());
Utils.stopLocationUpdate(context);
}
#Override
public void unregisterGeoFence(List<String> genFenceList) {
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
CustomLogger.logE("GeoFence","Remove GeoFence "+genFenceList.get(0));
mGeoFencingClient.removeGeofences(genFenceList);
}
/**
* Builds and returns a GeoFencingRequest. Specifies the list of geoFences to be monitored.
* Also specifies how the geoFence notifications are initially triggered.
*
* #param mGeoFenceList
*/
private GeofencingRequest getGeoFencingRequest(ArrayList<Geofence> mGeoFenceList) {
GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);
builder.addGeofences(mGeoFenceList);
return builder.build();
}
private PendingIntent getGeoFencePendingIntent() {
// Reuse the PendingIntent if we already have it.
if (geoFencePendingIntent != null) {
return geoFencePendingIntent;
}
Intent intent = new Intent(context, GeofenceTransitionsIntentService.class);
geoFencePendingIntent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
return geoFencePendingIntent;
}
//Location related code
private synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this.context)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API).build();
if (mGoogleApiClient != null && !mGoogleApiClient.isConnected()) {
mGoogleApiClient.connect();
}
}
#Override
public void onConnected(#Nullable Bundle bundle) {
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mLastLocation != null) {
double latitude = mLastLocation.getLatitude();
double longitude = mLastLocation.getLongitude();
CustomLogger.logE("tempLocation", "lat " + latitude + "long " + longitude);
List<GeoFenceModel> geoFenceLocations = DatabaseManager.getInstance(context).getGeoFenceLocation();
calculateLocationDistance(mLastLocation, geoFenceLocations);
try {
deleteLocations(geoFenceLocations);
addGeoFences(geoFenceEntries);
} catch (SQLException e) {
e.printStackTrace();
}
} else {
CustomLogger.logE("tempLocation", "(Couldn't get the tempLocation. Make sure tempLocation is enabled on the device)");
}
}
private void deleteLocations(List<GeoFenceModel> geoFenceLocations) throws SQLException {
int reduceCount = Math.abs(Constants.MAX_GEOFENCE_ENTRY_COUNT - geoFenceLocations.size());
CustomLogger.logE("GEOGENCE", "Geo Fence App lat = "+geoFenceLocations.get(0).getLatitude() + " log = "+ geoFenceLocations.get(0).getLongitude() + "App sepcific = "+ geoFenceLocations.get(0).isAppSpecific());
GeoFenceModel geoFenceModel = null;
for (int i = 0; i < reduceCount; i++) {
if(geoFenceLocations.get(0).isAppSpecific())
{
geoFenceModel = geoFenceLocations.remove(1); //because app specific item will be available at top of the list
}
else
{
geoFenceModel = geoFenceLocations.remove(0);
}
DatabaseManager.getInstance(context).getHelper().getNotificationGeoFenceModelDao().delete(geoFenceModel);
try {
List notificationIds = new ArrayList<String>();
notificationIds.add(String.valueOf(geoFenceModel.getId()));
unregisterGeoFence(notificationIds);
}
catch (Exception e)
{
CustomLogger.logE("GEOFENCE ","EXCEPTION"+e);
}
for (GeoFenceModel geoFence: geoFenceEntries) {
if (geoFence.getId()==geoFenceModel.getId())
{
geoFenceEntries.remove(geoFenceModel);
CustomLogger.logE("GEOGENCE", "Geo Fence Removed lat = "+geoFence.getLatitude() + " log = "+ geoFence.getLongitude() + "Radius = "+ geoFence.getRadius());
}
}
}
}
private void calculateLocationDistance(Location mLastLocation, List<GeoFenceModel> geoFenceLocations) {
for (GeoFenceModel geoFenceLocation : geoFenceLocations) {
tempLocation.setLatitude(geoFenceLocation.getLatitude());
tempLocation.setLongitude(geoFenceLocation.getLongitude());
geoFenceLocation.setDistanceInMeters(mLastLocation.distanceTo(tempLocation));
}
Collections.sort(geoFenceLocations);
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
In logs, geofence is getting register properly.
I have implemented IntentService in pending intent. I tried broadcast receiver also but result was same.
Tried same code with multiple devices and OS version.
Location updates on interval is missing in your code.
You have to request for location at HIGH_ACCURACY which enables GPS to give you accurate location at given interval time.
There are lot of changes required as per this tutorial.
go through above tutorial and let me know if it doesn't work.
You must have to create location request.
one more tutorial

wait till the GPS is enabled before getting the lat and long value in FusedLocationAPI

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);
}
}

Geofences do not trigger my Service

I have read various tutorials, forums and the official Google documentation and still cannot understand why my code does not work as expected. There are the relevant parts:
Activity
public class MainMap extends FragmentActivity implements OnMarkerClickListener, OnMapReadyCallback,
ConnectionCallbacks, OnConnectionFailedListener, LocationListener, ActivityCompat.OnRequestPermissionsResultCallback, ResultCallback<Status> {
private static final int REQUEST_ACCESS_FINE_LOCATION = 0;
protected GoogleApiClient mGoogleApiClient;
protected Location mCurrentLocation;
protected LocationRequest mLocationRequest;
private GoogleMap m_map;
private SupportMapFragment m_map_fragment;
protected ArrayList<Geofence> mGeofenceList;
private PendingIntent mGeofencePendingIntent;
private boolean m_geofences_added;
private SharedPreferences m_preferences;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_map);
m_preferences = this.getSharedPreferences("com.example",Context.MODE_PRIVATE);
// map fragment
m_map_fragment= (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
m_map_fragment.getMapAsync(this);
}
#Override
protected void onStart() {
super.onStart();
// location and geofences
add_location_and_geofences();
mGoogleApiClient.connect();
}
#Override
protected void onStop() {
// remove geofences
LocationServices.GeofencingApi.removeGeofences(mGoogleApiClient, getGeofencePendingIntent());
super.onStop();
mGoogleApiClient.disconnect();
}
#Override
public void onConnected(Bundle connectionHint) {
// permissions
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
request_fine_location_permission();
}
// location
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
// geofencing
try {
LocationServices.GeofencingApi.addGeofences(
mGoogleApiClient,
getGeofencingRequest(),
getGeofencePendingIntent()
).setResultCallback(this);
} catch (SecurityException securityException) {
Log.e(TAG, "Invalid location permission. " +
"You need to use ACCESS_FINE_LOCATION with geofences", securityException);
}
}
public void onResult(Status status) {
if (status.isSuccess()) {
} else {
String errorMessage = GeofenceErrorMessages.getErrorString(this,
status.getStatusCode());
Log.e(TAG, errorMessage);
}
}
private void add_location_and_geofences() {
for (int i =0; i < 3; i++) {
mGeofencePendingIntent = null;
mGeofenceList = new ArrayList<>();
mGeofenceList.add(new Geofence.Builder()
.setRequestId(Integer.toString(i)) // request id is the index so that I can later retrieve it
.setCircularRegion( /* I set coordinates here and a radius of 10meters*/)
.setExpirationDuration(NEVER_EXPIRE)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_DWELL)
.setLoiteringDelay(4000)
.build());
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(1000);
mLocationRequest.setFastestInterval(500);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
}
private PendingIntent getGeofencePendingIntent() {
if (mGeofencePendingIntent != null) {
return mGeofencePendingIntent;
}
Intent intent = new Intent(this, GeofenceTransitionsIntentService.class);
return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
private GeofencingRequest getGeofencingRequest() {
GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_DWELL);
builder.addGeofences(mGeofenceList);
return builder.build();
}
}
my Service:
public class GeofenceTransitionsIntentService extends IntentService {
private Intent m_intent;
#Override
public void onCreate() {
super.onCreate();
m_intent = new Intent(this, Guide.class);
}
#Override
protected void onHandleIntent(Intent intent) {
GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
if (geofencingEvent.hasError()) {
String errorMessage = GeofenceErrorMessages.getErrorString(this,
geofencingEvent.getErrorCode());
Log.e(TAG, errorMessage);
} else {
if (debug_mode) {
Log.i(TAG, "something has been received");
}
int geofenceTransition = geofencingEvent.getGeofenceTransition();
if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_DWELL) {
List<Geofence> triggeringGeofences = geofencingEvent.getTriggeringGeofences();
for (Geofence geofence : triggeringGeofences) {
Log.i(TAG, "INSIDE GEOFENCE");
}
} else {
Log.e(TAG, getString(R.string.geofence_transition_invalid_type, geofenceTransition));
}
}
}
}
and my manifest
<service android:name="com.example.GeofenceTransitionsIntentService" />
With this code geofencing silently fails - my service is never triggered, both using wifi indoors and using 3G/4G networks outdoors.
Are you looking only for dwell events, or enter and exit events? If the latter, set your initial trigger to INITIAL_TRIGGER_ENTER, and the transition types to GEOFENCE_TRANSITION_ENTER| GEOFENCE_TRANSITION_EXIT.
If you are looking for dwell events, you need to stay within the geofence for about 5 minutes to get the initial trigger. When you leave, you won't get any event about it, but once you re-enter it, you'll need to stay within your geofence again for another 5 minutes to get your event.

Not getting latitude and longitude from background service

I am new in android I want to run a service in background and get latitude and longitude or Geo address after 10 minutes and send to the server.
Please help me.
Here is my code:
In Activity
public void serviceCall(){
Log.e("INSIDE ALARM", "INSIDE ALARM");
Intent intent = new Intent(getApplicationContext(), MyService.class);
final PendingIntent pIntent = PendingIntent.getBroadcast(this, MyService.REQUEST_CODE,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
long firstMillis = System.currentTimeMillis();
AlarmManager alarm = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
alarm.setInexactRepeating(AlarmManager.RTC_WAKEUP, firstMillis,
6000, pIntent);
}
in Reciver
public static final int REQUEST_CODE = 9411;
#Override
public void onReceive(Context context, Intent intent) {
Intent inti = new Intent(context, LocationService.class);
intent1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK |Intent.FLAG_ACTIVITY_CLEAR_TOP |Intent.FLAG_ACTIVITY_NEW_TASK);
context.startService(inti);
}
in IntentService
protected void onHandleIntent(Intent intent) {
Log.e("imsidehandler Service", ":=");
mRequestingLocationUpdates = false;
buildGoogleApiClient();
createLocationRequest();
buildLocationSettingsRequest();
checkLocationSettings();
sendDataServer();
}
public void onConnected(Bundle bundle) {
if (mCurrentLocation == null) {
mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
updateLocationUI();
}
}
public void onConnectionSuspended(int i) {
}
public void onLocationChanged(Location location) {
mCurrentLocation = location;
mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
}
public void onConnectionFailed(ConnectionResult connectionResult) {
}
private synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
private void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
}
private void buildLocationSettingsRequest() {
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(mLocationRequest);
mLocationSettingsRequest = builder.build();
}
private void checkLocationSettings() {
PendingResult<LocationSettingsResult> result =
LocationServices.SettingsApi.checkLocationSettings(
mGoogleApiClient,
mLocationSettingsRequest
);
result.setResultCallback(this);
}
protected boolean startLocationUpdates() {
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this,
android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return true;
}
return false;
}
protected void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, (com.google.android.gms.location.LocationListener) this).setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
mRequestingLocationUpdates = false;
}
});
}
private void updateLocationUI() {
if (mCurrentLocation != null) {
updateCityAndPincode(mCurrentLocation.getLatitude(), mCurrentLocation.getLongitude());
}
}
private void updateCityAndPincode(double latitude, double longitude) {
try {
Log.e("latitude","==>"+longitude);
Log.e("longitude","==>"+longitude);
this.latitude = latitude;
this.longitude = longitude;
getGeoAddress(latitude, longitude);
} catch (Exception e) {
}
}
private void getGeoAddress(Double latitude, Double longitude) {
Geocoder geocoder = new Geocoder(this, Locale.getDefault());
String result = null;
List<Address> addressList = null;
try {
addressList = geocoder.getFromLocation(
latitude, longitude, 1);
if (addressList != null && addressList.size() > 0) {
Address address = addressList.get(0);
Log.e("address","==>"+address);
for (int i = 0; i < address.getMaxAddressLineIndex(); i++) {
result += address.getAddressLine(i);
result += " ";
}
if (result.contains("null")) {
result1 = result.replace("null", "");
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void onResult(LocationSettingsResult locationSettingsResult) {
final Status status = locationSettingsResult.getStatus();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
startLocationUpdates();
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
try {
status.startResolutionForResult((Activity) getApplicationContext(), REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException e) {
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
break;
}
}
please help me
The getLastLocation() method just gets the last known location that the device happens to know. Sometimes the device does not "happen to know" its location and null is returned.
The device doesn't determine its location on its own, but only when some application request the location. So your app is now dependent on other applications requesting location updates.
Also the "last known location" here means exactly that: It may not be up-to-date. Locations do come with a time stamp which could be used to asses if the location might still be relevant.
I don't see a call to requestLocationUpdates() anywhere in your code. That would request up-to-date location updates at an interval which you can specify.
Your onConnected() method could have:
public void onConnected(Bundle bundle) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
(The getLastLocation() call can be deleted.)
And your IntentService could implement LocationListener and do the same things as onConnected() now does, but only after a location update has arrived:
#Override
public void onLocationChanged(Location location) {
// Cancel the updates after the first one:
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
mCurrentLocation = location;
mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
updateLocationUI();
}
This would be the way to request and process location updates with the smallest code changes.
Of course there are also other ways like requesting the updates every 10 minutes and processing them via a PendingIntent. There's this version of requestLocationUpdates() that takes a PendingIntent:
public abstract PendingResult<Status> requestLocationUpdates (GoogleApiClient client, LocationRequest request, PendingIntent callbackIntent)
That would replace your current timer mechanism.

Google Maps android get longitude-latitude by moving a marker in the map

Hi i am developping an android application in which i need the user to choose a location by mouving a parker so i can get the informations i need exactly like this but in an android application.
I did some researchs but i'm still new so i couldn't find anything close to this.
Can anyone point me to the right direction ?
What i need to do is to create a mouving cursor in a simple google map that could give me long+lat data. all i coud do is put some static locations in my map.
Are you looking something like in the images below..
Here, if we drag marker on map it will automatically update the current lat, longs..
Here is the full complete solution with the code.
1.) Create a class AppUtils
public class AppUtils {
public class LocationConstants {
public static final int SUCCESS_RESULT = 0;
public static final int FAILURE_RESULT = 1;
public static final String PACKAGE_NAME = "your package name";
public static final String RECEIVER = PACKAGE_NAME + ".RECEIVER";
public static final String RESULT_DATA_KEY = PACKAGE_NAME + ".RESULT_DATA_KEY";
public static final String LOCATION_DATA_EXTRA = PACKAGE_NAME + ".LOCATION_DATA_EXTRA";
public static final String LOCATION_DATA_AREA = PACKAGE_NAME + ".LOCATION_DATA_AREA";
public static final String LOCATION_DATA_CITY = PACKAGE_NAME + ".LOCATION_DATA_CITY";
public static final String LOCATION_DATA_STREET = PACKAGE_NAME + ".LOCATION_DATA_STREET";
}
public static boolean hasLollipop() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
}
public static boolean isLocationEnabled(Context context) {
int locationMode = 0;
String locationProviders;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
try {
locationMode = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE);
} catch (Settings.SettingNotFoundException e) {
e.printStackTrace();
}
return locationMode != Settings.Secure.LOCATION_MODE_OFF;
} else {
locationProviders = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
return !TextUtils.isEmpty(locationProviders);
}
}
}
2.) create another class FetchAddressIntentService
This class will fetch the address and point to that particular location which user is going to type on Google AutocompleteTextView..
public class FetchAddressIntentService extends IntentService {
private static final String TAG = "FetchAddressIS";
/**
* The receiver where results are forwarded from this service.
*/
protected ResultReceiver mReceiver;
/**
* This constructor is required, and calls the super IntentService(String)
* constructor with the name for a worker thread.
*/
public FetchAddressIntentService() {
// Use the TAG to name the worker thread.
super(TAG);
}
/**
* Tries to get the location address using a Geocoder. If successful, sends an address to a
* result receiver. If unsuccessful, sends an error message instead.
* Note: We define a {#link ResultReceiver} in * MainActivity to process content
* sent from this service.
* <p>
* This service calls this method from the default worker thread with the intent that started
* the service. When this method returns, the service automatically stops.
*/
#Override
protected void onHandleIntent(Intent intent) {
String errorMessage = "";
mReceiver = intent.getParcelableExtra(AppUtils.LocationConstants.RECEIVER);
// Check if receiver was properly registered.
if (mReceiver == null) {
Log.wtf(TAG, "No receiver received. There is nowhere to send the results.");
return;
}
// Get the location passed to this service through an extra.
Location location = intent.getParcelableExtra(AppUtils.LocationConstants.LOCATION_DATA_EXTRA);
// Make sure that the location data was really sent over through an extra. If it wasn't,
// send an error error message and return.
if (location == null) {
errorMessage = getString(R.string.no_location_data_provided);
Log.wtf(TAG, errorMessage);
deliverResultToReceiver(AppUtils.LocationConstants.FAILURE_RESULT, errorMessage, null);
return;
}
// Errors could still arise from using the Geocoder (for example, if there is no
// connectivity, or if the Geocoder is given illegal location data). Or, the Geocoder may
// simply not have an address for a location. In all these cases, we communicate with the
// receiver using a resultCode indicating failure. If an address is found, we use a
// resultCode indicating success.
// The Geocoder used in this sample. The Geocoder's responses are localized for the given
// Locale, which represents a specific geographical or linguistic region. Locales are used
// to alter the presentation of information such as numbers or dates to suit the conventions
// in the region they describe.
Geocoder geocoder = new Geocoder(this, Locale.getDefault());
// Address found using the Geocoder.
List<Address> addresses = null;
try {
// Using getFromLocation() returns an array of Addresses for the area immediately
// surrounding the given latitude and longitude. The results are a best guess and are
// not guaranteed to be accurate.
addresses = geocoder.getFromLocation(
location.getLatitude(),
location.getLongitude(),
// In this sample, we get just a single address.
1);
} catch (IOException ioException) {
// Catch network or other I/O problems.
errorMessage = getString(R.string.service_not_available);
Log.e(TAG, errorMessage, ioException);
} catch (IllegalArgumentException illegalArgumentException) {
// Catch invalid latitude or longitude values.
errorMessage = getString(R.string.invalid_lat_long_used);
Log.e(TAG, errorMessage + ". " +
"Latitude = " + location.getLatitude() +
", Longitude = " + location.getLongitude(), illegalArgumentException);
}
// Handle case where no address was found.
if (addresses == null || addresses.size() == 0) {
if (errorMessage.isEmpty()) {
errorMessage = getString(R.string.no_address_found);
Log.e(TAG, errorMessage);
}
deliverResultToReceiver(AppUtils.LocationConstants.FAILURE_RESULT, errorMessage, null);
} else {
Address address = addresses.get(0);
ArrayList<String> addressFragments = new ArrayList<String>();
for (int i = 0; i < address.getMaxAddressLineIndex(); i++) {
addressFragments.add(address.getAddressLine(i));
}
deliverResultToReceiver(AppUtils.LocationConstants.SUCCESS_RESULT,
TextUtils.join(System.getProperty("line.separator"), addressFragments), address);
//TextUtils.split(TextUtils.join(System.getProperty("line.separator"), addressFragments), System.getProperty("line.separator"));
}
}
/**
* Sends a resultCode and message to the receiver.
*/
private void deliverResultToReceiver(int resultCode, String message, Address address) {
try {
Bundle bundle = new Bundle();
bundle.putString(AppUtils.LocationConstants.RESULT_DATA_KEY, message);
bundle.putString(AppUtils.LocationConstants.LOCATION_DATA_AREA, address.getSubLocality());
bundle.putString(AppUtils.LocationConstants.LOCATION_DATA_CITY, address.getLocality());
bundle.putString(AppUtils.LocationConstants.LOCATION_DATA_STREET, address.getAddressLine(0));
mReceiver.send(resultCode, bundle);
} catch (Exception e) {
e.printStackTrace();
}
}
}
3.) Create your MapActivity in this we are going to display our map
public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener {
private GoogleMap mMap;
private GoogleApiClient mGoogleApiClient;
private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
private static String TAG = "MAP LOCATION";
Context mContext;
TextView mLocationMarkerText;
public LatLng mCenterLatLong;
/**
* Receiver registered with this activity to get the response from FetchAddressIntentService.
*/
private AddressResultReceiver mResultReceiver;
/**
* The formatted location address.
*/
protected String mAddressOutput;
protected String mAreaOutput;
protected String mCityOutput;
protected String mStateOutput;
EditText mLocationAddress;
TextView mLocationText;
private static final int REQUEST_CODE_AUTOCOMPLETE = 1;
Toolbar mToolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
mContext = this;
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mLocationMarkerText = (TextView) findViewById(R.id.locationMarkertext);
mLocationAddress = (EditText) findViewById(R.id.Address); //sss
mLocationText = (TextView) findViewById(R.id.Locality); //sss
mToolbar = (Toolbar) findViewById(R.id.toolbar); //sss
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setTitle(getResources().getString(R.string.app_name));
mLocationText.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
openAutocompleteActivity();
}
});
mapFragment.getMapAsync(this);
mResultReceiver = new AddressResultReceiver(new Handler());
if (checkPlayServices()) {
if (!AppUtils.isLocationEnabled(mContext)) {
// notify user
AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
dialog.setMessage("Location not enabled!");
dialog.setPositiveButton("Open location settings", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
Intent myIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(myIntent);
}
});
dialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
// TODO Auto-generated method stub
}
});
dialog.show();
}
buildGoogleApiClient();
} else {
Toast.makeText(mContext, "Location not supported in this device", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onMapReady(GoogleMap googleMap) {
Log.d(TAG, "OnMapReady");
mMap = googleMap;
mMap.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() {
#Override
public void onCameraChange(CameraPosition cameraPosition) {
Log.d("Camera postion change" + "", cameraPosition + "");
mCenterLatLong = cameraPosition.target;
mMap.clear();
try {
Location mLocation = new Location("");
mLocation.setLatitude(mCenterLatLong.latitude);
mLocation.setLongitude(mCenterLatLong.longitude);
startIntentService(mLocation);
mLocationMarkerText.setText("Lat : " + mCenterLatLong.latitude + "," + "Long : " + mCenterLatLong.longitude);
} catch (Exception e) {
e.printStackTrace();
}
}
});
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
}
#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) {
return;
}
Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
if (mLastLocation != null) {
changeMap(mLastLocation);
Log.d(TAG, "ON connected");
} else
try {
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
} catch (Exception e) {
e.printStackTrace();
}
try {
LocationRequest mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(10000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "Connection suspended");
mGoogleApiClient.connect();
}
#Override
public void onLocationChanged(Location location) {
try {
if (location != null)
changeMap(location);
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
#Override
protected void onStart() {
super.onStart();
try {
mGoogleApiClient.connect();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
protected void onStop() {
super.onStop();
try {
} catch (RuntimeException e) {
e.printStackTrace();
}
if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
private boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS) {
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
GooglePlayServicesUtil.getErrorDialog(resultCode, this,
PLAY_SERVICES_RESOLUTION_REQUEST).show();
} else {
//finish();
}
return false;
}
return true;
}
private void changeMap(Location location) {
Log.d(TAG, "Reaching map" + mMap);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
// check if map is created successfully or not
if (mMap != null) {
mMap.getUiSettings().setZoomControlsEnabled(false);
LatLng latLong;
latLong = new LatLng(location.getLatitude(), location.getLongitude());
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(latLong).zoom(15).tilt(70).build();
mMap.setMyLocationEnabled(true);
mMap.getUiSettings().setMyLocationButtonEnabled(true);
mMap.animateCamera(CameraUpdateFactory
.newCameraPosition(cameraPosition));
mLocationMarkerText.setText("Lat : " + location.getLatitude() + "," + "Long : " + location.getLongitude());
startIntentService(location);
} else {
Toast.makeText(getApplicationContext(),
"Sorry! unable to create maps", Toast.LENGTH_SHORT)
.show();
}
}
/**
* Receiver for data sent from FetchAddressIntentService.
*/
class AddressResultReceiver extends ResultReceiver {
public AddressResultReceiver(Handler handler) {
super(handler);
}
/**
* Receives data sent from
* FetchAddressIntentService and updates the UI in MainActivity.
*/
#Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
// Display the address string or an error message sent from the intent service.
mAddressOutput = resultData.getString(AppUtils.LocationConstants.RESULT_DATA_KEY);
mAreaOutput = resultData.getString(AppUtils.LocationConstants.LOCATION_DATA_AREA);
mCityOutput = resultData.getString(AppUtils.LocationConstants.LOCATION_DATA_CITY);
mStateOutput = resultData.getString(AppUtils.LocationConstants.LOCATION_DATA_STREET);
displayAddressOutput();
// Show a toast message if an address was found.
if (resultCode == AppUtils.LocationConstants.SUCCESS_RESULT) {
// showToast(getString(R.string.address_found));
}
}
}
/**
* Updates the address in the UI.
*/
protected void displayAddressOutput() {
// mLocationAddressTextView.setText(mAddressOutput);
try {
if (mAreaOutput != null)
// mLocationText.setText(mAreaOutput+ "");
mLocationAddress.setText(mAddressOutput);
//mLocationText.setText(mAreaOutput);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Creates an intent, adds location data to it as an extra, and starts the intent service for
* fetching an address.
*/
protected void startIntentService(Location mLocation) {
// Create an intent for passing to the intent service responsible for fetching the address.
Intent intent = new Intent(this, FetchAddressIntentService.class);
// Pass the result receiver as an extra to the service.
intent.putExtra(AppUtils.LocationConstants.RECEIVER, mResultReceiver);
// Pass the location data as an extra to the service.
intent.putExtra(AppUtils.LocationConstants.LOCATION_DATA_EXTRA, mLocation);
// Start the service. If the service isn't already running, it is instantiated and started
// (creating a process for it if needed); if it is running then it remains running. The
// service kills itself automatically once all intents are processed.
startService(intent);
}
private void openAutocompleteActivity() {
try {
// The autocomplete activity requires Google Play Services to be available. The intent
// builder checks this and throws an exception if it is not the case.
Intent intent = new PlaceAutocomplete.IntentBuilder(PlaceAutocomplete.MODE_FULLSCREEN)
.build(this);
startActivityForResult(intent, REQUEST_CODE_AUTOCOMPLETE);
} catch (GooglePlayServicesRepairableException e) {
// Indicates that Google Play Services is either not installed or not up to date. Prompt
// the user to correct the issue.
GoogleApiAvailability.getInstance().getErrorDialog(this, e.getConnectionStatusCode(),
0 /* requestCode */).show();
} catch (GooglePlayServicesNotAvailableException e) {
// Indicates that Google Play Services is not available and the problem is not easily
// resolvable.
String message = "Google Play Services is not available: " +
GoogleApiAvailability.getInstance().getErrorString(e.errorCode);
Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();
}
}
/**
* Called after the autocomplete activity has finished to return its result.
*/
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Check that the result was from the autocomplete widget.
if (requestCode == REQUEST_CODE_AUTOCOMPLETE) {
if (resultCode == RESULT_OK) {
// Get the user's selected place from the Intent.
Place place = PlaceAutocomplete.getPlace(mContext, data);
// TODO call location based filter
LatLng latLong;
latLong = place.getLatLng();
//mLocationText.setText(place.getName() + "");
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(latLong).zoom(15).tilt(70).build();
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
return;
}
mMap.setMyLocationEnabled(true);
mMap.animateCamera(CameraUpdateFactory
.newCameraPosition(cameraPosition));
}
} else if (resultCode == PlaceAutocomplete.RESULT_ERROR) {
Status status = PlaceAutocomplete.getStatus(mContext, data);
} else if (resultCode == RESULT_CANCELED) {
// Indicates that the activity closed before a selection was made. For example if
// the user pressed the back button.
}
}
}
4.) Changes in Manifest
provide all the necessary internet permissions.
Don't forget to add these two things
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="Your google map api key" />
and,
<service
android:name=".FetchAddressIntentService"
android:exported="false" />
That's it, You're done with the code part!!
Just Run it..
Utilize draggable markers, via the onMarkerDragEnd method
#Override
public void onMarkerDragEnd(Marker marker) {
// TODO Auto-generated method stub
}
Within that method you could do something like
LatLng position = marker.getPosition();
double latitude = position.latitude;
double longitude = position.longitude;
There you have it. .........
#Override
public void onMapReady(GoogleMap googleMap)
{
mMap = googleMap;
mMap.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener()
{
#Override
public void onCameraChange(CameraPosition cameraPosition)
{
mCenterLatLong = cameraPosition.target;
mMap.clear();
try
{
Location mLocation = new Location("");
mLocation.setLatitude(mCenterLatLong.latitude);
mLocation.setLongitude(mCenterLatLong.longitude);
startIntentService(mLocation);
}
catch (Exception e)
{
e.printStackTrace();
}
}
});
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;
}
}

Categories

Resources