求未弃用的Java版Google Drive授权及文件交互完整代码
Google Drive授权与文件操作(弃用API替代方案)
问题背景
原有Google Drive授权代码依赖已弃用的GoogleSignInClient、GoogleSignIn类,改用Identity授权方案时,遇到startIntentSenderForResult弃用问题,同时不清楚如何通过AuthorizationResult替代GoogleAccountCredential构建Drive服务,需要一套包含授权、文件上传下载的完整未弃用Java代码。
完整实现代码
1. 主Activity核心代码
import android.app.PendingIntent; import android.content.IntentSender; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.RelativeLayout; import android.widget.Toast; import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; import androidx.appcompat.app.AppCompatActivity; import com.google.android.gms.auth.api.identity.Identity; import com.google.android.gms.auth.api.identity.AuthorizationRequest; import com.google.android.gms.auth.api.identity.AuthorizationResult; import com.google.android.gms.common.api.Scope; import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential; import com.google.api.client.http.javanet.NetHttpTransport; import com.google.api.client.json.gson.GsonFactory; import com.google.api.services.drive.Drive; import com.google.api.services.drive.DriveScopes; import java.util.Collections; public class BackupActivity extends AppCompatActivity { private Drive driveService; private DriveServiceHelper driveServiceHelper; // 处理授权IntentSender的Launcher(替代弃用的startIntentSenderForResult) private final ActivityResultLauncher<ActivityResultContracts.StartIntentSenderForResult.IntentSenderRequest> authResultLauncher = registerForActivityResult( new ActivityResultContracts.StartIntentSenderForResult(), result -> { if (result.getResultCode() == RESULT_OK) { // 授权成功后重新发起请求获取有效AuthorizationResult requestAuthorization(); } else { showToast("授权失败"); } }); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_backup); // 初始化授权流程 requestAuthorization(); } private void requestAuthorization() { AuthorizationRequest authorizationRequest = AuthorizationRequest.builder() .setRequestedScopes(Collections.singletonList(new Scope(DriveScopes.DRIVE_FILE))) .build(); Identity.getAuthorizationClient(this) .authorize(authorizationRequest) .addOnSuccessListener(authorizationResult -> { if (authorizationResult.hasResolution()) { // 需要用户手动授权,启动授权UI PendingIntent pendingIntent = authorizationResult.getPendingIntent(); try { authResultLauncher.launch( new ActivityResultContracts.StartIntentSenderForResult.IntentSenderRequest.Builder(pendingIntent.getIntentSender()).build() ); } catch (IntentSender.SendIntentException e) { Log.e("BackupActivity", "启动授权UI失败: " + e.getMessage()); showToast("启动授权UI失败"); } } else { // 已完成授权,构建Drive服务实例 buildDriveService(authorizationResult); // 切换到授权成功后的UI switchToAuthorizedUI(); } }) .addOnFailureListener(e -> { Log.e("BackupActivity", "授权请求失败: " + e.getMessage()); showToast("授权请求失败"); }); } private void buildDriveService(AuthorizationResult authorizationResult) { // 从AuthorizationResult中提取凭证信息,构建GoogleAccountCredential GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2( this, Collections.singleton(DriveScopes.DRIVE_FILE)); credential.setSelectedAccount(authorizationResult.getAccount()); credential.setToken(authorizationResult.getAccessToken()); // 初始化Drive服务 driveService = new Drive.Builder( new NetHttpTransport(), GsonFactory.getDefaultInstance(), credential) .setApplicationName("Hrady") .build(); driveServiceHelper = new DriveServiceHelper(driveService); } private void switchToAuthorizedUI() { RelativeLayout relativeLayout1 = findViewById(R.id.logscreen); RelativeLayout relativeLayout2 = findViewById(R.id.logmenu); relativeLayout1.setVisibility(View.GONE); relativeLayout2.setVisibility(View.VISIBLE); } private void showToast(String message) { Toast.makeText(this, message, Toast.LENGTH_SHORT).show(); } // 示例:触发文件上传(可绑定到按钮点击事件) public void uploadFile(View view) { if (driveServiceHelper != null) { // 替换为你的本地文件路径 String localFilePath = "/sdcard/test.txt"; driveServiceHelper.uploadFile(localFilePath, "application/text", "测试文件.txt") .addOnSuccessListener(fileId -> { showToast("文件上传成功,ID: " + fileId); }) .addOnFailureListener(e -> { Log.e("BackupActivity", "上传失败: " + e.getMessage()); showToast("文件上传失败"); }); } } // 示例:触发文件下载(可绑定到按钮点击事件) public void downloadFile(View view) { if (driveServiceHelper != null) { // 替换为目标文件的Drive ID String fileId = "your_target_file_id"; // 替换为本地保存路径 String savePath = "/sdcard/downloaded_test.txt"; driveServiceHelper.downloadFile(fileId, savePath) .addOnSuccessListener(() -> { showToast("文件下载成功"); }) .addOnFailureListener(e -> { Log.e("BackupActivity", "下载失败: " + e.getMessage()); showToast("文件下载失败"); }); } } }
2. DriveServiceHelper工具类(封装上传下载逻辑)
import com.google.api.services.drive.Drive; import com.google.api.services.drive.model.File; import com.google.api.services.drive.model.FileList; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.Collections; import java.util.concurrent.CompletableFuture; public class DriveServiceHelper { private final Drive driveService; public DriveServiceHelper(Drive driveService) { this.driveService = driveService; } // 上传本地文件到Google Drive public CompletableFuture<String> uploadFile(String localFilePath, String mimeType, String fileName) { return CompletableFuture.supplyAsync(() -> { try { java.io.File localFile = new java.io.File(localFilePath); File fileMetadata = new File(); fileMetadata.setName(fileName); // 如需上传到Drive应用专属文件夹,取消注释下面一行 // fileMetadata.setParents(Collections.singletonList("appDataFolder")); // 创建上传请求并执行 Drive.Files.Create createRequest = driveService.files().create( fileMetadata, new com.google.api.client.http.FileContent(mimeType, localFile)); createRequest.setFields("id"); File uploadedFile = createRequest.execute(); return uploadedFile.getId(); } catch (IOException e) { throw new RuntimeException("上传文件失败", e); } }); } // 从Google Drive下载文件到本地 public CompletableFuture<Void> downloadFile(String fileId, String savePath) { return CompletableFuture.runAsync(() -> { try { OutputStream outputStream = new FileOutputStream(savePath); driveService.files().get(fileId).executeMediaAndDownloadTo(outputStream); outputStream.close(); } catch (IOException e) { throw new RuntimeException("下载文件失败", e); } }); } // 可选:获取Drive应用专属文件夹内的文件列表 public CompletableFuture<FileList> getAppFolderFiles() { return CompletableFuture.supplyAsync(() -> { try { return driveService.files().list() .setSpaces("appDataFolder") .setFields("files(id, name)") .execute(); } catch (IOException e) { throw new RuntimeException("获取文件列表失败", e); } }); } }
关键说明
- 使用
ActivityResultContracts.StartIntentSenderForResult替代弃用的startIntentSenderForResult,通过authResultLauncher处理授权回调,符合Android最新的Activity Result API规范。 - 从
AuthorizationResult中提取用户账户和访问令牌,构建GoogleAccountCredential,以此初始化Drive服务实例,实现弃用API的无缝替换。 DriveServiceHelper采用CompletableFuture处理异步操作,避免阻塞主线程,同时封装了上传、下载、文件列表查询的核心逻辑,便于复用。
内容的提问来源于stack exchange,提问作者Darksymphony
相关产品推荐
相关产品推荐

