android - 运行时位置权限 - GoogleApiClient 尚未连接

标签 android runtime android-permissions google-api-client

我正在编写基于位置的应用程序。我的位置对于 API < 23 工作正常,但每当我在 API 23 的设备上运行时,它都会给出错误“GoogleApiClient 尚未连接”。

我检查了 GoogleApiClient 已连接的日志。但我不明白这是什么问题。以下是应用程序崩溃前的日志。

01-13 05:20:26.200 2028-2028/com.example.raj.wallpaper1 D/numbering: startGoogleApiClient
01-13 05:20:26.206 2028-2028/com.example.raj.wallpaper1 D/numbering: onCreate
01-13 05:20:26.233 2028-2028/com.example.raj.wallpaper1 D/numbering: onStart
01-13 05:20:26.233 2028-2028/com.example.raj.wallpaper1 D/numbering: onResume

01-13 05:20:26.452 2028-2028/com.example.raj.wallpaper1 D/numbering: Location services connected.
01-13 05:20:26.453 2028-2028/com.example.raj.wallpaper1 D/numbering: googleApiClient: com.google.android.gms.internal.zzaal@d66379f
01-13 05:20:26.453 2028-2028/com.example.raj.wallpaper1 D/numbering: startLocationUpdates()
01-13 05:20:26.453 2028-2028/com.example.raj.wallpaper1 D/numbering: checkPermission()
01-13 05:20:26.453 2028-2028/com.example.raj.wallpaper1 D/numbering: googleApiClient: com.google.android.gms.internal.zzaal@d66379f
01-13 05:20:26.453 2028-2028/com.example.raj.wallpaper1 D/numbering: askPermission()
01-13 05:20:26.553 2028-2028/com.example.raj.wallpaper1 D/numbering: onResume
01-13 05:20:47.053 2028-2028/com.example.raj.wallpaper1 D/numbering: onRequestPermissionsResult()
01-13 05:20:47.058 2028-2028/com.example.raj.wallpaper1 D/numbering: startLocationUpdates()
01-13 05:20:47.058 2028-2028/com.example.raj.wallpaper1 D/numbering: checkPermission()
01-13 05:20:47.059 2028-2028/com.example.raj.wallpaper1 D/numbering: googleApiClient: com.google.android.gms.internal.zzaal@d66379f
01-13 05:20:47.059 2028-2028/com.example.raj.wallpaper1 D/numbering: startLocationServices

我的错误日志:

Process: com.example.raj.wallpaper1, PID: 2028
                                                                      java.lang.RuntimeException: Failure delivering result ResultInfo{who=@android:requestPermissions:, request=940, result=-1, data=Intent { act=android.content.pm.action.REQUEST_PERMISSIONS (has extras) }} to activity {com.example.raj.wallpaper1/com.example.raj.wallpaper1.CuisinesList}: java.lang.IllegalStateException: GoogleApiClient is not connected yet.
                                                                          at android.app.ActivityThread.deliverResults(ActivityThread.java:3720)
                                                                          at android.app.ActivityThread.handleSendResult(ActivityThread.java:3763)
                                                                          at android.app.ActivityThread.-wrap16(ActivityThread.java)
                                                                          at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1403)
                                                                          at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                          at android.os.Looper.loop(Looper.java:148)
                                                                          at android.app.ActivityThread.main(ActivityThread.java:5443)
                                                                          at java.lang.reflect.Method.invoke(Native Method)
                                                                          at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
                                                                          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
                                                                       Caused by: java.lang.IllegalStateException: GoogleApiClient is not connected yet.
                                                                          at com.google.android.gms.internal.zzaak.zzb(Unknown Source)
                                                                          at com.google.android.gms.internal.zzaan.zzb(Unknown Source)
                                                                          at com.google.android.gms.internal.zzaal.zzb(Unknown Source)
                                                                          at com.google.android.gms.internal.zzarl.requestLocationUpdates(Unknown Source)
                                                                          at com.example.raj.wallpaper1.CuisinesList.startLocationUpdates(CuisinesList.java:384)
                                                                          at com.example.raj.wallpaper1.CuisinesList.onRequestPermissionsResult(CuisinesList.java:419)
                                                                          at android.app.Activity.dispatchRequestPermissionsResult(Activity.java:6567)
                                                                          at android.app.Activity.dispatchActivityResult(Activity.java:6446)
                                                                          at android.app.ActivityThread.deliverResults(ActivityThread.java:3716)
                                                                          at android.app.ActivityThread.handleSendResult(ActivityThread.java:3763) 
                                                                          at android.app.ActivityThread.-wrap16(ActivityThread.java) 
                                                                          at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1403) 
                                                                          at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                          at android.os.Looper.loop(Looper.java:148) 
                                                                          at android.app.ActivityThread.main(ActivityThread.java:5443) 
                                                                          at java.lang.reflect.Method.invoke(Native Method) 
                                                                          at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728) 
                                                                          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 

