我试图在我的Android应用程序中加入Google Drive API。
我已将Google Play服务添加到build.gradle
并获取Android API密钥。我的问题是在用户选择帐户的OnResume()
内。
它只是不断重新命令用户选择帐户而不会继续。
愿任何人帮助我吗?
public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener{
private static final String TAG = "Google Drive Activity";
private static final int REQUEST_CODE_RESOLUTION = 1;
private static final int REQUEST_CODE_OPENER = 2;
private GoogleApiClient mGoogleApiClient;
private boolean fileOperation = false;
private DriveId mFileId;
public DriveFile file;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void onResume() {
super.onResume();
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
mGoogleApiClient.connect();
}
@Override
protected void onStop() {
super.onStop();
if (mGoogleApiClient != null) {
// disconnect Google API client connection
mGoogleApiClient.disconnect();
}
super.onPause();
}
@Override
public void onConnectionFailed(ConnectionResult result) {
Log.i(TAG, "GoogleApiClient connection failed: " + result.toString());
if (!result.hasResolution()) {
GoogleApiAvailability.getInstance().getErrorDialog(this, result.getErrorCode(), 0).show();
return;
}
try {
result.startResolutionForResult(this, REQUEST_CODE_RESOLUTION);
} catch (IntentSender.SendIntentException e) {
Log.e(TAG, "Exception while starting resolution activity", e);
}
}
@Override
public void onConnected(Bundle connectionHint) {
Toast.makeText(getApplicationContext(), "Connected", Toast.LENGTH_LONG).show();
}
@Override
public void onConnectionSuspended(int cause) {
Log.i(TAG, "GoogleApiClient connection suspended");
}
public void onClickCreateFile(View view){
fileOperation = true;
Drive.DriveApi.newDriveContents(mGoogleApiClient)
.setResultCallback(driveContentsCallback);
}
public void onClickOpenFile(View view){
fileOperation = false;
Drive.DriveApi.newDriveContents(mGoogleApiClient)
.setResultCallback(driveContentsCallback);
}
public void OpenFileFromGoogleDrive(){
IntentSender intentSender = Drive.DriveApi
.newOpenFileActivityBuilder()
.setMimeType(new String[] { "text/plain", "text/html" })
.build(mGoogleApiClient);
try {
startIntentSenderForResult(
intentSender, REQUEST_CODE_OPENER, null, 0, 0, 0);
} catch (IntentSender.SendIntentException e) {
Log.w(TAG, "Unable to send intent", e);
}
}
final ResultCallback<DriveApi.DriveContentsResult> driveContentsCallback =
new ResultCallback<DriveApi.DriveContentsResult>() {
@Override
public void onResult(DriveApi.DriveContentsResult result) {
if (result.getStatus().isSuccess()) {
if (fileOperation == true) {
CreateFileOnGoogleDrive(result);
} else {
OpenFileFromGoogleDrive();
}
}
}
};
public void CreateFileOnGoogleDrive(DriveApi.DriveContentsResult result){
final DriveContents driveContents = result.getDriveContents();
new Thread() {
@Override
public void run() {
// write content to DriveContents
OutputStream outputStream = driveContents.getOutputStream();
Writer writer = new OutputStreamWriter(outputStream);
try {
writer.write("Hello abhay!");
writer.close();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle("abhaytest2")
.setMimeType("text/plain")
.setStarred(true).build();
Drive.DriveApi.getRootFolder(mGoogleApiClient)
.createFile(mGoogleApiClient, changeSet, driveContents)
.setResultCallback(fileCallback);
}
}.start();
}
final private ResultCallback<DriveFolder.DriveFileResult> fileCallback = new
ResultCallback<DriveFolder.DriveFileResult>() {
@Override
public void onResult(DriveFolder.DriveFileResult result) {
if (result.getStatus().isSuccess()) {
Toast.makeText(getApplicationContext(), "file created: "+""+
result.getDriveFile().getDriveId(), Toast.LENGTH_LONG).show();
}
return;
}
};
@Override
protected void onActivityResult(final int requestCode,
final int resultCode, final Intent data) {
switch (requestCode) {
case REQUEST_CODE_OPENER:
if (resultCode == RESULT_OK) {
mFileId = (DriveId) data.getParcelableExtra(
OpenFileActivityBuilder.EXTRA_RESPONSE_DRIVE_ID);
Log.e("file id", mFileId.getResourceId() + "");
String url = "https://drive.google.com/open?id="+ mFileId.getResourceId();
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
}
break;
default:
super.onActivityResult(requestCode, resultCode, data);
break;
}
}
}
这是我的清单。阻止API密钥。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="edu.moli9479csumb.version1googledrive">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="AIzaSyD_2eJ5pPdRMysVwxxxxxxxxxxxxxx"/>
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version"/>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
答案 0 :(得分:0)
你可以分享你的清单吗? 尝试向下一个屏幕的班级制作一个明确的清单
答案 1 :(得分:0)
当GoogleApiClient无法连接并且其分辨率要求用户为API授权应用时,您会获得AccountSelector。当你调用“result.startResolutionForResult(this,REQUEST_CODE_RESOLUTION);”时会发生这种情况。来自onConnectionFailed方法。
用户选择帐户后,您的活动会使用代码REQUEST_CODE_RESOLUTION获得回调。必须处理此代码,并且当在onActivityResult方法中收到此代码时,应该再次调用apiClient.connect()进行连接。
有关详细信息,请参阅this。我希望它有效:)
答案 2 :(得分:0)
您可以使用[Account Picker
](https://developer.android.com/reference/android/accounts/AccountManager.html#newChooseAccountIntent(android.accounts.Account,java.util.ArrayList,java.lang.String [],boolean,java.lang轻松强制提示用户选择帐户。 String,java.lang.String,java.lang.String [],android.os.Bundle)),普通帐户选择器类似于newChooseAccountIntent
中引入的标准框架帐户选择器。返回对Activity的意图,提示用户从帐户列表中进行选择。然后,呼叫者通常会通过呼叫startActivityForResult(intent, ...)
;来启动活动。
成功时,活动会返回一个包含使用密钥KEY_ACCOUNT_NAME和KEY_ACCOUNT_TYPE指定的帐户名称和类型的捆绑包。
最常见的情况是使用一种帐户类型来调用它,例如:
Intent intent = AccountPicker.newChooseAccountIntent(null, null, new String[]{"com.google"},
false, null, null, null, null);
startActivityForResult(intent, SOME_REQUEST_CODE);
当用户选择和/或创建帐户时,帐户选择器活动将返回,并且可以按如下方式检索生成的帐户名称:
protected void onActivityResult(final int requestCode, final int resultCode,
final Intent data) {
if (requestCode == SOME_REQUEST_CODE && resultCode == RESULT_OK) {
String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
}
}
以下是使用上述代码的官方Google示例代码,以及如何使用API的具体说明:https://developers.google.com/drive/v3/web/quickstart/android#step_5_setup_the_sample
答案 3 :(得分:0)
查看你的onResume()和onConnectionFailded()方法。
@Override
protected void onResume() {
super.onResume();
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
mGoogleApiClient.connect();
}
@Override
public void onConnectionFailed(ConnectionResult result) {
Log.i(TAG, "GoogleApiClient connection failed: " + result.toString());
if (!result.hasResolution()) {
GoogleApiAvailability.getInstance().getErrorDialog(this, result.getErrorCode(), 0).show();
return;
}
try {
result.startResolutionForResult(this, REQUEST_CODE_RESOLUTION);
} catch (IntentSender.SendIntentException e) {
Log.e(TAG, "Exception while starting resolution activity", e);
}
}
会发生什么?
在onResume()中,您可以创建GoogleApiClient并调用connect()。由于您未获得帐户授权,因此连接失败。方法onConnectionFailed()被执行,它打开一个分辨率,这实际上是另一个为结果调用的活动。您选择了一个帐户但我认为授权失败或被取消。 您将返回到原始活动并执行onResume()。然后你再去一圈。 为什么您的授权失败?我想因为你的凭证有问题。转到开发人员控制台,为您的包和密钥签名创建O Auth凭证。