2

我想以编程方式访问将包含在我的项目文件夹中的特定 Excel 电子表格并将其上传到 Google Drive。我将电子表格包含在我的 src 文件夹中,并使用以下代码:

private void saveFileToDrive() {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                try {

                    URL fileURL = getClass().getClassLoader().getResource("Untitled spreadsheet.xlsx");
                    String filePath2 = fileURL.getPath();

                    java.io.File fileContent = new java.io.File(filePath2);
                    FileContent mediaContent = new FileContent("application/vnd.ms-excel", fileContent);

                    File body = new File();
                    body.setTitle(fileContent.getName());
                    body.setMimeType("application/vnd.ms-excel");


                    File file = service.files().insert(body, mediaContent).setConvert(true).execute();

                    if (file != null) {
                        showToast("File uploaded: " + file.getTitle());
                    }
                    else
                             ;
                } catch (UserRecoverableAuthIOException e) {

                    startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
                } catch (IOException e) {

                    e.printStackTrace();
                }
            }
        });
        t.start();
    }

但是,我不断收到以下 FileNotFoundException:

11-29 14:43:45.189: W/System.err(21133): java.io.FileNotFoundException: /file:/data/app/com.example.drivequickstart-2.apk!/Untitled spreadsheet.xlsx: open failed: ENOENT (No such file or directory)

有谁知道是什么原因造成的?

编辑:我尝试按照以下建议修改我的代码:

private void saveFileToDrive() {
            Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {

                      String mime = "application/vnd.ms-excel";
                     InputStream in = getApplicationContext().getAssets().open("Untitled spreadsheet.xlsx");
                     InputStreamContent content = new InputStreamContent(mime, in);;

                        File body = new File();
                        body.setTitle("Untitled spreadsheet");
                        body.setMimeType("application/vnd.ms-excel");


                        File file = service.files().insert(body, content).setConvert(true).execute();

                        if (file != null) {
                            showToast("File uploaded: " + file.getTitle());
                        }
                        else
                                 ;
                    } catch (UserRecoverableAuthIOException e) {

                        startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
                    } catch (IOException e) {

                        e.printStackTrace();
                    }
                }
            });
            t.start();
        }

但是,这给了我以下错误:

11-29 20:31:08.118: E/AndroidRuntime(9833): java.lang.IllegalArgumentException
11-29 20:31:08.118: E/AndroidRuntime(9833):     at com.google.common.base.Preconditions.checkArgument(Preconditions.java:76)
11-29 20:31:08.118: E/AndroidRuntime(9833):     at com.google.api.client.googleapis.media.MediaHttpUploader.getMediaContentLength(MediaHttpUploader.java:328)
11-29 20:31:08.118: E/AndroidRuntime(9833):     at com.google.api.client.googleapis.media.MediaHttpUploader.executeUploadInitiation(MediaHttpUploader.java:347)
11-29 20:31:08.118: E/AndroidRuntime(9833):     at com.google.api.client.googleapis.media.MediaHttpUploader.upload(MediaHttpUploader.java:266)
11-29 20:31:08.118: E/AndroidRuntime(9833):     at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:408)
11-29 20:31:08.118: E/AndroidRuntime(9833):     at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:328)
11-29 20:31:08.118: E/AndroidRuntime(9833):     at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:449)
11-29 20:31:08.118: E/AndroidRuntime(9833):     at com.example.drivequickstart.MainActivity$3.run(MainActivity.java:303)
11-29 20:31:08.118: E/AndroidRuntime(9833):     at java.lang.Thread.run(Thread.java:864)

并指向行: File file = service.files().insert(body, content).setConvert(true).execute();仔细检查后,我发现 InputStreamContent 的长度为-1,因此问题可能出在此处。

4

2 回答 2

1

您使用 Java 习惯用法ClassLoader.getResource()CLASSPATH. 但是,这不是我们在 Android 上的做法。

您将把文件放在assets/目录或 中res/raw/,然后使用AssetManager或 之类的标识符检索它R.raw.untitled_spreadsheet.xlsx

官方指南

虽然不常见,但您可能需要访问原始文件和目录。如果这样做,那么将文件保存在 res/ 中对您不起作用,因为从 res/ 读取资源的唯一方法是使用资源 ID。相反,您可以将资源保存在 assets/ 目录中。

保存在 assets/ 目录中的文件没有资源 ID,因此您无法通过 R 类或 XML 资源引用它们。相反,您可以像普通文件系统一样查询 assets/ 目录中的文件,并使用 AssetManager 读取原始数据。

但是,如果您只需要读取原始数据(例如视频或音频文件)的能力,则将文件保存在 res/raw/ 目录中并使用 openRawResource() 读取字节流。

用代码说话,如果你把文件放在assets/sheet.xlsx

String mime = "application/vnd.ms-excel";
InputStream in = ctx.getAssets().open("sheet.xlsx");
InputStreamContent content = new InputStreamContent(mime, in);

哪里ctxContext。由于Activity是 a Context,如果您碰巧ctx在.getAssets()Activity

请注意,我没有使用FileContent: 而是选择InputStreamContent了,因为您实际上并没有java.io.File对象,而是输入流

基本上,您是在询问 Drive 客户端:“从该本地流中读取字节,上传它们并以 $NAME 名称访问它们。 ” 该名称$NAME通过com.google.api.services.drive.model.File对象的title字段提供给服务,可以是您喜欢的任何内容 - 我认为它也可以包括目录分隔符。

这是指向Google Drive V2 的 Javadoc的链接

于 2012-11-29T20:56:41.223 回答
0

要解决您的“是什么原因造成的?”的问题,请参阅此处的讨论(围绕评论 #13)。

这是一个简单的原因,你没有给它一个有效的文件路径。您正在从类加载器获取资源,并且该资源来自 jar(实际上从未解压缩到文件系统中)。

因此,当您使用 url.getPath() 向资源的 URL 询问路径时,您会返回一个(在您的情况下)文件:/data/app/com.example.drivequickstart-2.apk!/Untitled spreadsheet.xlsx

这不是合法的“文件:”网址字符串!

他还提出了一种非常恰当的方法来解决这个问题:

您应该做的只是将 URL.toString() 返回的字符串提供给构造函数。你应该得到的是某种注册的 url 类型,它仍然指向 jar 文件,但你的 VM 中的 url 解析器知道如何处理。

于 2012-11-29T21:04:24.440 回答