使用GooglePlayServicesUtil进行奇怪的对话

时间:2014-06-27 10:38:35

标签: android

我正在检查设备上的Google Play服务的可用性。我用这些代码做到了:

final int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS) {
 final DialogInterface.OnCancelListener cancelListener = new DialogInterface.OnCancelListener() {
                @Override
                public void onCancel(final DialogInterface dialog) {
                    finish();
                }
            };
            final Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(
                    resultCode, this, GOOGLE_PLAY_SERVICES_REQUEST_CODE, cancelListener
            );
            errorDialog.show();
}

我得到resultCode = 2(这意味着Google Play服务需要更新)。显示对话框,但不是文本,而是获得布局的路径。

enter image description here

看起来PlaYServices lib中的app和资源中存在一些资源干扰。但它是如何可能以及如何避免id?

6 个答案:

答案 0 :(得分:2)

由于接受的答案有点不清楚,我会留下一个路标,我的结论(大多是从问题的评论中提取出来),我认为这是正确的。

简短版本:此应用似乎错误地生成了资源ID。

很明显,Google Play服务对话框旨在在这些地方显示字符串。 getErrorDialog()方法是这样实现的(混淆了,但意思仍然可以理解):

...
case 1: 
    return localBuilder.setTitle(R.string.common_google_play_services_install_title).create();
case 3: 
    return localBuilder.setTitle(R.string.common_google_play_services_enable_title).create();
case 2: 
   return localBuilder.setTitle(R.string.common_google_play_services_update_title).create();
...

此外,错误地执行getResources().getString(R.layout.my_layout)之类的操作将返回一个包含原始资源文件("res/layout/my_layout.xml")名称的字符串。

因此,我们可以得出结论,由于某种原因,Play服务库资源(例如com.google.android.gms.R.string.common_google_play_services_install_title)的值实际上与应用程序项目中的资源R.layout.dialog_share相同。

这可能导致错误的构建过程或Google Play服务库的错误使用(例如,直接包括其jar,没有相应的库过程)。

答案 1 :(得分:1)

我已使用Google Play服务库版本4452000测试代码(使用版本> = 4452000)。代码如下:

public class MainActivity extends Activity{
    ProgressBar pBar;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       final int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
       if (resultCode != ConnectionResult.SUCCESS) {
       final DialogInterface.OnCancelListener cancelListener = new DialogInterface.OnCancelListener() {
                    @Override
                    public void onCancel(final DialogInterface dialog) {
                        finish();
                    }
                };
                final Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(
                        resultCode, this, 10, cancelListener
                );
                errorDialog.show();
        }
    } 
}

检查您的Google Play服务版本并根据需要进行更新。

答案 2 :(得分:1)

这是我一直在努力检查谷歌游戏的课程。如果你遇到问题,它将在今年夏天晚些时候开始制作,如果有评论,请告诉我。它在zten9120和HTC EVO上进行了测试。流程是这样的。如果静态方法是Google Play(上下文),则返回false。初始化类并调用非静态isgoogleplay(),如果未安装googleplay服务,则会向用户显示该对话框。 oncofigurationchange方法处理设备何时旋转。 onstop将类设置为null。

修改活动中的三个事件。

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

    if (!MyGooglePlay.isGooglePlay(getApplicationContext())) {
        myGP = new MyGooglePlay(this);
        myGP.isGooglePlay();
    }


@Override
public void onStop() {
    super.onStop();
    myGP = null;
}


@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    if (myGP != null) {
        if (myGP.errorFragment.isVisible()) {
            myGP.errorFragment.dismissAllowingStateLoss();
        }
    }
}

这是我保存在单独的类

中的代码
package com.gosylvester.bestrides.util;

import android.app.Dialog;

import android.content.Context;
import android.content.IntentSender;

import android.os.Bundle;
import android.support.v4.app.DialogFragment;

import android.support.v4.app.FragmentManager;
import android.support.v7.app.ActionBarActivity;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;

public class MyGooglePlay {

    private static final int CONNECTION_FAILURE_RESOLUTION_REQUEST = 31502;
    private ActionBarActivity activity;
    private FragmentManager fragManager;

    public MyGooglePlay(ActionBarActivity activity) {
        this.activity = activity;
        this.fragManager = activity.getSupportFragmentManager();
    }

    public static boolean isGooglePlay(Context context) {
        return (GooglePlayServicesUtil.isGooglePlayServicesAvailable(context) == ConnectionResult.SUCCESS);
    }

    public boolean isGooglePlay() {
        if (isGooglePlay(activity)) {
            return true;
        } else {
            return checkGooglePlay();
        }
    }

    private static final String DIALOG_ERROR = "dialog_error";

    public ErrorDialogFragment errorFragment;

