googles中的android NetworkOnMainThreadException Credential.refreshToken()

时间:2014-05-07 16:26:51

标签: android android-asynctask google-oauth google-fusion-tables service-accounts

我有一个Android应用程序,应该使用谷歌融合表。我使用的是Google服务帐户,必须获取我的xxxxxxxxxxxprivatekey.p12的路径。

public class CredentialProvider {

...

private static String PRIVATE_KEY = "xxxxxxxxxxxprivatekey.p12";

...

public static GoogleCredential getCredential() throws IOException, GeneralSecurityException {        
        return getCredential(Arrays.asList(SCOPES), SERVICE_ACCOUNT_EMAIL, new File(PRIVATE_KEY), HTTP_TRANSPORT, JSON_FACTORY);
    }

...

}

代码想要从PRIVATE_KEY路径创建一个新文件。我尝试了各种途径,但每次我都获得FileNotFoundExceptionopen failed: ENOENT (No such file or directory)

我已经阅读了有关资产文件夹的内容,但我不知道如何使用getCredential方法完成这项工作。

  • 我必须将我的私钥放在我的Android项目中
  • PRIVATE_KEY路径如何显示
  • 我如何获得"新文件(PRIVATE_KEY)"工作

谢谢;)


修改

现在我在你的链接中覆盖GoogleCredential.Builder创建我自己的setServiceAccountPrivateKeyFromP12File(InputStream p12File),它似乎工作正常。但是在getCredential() refreshToken()中调用并在 NetworkOnMainThreadException 中崩溃。 我已经读过,我应该使用AsyncTask 。你能否给我一个提示,我必须把AsyncTask 里面的内容doInBackground() 以及onPostExecute()内的内容或任何方法?

以下是getCredential()的代码。它在refreshToken()中以 NetworkOnMainThreadException 崩溃:

public static GoogleCredential getCredential(List<String> SCOPE, String SERVICE_ACCOUNT_EMAIL, 
            InputStream inputStreamFromP12File, HttpTransport HTTP_TRANSPORT, JsonFactory JSON_FACTORY) 
            throws IOException, GeneralSecurityException {        
        // Build service account credential.

        MyGoogleCredentialBuilder builder = new MyGoogleCredentialBuilder();
        builder.setTransport(HTTP_TRANSPORT);
        builder.setJsonFactory(JSON_FACTORY);
        builder.setServiceAccountId(SERVICE_ACCOUNT_EMAIL);
        builder.setServiceAccountScopes(SCOPE);
        builder.setServiceAccountPrivateKeyFromP12File(inputStreamFromP12File);

        GoogleCredential credential = builder.build();

        credential.refreshToken();
        return credential;
    }

EDIT2: 最后,我这样解决了:

private static class RefreshTokenTask extends AsyncTask<GoogleCredential, Void, Void> {
        @Override
        protected Void doInBackground(GoogleCredential... params) {
            try {
                params[0].refreshToken();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    }

并在我的getCredential方法中:

new RefreshTokenTask().execute(credential);

1 个答案:

答案 0 :(得分:1)

您无法访问常规文件,因为这些文件与应用程序捆绑在一起。 这就是为什么new File(PRIVATE_KEY)无法正常工作的原因,也没有任何可以让它发挥作用的路径。

您可以做的是获取该文件的InputStream:

AssetManager assetManager = context.getAssets();
InputStream input = assetManager.open(PRIVATE_KEY);

如果您需要以文件形式访问它,则可以在首次启动应用程序时将其复制到应用程序的内部存储。我不确定这是最好的解决方案(出于安全原因,您可能不想将私钥存储在设备的内部存储中),但它应该可行。然后,您可以从context.getFilesDir ()文件夹中访问它。

InputStream fis = assetManager.open(PRIVATE_KEY);
FileOutputStream fos = openFileOutput(PRIVATE_KEY, Context.MODE_PRIVATE);
byte buf[] = new byte[1024];
int len;
while ((len = fis.read(buf)) > 0) {
  fos.write(buf, 0, len);
}
fis.close();
fos.close();