Unable to retrieve Google Drive files and folders using new Drive API - android

I am trying to get a list of Files in a Folder from Google Drive from my Android app but have been unsuccessful so far. I'm using google-api-drive-v1-rev4-java-1.6.0-beta and google-api-client-1.9.0. I'm also building my code similar to calendar-android-sample and tasks-android-sample from the samples at http://code.google.com/p/google-api-java-client/wiki/Android.
I cant seem to find how to use files() to get a list of folders or even the id of the folder I want. The tasks-android-sample uses '#default' in the get() method to get a list of tasks. What would I use in the get method to get a list of folders first, search for my folder, get the id, then get a list of files in that folder?
AsyncLoadDocs.java: (Note: I'm using getFields() just to see if the Get object contains any metadata, which at this point doesn't.)
package com.mysite.myapp.docs;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.Drive.Files;
import com.google.api.services.drive.Drive.Files.Get;
import com.google.api.services.drive.model.File;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.ArrayAdapter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Asynchronously load the docs with a progress dialog.
*
* #author ms
*/
class AsyncLoadDocs extends AsyncTask<Void, Void, List<String>> {
private static final String TAG = "AsyncLoadDocs";
private final GDocsSync gDocsSync;
private final ProgressDialog dialog;
private final Drive entry = null;
private com.google.api.services.drive.Drive service;
AsyncLoadDocs(GDocsSync gDocsSync) {
this.gDocsSync = gDocsSync;
service = gDocsSync.driveClient;
dialog = new ProgressDialog(gDocsSync);
}
#Override
protected void onPreExecute() {
dialog.setMessage("Loading docs...");
dialog.show();
}
#Override
protected List<String> doInBackground(Void... arg0) {
try {
List<String> folderNames = new ArrayList<String>();
Get get = service.files().get("#default").setProjection("FULL");
String fields = get.getFields();
Log.d(TAG, "Fields: " + fields);
return folderNames;
} catch (IOException e) {
gDocsSync.handleGoogleException(e);
return Collections.singletonList(e.getMessage());
} finally {
gDocsSync.onRequestCompleted();
}
}
#Override
protected void onPostExecute(List<String> result) {
dialog.dismiss();
}
}
Any help would be appreciated. Both Calendar and Tasks samples successfully retrieve data from Google using my API key, why doesn't this Drive code?

The Drive API grants access only to two classes of files:
Files that a user has created with a given Drive app
Files that a user opens with a given Drive app
For security reasons, there's no method to list all files in a user Drive account:
https://developers.google.com/drive/apps_overview#granting_file-level_access
For more options in the Android environment, check out these other answers:
Android API for Google Drive?
Google Drive\Docs API for Android

Related

Implement Play Asset Delivery In flutter

How to implement on-demand Play Asset Delivery in flutter through methodchannels.
Actually i am trying to make a dashboard for some app which accesses assets using ContentProvider so i thought play asset delivery might work here.
I know that same can be achieved using deferred components and I have already tried deferred components which is provided by flutter.
You can find it here
Currently, there is an issue with flutter which causes assets to not load when deferred. You can find a link to the issue here.
I do not have any idea of native language and this is the only option I have right now which is implementing a methodchannel so any help would be appreciated
I dont think you can achieve the same thing using play asset delivery. You can try a workaround for this
Disable android:enabled by default by adding android:enabled="false" in your content provider and then use below methodchannel to enable it later
package dev.blah.blah;
import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugin.common.MethodChannel;
import android.content.ContextWrapper;
import android.widget.Toast;
public class MainActivity extends FlutterActivity {
private static final String CHANNEL = "dev.dhanraj.kwgt.test.dashboard";
#Override
public void configureFlutterEngine(#NonNull FlutterEngine flutterEngine) {
super.configureFlutterEngine(flutterEngine);
new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL)
.setMethodCallHandler(
(call, result) -> {
// Note: this method is invoked on the main thread.
if (call.method.equals("enable")) {
ContextWrapper aContext = new ContextWrapper(getApplicationContext());
aContext.getPackageManager().setComponentEnabledSetting(new android.content.ComponentName(aContext, "org.kustom.api.Provider"), android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 1);
result.success(null);
Toast.makeText(this, "Done", Toast.LENGTH_SHORT).show();
} else{
result.notImplemented();
}
}
);
}
}

Example for replacement for InstrumentationRegistry.getContext()

