Google Endpoints - Android GoogleAuthIOException T

2019-04-01 23:20发布

I downloaded the Google Endpoints Tic Tac Toe example - the server code in Java.

Just to quickly run it up, I removed the clientIds from the API definition, so I could quickly see it working in the API Explorer:

@Api(name = "tictactoe", version = "v1")
public class ScoresV1
{
...

I could run the following method just fine using the API Explorer, with OAuth turned on and authenticating with my gmail accoumnt. I could see the "user" object set to that account in the debugger:

@ApiMethod(name = "scores.list")
@SuppressWarnings("unchecked")
public List<Score> list(@Nullable @Named("limit") String limit,
        @Nullable @Named("order") String order, User user)
        throws OAuthRequestException, IOException
{
    ...

I then went ahead and generated the Android client (with the clientIds still removed). I also downloaded the official Android app to get the UI classes and res files (account picker and the game interface).

And this is where I'm stuck. When running on a real Android device, the following code in TictactoeActivity threw a GoogleAuthIOException:

    @Override
    protected ScoreCollection doInBackground(Void... unused)
    {
        ScoreCollection scores = null;
        try
        {
            scores = service.scores().list().execute();
        }
        catch (IOException e)
        {
            e.printStackTrace();

Here's the exception:

02-21 16:38:47.051: D/TicTacToe(6151): com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAuthIOException
02-21 16:38:47.051: D/TicTacToe(6151):  at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential$RequestHandler.intercept(GoogleAccountCredential.java:286)
02-21 16:38:47.051: D/TicTacToe(6151):  at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:858)
...

Digging a bit more into the source, I found the root exception was thrown by this code in GoogleAuthUtil.getToken(), which is somewhat unhelpful:

com.google.android.gms.auth.GoogleAuthException: Unknown

Now, I have a breakpoint on the local dev server at ScoreV1.list(), which was hit when testing with the API Explorer, but the Android client failed without even hitting the server. Now, "-a 0.0.0.0" was set on the local dev server to accept incoming connections. I've checked the URL is correct as well, and I could run the following URL from the phone's Chrome browser (it gave me an Auth error since no user was set, but that's okay):

http://192.168.2.23:8888/_ah/api/tictactoe/v1/score?limit=1&order=1

So I know the network is working and the phone had access to it. I've also verified that AndroidManifest.xml has the following permissions set:

<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="14"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />

Here's the code showing my URL and path in TicTacToe.java:

    public static final String DEFAULT_ROOT_URL = "http://192.168.2.23:8888/_ah/api/";

/**
 * The default encoded service path of the service. This is determined when
 * the library is generated and normally should not be changed.
 * 
 * @since 1.7
 */
public static final String DEFAULT_SERVICE_PATH = "tictactoe/v1/";

/**
 * The default encoded base URL of the service. This is determined when the
 * library is generated and normally should not be changed.
 */
public static final String DEFAULT_BASE_URL = DEFAULT_ROOT_URL
        + DEFAULT_SERVICE_PATH;
...

Now, the thing that really baffles me is even if I change the DEFAULT_ROOT_URL to something random, like 5.5.5.5, I get the exact same GoogleAuthIOException! I would expected to get a different exception when the host is unreachable...

Also, I tried deploying the server to production, and repoint the URL to the [myapp].appspot.com address - same result. The server Log never registered a request coming in.

As it is, I'm now really stuck. Please do help! Thanks a million!!!

2条回答
男人必须洒脱
2楼-- · 2019-04-01 23:46

The error is most likely due to the authorization not happening between your Android application and the Cloud Endpoints API.

Since I do not have full access to your actual Endpoint API annotations and the Android code, I would suggest that you look at the following points closely:

  • Ensure that you have annotated your Cloud Endpoints API correctly with the clientIds and audiences. The Android Audience value is the same as that of the Web Client Id.

  • Make sure you have deployed the updated API and regenerated the Endpoints API sources for inclusion in your Android application.

  • Finally, in your Androids source code, you must build an instance of the GoogleAccountCredential, using the GoogleAccountCredential.usingAudience(...) and then use this credential object while making a call to the endpoint API. For e.g. the Endpoint builder takes a HTTP Transport, GSON Factory and the Credential. Do not leave the last parameter (i.e. Credential) as empty.

查看更多
\"骚年 ilove
3楼-- · 2019-04-01 23:57

I was also getting a similar GoogleAuthIOException exception:

com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAuthIOException
at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential$RequestHandler.intercept(GoogleAccountCredential.java:286)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:859)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:410)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:343)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:460)
at com.example.MainActivity$ListPartiesTask.doInBackground(MainActivity.java:188)
at com.example.MainActivity$ListPartiesTask.doInBackground(MainActivity.java:178)
at android.os.AsyncTask$2.call(AsyncTask.java:287)
at java.util.concurrent.FutureTask.run(FutureTask.java:234)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:841)
Caused by: com.google.android.gms.auth.GoogleAuthException: Unknown
at com.google.android.gms.auth.GoogleAuthUtil.zzb(Unknown Source)
at com.google.android.gms.auth.GoogleAuthUtil.zza(Unknown Source)
at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source)
at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source)
at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source)
at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential.getToken(GoogleAccountCredential.java:255)
at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential$RequestHandler.intercept(GoogleAccountCredential.java:279)
... 12 more

Turns out I needed to create a Client ID with the sha1 fingerprint of the debug version of the app (I had already created one for the signed version of the app, but if you haven't done that you'll need to do that too).

You can get the fingerprint with the following command (on a Mac, address of debug.keystore might be different on other systems):

keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android

If you need to get the fingerprint for your release key you can do this:

keytool -list -v -keystore /PATH/TO/YOUR/release-key.jks -alias RELEASE_KEY_ALIAS
查看更多
登录 后发表回答