You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Google Drive实现双安卓设备字符串共享的Java方案

安卓端用Java读写Google Drive文件实现双向字符串共享

前置准备

  • 在Google Cloud Console创建项目,启用Google Drive API,生成匹配安卓包名与SHA-1签名的OAuth 2.0客户端ID。
  • 在安卓项目的build.gradle(Module)中添加Drive依赖:
    dependencies {
        implementation 'com.google.android.gms:play-services-drive:17.0.0'
    }
    
  • 配置AndroidManifest.xml,添加必要权限与Drive服务声明:
    <uses-permission android:name="android.permission.INTERNET" />
    <application ...>
        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
        <service
            android:name="com.google.android.gms.drive.DriveApiService"
            android:exported="true"
            android:permission="com.google.android.gms.permission.DRIVE_SERVICE" />
    </application>
    

授权获取Drive客户端

首先完成用户授权,拿到可操作Drive的客户端实例:

private static final int REQUEST_CODE_SIGN_IN = 1001;
private Drive mDriveClient;

private GoogleSignInClient buildGoogleSignInClient() {
    GoogleSignInOptions signInOptions = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestScopes(new Scope(DriveScopes.DRIVE_FILE)) // 仅请求文件级权限,更安全
            .requestEmail()
            .build();
    return GoogleSignIn.getClient(this, signInOptions);
}

// 启动授权流程
private void requestSignIn() {
    startActivityForResult(buildGoogleSignInClient().getSignInIntent(), REQUEST_CODE_SIGN_IN);
}

// 处理授权结果
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_CODE_SIGN_IN) {
        Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
        handleSignInResult(task);
    }
}

private void handleSignInResult(Task<GoogleSignInAccount> completedTask) {
    try {
        GoogleSignInAccount account = completedTask.getResult(ApiException.class);
        mDriveClient = Drive.get(this, account);
        // 授权成功,可执行后续读写操作
    } catch (ApiException e) {
        Log.e(TAG, "Sign-in failed: " + e.getStatusCode());
    }
}

读取Google Drive中的TXT文件

先按文件名查找目标文件,再读取文本内容:

private void readSharedTxt() {
    if (mDriveClient == null) return;

    // 构建查询条件:查找未被删除的"SharedString.txt"文件
    Query query = new Query.Builder()
            .addFilter(Filters.eq(SearchableField.TITLE, "SharedString.txt"))
            .addFilter(Filters.eq(SearchableField.TRASHED, false))
            .build();

    mDriveClient.files().list(query)
            .setFields("files(id, name)")
            .executeAsync(new ResultCallback<DriveFiles.ListResult>() {
                @Override
                public void onResult(@NonNull DriveFiles.ListResult result) {
                    if (!result.getStatus().isSuccess()) {
                        Log.e(TAG, "Failed to find file: " + result.getStatus().getStatusCode());
                        return;
                    }

                    List<DriveFile> files = result.getFiles();
                    if (files.isEmpty()) {
                        // 文件不存在,创建新文件
                        createSharedTxt("");
                        return;
                    }

                    DriveFile targetFile = files.get(0);
                    // 以只读模式打开文件流
                    targetFile.open(mDriveClient, DriveFile.MODE_READ_ONLY, null)
                            .executeAsync(new ResultCallback<DriveContents>() {
                                @Override
                                public void onResult(@NonNull DriveContents result) {
                                    if (!result.getStatus().isSuccess()) {
                                        Log.e(TAG, "Failed to open file: " + result.getStatus().getStatusCode());
                                        return;
                                    }

                                    // 读取文本内容
                                    InputStream inputStream = result.getInputStream();
                                    String content = new BufferedReader(new InputStreamReader(inputStream))
                                            .lines().collect(Collectors.joining("\n"));
                                    // 这里更新UI显示共享字符串

                                    // 关闭文件流
                                    result.discard(mDriveClient);
                                }
                            });
                }
            });
}

写入/更新TXT文件内容

找到目标文件后,写入新的共享字符串:

private void writeSharedTxt(String newContent) {
    if (mDriveClient == null) return;

    Query query = new Query.Builder()
            .addFilter(Filters.eq(SearchableField.TITLE, "SharedString.txt"))
            .addFilter(Filters.eq(SearchableField.TRASHED, false))
            .build();

    mDriveClient.files().list(query)
            .setFields("files(id, name)")
            .executeAsync(new ResultCallback<DriveFiles.ListResult>() {
                @Override
                public void onResult(@NonNull DriveFiles.ListResult result) {
                    if (!result.getStatus().isSuccess()) {
                        Log.e(TAG, "Failed to find file: " + result.getStatus().getStatusCode());
                        return;
                    }

                    List<DriveFile> files = result.getFiles();
                    DriveFile targetFile;
                    if (files.isEmpty()) {
                        targetFile = createSharedTxt(newContent);
                        return;
                    }
                    targetFile = files.get(0);

                    // 以写入模式打开文件流
                    targetFile.open(mDriveClient, DriveFile.MODE_WRITE_ONLY, null)
                            .executeAsync(new ResultCallback<DriveContents>() {
                                @Override
                                public void onResult(@NonNull DriveContents result) {
                                    if (!result.getStatus().isSuccess()) {
                                        Log.e(TAG, "Failed to open file for write: " + result.getStatus().getStatusCode());
                                        return;
                                    }

                                    // 写入新内容
                                    OutputStream outputStream = result.getOutputStream();
                                    try {
                                        outputStream.write(newContent.getBytes(StandardCharsets.UTF_8));
                                    } catch (IOException e) {
                                        Log.e(TAG, "Write failed: " + e.getMessage());
                                    }

                                    // 提交文件更改
                                    targetFile.commit(mDriveClient, result, null)
                                            .executeAsync(new ResultCallback<Void>() {
                                                @Override
                                                public void onResult(@NonNull Void result) {
                                                    Log.d(TAG, "File updated successfully");
                                                    // 可触发另一设备同步,比如用WorkManager定时拉取或推送通知
                                                }
                                            });
                                }
                            });
                }
            });
}

// 创建新的共享TXT文件
private DriveFile createSharedTxt(String initialContent) {
    MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
            .setTitle("SharedString.txt")
            .setMimeType("text/plain")
            .build();

    mDriveClient.getRootFolder().createFile(mDriveClient, changeSet, null)
            .executeAsync(new ResultCallback<DriveFile>() {
                @Override
                public void onResult(@NonNull DriveFile result) {
                    if (result.getStatus().isSuccess()) {
                        // 创建成功后写入初始内容
                        writeSharedTxt(initialContent);
                    } else {
                        Log.e(TAG, "Failed to create file: " + result.getStatus().getStatusCode());
                    }
                }
            });
    return result;
}

双向同步关键注意事项

  • 冲突处理:两部设备可能同时修改文件,建议在TXT中加入版本号或时间戳,写入前对比版本,避免覆盖对方修改。
  • 同步触发:可用WorkManager定时拉取文件更新,或配置Drive API推送通知实现实时同步。
  • 权限控制:仅请求DRIVE_FILE范围权限,不要申请全Drive权限,提升应用安全性。

内容的提问来源于stack exchange,提问作者IdoSC

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.02 04:54:53