With AndroidX the InstrumentationRegistry is now deprecated. The documentation states
This method is deprecated. In most scenarios, getApplicationContext() should be used instead of the instrumentation test context. If you do need access to the test context for to access its resources, it is recommended to use getResourcesForApplication(String) instead.
However, I cannot find any examples of how to obtain the instance of PackageManager in test to invoke getResourcesForApplication and which package name should be provided to its string parameter.
For instance, here is the code that currently works:
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.io.IOException;
import java.io.InputStream;
import androidx.test.InstrumentationRegistry;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import static org.junit.Assert.*;
#RunWith(AndroidJUnit4.class)
public class MyTest {
#Test
public void processImage() {
// load image from test assets
AssetManager am = InstrumentationRegistry.getContext().getAssets();
InputStream is = null;
Bitmap image = null;
try {
is = am.open("image.jpg");
image = BitmapFactory.decodeStream(is);
} catch (IOException e) {
e.printStackTrace();
} finally {
if ( is != null ) {
try {
is.close();
} catch (IOException ignored) { }
}
}
assertNotNull(image);
// do something with the image
}
}
Now, how to rewrite this test without using the deprecated InstrumentationRegistry.getContext()? Keep in mind that image.jpg is not part of the application's assets - it's located in src/androidTest/assets folder and gets packaged into AppName-buildType-androidTest.apk (it's not present in the AppName-buildType.apk, for which I know the package name).
How to deduce the package name of the test APK? Is it possible to avoid hardcoding package name strings in my unit test? I am looking for a solution that is as elegant as the original code, but does not use deprecated methods.
I think you should simply use InstrumentationRegistry.getInstrumentation().getContext().getAssets() instead of InstrumentationRegistry.getContext().getAssets().
It will use your test context, so you should get your assets.

Android: MobileFirst sending data from Native to cross page

My Task is as follows: using IBM MobileFirst create a Hybrid app and implement a JS calculator. show date retrieved from native java APIs to the web page.
My attempts:
I followed Documentations here and implemented the whole Native code onCreate method
I found this answer"the first one" illustrating that i should use it on onInitWebFrameworkComplete,
Solution provided didn't work
I am working with MobileFirst version 7
full sample code is provided
Suggestion: should i create the whole action bar in native code then merge it in the cross ui, is that available? I only need to send a petite string of date
I am not clear on your attempts, so here is a quick demonstration how to click a button in HTML and trigger the Send Action API to get the current Date in Java and return it to JavaScript, and then display it.
index.html
<button onclick="getDateFromJava();">show current date from Java</button>
main.js
function wlCommonInit(){
WL.App.addActionReceiver ("returneDdateFromJava", returnedDateFromJava);
}
function getDateFromJava() {
WL.App.sendActionToNative("retrieveDate");
}
function returnedDateFromJava(received){
if (received.action === "returnedDateFromJava"){
alert (JSON.stringify(received));
}
}
main Java class file
Find onInitWebFrameworkComplete
Add an ActionReceiver after the else:
import com.worklight.androidgap.api.WLActionReceiver;
...
...
public void onInitWebFrameworkComplete(WLInitWebFrameworkResult result){
if (result.getStatusCode() == WLInitWebFrameworkResult.SUCCESS) {
super.loadUrl(WL.getInstance().getMainHtmlFilePath());
} else {
handleWebFrameworkInitFailure(result);
}
ActionReceiver ActionReceiver = new ActionReceiver();
WL.getInstance().addActionReceiver(ActionReceiver);
}
ActionReceiver class
package com.getDateApp;
import java.util.Date;
import org.json.JSONException;
import org.json.JSONObject;
import com.worklight.androidgap.api.WL;
import com.worklight.androidgap.api.WLActionReceiver;
public class ActionReceiver implements WLActionReceiver{
public void onActionReceived(String action, JSONObject data){
if (action.equals("retrieveDate")){
Date date = new Date();
JSONObject returnedDate = new JSONObject();
try {
returnedDate.put("dateFromJava", date);
} catch (JSONException e) {
e.printStackTrace();
}
WL.getInstance().sendActionToJS("returnedDateFromJava", returnedDate);
}
}
}

Error in connecting App Engine backend to Async Task

I am trying to write a backend service in Android, which reads a remote database and executes a query on it, returning the result in a ResultSet object. This is the code for my Java Bean which I return from the API call (called SQLResult):
package com.gradai.rushhour.backend;
import java.sql.ResultSet;
public class SQLResult
{
ResultSet result;
public SQLResult()
{
}
public ResultSet getResult()
{
return result;
}
public void setResult(ResultSet rs)
{
result = rs;
}
}
Now I try to use this API (called sqlBackend) in an AsyncTask in the actual app. In the onPostExecute function, I am getting an error:
error: incompatible types: com.gradai.rushhour.backend.sqlBackend.model.ResultSet cannot be converted to java.sql.ResultSet
This is the code for the said function:
protected void onPostExecute(SQLResult result)
{
ResultSet rs = result.getResult();
Toast toast = Toast.makeText(context, rs.toString(), Toast.LENGTH_LONG);
toast.show();
}
I don't get why is a ResultSet class being created in the backend model. Please help me in understanding what is going on. I'll be glad to provide further code if needed for debugging.
EDIT: These are the import statements used in the AsyncTask program:
import android.content.Context;
import android.os.AsyncTask;
import android.widget.Toast;
import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.json.gson.GsonFactory;
import com.gradai.rushhour.backend.sqlBackend.SqlBackend;
import com.gradai.rushhour.backend.sqlBackend.model.SQLResult;
import java.io.IOException;
import java.sql.ResultSet;
Also, please note that: I tried to convert the ResultSet in the API function to an ArrayList, and changed the SQLResult class to contain the same. Now, when I try to access the ArrayList in the same function, I get the error that a List is expected instead of an ArrayList. Could that be helpful?

Android List filter

I have a List of File object I want to filter according to some rules like typology (audio, video, photo) or capture date/time, or Exif informations (in case of photos). I can do it with some for cicles for example.
There's a smart way to do it? I read somewhere that the solution probably is to use Predicates from Google Guava, but I can't understand how it works. Any suggestion? Thanks
Using Guava Predicates you would do something along the lines of
import java.io.File;
import java.util.Collection;
import java.util.List;
import javax.annotation.Nullable;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.common.io.Files;
public class FileFiltering {
public static void main(String[] args) {
List<File> files = getFiles();
Collection<File> audioFiles = Collections2.filter(files,
new AudioPredicate());
Collection<File> videoFiles = Collections2.filter(files,
new VideoPredicate());
}
private static List<File> getFiles() {
// TODO Auto-generated method stub
return null;
}
}
class AudioPredicate implements Predicate<File> {
#Override
public boolean apply(#Nullable File file) {
return Files.getFileExtension(file.getName()).equalsIgnoreCase("mp3");
}
}
class VideoPredicate implements Predicate<File> {
#Override
public boolean apply(#Nullable File file) {
return Files.getFileExtension(file.getName()).equalsIgnoreCase("mkv");
}
}
In the apply method(s) you will need to write code that will return true for the kind of file you want.

Categories

Resources