简体   繁体   中英

LocationClient works only on some devices

I'm trying to get user location in the background. Everything works great on my phone (htc one m7), but from some reason it's not working on two devices I tested: Samsung galaxy s3 Sony Xperia Z1

btw: I added everything to the manifest as it should be.

this is my code: **BackgroundLocationService **

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.location.LocationClient;
import com.google.android.gms.location.LocationRequest;

public class BackgroundLocationService extends Service implements
  GooglePlayServicesClient.ConnectionCallbacks,
  GooglePlayServicesClient.OnConnectionFailedListener {

IBinder mBinder = new LocalBinder();

private LocationClient mLocationClient;
private LocationRequest mLocationRequest;
// Flag that indicates if a request is underway.
private boolean mInProgress;

private Boolean servicesAvailable = false;

public class LocalBinder extends Binder {
    public BackgroundLocationService getServerInstance() {
        return BackgroundLocationService.this;
    }
}

@Override
public void onCreate() {
    super.onCreate();


    mInProgress = false;
    // Create the LocationRequest object
    mLocationRequest = LocationRequest.create();
    // Use high accuracy
    mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
    // Set the update interval to 5 seconds
    mLocationRequest.setInterval(0);
    // Set the fastest update interval to 1 second
    mLocationRequest.setFastestInterval(1);

    servicesAvailable = servicesConnected();

    /*
     * Create a new location client, using the enclosing class to
     * handle callbacks.
     */
    mLocationClient = new LocationClient(this, this, this);


}

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) {

        return true;
    } else {

        return false;
    }
}

public int onStartCommand (Intent intent, int flags, int startId)
{
    super.onStartCommand(intent, flags, startId);

    if(!servicesAvailable || mLocationClient.isConnected() || mInProgress)
        return START_STICKY;

    setUpLocationClientIfNeeded();
    if(!mLocationClient.isConnected() || !mLocationClient.isConnecting() && !mInProgress)
    {
        mInProgress = true;
        mLocationClient.connect();
    }

    return START_STICKY;
}

/*
 * Create a new location client, using the enclosing class to
 * handle callbacks.
 */
private void setUpLocationClientIfNeeded()
{
    if(mLocationClient == null) 
        mLocationClient = new LocationClient(this, this, this);
}

// Define the callback method that receives location updates


@Override
public IBinder onBind(Intent intent) {
    return mBinder;
}



public void appendLog(String text, String filename)
{       
   File logFile = new File(filename);
   if (!logFile.exists())
   {
      try
      {
         logFile.createNewFile();
      } 
      catch (IOException e)
      {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }
   }
   try
   {
      //BufferedWriter for performance, true to set append to file flag
      BufferedWriter buf = new BufferedWriter(new FileWriter(logFile, true)); 
      buf.append(text);
      buf.newLine();
      buf.close();
   }
   catch (IOException e)
   {
      // TODO Auto-generated catch block
      e.printStackTrace();
   }
}

@Override
public void onDestroy(){
    // Turn off the request flag
    mInProgress = false;
    if(servicesAvailable && mLocationClient != null) {
        //mLocationClient.removeLocationUpdates(callbackIntent);
        // Destroy the current location client
        mLocationClient = null;
    }
    // Display the connection status
    // Toast.makeText(this, DateFormat.getDateTimeInstance().format(new Date()) + ": Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show();
    super.onDestroy();  
}

/*
 * Called by Location Services when the request to connect the
 * client finishes successfully. At this point, you can
 * request the current location or start periodic updates
 */
@Override
public void onConnected(Bundle bundle) {

    // Request location updates using static settings
    Intent intent = new Intent(this, LocationReceiver.class);
      PendingIntent locationIntent = PendingIntent.getBroadcast(getApplicationContext(), 14872, intent, PendingIntent.FLAG_CANCEL_CURRENT);
      mLocationClient.requestLocationUpdates(mLocationRequest, locationIntent);
}

/*
 * Called by Location Services if the connection to the
 * location client drops because of an error.
 */
