我有一个Android应用程序,应该使用Google融合表。我正在使用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)时,都尝试过。

我已经阅读了一些有关Assets文件夹的内容,但是我不知道如何使用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;
    }




编辑2:
最后,我以这种方式解决了这个问题:

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);

最佳答案

您无法像访问常规文件那样访问资产,因为这些文件与应用程序捆绑在一起。
这就是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();

10-08 07:19