I am trying to get users current location using FusedLocationApi using the following code. I am following the guide provided here https://developer.android.com/training/location/retrieve-current.html
public class MapActivity extends ActionBarActivity implements
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener,LocationListener {
private Toolbar mToolbar;
private GoogleMap googleMap;
GoogleApiClient mGoogleApiClient;
private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 1000;
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST =5000;
private Location mLastLocation;
private LocationRequest mLocationRequest;
LocationManager locationManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
mToolbar = (Toolbar)findViewById( R.id.toolbar );
mToolbar.setTitle(R.string.title_activity_map);
setSupportActionBar(mToolbar);
try {
initilizeMap();
} catch (Exception e) {
e.printStackTrace();
}
if (checkPlayServices()) {
buildGoogleApiClient();
}
mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(10 * 1000) // 10 seconds, in milliseconds
.setFastestInterval(1 * 1000);
}
private void initilizeMap() {
if (googleMap == null) {
googleMap = ((MapFragment) getFragmentManager().findFragmentById(
R.id.map)).getMap();
// check if map is created successfully or not
if (googleMap == null) {
Toast.makeText(getApplicationContext(),
"Sorry! unable to create maps", Toast.LENGTH_SHORT)
.show();
}
googleMap.setMyLocationEnabled(true);
}
}
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 {
Toast.makeText(getApplicationContext(),
"This device is not supported.", Toast.LENGTH_LONG)
.show();
finish();
}
return false;
}
return true;
}
#Override
protected void onResume() {
super.onResume();
initilizeMap();
checkPlayServices();
if (mGoogleApiClient != null) {
mGoogleApiClient.connect();
}
}
#Override
protected void onPause() {
super.onPause();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.map, 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();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onConnectionFailed(ConnectionResult arg0) {
// TODO Auto-generated method stub
if (arg0.hasResolution()) {
try {
// Start an Activity that tries to resolve the error
arg0.startResolutionForResult(this, CONNECTION_FAILURE_RESOLUTION_REQUEST);
} catch (Exception e) {
e.printStackTrace();
}
} else {
Log.e("Fail", "Location services connection failed with code " + arg0.getErrorCode());
}
}
#Override
public void onConnected(Bundle arg0) {
// TODO Auto-generated method stub
new GetLocation().execute();
}
#Override
public void onConnectionSuspended(int arg0) {
// TODO Auto-generated method stub
}
private class GetLocation extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
if (mLastLocation != null) {
Log.e("If", "If");
} else {
Log.e("else", "else");
}
return null;
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
}
}
#Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
}
When I run the code it always shows else in log, this means that I am not getting any Location. Is there something missing? what am I doing wrong?
Moved from comments:
make sure you have gps enabled on your phone. When enabling gps, phone may also ask you to send data anonymously to google, you should accept it.
Related
Fatal Exception: java.lang.RuntimeException
Unable to destroy activity : java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
problem is Samsung SM G355H and micromax A106
Here is my code
public class EnRouteFragment extends Fragment implements LocationListener{
View rootView;
LayoutInflater inflater;
ViewGroup container;
Context context;
private GoogleMap googleMap;
// flag for GPS status
boolean isGPSEnabled = false;
boolean canGetLocation = false;
// flag for network status
boolean isNetworkEnabled = false;
Location location; // location
Double dblIntLat=null; // latitude
Double dblIntLog=null; // longitude
// The minimum distance to change Updates in meters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 0; // 10 meters
// The minimum time between updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = 0; // 1 minute
// Declaring a Location Manager
protected LocationManager locationManager;
MarkerOptions dynamicMarker;
Marker markerCurre;
public EnRouteFragment()
{
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
final Bundle savedInstanceState) {
// TODO Auto-generated method stub
this.inflater = inflater;
this.container = container;
initializeVariables();
initializeUIVariables();
initializeListeners();
attachEventListeners();
return rootView;
}
#Override
public void initializeVariables() {
// TODO Auto-generated method stub
context=getActivity();
if (rootView != null) {
ViewGroup parent = (ViewGroup) rootView.getParent();
if (parent != null)
parent.removeView(rootView);
}
try {
rootView = inflater.inflate(R.layout.fragment_enroute_marchent, container, false);
} catch (InflateException e) {
/* map is already there, just return view as it is */
}
}
#Override
public void initializeUIVariables() {
// TODO Auto-generated method stub
}
#Override
public void initializeListeners() {
// TODO Auto-generated method stub
}
#Override
public void attachEventListeners() {
// TODO Auto-generated method stub
}
// ------------------------------------fetch lat long from GPS OR NETWORK provider-------
public Location getLocation() {
try {
locationManager = (LocationManager) context.getSystemService(Context.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;
// First get location from Network Provider
if (isNetworkEnabled) {
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) {
dblIntLat = location.getLatitude();
dblIntLog = location.getLongitude();
}
}
}
// if GPS Enabled get lat/long using GPS Services
if (isGPSEnabled) {
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) {
dblIntLat = location.getLatitude();
dblIntLog = location.getLongitude();
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return location;
}
// -----------------------------------------end---------------
// --------------------------------------initialize google map---------------
private void initilizeMap() {
if (googleMap == null) {
System.out.println("--------- initilizeMap() if");
googleMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.enroute_map)).getMap();
googleMap.setMyLocationEnabled(true);
googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
googleMap.getUiSettings().setRotateGesturesEnabled(false);
googleMap.getUiSettings().setZoomControlsEnabled(true);
if(dblIntLat!=null && dblIntLog !=null)
{
markerCurre = googleMap.addMarker(new MarkerOptions().position(
new LatLng(dblIntLat, dblIntLog)).icon(BitmapDescriptorFactory.fromResource(R.drawable.bike)));
}
if(dblIntLat!=null && dblIntLog !=null)
{
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(dblIntLat,dblIntLog) , 12.0f) );
}
if (googleMap == null) {
Toast.makeText(context,
"Sorry! unable to create maps", Toast.LENGTH_SHORT)
.show();
}
}
else
{
System.out.println("--------- initilizeMap() else");
if(markerCurre!=null)
{
markerCurre.remove();
}
if(dblIntLat!=null && dblIntLog !=null)
{
markerCurre = googleMap.addMarker(new MarkerOptions().position(
new LatLng(dblIntLat, dblIntLog)).icon(BitmapDescriptorFactory.fromResource(R.drawable.bike)));
}
}
}
#Override
public void onLocationChanged(Location loc) {
// TODO Auto-generated method stub
dblIntLat = loc.getLatitude();
dblIntLog = loc.getLongitude();
initilizeMap();
}
#Override
public void onProviderDisabled(String arg0) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String arg0) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
// TODO Auto-generated method stub
}
#Override
public void onDestroyView() {
// TODO Auto-generated method stub
super.onDestroyView();
Fragment fragment = getFragmentManager().findFragmentById(R.id.enroute_map);
if(fragment!=null)
{
FragmentTransaction ft = getActivity().getFragmentManager().beginTransaction();
ft.remove(fragment);
ft.commitAllowingStateLoss();
}
}
#Override
public void onPause() {
super.onPause();
if(locationManager!=null)
{
locationManager.removeUpdates(this);
}
}
#Override
public void onResume() {
super.onResume();
getLocation();
}
#Override
public void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
//super.onSaveInstanceState(outState);
}
}
here is the error log cat
java.lang.RuntimeException: Unable to destroy activity : java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3733)
at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3751)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3951)
at android.app.ActivityThread.access$1000(ActivityThread.java:166)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1287)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5511)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
at dalvik.system.NativeStart.main(NativeStart.java)
Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1323)
at android.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1341)
at android.app.BackStackRecord.commitInternal(BackStackRecord.java:597)
at android.app.BackStackRecord.commit(BackStackRecord.java:575)
at com.matrix.hungerz.EnRouteFragment.onDestroyView(EnRouteFragment.java:744)
at android.app.Fragment.performDestroyView(Fragment.java:1898)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:954)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1062)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1044)
at android.app.FragmentManagerImpl.dispatchDestroy(FragmentManager.java:1887)
at android.app.Activity.performDestroy(Activity.java:5493)
at android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1123)
at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3720)
at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3751)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3951)
at android.app.ActivityThread.access$1000(ActivityThread.java:166)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1287)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5511)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
at dalvik.system.NativeStart.main(NativeStart.java)
This logcat error doesn't correspond to the code you've provided.
Note this line in the logcat:
android.app.BackStackRecord.commit(BackStackRecord.java:575)
This means that the error was caused by a call to FragmentTransaction.commit(), but your code suggests that you call FragmentTransaction.commitAllowingStateLoss().
I can think of three possible reasons:
You are looking at the wrong part of the code
You previously had commit() in place of commitAllowingStateLoss(), and the errors happen on the older version of your app
Your code has been run on a custom ROM that screwed up parts of AOSP code (see below).
The relevant parts of AOSP code:
From BackStackRecord:
public int commit() {
return commitInternal(false);
}
public int commitAllowingStateLoss() {
return commitInternal(true);
}
int commitInternal(boolean allowStateLoss) {
if (mCommitted) {
throw new IllegalStateException("commit already called");
}
...
mManager.enqueueAction(this, allowStateLoss);
return mIndex;
}
From FragmentManagerImpl:
public void enqueueAction(Runnable action, boolean allowStateLoss) {
if (!allowStateLoss) {
checkStateLoss();
}
...
}
private void checkStateLoss() {
if (mStateSaved) {
throw new IllegalStateException(
"Can not perform this action after onSaveInstanceState");
}
if (mNoTransactionsBecause != null) {
throw new IllegalStateException(
"Can not perform this action inside of " + mNoTransactionsBecause);
}
}
I'm trying to get Google maps to start on the users current location. Right now it starts zoomed all the way out. I have the correct code for finding and animating the camera to the user's location but this code only works if I put it in a button and touch it on my own. How can I get it to move at the start of the activity?
I've been trying a lot of different things. this was one of them.
public class FindBar extends Activity implements ConnectionCallbacks,
OnConnectionFailedListener, LocationListener,
OnMyLocationButtonClickListener {
private GoogleMap mMap;
private LocationClient mLocationClient;
// Button test;
boolean locationClientConnected = false;
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
setUpMapIfNeeded();
setUpLocationClientIfNeeded();
mLocationClient.connect();
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
if (mLocationClient != null) {
mLocationClient.disconnect();
Log.d("tag", "locationclient disconnected");
}
}
private void setUpMapIfNeeded() {
Log.d("tag", "entered set up map");
// Check if we were successful in obtaining the map.
if (mMap != null) {
mMap.setMyLocationEnabled(true);
mMap.setOnMyLocationButtonClickListener(this);
Log.d("tag", "map location set true and click listener set");
}
}
private void setUpLocationClientIfNeeded() {
if (mLocationClient == null) {
mLocationClient = new LocationClient(getApplicationContext(), this, // ConnectionCallbacks
this); // OnConnectionFailedListener
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// removes the title bar
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.fragment_find_bar);
// Get a handle to the Map Fragment
mMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map))
.getMap();
// test = (Button) findViewById(R.id.bTest);
// test.setOnClickListener(new OnClickListener() {
//
// #Override
// public void onClick(View v) {
// // TODO Auto-generated method stub
// moveCameraTo(mMap.getMyLocation());
// }
//
// });
moveCameraTo(mLocationClient.getLastLocation());
}
// Takes a Location and centers camera on that location
public void moveCameraTo(Location mLocation) {
Log.d("camera", "entered moveToCamera");
LatLng camPos = new LatLng(mLocation.getLatitude(),
mLocation.getLongitude());
Log.d("camera", "created camera position");
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(camPos, 15));
Log.d("camera", "moved camera");
}
#Override
public boolean onMyLocationButtonClick() {
// TODO Auto-generated method stub
return false;
}
#Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
}
#Override
public void onConnectionFailed(ConnectionResult result) {
// TODO Auto-generated method stub
}
#Override
public void onConnected(Bundle connectionHint) {
// TODO Auto-generated method stub
Log.d("camera", "entered onConnected");
// moveCameraTo(mMap.getMyLocation());
locationClientConnected = true;
}
#Override
public void onDisconnected() {
// TODO Auto-generated method stub
}
}
this code comes pretty much out of the samples. If you get a non null location from getLastLocation() then plug that location into your setupmap method.
if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
// mMap = mMapFragment.getMap();
// // Check if we were successful in obtaining the map.
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map)).getMap();
// use the settings maptype
// Check if we were successful in obtaining the map.
if (mMap != null) {
setUpMap();
// Start Parsing the map
}
}
private void setUpMap() {
final View mapView = getSupportFragmentManager().findFragmentById(
R.id.map).getView();
if (mapView.getViewTreeObserver().isAlive()) {
mapView.getViewTreeObserver().addOnGlobalLayoutListener(
new OnGlobalLayoutListener() {
#SuppressWarnings("deprecation")
// We use the new method when supported
#SuppressLint("NewApi")
// We check which build version we are using.
#Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
mapView.getViewTreeObserver()
.removeGlobalOnLayoutListener(this);
} else {
mapView.getViewTreeObserver()
.removeOnGlobalLayoutListener(this);
}
//
// put your move code here replacing code below
// which moves the map.
//
if (currentCameraPosition != null) {
mMap.moveCamera(CameraUpdateFactory
.newCameraPosition(currentCameraPosition));
} else {
// else move to bounds of the map
if (bounds != null) {
mMap.moveCamera(CameraUpdateFactory
.newLatLngBounds(bounds, 50));
}
}
}
});
}
}
I am using the periodic location updates and wanted to know which part should be put in service so that even when the app is closed it keeps running. Here is the code
public class MainActivity extends FragmentActivity implements LocationListener,
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener {
private LocationRequest mLocationRequest;
private LocationClient mLocationClient;
private TextView mLatLng;
private TextView mConnectionState;
private TextView mConnectionStatus;
SharedPreferences mPrefs;
SharedPreferences.Editor mEditor;
boolean mUpdatesRequested = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLatLng = (TextView) findViewById(R.id.lat_lng);
mConnectionState = (TextView) findViewById(R.id.text_connection_state);
mConnectionStatus = (TextView) findViewById(R.id.text_connection_status);
mLocationRequest = LocationRequest.create();
mLocationRequest
.setInterval(LocationUtils.UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest
.setFastestInterval(LocationUtils.FAST_INTERVAL_CEILING_IN_MILLISECONDS);
mUpdatesRequested = false;
mPrefs = getSharedPreferences(LocationUtils.SHARED_PREFERENCES,
Context.MODE_PRIVATE);
mEditor = mPrefs.edit();
mLocationClient = new LocationClient(this, this, this);
}
#Override
public void onStop() {
if (mLocationClient.isConnected()) {
stopPeriodicUpdates();
}
mLocationClient.disconnect();
super.onStop();
}
#Override
public void onPause() {
mEditor.putBoolean(LocationUtils.KEY_UPDATES_REQUESTED,
mUpdatesRequested);
mEditor.commit();
super.onPause();
}
#Override
public void onStart() {
super.onStart();
mLocationClient.connect();
}
#Override
public void onResume() {
super.onResume();
// If the app already has a setting for getting location updates, get it
if (mPrefs.contains(LocationUtils.KEY_UPDATES_REQUESTED)) {
mUpdatesRequested = mPrefs.getBoolean(
LocationUtils.KEY_UPDATES_REQUESTED, false);
// Otherwise, turn off location updates until requested
} else {
mEditor.putBoolean(LocationUtils.KEY_UPDATES_REQUESTED, false);
mEditor.commit();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {
// Choose what to do based on the request code
switch (requestCode) {
// If the request code matches the code sent in onConnectionFailed
case LocationUtils.CONNECTION_FAILURE_RESOLUTION_REQUEST:
switch (resultCode) {
// If Google Play services resolved the problem
case Activity.RESULT_OK:
// Log the result
Log.d(LocationUtils.APPTAG, getString(R.string.resolved));
// Display the result
mConnectionState.setText(R.string.connected);
mConnectionStatus.setText(R.string.resolved);
break;
// If any other result was returned by Google Play services
default:
// Log the result
Log.d(LocationUtils.APPTAG, getString(R.string.no_resolution));
// Display the result
mConnectionState.setText(R.string.disconnected);
mConnectionStatus.setText(R.string.no_resolution);
break;
}
// If any other request code was received
default:
// Report that this Activity received an unknown requestCode
Log.d(LocationUtils.APPTAG,
getString(R.string.unknown_activity_request_code,
requestCode));
break;
}
}
private boolean servicesConnected() {
// Check that Google Play services is available
int resultCode = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(this);
// If Google Play services is available
if (ConnectionResult.SUCCESS == resultCode) {
// In debug mode, log the status
Log.d(LocationUtils.APPTAG,
getString(R.string.play_services_available));
// Continue
return true;
// Google Play services was not available for some reason
} else {
// Display an error dialog
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(resultCode,
this, 0);
if (dialog != null) {
ErrorDialogFragment errorFragment = new ErrorDialogFragment();
errorFragment.setDialog(dialog);
errorFragment.show(getFragmentManager(), LocationUtils.APPTAG);
}
return false;
}
}
public void getLocation(View v) {
if (servicesConnected()) {
Location currentLocation = mLocationClient.getLastLocation();
mLatLng.setText(LocationUtils.getLatLng(this, currentLocation));
}
}
public void startUpdates(View v) {
mUpdatesRequested = true;
if (servicesConnected()) {
startPeriodicUpdates();
}
}
public void stopUpdates(View v) {
mUpdatesRequested = false;
if (servicesConnected()) {
stopPeriodicUpdates();
}
}
#Override
public void onConnected(Bundle bundle) {
mConnectionStatus.setText(R.string.connected);
if (mUpdatesRequested) {
startPeriodicUpdates();
}
}
#Override
public void onDisconnected() {
mConnectionStatus.setText(R.string.disconnected);
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
/*
* Google Play services can resolve some errors it detects. If the error
* has a resolution, try sending an Intent to start a Google Play
* services activity that can resolve error.
*/
if (connectionResult.hasResolution()) {
try {
// Start an Activity that tries to resolve the error
connectionResult.startResolutionForResult(this,
LocationUtils.CONNECTION_FAILURE_RESOLUTION_REQUEST);
/*
* Thrown if Google Play services canceled the original
* PendingIntent
*/
} catch (IntentSender.SendIntentException e) {
// Log the error
e.printStackTrace();
}
} else {
// If no resolution is available, display a dialog to the user with
// the error.
showErrorDialog(connectionResult.getErrorCode());
}
}
#Override
public void onLocationChanged(Location location) {
mConnectionStatus.setText(R.string.location_updated);
mLatLng.setText(LocationUtils.getLatLng(this, location));
}
private void startPeriodicUpdates() {
mLocationClient.requestLocationUpdates(mLocationRequest, this);
mConnectionState.setText(R.string.location_requested);
}
private void stopPeriodicUpdates() {
mLocationClient.removeLocationUpdates(this);
mConnectionState.setText(R.string.location_updates_stopped);
}
private void showErrorDialog(int errorCode) {
Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(errorCode,
this, LocationUtils.CONNECTION_FAILURE_RESOLUTION_REQUEST);
if (errorDialog != null) {
ErrorDialogFragment errorFragment = new ErrorDialogFragment();
errorFragment.setDialog(errorDialog);
errorFragment.show(getFragmentManager(), LocationUtils.APPTAG);
}
}
public static class ErrorDialogFragment extends DialogFragment {
private Dialog mDialog;
public ErrorDialogFragment() {
super();
mDialog = null;
}
public void setDialog(Dialog dialog) {
mDialog = dialog;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return mDialog;
}
}
}
#Override
public void onLocationChanged(Location location) {
}
is the callback which is called when the location changes. So, this should be put in your service so that it is able to receive the updates.
I need a help with my app.
I've been trying yo build a simple location app. Therefore, I followed the Android Developer Training (http://developer.android.com/training/location/retrieve-current.html). However, I am stuck with the last part.
My app seems to crash whenever it hits this code,
mLocationClient.connect();
I've added permission and activated location service in my device. Can anyone help me?
This is my whole code.
public class MainActivity extends FragmentActivity
implements
ConnectionCallbacks,
OnConnectionFailedListener{
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
private LocationClient mLocationClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLocationClient = new LocationClient(this, this, this);
}
#Override
protected void onStart(){
super.onStart();
mLocationClient.connect();
}
#Override
protected void onStop(){
mLocationClient.disconnect();
super.onStop();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public static class ErrorDialogFragment extends DialogFragment{
private Dialog mDialog;
public ErrorDialogFragment(){
super();
mDialog = null;
}
public void setDialog(Dialog dialog){
mDialog = dialog;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState){
return mDialog;
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
switch (requestCode) {
case CONNECTION_FAILURE_RESOLUTION_REQUEST :
switch (resultCode) {
case Activity.RESULT_OK:
break;
default:
break;
}
default:
break;
}
}
private boolean servicesConnected() {
int resultCode =
GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (ConnectionResult.SUCCESS == resultCode) {
Log.d("Location Update", "Google Play Services is available");
return true;
} else {
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(resultCode, this, 0);
if (dialog != null) {
//ErrorDialogFragment errorFragment = new ErrorDialogFragment();
//errorFragment.setDialog(dialog);
//errorFragment.show(getFragmentManager(), "Location Updates");
//errorFragment.show(getSupportFragmentManager(), "Location Updates");
}
return false;
}
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
// TODO Auto-generated method stub
if (connectionResult.hasResolution()) {
try {
connectionResult.startResolutionForResult(
this,
CONNECTION_FAILURE_RESOLUTION_REQUEST);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
} else {
showErrorDialog(connectionResult.getErrorCode());
}
}
private void showErrorDialog(int errorCode) {
Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(
errorCode,
this,
CONNECTION_FAILURE_RESOLUTION_REQUEST);
if (errorDialog != null) {
ErrorDialogFragment errorFragment = new ErrorDialogFragment();
errorFragment.setDialog(errorDialog);
}
}
#Override
public void onConnected(Bundle arg0) {
// TODO Auto-generated method stub
Toast.makeText(this, "Connected", Toast.LENGTH_SHORT).show();
}
#Override
public void onDisconnected() {
// TODO Auto-generated method stub
Toast.makeText(this, "Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show();
}
}
I think you don't have Google Play Services installed. You have the method servicesConnected(), but you don't use it. You should wrap your call to mLocationClient.connect() in an if statement that checks servicesConnected().
I had a similar issue and I had forgotten to add this in my manifest under application:
<meta-data android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
Read this again for help.
I'm trying to write a simple app that updates the MainActivity with the Lat/Lng values returned by the service. But it always returns the null value. I have added permissions and added TheService.java as service in AndroidManifest.xml file...Kindly tell me where I have gone wrong.
MainActivity.java
public class MainActivity extends Activity {
TextView tv1, tv2;
IntentFilter filter;
receive rec;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv1 =(TextView)findViewById(R.id.textView1);
tv2 = (TextView)findViewById(R.id.textView2);
filter = new IntentFilter("Updated");
rec = new receive();
Intent gps_int = new Intent(this,TheService.class);
startService(gps_int);
}
#Override
public void onPause()
{
super.onPause();
unregisterReceiver(rec);
}
#Override
public void onResume()
{
super.onResume();
rec = new receive();
registerReceiver(rec, filter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public class receive extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
tv1.setText(intent.getExtras().getString("lat"));
tv2.setText(intent.getExtras().getString("lon"));
Toast.makeText(getApplicationContext(), "Toast Executed", Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), "BR Latitude "+intent.getExtras().getString("lat"),Toast.LENGTH_SHORT).show();
}
}}
TheService.java
public class TheService extends Service implements LocationListener {
LocationManager lm;
Location loc;
double lat = 0;
double lon = 0;
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
lm=(LocationManager)getSystemService(LOCATION_SERVICE);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, this);
loc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
onLocationChanged(loc);
return START_STICKY;
}
#Override
public void onCreate()
{
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
updateui(location);
}
private void updateui(Location location) {
// TODO Auto-generated method stub
lat = location.getLatitude();
lon = location.getLongitude();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Intent gps_intent = new Intent("Updated");
gps_intent.putExtra("lat", lat);
gps_intent.putExtra("lon", lon);
sendBroadcast(gps_intent);
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}}
You should use the Google Play Services for the location, that's easier to handle.
What for do you even need a Service? Having a location listener in your Activity is totally fine.
If you want to stay with the Service, than bind the Activity to it, instead of using a Broadcast.