@Override
public void onDisconnected() {
    // Turn off the request flag
    mInProgress = false;
    // Destroy the current location client
    mLocationClient = null;
    // Display the connection status
    // Toast.makeText(this, DateFormat.getDateTimeInstance().format(new Date()) + ": Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show();
}

/*
 * Called by Location Services if the attempt to
 * Location Services fails.
 */
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
    mInProgress = false;

    /*
     * 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()) {

    // If no resolution is available, display an error dialog
    } else {

    }
}


}

**LocationReceiver **

import java.util.List;
import java.util.Locale;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
 import android.util.Log;

import com.google.android.gms.location.LocationClient;

public class LocationReceiver extends BroadcastReceiver {
public static double lat;
public static double alt;
public static String address;


@Override
public void onReceive(Context context, Intent intent) {

    Location location = (Location) intent.getExtras().get(LocationClient.KEY_LOCATION_CHANGED);
    Log.d("New Location Reciver", "location "+location.toString());

    lat = location.getLatitude();
    alt = location.getAltitude();
    address = getAddressByCord(lat, alt, context);
}


public static String getAddressByCord(double lat, double longi, Context context) {

    try {
        Geocoder geo = new Geocoder(context, Locale.getDefault());
        List<Address> addresses = geo.getFromLocation(lat, longi, 1);
        if (addresses.isEmpty()) {
            return "Waiting for Location";
        } else {
            if (addresses.size() > 0) {
                String s = "";
                if (addresses.get(0).getFeatureName() != null)
                    s += addresses.get(0).getFeatureName();
                if (addresses.get(0).getThoroughfare() != null)
                    s += "," +          addresses.get(0).getThoroughfare();
                if (addresses.get(0).getLocality() != null)
                    s += "," + addresses.get(0).getLocality();
                if (addresses.get(0).getAdminArea() != null)
                    s += "," + addresses.get(0).getAdminArea();
                if (addresses.get(0).getCountryName() != null)
                    s += "," +   addresses.get(0).getCountryName();
                return s;
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return "";
}
}

if someone has any idea, Thank you!

code to check for google play services.

private static final int CONNECTION_FAILURE_RESOLUTION_REQUEST = 94378;

private boolean isGooglePlay() {
    int mIsGooglePlayServicesAvailable = GooglePlayServicesUtil
            .isGooglePlayServicesAvailable(context);

    switch (mIsGooglePlayServicesAvailable) {
    case ConnectionResult.SUCCESS:
        return true;
    default:
        Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(
                mIsGooglePlayServicesAvailable, this,
                CONNECTION_FAILURE_RESOLUTION_REQUEST);
        // If Google Play services can provide an error dialog
        if (errorDialog != null) {
            // Create a new DialogFragment for the error dialog
            ErrorDialogFragment errorFragment = new ErrorDialogFragment();
            // Set the dialog in the DialogFragment
            errorFragment.setDialog(errorDialog);
            // Show the error dialog in the DialogFragment
            errorFragment.show(getSupportFragmentManager(),
                    "Location Updates");
        }
        // case ConnectionResult.SERVICE_MISSING:
        // case ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED:
        // case ConnectionResult.SERVICE_DISABLED:
        // case ConnectionResult.SERVICE_INVALID:
        // case ConnectionResult.DATE_INVALID:
    }
    return false;
}

/*
 * This is a class used to resolve errors with google play services It is
 * copied code that doesn't run durring normal operation.
 */
public static class ErrorDialogFragment extends DialogFragment {
    // Global field to contain the error dialog
    private Dialog mDialog;

    // Default constructor. Sets the dialog field to null
    public ErrorDialogFragment() {
        super();
        mDialog = null;
    }

    // Set the dialog to display
    public void setDialog(Dialog dialog) {
        mDialog = dialog;
    }

    // Return a Dialog to the DialogFragment.
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        return mDialog;
    }
}

I found the answer. It was the devices own definitions. The device was not enabling apps to use location .

thank you anyway!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM