How to read from Drive application data folder? - android

This is a follow-up of this question. I have written my data file on Drive application folder, now the same app that created these files needs to retrieve them.
This doesn't work (I get the listing of the file, but the request of file download return with a 401 error):
private ArrayList<File> listFilesInApplicationDataFolder(Drive service) throws IOException {
ArrayList<File> result = new ArrayList<File>();
Files.List request = service.files().list();
request.setQ("'appdata' in parents");
do {
try {
FileList files = request.execute();
result.addAll(files.getItems());
request.setPageToken(files.getNextPageToken());
} catch (IOException e) {
System.out.println("An error occurred: " + e);
request.setPageToken(null);
}
} while (request.getPageToken() != null &&
request.getPageToken().length() > 0);
for (File file:result){
System.out.println("##### "+file.getOriginalFilename()+ " "+file.toPrettyString());
if (file.getDownloadUrl() != null && file.getDownloadUrl().length() > 0) {
try {
HttpResponse resp =
service.getRequestFactory().buildGetRequest(new GenericUrl(file.getDownloadUrl()))
.execute();
InputStream in= resp.getContent();
FileOutputStream fos = openFileOutput("pinmemo",
Context.MODE_PRIVATE);
while(in.available()>0)
fos.write(in.read());
fos.close();
} catch (UserRecoverableAuthIOException e) {
startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
return null;
} catch (IOException e) {
// An error occurred.
e.printStackTrace();
return null;
}
} else {
// The file doesn't have any content stored on Drive.
return null;
}
}
return result;
}
What should I do?
EDIT:
I get this error message:
04-17 11:19:30.614: W/System.err(2022): com.google.api.client.http.HttpResponseException: 401 Unauthorized
04-17 11:19:30.614: W/System.err(2022): at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1095)
EDIT: the new Google play games services basically covers my needs (the only problem is that my app isn't a game...), therefore this question is now partially obsolete. Of course, Google play games uses "Cloud save" instead of "drive", but for my needs that's sufficent. However, should I use Google play games for non-gaming app?

Make sure that your access token has permissions for the appdata scope:
https://www.googleapis.com/auth/drive.appdata

Related

how to read public folder from google drive on android

i want to create a comic reader project on android. In my database, i only save path to the chapter directory which was taken from folderID on google drive. When user request to read comic, i want to through google client api to browse folder and get all file inside it.
i've seen guilde on https://developers.google.com/drive/v2/reference/files/list
but i still do not understand how it works, specials parameter Drive, how can i get it?
Thanks for any supports.
private static List<File> retrieveAllFiles(Drive service) throws IOException {
List<File> result = new ArrayList<File>();
Files.List request = service.files().list();
do {
try {
FileList files = request.execute();
result.addAll(files.getItems());
request.setPageToken(files.getNextPageToken());
} catch (IOException e) {
System.out.println("An error occurred: " + e);
request.setPageToken(null);
}
} while (request.getPageToken() != null &&
request.getPageToken().length() > 0);
return result;
}

Android OS - How to track Azure upload progress

I've been working with Azure on the Android OS and I managed to upload my video file (.mp4) to a Container I had already prepared for it.
I did this by getting a Shared Access Signature (SAS) first, which provided me with:
a temporary key
the name of the container to where I want to send the files
the server URI
Then, I started an AsyncTask to send the file to the container using the "upload".
I checked the container, and the file gets uploaded perfectly, no problems on that end.
My question is regarding the progress of the upload. Is it possible to track it? I would like to have an upload bar to give a better UX.
P.S - I'm using the Azure Mobile SDK
Here's my code:
private void uploadFile(String filename){
mFileTransferInProgress = true;
try {
Log.d("Funky Stuff", "Blob Azure Config");
final String gFilename = filename;
File file = new File(filename); // File path
String blobUri = blobServerURL + sharedAccessSignature.replaceAll("\"", "");
StorageUri storage = new StorageUri(URI.create(blobUri));
CloudBlobClient blobCLient = new CloudBlobClient(storage);
//Container name here
CloudBlobContainer container = blobCLient.getContainerReference(blobContainer);
blob = container.getBlockBlobReference(file.getName());
//fileToByteConverter is a method to convert files to a byte[]
byte[] buffer = fileToByteConverter(file);
ByteArrayInputStream inputStream = new ByteArrayInputStream(buffer);
if (blob != null) {
new UploadFileToAzure().execute(inputStream);
}
} catch (StorageException e) {
Log.d("Funky Stuff", "StorageException: " + e.toString());
e.printStackTrace();
} catch (IOException e) {
Log.d("Funky Stuff", "IOException: " + e.toString());
e.printStackTrace();
} catch (Exception e) {
Log.d("Funky Stuff", "Exception: " + e.toString());
e.printStackTrace();
}
mFileTransferInProgress = false;
//TODO: Missing ProgressChanged method from AWS
}
private class UploadFileToAzure extends
AsyncTask <ByteArrayInputStream, Void, Void>
{
#Override
protected Void doInBackground(ByteArrayInputStream... params) {
try {
Log.d("Funky Stuff", "Entered UploadFileToAzure Async" + uploadEvent.mFilename);
//Method to upload, takes an InputStream and a size
blob.upload(params[0], params[0].available());
params[0].close();
} catch (StorageException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
Thanks!
You can split your file and send its part using Block, there is a good example of your case in this link but it used C# so you should find the corresponding function in the android library reference.
Basically instead of sending you file as one big file, you split it to multiple files (bytes) and send it to azure so you can track the progress on how many bytes that already sent to azure

Reading text from Google Drive files

Is there any possible way to read the text from a file on Google Drive and store it in a String? This file may contain images as well. I was looking into the Google Drive SDK but they only allow us to download the entire file. How should I go about doing this?
From Files.get() documentation.
private static InputStream downloadFile(Drive service, File file) {
if (file.getDownloadUrl() != null && file.getDownloadUrl().length() > 0) {
try {
HttpResponse resp =
service.getRequestFactory().buildGetRequest(new GenericUrl(file.getDownloadUrl()))
.execute();
return resp.getContent();
} catch (IOException e) {
// An error occurred.
e.printStackTrace();
return null;
}
} else {
// The file doesn't have any content stored on Drive.
return null;
}
}
You can convert InputStream to String or File as you want.

Download thumbnail of file from Google Drive

I can download the original file from Google Drive by using the following code :
public static InputStream downloadFile(Drive service, File file)
throws IOException {
if (file.getDownloadUrl() != null && file.getDownloadUrl().length() > 0) {
try {
HttpResponse resp = service.getRequestFactory()
.buildGetRequest(new GenericUrl(file.getDownloadUrl()))
.execute();
return resp.getContent();
} catch (IOException e) {
// An error occurred.
e.printStackTrace();
return null;
}
} else {
// The file doesn't have any content stored on Drive.
return null;
}
}
But it looks like the connection really low when downloading many files to add into the grid view.
Therefore, I need to list thumb nail instead of original file as it will be better for the connection.
Please help me how?
Use File.getThumbnail method to get the thumbnail or File.getIconLink to get the icon link.

What exceptions can be thrown when downloading a file?

In my app I have a facility to download reference data updates. The user can modify base url in a PreferenceActivity - and then I append the actual file name to the base URL. When I attempt to download the file, an exception may be thrown if something went wrong. I'd like to present the user with the most appropriate error message rather than simply "error occurred". To do this, I want to catch individual exception and format messages accordingly. So, what exceptions can be thrown when downloading a file? For the reference, here's my downloading code (simplified):
int msgId;
try {
String url = props.getProperty(Constants.SETTINGS_REFDATA_SOURCE);
if(!url.endsWith("/")) {
url += "/";
}
url += Constants.UPDATE_CUSTOMER_FILE;
CSVReader in = new CSVReader(new InputStreamReader(url.openStream()));
...//read and parse file here
}
catch(MalformedURLException e) {
msgId = R.string.error_invalid_base_url;
}
catch(UnknownHostException e) {
msgId = R.string.error_unknown_host;
}
catch(FileNotFoundException e) {
msgId = R.string.error_file_not_found;
}
catch(IOException e) {
msgId = R.string.error_reading_data;
}
catch(MyParseException e) {
msgId = R.string.error_invalid_file_format;
}
catch(Exception e) {
msgId = R.string.error_other_error;
}
finally {
try { in.close(); } catch(Exception e2) {}
}
// then I display AlertDialog using msgId as the message
As you can see, I'm already catching several exception - some that I know can be thrown, some that I encountered in testing. What other exceptions do I need to cater for? Note that the amount of data being download is quite small (at most 15-20 Kb) so things like OutOfMemoryError shouldn't be applicable.
There is the ConnectException due to connection timeout or connection refused (HTTP 403)
//edit: I just read, that "Most applications should not catch the ConnectException; it is more robust to catch the superclass SocketException."
Furthermore you could test if there is an active Internet connection:
private boolean checkCon() {
ConnectivityManager conMgr = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
if ( conMgr.getNetworkInfo(0).getState() == NetworkInfo.State.DISCONNECTED
&& conMgr.getNetworkInfo(1).getState() == NetworkInfo.State.DISCONNECTED) {
return false;
}
return true;
}

Categories

Resources