    private boolean checkGooglePlay() {
        int mIsGooglePlayServicesAvailable = GooglePlayServicesUtil
                .isGooglePlayServicesAvailable(activity);

        switch (mIsGooglePlayServicesAvailable) {
        case ConnectionResult.SUCCESS:
            return true;
        default:

            Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(
                    mIsGooglePlayServicesAvailable, activity,
                    CONNECTION_FAILURE_RESOLUTION_REQUEST);
            // If Google Play services can provide an error dialog
            if (errorDialog != null) {
                // Create a new DialogFragment for the error dialog
                errorFragment = ErrorDialogFragment.newInstance();
                // Set the dialog in the DialogFragment
                errorFragment.setDialog(errorDialog);

                // Show the error dialog in the DialogFragment
                errorFragment.show(fragManager, "LocationUpdates");
            }
            // case ConnectionResult.SERVICE_MISSING:
            // case ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED:
            // case ConnectionResult.SERVICE_DISABLED:
            // case ConnectionResult.SERVICE_INVALID:
            // case ConnectionResult.DATE_INVALID:
        }

        return false;
    }

    public void dismissMe() {
        DialogFragment frag = (DialogFragment) fragManager
                .findFragmentByTag("LocationUpdates");
        if (frag != null) {
            frag.dismissAllowingStateLoss();
        }
    }

    public static class ErrorDialogFragment extends DialogFragment {
        // Global field to contain the error dialog
        private Dialog mDialog;




        static ErrorDialogFragment newInstance() {
            ErrorDialogFragment d = new ErrorDialogFragment();
            return d;
        }

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


        public void onPause(){
            super.onPause();
            this.dismissAllowingStateLoss();
        }

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

    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(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.
             */
            showErrorDialog(connectionResult.getErrorCode(), activity);
        }
    }

    /* Creates a dialog for an error message */
    private void showErrorDialog(int errorCode, ActionBarActivity activity) {
        // Create a fragment for the error dialog
        ErrorDialogFragment dialogFragment = new ErrorDialogFragment();
        // Pass the error that should be displayed
        Bundle args = new Bundle();
        args.putInt(DIALOG_ERROR, errorCode);
        dialogFragment.setArguments(args);
        dialogFragment
                .show(activity.getSupportFragmentManager(), "errordialog");
    }

}

安装谷歌播放服务确实很好。

答案 3 :(得分:-2)

  public static boolean isGooglePlayServiceAvailable(Context context) {
    boolean isAvailable = false;
    int result = GooglePlayServicesUtil
            .isGooglePlayServicesAvailable(context);
    if (result == ConnectionResult.SUCCESS) {
        Log.d(TAG, "Play Service Available");
        isAvailable = true;
    } else {
        Log.d(TAG, "Play Service Not Available");
        if (GooglePlayServicesUtil.isUserRecoverableError(result)) {
            GooglePlayServicesUtil.getErrorDialog(result,
                    (Activity) context, PLAY_SERVICES_RESOLUTION_REQUEST)
                    .show();
        } else {
            Log.d(TAG, "Play Service Not Available");
            GooglePlayServicesUtil.getErrorDialog(result,
                    (Activity) context, PLAY_SERVICES_RESOLUTION_REQUEST)
                    .show();
        }
    }
    return isAvailable;
} 

答案 4 :(得分:-2)

更新的答案:(根据GooglePlayServicesUtil.getErrorDialog is null

如果设备上未安装Google Play服务,您可能无法使用错误对话框。

根据Rahim在上面的评论,如果你有一个" isUserRecoverableError"你应该只使用对话框。 (他的代码):

int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (status != ConnectionResult.SUCCESS) {
    if (GooglePlayServicesUtil.isUserRecoverableError(status)) {
    GooglePlayServicesUtil.getErrorDialog(status, this, 
    REQUEST_CODE_RECOVER_PLAY_SERVICES).show();
    } else {
      Toast.makeText(this, "This device is not supported.", Toast.LENGTH_LONG).show();
      finish();
    }
}

更新 - (来自http://www.riskcompletefailure.com/2013/03/common-problems-with-google-sign-in-on.html

  

在发布最新版本的Google Play服务时出现的另一个错误是使用ConnectionResult调用onConnectionFailed方法,该方法没有解决方案,并且错误代码为ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED。

     

正如您可能从名称中猜到的那样,这表明该设备上的Google Play服务版本太低。通常情况下,新版本会自动更新,但推出时总会有时间延迟,因此在更新发布时很可能会出现此错误。

     

您可以通过在GooglePlayServicesUtil上调用getErrorDialog来解决onConnectionFailed中的问题,但最好的方法是在尝试连接之前实际检查Google Play服务是否已安装且是最新的。您可以在文档中看到如何执行此操作的片段。

所以这表明这个错误(正如你自己所说)应该是可以恢复的,尽管请注意我已经做出粗体的条款。我不相信这个对话将永远可用。常识告诉我,这可能取决于您升级的版本。因此,我建议您明确检查错误是否已标记为可恢复。如果它被标记为可恢复,那么这看起来像是Google Play服务中的错误。

答案 5 :(得分:-4)

我找到了解决方案。我不承认它为什么会发生,但有一个解决方案。

我用maven构建了我的项目,并将google play服务框架作为android库项目。

今天,我已经迁移到gradle并包含依赖性GPS和gradle,它解决了我的问题。