Android Google Drive Api share files across devices and accounts - android

I'am using the Google Drive Android API. My application is synchronizing files to a google drive folder. This is working properly.
Additionally, I want to share those folders and files with other users. Unfortunately from another device and account in the same app I can only access files/folders which I have picked through the Files/Folder pickers (see https://github.com/googledrive/android-demos/tree/master/app/src/main/java/com/google/android/gms/drive/sample/demo)
My GoogleApiClient is getting the scope: Drive.SCOPE_FILE. So description says:
Per-file access to files created or opened by the app
Since I am using the same app on another device with a different account shouldn't I be able to access those files? Btw with the same account on another device this is working.
Is there any other solution? I've already checked the REST API but I am afraid this would make the whole code much more complex.

For everyone who is interested in a solution:
I found no way to sync shared files with the google android native API. (besides the file picker)
In case you want to do so you have to use the google drive rest API.
A little advantage for this solution. I think the java rest API is anyway much more suited for this kind of work. Code gets in that way much more readable.

You just need to authorized the user. Take note that in every request your application sends to the Drive API must include an authorization token. The token also identifies your application to Google. You must impliment OAuth 2.0 to authorize requests. No other authorization protocols are supported.
All requests to the Drive API must be authorized by an authenticated user.
The details of the authorization process, or "flow," for OAuth 2.0 vary somewhat depending on what kind of application you're writing. The following general process applies to all application types:
When you create your application, you register it using the Google API Console. Google then provides information you'll need later, such as a client ID and a client secret.
Activate the Drive API in the Google API Console. (If the API isn't listed in the API Console, then skip this step.)
When your application needs access to user data, it asks Google for a particular scope of access.
Google displays a consent screen to the user, asking them to authorize your application to request some of their data.
If the user approves, then Google gives your application a short-lived access token.
Your application requests user data, attaching the access token to the request.
If Google determines that your request and the token are valid, it returns the requested data.
Some flows include additional steps, such as using refresh tokens to acquire new access tokens. For detailed information about flows for various types of applications, see Google's OAuth 2.0 documentation.
Scope:
https://www.googleapis.com/auth/drive.file - Per-file access to files created or opened by the app
Full access to all files in the user's Drive (https://www.googleapis.com/auth/drive) may be necessary for some apps. An app designed to sync files, for instance, needs this level of access to Drive. Apps with special needs related to listing or reorganizing files might need full scope.

Related

How to add client id to Google Drive Client API for Java

I'm just getting started with using the Google Drive REST API in an Android app. (I can't use the Google Drive API for Android because the app needs to share files, and perhaps a few other things, that GDAA doesn't support.) I'm stuck on a couple of points.
The first has to do with OAuth2.0 credentials. I went through the Android quick start example and it works fine. I set up a project on my Google developer console and generated an OAuth2.0 client ID and secret and also downloaded the JSON credentials file. However, the quick start example doesn't show how to plug any of this into the app. The only thing I found in the docs that seems relevant is GoogleClientSecrets, but I don't see anything about how to use that in an Android app. (The Java quick start example uses this, but it's not integrated with Android's account manager and doesn't seem right for an Android app.) When I run the Android version of the quick start app, no activity shows up on my developer console, which suggests to me that the app is running in some sort of anonymous mode. As I understand it, that would limit the app to a very low daily quota of transactions.
Second, I noticed that the GDAA and the REST API for JavaScript both have nice file picker APIs. I couldn't find anything similar in the Java/Android API.
So here are my specific questions:
How do I use my app's OAuth2.0 credentials from the developer console in a REST API for Android Java app? I feel like I'm just missing something obvious.
Is there a file picker API for the Google Rest API for Android?
After stepping through the library as I executed the Quickstart example (a painful process, as there is no source code), I discovered the answer. It turns out that you need to specify the client ID in the manifest. Specifically, you needs the following under the <application> tag:
<meta-data
android:name="com.google.app.id"
android:value="app ID from your API console"/>
Once this entry is in the manifest, then when the app uses the Google Drive REST API to interact with Google's servers, the transaction is correctly logged as traffic in your app's console. Without this entry, the app seemed to work in my testing, but no traffic was logged. I seem to recall (from an old Google I/O video) that such "anonymous" apps still work, but have a very low usage quota (something like 10 or 100 queries/day).
For those who are curious, I found this key in the class com.google.android.gms.common.internal.zzz, found in the play-services-basement-10.2.0 library.
Save the client_id.json file downloaded from the Google API console into into your app's src/main/res directory.
I was stuck exactly the same, but after I built my app with the file included the Google API started working.
How do I use my app's OAuth2.0 credentials from the developer console in a REST API
The pages around https://developers.google.com/android/guides/api-client give you all that you need to know. In particular, note the Java Quickstart you were using is for generic Java. The way Google Play Services on Android manage credentials and accounts is very Android-specific.
Is there a file picker API for the Google Rest API for Android?
Not that I know of, but depending on your use case, you might be able to use the GDAA picker. Ultimately, both GDAA and the Java REST API are layers above your Drive storage.

Android app check for user Dropbox accounts on device

I am developing an app to download all the images from Dropbox. I am using Dropbox Core API and have followed this example: Android Dropbox Core API official documentation
I would like to check if there are an account already opened on the device. In this case I want to get this session, otherwise I will build a new session with the Dropbox Core API. Is it that possible?
Thanks!
As noted in the tutorial you linked to, when using the Android Dropbox Core API, you can and should store and re-use the resulting access token for a user after they first authorize the app. (This is typically done using SharedPreferences.)
On later runs of your app, your app should check wherever it stored the token to see if it has one. If it does, it can try to use that.
If you do have an access token, you can construct an AndroidAuthSession, e.g., using this constructor:
https://www.dropboxstatic.com/static/developers/dropbox-android-sdk-1.6.3-docs/com/dropbox/client2/android/AndroidAuthSession.html#AndroidAuthSession(com.dropbox.client2.session.AppKeyPair,%20java.lang.String)

Drive API for Android unable to access the file created by same App

I am writing an app where one user will write a file through this app and share it with other users using a link. Other users will read the file using same mobile app. I am using 'Drive API for Android' to use the offline writing and incremental updates feature so that readers will be able to download only that part of file which is newly added or updated instead of full file download every time.
But unfortunately the file/folder created by this app by one user is not accessible through the same app on other devices. I am using method Drive.DriveApi.fetchDriveId with the folder id and getting following error message.
"Drive item not found, or you are not authorized to access it."
File/folder is accessible on same device with same id, but not accessible on other device, which indicates that second part of error message is the real reason.
With the current scope (Drive.SCOPE_FILE), I was hoping that file will be accessible as it is created by the same app, but it is not working.
So my question is "does Google Drive store device information also while creating files/folders and doesn't allow the same app on different devices to use it?" If not, it must be my mistake in the implementation, which I can debug further.
I had a similar issue but not with an android app but a JavaScript app (should not matter IMO) and I wanted to access a shared file not a folder. However, I guess my workaround could help you as well.
The first approach is using the full auth scope (see https://developers.google.com/drive/web/scopes)
https://www.googleapis.com/auth/drive
But that is not really desired since you should request as few rights as possible from your users. My work-around was therefore as follows:
I used the Drive UI Integration
Goto https://console.developers.google.com/apis/api/drive/drive_sdk
select the "Drive UI Integration" tab
fill out the form, I have used the following:
"Application Name"
The mandatory "Application icons"
activated "Automatically show OAuth 2.0 consent screen when users open my application from Google Drive" and entered my "CLIENT ID"
used a dummy url for "Open Url" (e.g., http://example.com)
provided a default file extension (this way your app will be suggested afterwards when the user opens a file)
save your changes
Add the following scope to your app
https://www.googleapis.com/auth/drive.install
The users will install your app when approving the requested rights
Request your users to open the shared files with your "dummy" app in the google drive folder, which will grant your app access to the file (as stated here: https://developers.google.com/drive/web/scopes -- https://www.googleapis.com/auth/drive.file = Per-file access to files created or opened by the app) -- notice that the user will see an error message when opening your dummy app. You should probably implement an open url with something saying "thank's for granting access to the file xYZ".
your app is now able to access the shared file.
I know, it is not very user-friendly but it works (at least now, might be that this is not intentional)
If you know a way to automatically open a file with an app by invoking some URL, then please let me know. (yet, that would kind of be a security issue in the Google API, so I guess it is not possible).
Since it is somewhat cumbersome, I will propose the following two options to the user (so she/he can decide on her/his own):
Give the app full access and don't be concerned about this issue at the cost of privacy (I am certainly not evil and would not do anything with the files, but might be that someone can hack my app and get access to the accounts and then... well, then the user would have wished to give my app less rights.)
Give only install rights in addition but with the pain to open every single file which the app needs access to. In my case this is relatively rare so it should not really bother the user.
I hope that helps.
Assuming this as a limitation of Drive API for Android, I am switching to Drive REST API. I found the functionality I was looking for in the Drive REST API i.e. incremental updates to the file and resumable downloads. Just that I need to manage some of the things on my own.
In that way, Drive REST API is complete and it can provide all the functionalities whereas Drive API for Android is constrained with lot of limitations. With no answers to my questions, I am assuming that it is not possible to share files with other users through Google Drive using Drive API for Android.
You can add full permissive drive scope -
https://www.googleapis.com/auth/drive
request scope using -
.requestScopes(new Scope("https://www.googleapis.com/auth/drive"))
instead of
.resuestScopes(Drive.SCOPE_FILE)

How to connect to Google Drive using the Android API and a specific account?

I want to use Google Drive for cloud sync purposes.
Is it possbile using Google Drive API for Android to connect to a specific account that will act as a cloud storage server ?
How can I set the user account and password when I try to connect with that specified Google account ?
So far I'm using:
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
But this provides the user with a login dialog to select its own local account which is not what I'm intending to do. Thanks.
This is an excerpt from this answer I gave on a similar question:
There are two main items you need to make a request to a Google API:
refresh_token - Used to get more access_tokens and never expires
access_token - Used to send API calls (example: upload a file) and expires every 60 minutes.
In order to get either of these you have to follow certain steps.
Obtain a OAuth 2.0 client ID through the Google Developers Console
Obtain an access token from the Google Authorization Server
Send the access token to an API
Refresh the access token, if necessary
More specific information about this "general" process can be found here.
The tricky step is getting the refresh token because once you have that stored in a secure location, you can do anything with simple httpRequests.
To get a refresh token, a user has to agree to give your project access to certain features. This is called scopes in Google language. You can do this in many different ways (according to Google):
There are several ways to make this request, and they vary based on
the type of application you are building. For example, a JavaScript
application might request an access token using a browser redirect to
Google, while an application installed on a device that has no browser
uses web service requests.
The one thing they don't tell you is that, in your case, it doesn't matter what medium you use to get the refresh_token because you are only using one account. The Google Drive API isn't really designed to be used like a server. It is designed to be used by a developer that wants to store information on each of its user's accounts. Like if you had a picture app, you could have a feature that stores edited picture on someone's personal Google Drive account.
What you (and many others who have recently asked about) want to do is essentially use a Drive account as a server. That means that the medium through which you get your refresh_token does not have to be related to the medium in which you are using the Drive Account.
For example in my specific case, I wanted a way to store user pictures on a server for free for an android app. I am using this free service called Parse to act as my database server, but they give you very limited file storage in their free tier.
Because of this, I decided to try and figure out how to use Google drive accounts to expand my storage. I created a generic gmail account something like "hostingaccount#gmail.com" to be the host of the files (15g for free).
To get my refresh_token, I setup a php server to authenticate that one account. When someone goes to the page I setup, they are prompted to login and then grant access to my project to use their Google Drive account (Specific scope: https://www.googleapis.com/auth/drive). I then setup the script to print the refresh_token for that account on the screen. I copied that string an put it into my server when now I can easily send httpRequests to:
https://www.googleapis.com/oauth2/v3/token/ to get an access token and to:
https://www.googleapis.com/upload/drive/v2/files to upload files.
I link it at the top of this edit, but this answer shows you how to get a refresh token using my php method. I never spent the time to try an figure out how to get a refresh token any other way, but if you read my whole long answer I think I mention that I believe that this can also be done with the Android Google Drive API.
I have tried to help so many people with this problem, maybe I should just start a blog and make a tutorial about it ;)

Can we share GooglePlus_ClientID and GoogkePlus_simpleAPI_key?

I want to use googleplus API for my Android application.
Can I share my googeplus Client ID and API keys in menifest.xml file without any security being compromised?
Can somebody do some malicious activity using this information?
They could exhaust your API call quota by impersonating your app. Then your app will stop working (either temporarily or permanently if they ban your key). That said, for your app to work, they need to be inside the app, so you have to put them there. You might try to obfuscate them somewhat to make them less obvious.
There's a better way to setup client authentication in Android than using the simple API key. Full instructions are available from the Google+ Platform for Android page. At a high level, the following steps are taken:
Create a client ID for Android using your package name and a signing fingerprint from your Android keystore. This will protect your application because only you can sign your apps.
Use the Google Play Services SDK to perform operations against the Google+ API.
You will not need to authenticate in the same sense that you would for Web applications because your package and its certificate are sufficient to identify your application. For this reason, you will need a unique package per application.

Categories

Resources