I am using Google Play Services SDK to integrate Google Drive.
My application need to show a list of all files in a folder.
From the demos: ListFilesInFolderActivity
I get the folder properly without any Authorization errors etc.. Because I changed the
com.google.android.gms.drive.sample.demo.BaseDemoActivity.EXISTING_FOLDER_ID
com.google.android.gms.drive.sample.demo.BaseDemoActivity.EXISTING_FILE_ID
values as per my application folder and file etc.
But in the
final private ResultCallback<MetadataBufferResult> metadataResult = new
ResultCallback<MetadataBufferResult>() {
#Override
public void onResult(MetadataBufferResult result) {
if (!result.getStatus().isSuccess()) {
showMessage("Problem while retrieving files");
return;
}
mResultsAdapter.clear();
mResultsAdapter.append(result.getMetadataBuffer());
showMessage("Successfully listed files.");
}
};
I only see the Toast "Successfully listed files." but nothing in the List. When checked for mResultsAdapter.getCount() it returns 0.
But the folder definitely has 1 file. What am I missing?
EDIT :
When I created folders/files from my application, they are visible. But folders/files added from web etc.. are not visible in the List.
Is it something like:
Only folders/files created by your application are accessible?
using
folder.listChildren(getGoogleApiClient()).setResultCallbackmetadataResult);
The Android API uses Drive.File scope, which means your app will only be able to see the files that the user has explicitly authorized your app to access. (Users much prefer this scope, since they have more control over who can see what data.)
If you open items with the same app on the web, they should be accessible to your Android app, but there may be some small delay in the showing up in the list response.
Related
I am programming an app that use a string (e.g. full name = "Adam Smith") and thus open corresponding "Adam Smith" folder in google drive. The next step is to show the content inside the folder.
Actually I am now able to access into google drive but unable to go into this specific folder. Can anyone post a sample code for me since I read the GoogleAPI webpage but cannot finish my app.
I am appreciated for suggestion in advance. Thank you
It is stated in this documentation that Folders provide a convenience method for listing their direct children using DriveFolder.listChildren. The sample code illustrates how to list files in a folder.
public void onConnected(Bundle connectionHint) {
super.onCreate(connectionHint);
setContentView(R.layout.activity_listfiles);
mResultsListView = (ListView) findViewById(R.id.listViewResults);
mResultsAdapter = new ResultsAdapter(this);
mResultsListView.setAdapter(mResultsAdapter);
DriveFolder folder = Drive.DriveApi.getFolder(getGoogleApiClient(), sFolderId);
folder.listChildren(getGoogleApiClient()).setResultCallback(childrenRetrievedCallback);
}
ResultCallback<MetadataBufferResult> childrenRetrievedCallback = new
ResultCallback<MetadataBufferResult>() {
#Override
public void onResult(MetadataBufferResult result) {
if (!result.getStatus().isSuccess()) {
showMessage("Problem while retrieving files");
return;
}
mResultsAdapter.clear();
mResultsAdapter.append(result.getMetadataBuffer());
showMessage("Successfully listed files.");
}
You can see more examples here.
Here are some related SO posts which might also help:
Android Google Drive SDK - how to show list of files in selected folder
Listing files and folders of GDrive using Google Drive Api
Happy coding!
I want to retrieve metadata from files or folders in Google Drive on Android device in order to get deviceID or resourceID, so then I could download the file to local storage of the device. The problem with my application is that, the application doesn't need user interaction. It mean that, just tell the application the name so then the app will try to find the files in every directory and download it.
I have try to use query (link) follow quickstart tutorial but it return me only the name of the existing file only.
Note again: User does not need to select files or folders, just tell the name of the file is enough. And the file or folder is created by the application too.
How to get metadata from files or folders in Google Drive on Android?
According to Working with File and Folder Metadata:
Metadata is encapsulated in the Metadata class and contains all details about a file or folder including the title, the MIME type, and whether the file is editable, starred or trashed. The metadata is fetched for a DriveResource by calling the DriveResource.getMetadata method.
Here's a snippet from the docs:
/**
* An activity to retrieve the metadata of a file.
*/
public class RetrieveMetadataActivity extends BaseDemoActivity implements
ResultCallback {
#Override
public void onConnected(Bundle connectionHint) {
DriveFile file = Drive.DriveApi.getFile(getGoogleApiClient(),
DriveId.decodeFromString("0ByfSjdPVs9MZcEE3bzJCc3NsRkE"));
file.getMetadata(getGoogleApiClient()).setResultCallback(metadataRetrievedCallback);
}
ResultCallback<MetadataResult> metadataRetrievedCallback = new
ResultCallback<MetadataResult>() {
#Override
public void onResult(MetadataResult result) {
if (!result.getStatus().isSuccess()) {
showMessage("Problem while trying to fetch metadata");
return;
}
Metadata metadata = result.getMetadata();
showMessage("Metadata succesfully fetched. Title: " + metadata.getTitle());
}
}
}
How to get resource ID?
Still on the Android API for Drive, DriveId class has a method getResourceId () which returns the resource ID.
How to get device ID?
I don't think you can use the Android Drive API to get this. It seems you've mistaken this for fileID which you'll be using to Download Files.
Locate fileID manually in Google Drive:
If it's a spreadSheet file
https://docs.google.com/spreadsheets/d/1pE9ejBTBH38oCoOHU2O42qU6vzxagAJ9J1237dYB1Eg/edit#gid=0
fileID -> 1pE9ejBTBH38oCoOHU2O42qU6vzxagAJ9J1237dYB1Eg
If it's a doc file:
https://docs.google.com/document/d/1Fh6s7an-7I6VuDBxZKcxcaU3cG1XpSryHQXGnznWlns/edit
fileID -> 1Fh6s7an-7I6VuDBxZKcxcaU3cG1XpSryHQXGnznWlns
You get the pattern. It's a string of alphanumeric characters in the URL.
I'm running a query on the Android SDK for Google Drive to check if a directory with a specific name exists or creating it otherwise (directory name is the resource title on Google Drive).
The problem I'm having with the following code is that it never finds my folder and creates a new one every time and I'm not sure why. It successfully finds the directory if the SDK created it itself.
public static final String FOLDER_NAME_CORE = "My Core Folder";
MetadataBuffer meta = Drive.DriveApi.query(mGoogleApiClient, new Query.Builder()
.addFilter(Filters.eq(SearchableField.TRASHED, false))
.addFilter(Filters.eq(SearchableField.TITLE, FOLDER_NAME_CORE ))
.setSortOrder(new SortOrder.Builder().addSortDescending(SortableField.MODIFIED_DATE).build())
.build()).await().getMetadataBuffer();
if (metadataBufferResult.getCount() > 0) {
Log.d(TAG, "Creating new folder");
...
} else {
Log.d(TAG, "Using existing folder");
}
I've tried making the folder publicly shared but it didn't change anything (as expected). Does anyone know what I have to change to make it find the existing folder instead? As far as I know this list is the only possible search options.
I hope you are aware of the supported scopes.
I think there are 2 things that cause your problem and you will have to re-think your app's logic.
First, GDAA (unlike the REST Api), introduces some latency, so the file/folder may not exist on the Drive for awhile, even if you got your DriveId (see this).
Second, the fact that you use TITLE as an indicator of existence does not work in the GooDrive universe, since TITLE is not unique (you already know that).
I would recommend this approach:
when your (GDAA based) app creates a file/folder, wait until you get it's ResourceId. That confirms it's existence (again here).
always check for the existence of a file/folder in the Drive using it's ResourceId (turned into DriveId)
I am introducing in Google Drive Android Api as docs and examples show.
I created two activities which extend BaseDemoActivity of the example: the first one adds empty files to Drive customizing on each file some CustomProperties, the second one lists from Drive the files added grabbing the owned CustomProperties of each file.
first activity - code which adds files like this:
DriveFolder folder = Drive.DriveApi.getFolder(getGoogleApiClient(),
mFolderDriveId);
CustomPropertyKey customPropertyKeyExample = new CustomPropertyKey(
"custom", CustomPropertyKey.PRIVATE);
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle("New empty file")
.setMimeType("text/plain")
.setCustomProperty(customPropertyKeyExample, "xyz")
.build();
folder.createFile(getGoogleApiClient(), changeSet, null)
.setResultCallback(fileCallback);
second activity - code which reads properties like this:
for (Iterator<Metadata> i = result.getMetadataBuffer().iterator(); i
.hasNext();) {
Metadata mChildren = ((Metadata) i.next());
if (!mChildren.isTrashed()) {
Map<CustomPropertyKey, String> mapProperties = mChildren
.getCustomProperties();
if (mapProperties.get(customPropertyKeyExample) == null)
// THIS TEST RETURNS TRUE UNTIL DRIVE SYNC EXECUTES
}
}
}
Them work, but i notice that the second activity, the list activity, must wait a Drive variable sync time to have the CustomProperties available.
Is there a way to get the CustomProperties from an activity immediately after them added by a different activity?
This isn't expected behavior. Custom file properties should be available locally without performing a sync.
I've created a bug on our issue tracker to discuss this further:
https://code.google.com/a/google.com/p/apps-api-issues/issues/detail?id=3848
Could you please respond on the bug, answering the following question:
Can you verify that the title is also changed immediately?
Which example class specifically are you using for your first and second activity?
How are you sharing the DriveId for the folder between the activities?
Are you using DriveFolder#listChildren or another query to get [result] in the second example?
Having Google Drive account with folders and files. I want to make android application for adding and geting files to there. Class QUERY is useful, but it can work with data making by application only
The Android Drive API only works with the https://www.googleapis.com/auth/drive.file scope. This means that only files which a user has opened or created with your application can be matched by a query.
Help, please, how can I add files to any folder, that was created via webinterface early?
You want to avoid using full drive scope unless you really need it. Users much prefer that your app have a narrower scope, as it makes it easier to trust you with their data. There are a couple of methods that you can accomplish most folder use cases while still only requiring file scope:
Use the OpenFileActivity to have the user select the folder that they want the file to be added to.
You can do this by configuring the OpenFileActivityBuilder to only display the folder mimetypes.
IntentSender intent = driveApi.newOpenFileActivityBuilder()
.setActivityTitle("Pick a destination folder")
.setMimeType(new String[] { DriveFolder.MIME_TYPE } })
.build();
startIntentSenderForResult(intent, REQUEST_CODE, null, 0, 0, 0);
Alternatively, if you have a corresponding web app that created the folder, just use the same developer console entry for both apps and you should already have access to the folder.
Don't use the latest google API, it was just released a few weeks ago. It currently only works with the drive.file scope, hasn't yet implemented a number of capabilities (e.g. setting multiple parents), and in my experience, contains some bugs that need to be fixed as well.
com.google.android.gms.common.api.GoogleApiClient
Use this API instead:
com.google.api.services.drive.Drive
try {
List<String> scopes = new ArrayList<String>();
scopes.add("https://www.googleapis.com/auth/drive.appdata");
scopes.add(DriveScopes.DRIVE);
GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2(m_context, scopes);
credential.setSelectedAccountName(m_account.name);
//Get token cannot be run from the main thread;
//Trying to get a token right away to see if we are authorized
token = credential.getToken();
if(token == null){
Log.e(TAG, "token is null");
}else{
Log.i(TAG, "GDrive token: " + token);
g_drive = new Drive.Builder(
AndroidHttp.newCompatibleTransport(),
new GsonFactory(), credential).build();
} catch ( UserRecoverableAuthException e) {
....
}