目前,我正在使用Google Drive Android API将我的Android应用数据存储到Google云端硬盘应用文件夹.
这是我在保存应用程序数据时正在做的事情
这是执行上述操作的代码.
public static boolean saveToGoogleDrive(GoogleApiClient googleApiClient, File file, HandleStatusable h, PublishProgressable p) {
// Should we new or replace?
GoogleCloudFile googleCloudFile = searchFromGoogleDrive(googleApiClient, h, p);
try {
p.publishProgress(JStockApplication.instance().getString(R.string.uploading));
final long checksum = org.yccheok.jstock.gui.Utils.getChecksum(file);
final long date = new Date().getTime();
final int version = org.yccheok.jstock.gui.Utils.getCloudFileVersionID();
final String title = getGoogleDriveTitle(checksum, date, …Run Code Online (Sandbox Code Playgroud) Google已弃用Google Drive Android API.
我们正在迁移到Google Drive REST API(v3).
2年前,我们有使用Google Drive REST API(v2)的经验.我们知道需要GET_ACCOUNTS权限才能GoogleAuthUtil.getToken()正常使用 - Google Drive API - 名称不能为空:null(但我已将有效的帐户名称传递给GoogleAccountCredential)
当我们查看Google Drive REST API(v3)的示例 - https://github.com/gsuitedevs/android-samples/blob/master/drive/deprecation/app/src/main/AndroidManifest.xml#L5时,我们注意到谷歌团队确实明确提到过
<!-- Permissions required by GoogleAuthUtil -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
Run Code Online (Sandbox Code Playgroud)
令人惊讶的是,当我们运行示例应用程序(https://github.com/gsuitedevs/android-samples/tree/master/drive/deprecation)时,Android 6和8没有弹出运行时权限对话框.但是,该应用程序可以正常工作.
我们预计应用程序无法正常运行,因为没有GET_ACCOUNTS为该应用授予任何权限.但是,它仍可以使用Google云端硬盘服务进行身份验证和通信,而不会出现问题.
我已经在Android 5,Android 6和Android 8中进行了测试.没有GET_ACCOUNTS为Android 6和Android 8授予运行时权限.
我也进一步的测试,通过移除GET_ACCOUNTS并MANAGE_ACCOUNTS从清单完全.不过,Android 5,Android 6和Android 8都可行.在运行之前,我有清晰的缓存和清晰的应用程序存储空间.
那么,GET_ACCOUNTSGoogle Drive REST API仍然需要运行时权限请求吗?
android google-api google-drive-api google-drive-android-api
我遇到了"java.lang.IllegalArgumentException:名称不能为空:null"Google Drive Android应用中的例外情况.
我一直在谷歌搜索几天没有得到任何线索.这是我在Google云端硬盘上获取文件列表的代码(一个简单示例):(这是从这里获取的:Google Drive SDK Exception)
import java.io.IOException;
import java.util.ArrayList;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import com.google.android.gms.auth.GoogleAuthException;
import com.google.android.gms.auth.GoogleAuthUtil;
import com.google.android.gms.auth.UserRecoverableAuthException;
import com.google.android.gms.common.AccountPicker;
import com.google.api.client.auth.oauth2.BearerToken;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.googleapis.extensions.android.accounts.GoogleAccountManager;
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.json.JsonHttpRequest;
import com.google.api.client.http.json.JsonHttpRequestInitializer;
import com.google.api.client.json.jackson.JacksonFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.Drive.Files;
import com.google.api.services.drive.DriveRequest;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.File;
import com.google.api.services.drive.model.FileList;
import com.maiko.xscanpet.R;
import …Run Code Online (Sandbox Code Playgroud) 我收到一个无效的父文件夹错误,我已经看到使用资源ID而不是驱动器ID的解决方案,但这是一个不同的场景.
我正在尝试访问AppFolder,这只是使用GoogleApiClient,如下所示:
this.appFolder = Drive.DriveApi.getAppFolder(mGoogleApiClient);
Run Code Online (Sandbox Code Playgroud)
当我稍后尝试在其中创建文件时,我得到上述错误.
DriveFolder.DriveFileResult fileResult = appFolder.createFile(mGoogleApiClient, changeSet, driveContentsResult.getDriveContents()).await();
Run Code Online (Sandbox Code Playgroud)
然后fileResult.getStatus()给了我错误.
这曾经对我有用.不同的是,我在Google云端硬盘上手动清空了应用的数据(删除隐藏的应用数据).但我没有断开应用程序 - 所以我认为appFolder将继续以相同的方式工作......
到目前为止,唯一的解决方法是卸载应用程序,但这样我就丢失了数据.
这是可重复的.请帮忙.
您好我正在使用Google Drive Api使用AppDataFolder工具存储数据库.我有一个测试应用程序在一台设备上成功运行.我能够上传/更新/删除/下载数据库文件,并将其重新集成到程序中,没有任何问题.
我遇到的问题是,当我想与运行相同应用程序的其他设备共享此数据库时,事情无法按预期工作.示例设备AI上传数据库,设备B - 我想下载数据库但没有找到文件(这种延迟可能在几秒到几小时之间变化很大).原因 - 当使用Api时,它决定何时"同步"数据,因为它排队而不是即时上传.因此,当在一台设备上使用时,这不是问题,因为它需要来自云存储的"同步"文件或等待同步的文件.
我尝试过各种各样的事情,例如尝试列出所有AppDataFolder文件或通过带有可搜索过滤器的查询检索元数据,然后再发出请求更新/删除等等.但是,我无法让它根据需要从根本上选择何时同步.
所以我的实际问题是:如何在我需要时强制Google Drive同步我的文件,即每次发出请求时,都可以使用同一个应用程序在多个设备上实现同步.必须有一个答案,因为我认为这是你使用AppDataFolder的第一个根本原因.
提前致谢
编辑/ UPDATE:
我已经能够在Api中找到一个选项,使用以下代码"同步"驱动器内容:
// try to sync
Drive.DriveApi.requestSync(mGoogleApiClient).setResultCallback(new ResultCallback<com.google.android.gms.common.api.Status>() {
@Override
public void onResult(com.google.android.gms.common.api.Status status) {
if (!status.getStatus().isSuccess()) {
Log.e("SYNCING", "ERROR" + status.getStatusMessage());
} else {
Log.e("SYNCING", "SUCCESS");
// execute async task to list AppFolderContents
new AppFolderContentsAsyncTask(getActivity()).execute();
}
}
});
Run Code Online (Sandbox Code Playgroud)
这适用于快速连续3/4次尝试,但是我达到了同步限制和状态消息:
超出了ERRORSync请求速率限制.
是否有任何方法可以提高请求率,因为如果我必须有一个提示用户的应用程序'请稍后再试一次同步 - 不确定你需要多久等到你可以!
解决方案 - 对于港口和我的想法(其价值)
我正在寻找的解决方案(通过电子邮件发送一个发布了同步而没有问题的驱动器应用程序的应用程序开发者)是使用Drive REST Api,而不是更新(和Google首选)的Drive API.我尝试将'requestSync'限制为仅当用户导航到带有Drive选项的片段(而不是每个文件事务)时.然而,这可能会解决大多数情况下的requestSync速率限制,但它仍然可以达到该限制.此外,如果多个设备正在运行应用程序,并且链接到同一个驱动器帐户同时在应用程序中同步/上传/删除文件,则可能会失去同步 - 可能是一种罕见的情况,但仍然可能.在用户体验或应用程序设计方面,我不认为让用户等待同步文件是一个可行的选择.
但好奇 - 实际的Drive应用程序允许您根据需要多次刷新(requestSync?).我在网络界面上快速连续创建了20个文件夹,在创建每个文件夹后,我刷新了手机上的云端硬盘应用程序并同步了20次.谷歌似乎理解同步的重要性,但选择在新的Drive API中确保这一点非常困难.如前所述,将文件上传到云存储通常会立即发生(它排队等候,但是如果你有连接,它几乎会立即发生).我认为这是移动数据/更新驱动器内容方面的代价高昂的交易,而不仅仅是查询文件的同步.但是,您可以一次一个地向您的驱动器应用程序添加文件,并且几乎立即上传一个文件 - 在30秒内请求同步超过4次然后失败并且您必须'冷静下来' 一阵子.
我对编程/ Android一般都很陌生 - 只要我学到新东西,我就会意识到我实际上并不知道,所以如果他们使用Drive API(而不是REST API)是更好的解决方案我会非常欢迎它.
android google-api google-drive-api google-drive-android-api
我正在尝试使用GoogleAccountCredential登录我的应用程序进行身份验证:
mGoogleAccountCredential = GoogleAccountCredential.usingOAuth2(context, Arrays.asList(Scopes.EMAIL, Scopes.PLUS_LOGIN));
mGoogleAccountCredential.setSelectedAccountName(accountName);
String token = mGoogleAccountCredential.getToken();
Run Code Online (Sandbox Code Playgroud)
它在真实设备上工作正常,但在android模拟器上mGoogleAccountCredential.getToken()失败,出现以下异常:
java.lang.IllegalArgumentException: the name must not be empty: null
03-01 19:41:31.604 3203-3361/com.myapp W/System.err: at android.accounts.Account.<init>(Account.java:48)
03-01 19:41:31.604 3203-3361/com.myapp W/System.err: at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source)
03-01 19:41:31.604 3203-3361/com.myapp W/System.err: at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential.getToken(GoogleAccountCredential.java:255)
Run Code Online (Sandbox Code Playgroud)
GoogleApiAvailability.isGooglePlayServicesAvailable(context)返回0)accountName传递到setSelectedAccountName(设置为"myuser@gmail.com")时设置并正确任何线索为什么它不在模拟器上工作?
UPD:
在谷歌的代码中挖掘了一下之后:问题发生在setSelectedAccountName(accountName)方法中.此方法要求GoogleAccountManager为其提供与给定帐户名称关联的帐户.如果没有此类帐户,则帐户名称将设置为null:
public final GoogleAccountCredential setSelectedAccountName(String accountName) {
selectedAccount = accountManager.getAccountByName(accountName);
// check if account has been deleted
this.accountName = selectedAccount …Run Code Online (Sandbox Code Playgroud) authentication android google-api android-emulator oauth-2.0