Android:关闭位置时,Google Fused Location 不起作用

Posted

技术标签:

【中文标题】Android:关闭位置时,Google Fused Location 不起作用【英文标题】:Android: Google Fused Location doesn't work while location is turned off 【发布时间】:2017-01-06 16:10:07 【问题描述】:

getLastLocation() 在我的 6.0 Nexus 7 平板电脑上关闭手机位置时返回 NULL,但它在另一台设备上无需 GPS 即可工作。为什么会这样以及有什么方法可以解决它?我想关闭 GPS,只使用网络获取位置。

下面是我用来获取位置的类:

public class GPSCenter 
public static GoogleApiClient mGoogleApiClient;
public static Location mLastLocation;
private static Context mContext;

static GoogleApiClient.ConnectionCallbacks ccb = new GoogleApiClient.ConnectionCallbacks() 

    @Override
    public void onConnectionSuspended(int arg0) 
    

    @Override
    public void onConnected(Bundle arg0) 

        if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) 
            return;
        

        LocationRequest mLocationRequest = LocationRequest.create();
        mLocationRequest.setPriority(LocationRequest.PRIORITY_NO_POWER);

        mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
    
;
static GoogleApiClient.OnConnectionFailedListener odfl = new GoogleApiClient.OnConnectionFailedListener() 
    @Override
    public void onConnectionFailed(ConnectionResult arg0) 
    
;

public static synchronized void buildGoogleApiClient(Context c) 
    try 

        mContext = c;
        mGoogleApiClient = new GoogleApiClient.Builder(c)
                .addConnectionCallbacks(ccb)
                .addOnConnectionFailedListener(odfl)
                .addApi(LocationServices.API)
                .build();

        mGoogleApiClient.connect();
     catch (Exception ex) 
        Log.i("location", "error " + ex.toString());
        ex.printStackTrace();
    


public static double getLatitude(Context c) 
    try 
        return mLastLocation.getLatitude();
     catch (Exception ex) 
        return 0.0;
    


public static double getLongitude(Context c) 
    try 
        return mLastLocation.getLongitude();
     catch (Exception ex) 
        return 0.0;
    


【问题讨论】:

你找到解决办法了吗 @M.Yogeshwaran 是的,请检查下面的答案:) 【参考方案1】:

这不是因为 GPS 的问题,而是设备中尚未启用 Location Settings,它位于您的设备设置>Google>服务>位置,或设置>隐私和安全>位置,或只是设置>地点。我很困惑,因为在某些设备中,下拉状态栏显示 GPS 启用按钮,有些显示位置启用按钮。 有一种方法可以自动启用位置设置(无需将用户导航到设备设置),它解决了我的问题,希望对您有所帮助:

GoogleApiClient 连接后,进行如下位置设置检查:

public static GoogleApiClient mGoogleApiClient;
private static PendingResult<LocationSettingsResult> result;
private static LocationSettingsRequest.Builder builder;
public static Location mLastLocation;
public static boolean isLocationON = false;

public static synchronized void buildGoogleApiClient(Activity a, Context c) 

    try 

        mActivity = a;
        mContext = c;
        mGoogleApiClient = new GoogleApiClient.Builder(c)
                .addConnectionCallbacks(ccb)
                .addOnConnectionFailedListener(odfl)
                .addApi(LocationServices.API)
                .build();

        builder = new LocationSettingsRequest.Builder()
                .addLocationRequest(locationRequest);
        builder.setAlwaysShow(true);

        mGoogleApiClient.connect();

     catch (Exception ex) 
        ex.printStackTrace();
    


private static GoogleApiClient.ConnectionCallbacks ccb = new GoogleApiClient.ConnectionCallbacks() 

    @Override
    public void onConnected(Bundle arg0) 
        checkLocationSettings();
    

    @Override
    public void onConnectionSuspended(int arg0) 
    
;

private static void checkLocationSettings() 

    result = LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());

    result.setResultCallback(new ResultCallback<LocationSettingsResult>() 

        @Override
        public void onResult(@NonNull LocationSettingsResult locationSettingsResult) 
            final Status status = locationSettingsResult.getStatus();
            switch (status.getStatusCode()) 
                case LocationSettingsStatusCodes.SUCCESS:

                    isLocationON = true;

                    if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) 
                        return;
                    
                    mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);

                    if (mLocationSettingsListener != null) 
                        mLocationSettingsListener.onLocationON();
                    

                    break;

                case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:

                    isLocationON = false;

                    try 
                        // This line will check the result and prompt a dialog if the device location settings is not enabled
                        status.startResolutionForResult(mActivity, REQUEST_CHECK_SETTINGS);

                     catch (IntentSender.SendIntentException e) 
                    
                    break;

                case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                    isLocationON = false;
                    // Location settings are unavailable so not possible to show any dialog now
                    if (mLocationSettingsListener != null) 
                        mLocationSettingsListener.onLocationError();
                    
                    break;
            
        
    );

【讨论】:

谢谢@BeeingJK 是否可以在后台运行这些东西 您可以使用服务在后台运行它。位置服务here 的即时示例(我从未尝试过),它包括Google Play 服务检查和位置更新监听器的功能,您可以在连接GoogleApiClient 后,在请求位置之前执行checkLocationSettings 相同的操作。但是对于startResolutionForResult,您可能需要一个 dialogActivity,因为它需要一个活动来提示对话框。为了简化它,我只是将这些东西放在一个类中并从活动中调用,并在位置打开时进行回调 @BeeingJk 但你的问题是如何在不启用 GPS 的情况下获取位置。但是在这里你启用了 gps。不是吗?【参考方案2】:

通过 Google Api 我认为这是不可能的。为此,您需要使用一些 api 进行 ip 地理定位,或者您可以使用 MNC-Mobile 网络位置或 MCC-Mobile 国家代码,您可以获得。 它可能会帮助你。

【讨论】:

感谢您的回复,您的“不可能”是否意味着Google Fused Location 在没有开启 GPS 的情况下无法获取设备位置?但它适用于其他设备【参考方案3】:

以下解释不返回任何位置值部分:LocationRequest.PRIORITY_NO_POWER:

除非其他客户请求,否则不会返回任何位置 位置更新在这种情况下,此请求将充当被动请求 那些位置的听众。

对于FusedLocationProvider,

no explicitly unique source is specified anywhere within documentation。

因此,在不启用 GPS 的情况下获取位置,您可以信任 PRIORITY_BALANCED_POWER_ACCURACY。据我观察,只有PRIORITY_HIGH_ACCURACY 强制使用 GPS。

平板电脑可能只有 wifi 或没有 SIM 卡,与其他设备不同,它排除了其他应用程序获取位置的情况 - 可能使用网络。

【讨论】:

感谢您的解释,我已将PRIORITY_NO_POWER 替换为PRIORITY_BALANCED_POWER_ACCURACY,但是当它的位置关闭时,平板电脑仍然返回NULL,您知道吗?【参考方案4】:

您必须在模拟器中将位置精度设置为仅设备。模拟器中的FusedLocationProviderApi 将无法使用高精度或省电模式。

【讨论】:

以上是关于Android:关闭位置时,Google Fused Location 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

如何在服务中使用 Fuse android 位置提供程序?

Android:如何在用户关闭位置设置时获取地理围栏事件?

Android GEO位置教程[关闭]

在设备位置关闭时从 Google Play 服务获取最后一个已知位置

使用Google Play服务位置API来监听位置服务更新

提交到 Google Play 时出错 - Android 应用程序 [关闭]