Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/203.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 上载到Google驱动器文件未找到异常_Java_Android_File - Fatal编程技术网

Java 上载到Google驱动器文件未找到异常

Java 上载到Google驱动器文件未找到异常,java,android,file,Java,Android,File,我想以编程方式访问特定的Excel电子表格,该电子表格将包含在我的项目文件夹中,并将其上载到Google Drive。我将电子表格包含在我的src文件夹中,并使用以下代码: private void saveFileToDrive() { Thread t = new Thread(new Runnable() { @Override public void run() { try {

我想以编程方式访问特定的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,因此问题可能源自于此。

您使用Java惯用语
ClassLoader.getResource()
类路径
加载资源。然而,这不是我们在Android上的做法

您将把文件放在
assets/
目录或
res/raw/
中,然后使用或类似
R.raw.untitled\u spreadsheet.xlsx的标识符检索它

见:

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

保存在资产/目录中的文件没有资源ID,因此 不能通过R类或从XML资源引用它们。 相反,您可以像普通用户一样查询资产/目录中的文件 并使用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);
其中,
ctx
是一个。由于
活动
是一个
上下文
,如果您碰巧在
活动
中编写此代码,可以跳过
ctx
,直接调用
getAssets()

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

基本上,您要求驱动器客户机:“从本地流读取字节,上载它们,并使它们可以在$name名称下访问”。名称
$name
是通过
com.google.api.services.drive.model.File
对象的
标题
字段提供给服务的,该字段可以是您喜欢的任何字段-我认为它也可以包括目录分隔符


这是一个到

的链接,要解决您关于“这是什么造成的?”的问题,请参阅讨论(围绕评论13)

这是一个简单的原因,您没有给它一个有效的文件路径。你 正在从类加载器获取资源,并且该资源是 来自一个罐子(实际上它从来没有被打开到盒子里) 文件系统)

因此,当您向资源的URL询问路径时 getPath()返回一个 (在您的情况下)文件:/data/app/com.example.drivequickstart-2.apk/无标题电子表格.xlsx

这不是合法的“文件:”url字符串

他还提出了一个非常恰当的解决方法:

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


但是如何从InputStreamContent获取文件路径?什么文件路径?
InputStreamContent
就是一个围绕输入流的包装器,它表示apkt中的本地资源。驱动器的
File
对象表示存储在云中的文件的元数据。要上传文件(新文件或更新文件),您不需要任何元数据:只需要一个字节数组和一个MIME类型,这就是
InputStreamContent
的用途。然后,您需要一个
文件
对象来告诉如何在云中调用这个字节流。请注意,这不是一个
java.io.File
,而是一个驱动器。你可以用任何你喜欢的名字调用
setTitle()
。你的上一个建议非常有效。尽管我不得不手动设置这个长度属性,但我确实发现这很不寻常。@JohnRoberts确实如此。HTTP并不严格地需要它,必须有一种方法来跳过该度量,但是很难说是如何做到的-似乎当
传输编码
设置为
分块
时,您可以跳过
内容长度
标题。这应该是默认行为,但可能我没有很好地读取文档…传入URL.toString()而不是文件路径会产生相同的错误。因此,如果您(正确地)认为问题在于InputStreamContent的长度,为什么不尝试设置它呢?因为资源是一项资产,您可以在您的开发机器上计算长度——否则您可以从输入流中一次读取一个字节(或者使用缓冲区),直到EOS,然后设置内容长度