我有一个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
路径创建一个新文件。我尝试了各种途径,但每次我都获得FileNotFoundException
和open failed: ENOENT (No such file or directory)
。
我已经阅读了有关资产文件夹的内容,但我不知道如何使用getCredential方法完成这项工作。
谢谢;)
修改
现在我在你的链接中覆盖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);
答案 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();