2

プロジェクトフォルダに含まれる特定のExcelスプレッドシートにプログラムでアクセスし、Googleドライブにアップロードしたいと思います。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/取得します。AssetManagerR.raw.untitled_spreadsheet.xlsx

公式ガイドを参照してください:

まれですが、元のファイルとディレクトリにアクセスする必要がある場合があります。その場合、res /からリソースを読み取る唯一の方法はリソースIDを使用することであるため、ファイルをres/に保存しても機能しません。代わりに、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);

はどこにctxありますかContextActivityはであるため、このコードを。内に記述した場合は、Contextをスキップしctxて直接呼び出すことができます。getAssets()Activity

:を使用しなかったことに注意してくださいFileContent。代わりにInputStreamContent、実際にはjava.io.Fileオブジェクトがなく、入力ストリームがあるために選択しました。

基本的に、ドライブクライアントに次のように要求します。「このローカルストリームからバイトを読み取り、アップロードして、$NAMEという名前でアクセスできるようにします」。名前は、オブジェクトのフィールド$NAMEを介してサービスに提供されます。このフィールドは、任意の名前にすることができます。ディレクトリ区切り文字を含めることもできると思います。com.google.api.services.drive.model.Filetitle

これは、 GoogleドライブV2のJavadocへのリンクです。

于 2012-11-29T20:56:41.223 に答える
0

「これを引き起こしているのは何ですか?」という質問に取り組むには、ここでの説明(コメント#13周辺)を参照してください。

有効なファイルパスを指定していないのは単純な理由です。クラスローダーからリソースを取得しており、そのリソースはjarから取得されています(実際にはファイルシステムに解凍されることはありません)。

したがって、url.getPath()を使用してリソースのURLにパスを要求すると、(あなたの場合は)ファイルが返されます:/data/app/com.example.drivequickstart-2.apk!/Untitledspreadsheet.xlsx

これは正当なファイルではありません:'url文字列!

彼はまた、これに取り組むための非常に適切な方法を提案しています:

あなたがすべきことは、URL.toString()によって返される文字列をコンストラクターにフィードすることです。そのとき取得する必要があるのは、まだjarファイルを指しているある種の登録済みURLタイプですが、VMのURLリゾルバーは処理方法を知っています。

于 2012-11-29T21:04:24.440 に答える