I want to programmatically access a specific Excel spreadsheet which will be included in my project folder and upload it to Google Drive. I am including the spreadsheet within my src folder and using the following code:
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();
}
However, I keep getting the following 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)
Does anyone know what is causing this?
EDIT:
I have tried to modify my code as follows in line with suggestions below:
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();
}
However, this gives me the following error:
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)
and points to the line: File file = service.files().insert(body, content).setConvert(true).execute(); Upon closer inspection, I discovered that the length of the InputStreamContent is -1, so the problem probably originates there.
You use the Java idiom
ClassLoader.getResource()to load resources from theCLASSPATH. However, that’s not how we do it on Android.You’ll place your file in the
assets/directory or inres/raw/, and then retrieve it with theAssetManageror an identifier likeR.raw.untitled_spreadsheet.xlsx.See the official guide:
Speaking in code, if you put the file in
assets/sheet.xlsx:where
ctxis aContext. SinceActivityis aContextyou can skip thectxand directly callgetAssets()if you happen to write this code inside anActivity.Notice I didn’t use a
FileContent: instead I choosedInputStreamContentbecause you don’t really have ajava.io.Fileobject, but an input stream.Basically, you are asking the Drive client: “Read bytes from this local stream, upload them and make them accessible under the name $NAME”. The name
$NAMEis supplied to the service via acom.google.api.services.drive.model.Fileobject’stitlefield, which can be whatever you like – I think it can include directory separators, too.This is a link to the Javadoc for Google Drive V2