android - 使用服务帐户从android更新谷歌表?
问题描述
在使用服务帐户将 Android 应用程序的数据记录到 Google 表格时,我需要帮助。我阅读了数百个线程,这些线程大多使用已弃用的 Google 凭据,但这些凭据不起作用。有人可以帮助或知道如何在 Google 表格中写一行(数据)吗?
更新:
在我的 gradle 中,我添加了这个:
implementation 'com.google.android.gms:play-services-auth:19.0.0'
implementation 'pub.devrel:easypermissions:0.3.0'
implementation('com.google.api-client:google-api-client-android:1.23.0') {
exclude group: 'org.apache.httpcomponents'
}
implementation('com.google.apis:google-api-services-sheets:v4-rev581-1.25.0') {
exclude group: 'org.apache.httpcomponents'
}
implementation 'com.google.oauth-client:google-oauth-client-jetty:1.23.0'
这是我从谷歌表中阅读的课程,如谷歌示例所示:
public class GoogleSheetHelper {
private static final String APPLICATION_NAME = "Google Sheets API Java Quickstart";
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
private static final String TOKENS_DIRECTORY_PATH = "tokens";
private static final List<String> SCOPES = Collections.singletonList(SheetsScopes.SPREADSHEETS_READONLY);
private static final String CREDENTIALS_FILE_PATH = "/credentials.json";
private static Credential getCredentials(final NetHttpTransport HTTP_TRANSPORT, Context context) throws IOException {
// Load client secrets.
//InputStream in = GoogleSheetHelper.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
InputStream in = context.getAssets().open("credentials.json");;
if (in == null) {
throw new FileNotFoundException("Resource not found: " + CREDENTIALS_FILE_PATH);
}
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
File tokenFolder = new File(Environment.getExternalStorageDirectory() +
File.separator + TOKENS_DIRECTORY_PATH);
if (!tokenFolder.exists()) {
boolean success = tokenFolder.mkdirs();
if( !success ){
throw new RuntimeException("File Error in writing new folder");
}
}
FileDataStoreFactory f = new FileDataStoreFactory(tokenFolder);
// Build flow and trigger user authorization request.
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
.setDataStoreFactory(f)
.setAccessType("offline")
.build();
//LocalServerReceiver receiver = new LocalServerReceiver.Builder().setPort(8888).build();
return new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
}
public static void napravi(Context context) throws IOException, GeneralSecurityException {
// Build a new authorized API client service.
//final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
final NetHttpTransport HTTP_TRANSPORT = new com.google.api.client.http.javanet.NetHttpTransport();
final String spreadsheetId = "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms";
final String range = "Class Data!A2:E";
Sheets service = new Sheets.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT, context))
.setApplicationName(APPLICATION_NAME)
.build();
ValueRange response = service.spreadsheets().values()
.get(spreadsheetId, range)
.execute();
List<List<Object>> values = response.getValues();
if (values == null || values.isEmpty()) {
System.out.println("No data found.");
} else {
System.out.println("Name, Major");
for (List row : values) {
System.out.printf("%s, %s\n", row.get(0), row.get(4));
}
}
}
因为我在 MainActivity 中得到 NetworkOnMainThreadException,所以我在 Thread 中调用它:
new Thread(() -> {
try {
GoogleSheetHelper.napravi(getApplicationContext());
} catch (IOException e) {
e.printStackTrace();
} catch (GeneralSecurityException e) {
e.printStackTrace();
}
runOnUiThread(()->{
// OnPostExecute stuff here
});
}).start();
但我现在得到了这个例外:
2020-11-26 06:50:06.447 30966-31002/hr.krkec.orchestrabarcodeapp E/AndroidRuntime: FATAL EXCEPTION: Thread-3
Process: hr.krkec.orchestrabarcodeapp, PID: 30966
java.lang.NoClassDefFoundError: Failed resolution of: Ljava/awt/Desktop;
at com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp.browse(AuthorizationCodeInstalledApp.java:129)
at com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp.onAuthorization(AuthorizationCodeInstalledApp.java:113)
at com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp.authorize(AuthorizationCodeInstalledApp.java:81)
at hr.krkec.orchestrabarcodeapp.Helpers.GoogleSheetHelper.getCredentials(GoogleSheetHelper.java:75)
at hr.krkec.orchestrabarcodeapp.Helpers.GoogleSheetHelper.napravi(GoogleSheetHelper.java:89)
at hr.krkec.orchestrabarcodeapp.MainActivity.lambda$onCreate$1$MainActivity(MainActivity.java:112)
at hr.krkec.orchestrabarcodeapp.-$$Lambda$MainActivity$dMONIKNVXAJxtq31-j2RI7GKpKk.run(Unknown Source:2)
at java.lang.Thread.run(Thread.java:764)
Caused by: java.lang.ClassNotFoundException: Didn't find class "java.awt.Desktop" on path: DexPathList[[zip file "/data/app/hr.krkec.orchestrabarcodeapp-DmJDmyzrsZ1Fz0c3Wtg9xg==/base.apk"],nativeLibraryDirectories=[/data/app/hr.krkec.orchestrabarcodeapp-DmJDmyzrsZ1Fz0c3Wtg9xg==/lib/x86, /data/app/hr.krkec.orchestrabarcodeapp-DmJDmyzrsZ1Fz0c3Wtg9xg==/base.apk!/lib/x86, /system/lib, /vendor/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:93)
at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
at com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp.browse(AuthorizationCodeInstalledApp.java:129)
at com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp.onAuthorization(AuthorizationCodeInstalledApp.java:113)
at com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp.authorize(AuthorizationCodeInstalledApp.java:81)
at hr.krkec.orchestrabarcodeapp.Helpers.GoogleSheetHelper.getCredentials(GoogleSheetHelper.java:75)
at hr.krkec.orchestrabarcodeapp.Helpers.GoogleSheetHelper.napravi(GoogleSheetHelper.java:89)
at hr.krkec.orchestrabarcodeapp.MainActivity.lambda$onCreate$1$MainActivity(MainActivity.java:112)
at hr.krkec.orchestrabarcodeapp.-$$Lambda$MainActivity$dMONIKNVXAJxtq31-j2RI7GKpKk.run(Unknown Source:2)
at java.lang.Thread.run(Thread.java:764)
我究竟做错了什么?
解决方案
如果您正在寻找一种通过 Android SDK 在您的 android 应用程序中使用 Google Sheets API 的方法,这可能会对您有所帮助。
为 Android 设置 Google Workspace API https://developers.google.com/gsuite/guides/android
先决条件:
- 必须有一个谷歌帐户
- Android Studio SDK 1.2 或更高版本
- 适用于 API 23 或更高版本的 Android SDK 包
准备项目:
在您的 Android 项目中,包含一个带有以下依赖项的build.gradle文件:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:25.0.1'
compile 'com.google.android.gms:play-services-auth:15.0.1'
compile 'pub.devrel:easypermissions:0.3.0'
compile('com.google.api-client:google-api-client-android:1.23.0') {
exclude group: 'org.apache.httpcomponents'
}
compile('com.google.apis:google-api-services-<API>-<VERSION>') {
exclude group: 'org.apache.httpcomponents'
}
}
请务必将API和VERSION替换为 Google Workspace API 和版本。例如,Google Sheets API 将使目标编译“ com.google.apis:google-api-services-sheets:v4-rev581-1.25.0 ”
服务通过身份验证后,执行 API 调用与任何 G Suite Java 快速入门中所示的相同。
Java 快速入门过程总结:
- 开启 Google 表格 API
- 准备项目
- 设置示例
- 运行示例
有关 Java 快速入门的更多详细信息,请参阅此处: https ://developers.google.com/sheets/api/quickstart/java
推荐阅读
- gitkraken - 在 GitKraken 中提交。使摘要成为必填项
- ansible - anislble with_items with_nested 在角色任务内的循环中
- ios - 快速从一个模态 VC 转换到另一个模态 VC
- github - 如何向我只有他的电子邮件的人发送拉取请求
- c# - 尽管有全局范围,但 Unity 刚体拒绝存在
- css - SquareSpace 的 SASS Escape Calc
- microservices - 使用 Ribbon 和 Hystrix 自定义重试行为
- javascript - HTML5 视频的自定义控件不起作用
- c# - 如何使用 C# 调用队列客户端 sendasync 方法
- regex - 正则表达式捕获:和@