我一直在开发一款应用程序,可以在某些时刻将一小部分数据发送回Google Sheet,但是我无法让它正常工作:
public void SheetUpdate() {
GoogleAccountCredential mCredential;
Sheets mService;
final String[] SCOPES = { SheetsScopes.SPREADSHEETS };
mCredential = GoogleAccountCredential.usingOAuth2(getApplicationContext(), Arrays.asList(SCOPES))
.setBackOff(new ExponentialBackOff())
.setSelectedAccountName("oscarcookeabbott@gmail.com");
Log.e("DEBUG", "SheetUpdate: " + mCredential.getSelectedAccountName());
HttpTransport transport = AndroidHttp.newCompatibleTransport();
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
mService = new Sheets.Builder(transport, jsonFactory, mCredential)
.setApplicationName("Listeau")
.build();
/*
String range = "[Sheet Name]![Start]:[End]";
mService.spreadsheets().values().update(enumId, range, valueRange)
.setValueInputOption("RAW")
.execute();
*/
ValueRange values = new ValueRange();
values.set("EMAIL", "tonyjones@abc.net.au");
values.set("AUTH", "[INSERT DATE]");
values.set("SUB", "[INSERT DATE + MONTH]");
try {
mService.spreadsheets().values().append("1meAAvjdPmghn6wl_IKc-_NJx_M85I_yqsn4Nwm_j_X0", "Users", values)
.setValueInputOption("RAW")
.execute();
} catch(IOException e) {
Log.e("BUG", "SheetUpdate: IOException");
}
}
在我的清单中,我有:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
我收到的错误指向mCredential
,因为它的名称未设置(null
),在调用mService.execute时会被捕获。
我手动(只是为了尝试并查明问题)允许在Settings-Apps菜单中使用权限,以及在Jellybean上尝试过,但所有人都声称存在同样的问题。
[编辑]这是完整的错误输出: `
E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.pybuspr.listeriafoodusa/com.pybuspr.listeau.Master}: java.lang.IllegalArgumentException: the name must not be empty: null
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
at android.app.ActivityThread.access$600(ActivityThread.java:130)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalArgumentException: the name must not be empty: null
at android.accounts.Account.<init>(Account.java:48)
at com.google.android.gms.auth.zze.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:269)
at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential$RequestHandler.intercept(GoogleAccountCredential.java:294)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:868)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
at com.pybuspr.listeau.Master.SheetUpdate(Master.java:167)
at com.pybuspr.listeau.Master.onCreate(Master.java:48)
at android.app.Activity.performCreate(Activity.java:5008)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
at android.app.ActivityThread.access$600(ActivityThread.java:130)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
`
答案 0 :(得分:0)
您的execute()
来自您创建的GoogleAccountCredential
对象,并且内部失败。
查看开源的Account.java代码,可以看到传入的名称为null。呼叫者GoogleAuthUtil
是Play服务库的一个封闭源代码部分,但我们可以很好地猜测正在发生的事情。它会尝试从手机设置中获取Google帐户,但无法找到匹配项。
正如您已经怀疑的那样,权限是一个因素,我认为这是您失败的原因。在定位Android 6及更高版本时,在清单中声明权限可能不够,在您的情况下,GET_ACCOUNTS
会受此影响。请参阅here。
您需要在运行时请求权限(并清楚地处理用户拒绝它们的情况)。有关如何执行此操作,请参阅here。或者,如果您没有任何相关的依赖关系,则可以将目标级别降低到5.1或更低,现在至少,它将使用较旧的权限模型。
答案 1 :(得分:0)
今天我遇到了同样的错误。但是终于我成功了。我在这里描述了我所做的事情,以便对任何人都有帮助。
所以,原因是:mCredential.getSelectedAccountName() == null
所以,我这样称呼api调用是否成功:
private void getResultsFromApi() {
if (! isGooglePlayServicesAvailable()) {
acquireGooglePlayServices();
} else if (mCredential.getSelectedAccountName() == null) {
chooseAccount();
} else if (! isDeviceOnline()) {
mOutputText.setText("No network connection available.");
} else {
Toast.makeText(this, "API CALL SUCCESS", Toast.LENGTH_SHORT).show();
}
}
当我收到上述消息API CALL SUCCESS
时,我将调用readData或Append Data函数。然后读取或追加数据。
因此,请仔细检查您的代码,初始化,实现,权限等,以确保mCredential.getSelectedAccountName() != null
成功。