这是我正在尝试运行的代码。

    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_cuisines_list);

    startGoogleApiClient();
latitude = (TextView) findViewById(R.id.latitude);
    longitude = (TextView) findViewById((R.id.longitude));
}

@Override
protected void onStart() {
    super.onStart();
    Log.d("numbering", "onStart");
    googleApiClient.connect();
}

@Override
protected void onResume() {
    Log.d("numbering", "onResume");
    super.onResume();

}

@Override
protected void onPause() {
    super.onPause();
    if (googleApiClient.isConnected()) {
        LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, this);
        googleApiClient.disconnect();
    };
}

public void startGoogleApiClient()
{
    Log.d("numbering", "startGoogleApiClient");
    googleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();


}

public void startLocationServices()
{
    Log.d("numbering", "startLocationServices");
    locationRequest = LocationRequest.create()
            .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
            .setInterval(10 * 1000)   ;     // 10 seconds, in milliseconds

}

@Override
public void onConnected(@Nullable Bundle bundle) {

    Log.d("numbering", "Location services connected.");
    Log.d("numbering", "googleApiClient: " + googleApiClient.toString());
    startLocationUpdates();
}

@Override
public void onConnectionSuspended(int i) {

}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    if (connectionResult.hasResolution() && this instanceof Activity) {
        try {
            Activity activity = (Activity) this;
            // Start an Activity that tries to resolve the error
            connectionResult.startResolutionForResult(activity, 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.
         */
        Log.d("numbering", "Location services connection failed with code " + connectionResult.getErrorCode());
    }

}

@Override
public void onLocationChanged(Location location) {
    Log.d("numbering", "onLocationChanged()");
    if(googleApiClient.isConnected()) {
        latitude.setText(String.valueOf(location.getLatitude()));
        longitude.setText(String.valueOf(location.getLongitude()));
    }
}

public  void startLocationUpdates() {
    Log.d("numbering", "startLocationUpdates()");

    if ( checkPermission() ) {
        Log.d("numbering", "googleApiClient: " + googleApiClient.toString());
        startLocationServices();
        LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
    }
    else
    {
        Log.d("numbering", "googleApiClient: " + googleApiClient.toString());
        askPermission();
    }

}

private boolean checkPermission() {
    Log.d("numbering", "checkPermission()");
    // Ask for permission if it wasn't granted yet
    return (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
            == PackageManager.PERMISSION_GRANTED );
}

private void askPermission() {
    Log.d("numbering", "askPermission()");
    ActivityCompat.requestPermissions(
            this,
            new String[] { Manifest.permission.ACCESS_FINE_LOCATION },
            REQ_PERMISSION
    );
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    Log.d("numbering", "onRequestPermissionsResult()");
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch ( requestCode ) {
        case REQ_PERMISSION: {
            if ( grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED ){
                // Permission granted
                startLocationUpdates();

            } else {
                // Permission denied
                permissionsDenied();
            }
            break;
        }
    }
}

private void permissionsDenied() {
    Log.d("numbering", "permissionsDenied()");
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)) {
            showMessageOKCancel("You need to allow locationForService permissions to run the application ",
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                                requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                                        REQ_PERMISSION);
                            }
                        }
                    });
            Log.w("numbering", "permissionsDenied()");
        }
        return;
    }
}


private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
    new AlertDialog.Builder(this)
            .setMessage(message)
            .setPositiveButton("OK", okListener)
            .setNegativeButton("Cancel", null)
            .create()
            .show();
}

我已经尝试了所有我能想到的可能的解决方案。请让我知道我缺少什么。

最佳答案

问题出在 onRequestPermissionsResult 方法中。

授予所需的权限后,方法 startLocationUpdates() 在 GoogleApiClient 能够正确连接之前被调用。 您应该将 startLocationUpdates() 放在 onConnect() 回调方法中,以确保正确初始化和连接 GoogleApiClient

这种情况仅从 API 23 开始发生的原因是,您将仅从该 API 开始结束调用此方法,该 API 改变了向用户请求某些权限的方式

关于android - 运行时位置权限 - GoogleApiClient 尚未连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41625326/

相关文章:

javascript - Cordova minifier 不会缩小浏览器平台

c - 如何保证数组内指针比较的有效性?

Java:在运行时将类添加到 Jar 存档

android - 即时应用相机 Intent

java - 如何*正确*请求权限?

android - 应用程序启动后选择默认选项卡

Android Webview 视口(viewport)问题

ListView 中的 Android Universal ImageLoader 滚动非常慢

java - 当涉及多态时如何确定JAVA类中使用的变量

android - Caused by : java. lang.SecurityException: "gps"location provider requires ACCESS_FINE_LOCATION 权限