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

Android应用获取用户Google Drive文件遇阻,含NetworkOnMainThreadException错误

Android Google Drive 文件列表获取实现指导

1. 先解决android.os.NetworkOnMainThreadException异常

这个异常是Android的强制限制:主线程(UI线程)不允许执行网络请求,你需要把Drive API的调用逻辑放到子线程,完成后再切回主线程更新UI。

Java 实现示例(两种方案)

方案1:使用ExecutorService + Handler(推荐)

// 在MainActivity中执行
ExecutorService executor = Executors.newSingleThreadExecutor();
Handler mainHandler = new Handler(Looper.getMainLooper());

executor.execute(() -> {
    // 子线程中执行Drive API请求
    List<com.google.api.services.drive.model.File> files = null;
    try {
        files = fetchDriveFiles(driveInstance);
    } catch (IOException e) {
        e.printStackTrace();
    }
    final List<com.google.api.services.drive.model.File> finalFiles = files;
    // 切回主线程更新UI
    mainHandler.post(() -> {
        if (finalFiles != null) {
            // 绑定数据到RecyclerView/ListView等
            updateFileListUI(finalFiles);
        }
    });
});

方案2:使用AsyncTask(兼容旧版本,已过时但易理解)

private class FetchDriveFilesTask extends AsyncTask<Void, Void, List<com.google.api.services.drive.model.File>> {
    private Drive driveInstance;

    public FetchDriveFilesTask(Drive drive) {
        this.driveInstance = drive;
    }

    @Override
    protected List<com.google.api.services.drive.model.File> doInBackground(Void... voids) {
        try {
            return fetchDriveFiles(driveInstance);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    protected void onPostExecute(List<com.google.api.services.drive.model.File> files) {
        super.onPostExecute(files);
        if (files != null) {
            updateFileListUI(files);
        }
    }
}

// 调用方式
new FetchDriveFilesTask(driveInstance).execute();

2. Google Drive API 正确集成步骤(无需后端)

你不需要后端服务器,直接在Android端即可完成,以下是完整流程:

步骤1:确认OAuth 2.0配置

  • 确保Google Cloud控制台生成的是Android类型的OAuth客户端ID,而非Web/其他类型。
  • 将credentials.json放到app/src/main/res/raw目录下。
  • 在OAuth同意屏幕中添加所需权限范围:比如../auth/drive.readonly(读取所有文件)或../auth/drive.file(仅读取用户授权的文件)。
  • 验证Google Cloud中配置的包名和SHA-1指纹与本地项目完全一致(debug和release指纹都要加)。

步骤2:从Firebase登录凭证初始化Drive服务

利用已有的Firebase Google登录凭证,直接生成Drive API的授权实例:

FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
if (firebaseUser != null) {
    firebaseUser.getIdToken(false).addOnSuccessListener(idTokenResult -> {
        String accessToken = idTokenResult.getToken();
        // 创建授权凭证
        GoogleCredential credential = new GoogleCredential().setAccessToken(accessToken);
        // 初始化Drive服务
        Drive drive = new Drive.Builder(
            AndroidHttp.newCompatibleTransport(),
            new GsonFactory(),
            credential
        ).setApplicationName("你的应用名称").build();
        
        // 拿到drive实例后,调用子线程获取文件列表(用上面的Executor/AsyncTask方案)
        fetchFilesInBackground(drive);
    });
}

步骤3:实现文件列表获取逻辑

private List<com.google.api.services.drive.model.File> fetchDriveFiles(Drive drive) throws IOException {
    // 调用Drive API获取文件列表,可自定义分页、字段
    FileList result = drive.files().list()
        .setPageSize(20) // 每页返回20条
        .setFields("nextPageToken, files(id, name, mimeType, modifiedTime)") // 指定返回的字段,减少数据量
        .execute();
    return result.getFiles();
}

步骤4:添加必要权限

在AndroidManifest.xml中声明网络权限:

<uses-permission android:name="android.permission.INTERNET" />

3. 是否需要后端服务器?

不需要。Android客户端可以直接通过OAuth 2.0授权调用Google Drive API。只有当你需要处理大规模文件操作、敏感数据处理,或者需要统一管理授权逻辑时,才考虑引入后端。

常见问题排查

  • 如果出现授权失败:检查包名、SHA-1指纹、权限范围是否配置正确,确保OAuth同意屏幕已发布(测试阶段可添加测试用户)。
  • 如果返回空文件列表:检查权限范围是否足够,比如drive.file需要用户手动授权特定文件,而drive.readonly需要用户同意读取所有文件。
  • 避免在主线程执行任何网络操作,包括Drive API的初始化和调用。

内容的提问来源于stack exchange,提问作者Edemir Santos de Paula

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 06:45:31