I am trying to develop an app wherein I am using Google Drive to upload and share of file in service. However, the problem is that shared link has private access. I want to change that access to anyone with link. To achieve that I am using Google Drive REST API, however nothing seems to happen when I execute the code. Here is my code:
public void changePermissionSettings(String resourceId) throws GeneralSecurityException, IOException, URISyntaxException {
com.google.api.services.drive.Drive driveService = getDriveService();
JsonBatchCallback<Permission> callback = new JsonBatchCallback<com.google.api.services.drive.model.Permission>() {
#Override
public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) throws IOException {
Log.e("upload", "Permission Setting failed");
}
#Override
public void onSuccess(com.google.api.services.drive.model.Permission permission, HttpHeaders responseHeaders) throws IOException {
Log.e("upload", "Permission Setting success");
}
};
final BatchRequest batchRequest = driveService.batch();
com.google.api.services.drive.model.Permission contactPermission = new com.google.api.services.drive.model.Permission()
.setType("anyone")
.setRole("reader");
driveService.permissions().create(resourceId, contactPermission)
.setFields("id")
.queue(batchRequest, callback);
new Thread(new Runnable() {
#Override
public void run() {
try {
batchRequest.execute();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
private com.google.api.services.drive.Drive getDriveService() throws GeneralSecurityException,
IOException, URISyntaxException {
Collection<String> elenco = new ArrayList<>();
elenco.add("https://www.googleapis.com/auth/drive");
GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2(this, elenco)
.setSelectedAccountName(getAccountName());
return new com.google.api.services.drive.Drive.Builder(
AndroidHttp.newCompatibleTransport(), new JacksonFactory(), credential).build();
}
I have two questions here:
Is it right to use both Google Drive Android API and Google Drive REST API together??
How to change permission setting of file from private to anyone with link?? Documentation mentions that Authorization happens in response to receiving an error when sending a request. How can that be achieved in service??
"Is it right to use both Google Drive Android API and Google Drive REST API together??"
As stated here, it is possible. "Just looking at the this Lifecycle of a Drive file, you can imagine your app on top of that picture (Android App) and the REST API on the bottom (Drive Service)."
There is a few points to keep in mind, though:
The GDAA's main identifier, the DriveId lives in GDAA (GooPlaySvcs) only and does not exist in the REST Api. You must retrieve 'ResourceId' which is the main identifier in the REST Api (see SO 29030110).
ResourceId can be obtained from the DriveId only after GDAA committed (uploaded) the file/folder (see SO 22874657)
You will run into a lot of timing issues caused by the fact that GDAA 'buffers' network requests on it's own schedule (system optimized), whereas the REST Api let your app control the waiting for the response. In general, if you scan these SO questions, you'll find a lot of chatter about these issues (it's a mess, though).
I maintain a minimal CRUD wrappers for both GDAA and the REST API that can help you if you merge them (the MainActivity in both of them is almost identical and the CRUD methods have the same signatures).
"How to change permission setting of file from private to anyone with link?? Documentation mentions that Authorization happens in response to receiving an error when sending a request. How can that be achieved in service??"
Based from this thread, you have to set the following permissions:
private Permission insertPermission(Drive service, String fileId) throws Exception{
Permission newPermission = new Permission();
newPermission.setType("anyone");
newPermission.setRole("reader");
newPermission.setValue("");
newPermission.setWithLink(true);
return service.permissions().insert(fileId, newPermission).execute();
}
You can also check this link: Google Drive SDK - change item sharing permissions.
Related
I'm building an app that uses Google Cloud Speech.
I have a Google Service account key in my app, and I use it to call the API.
It works well when used by one user, but does not work when multiple users use it at the same time.
For example, only one user is available or all are unavailable.
The rights of the service account key are project owner.
I think it's a service account key issue...
How do I fix it?
private class AccessTokenTask extends AsyncTask<Void, Void, AccessToken> {
#Override
protected AccessToken doInBackground(Void... voids) {
final SharedPreferences prefs = mContext.getSharedPreferences(PREFS, Context.MODE_PRIVATE);
String tokenValue = prefs.getString(PREF_ACCESS_TOKEN_VALUE, null);
long expirationTime = prefs.getLong(PREF_ACCESS_TOKEN_EXPIRATION_TIME, -1);
// Check if the current token is still valid for a while
if (tokenValue != null && expirationTime > 0) {
if (expirationTime > System.currentTimeMillis() + ACCESS_TOKEN_EXPIRATION_TOLERANCE) {
return new AccessToken(tokenValue, new Date(expirationTime));
}
}
final InputStream stream = mContext.getResources().openRawResource(R.raw.credential);
try {
final GoogleCredentials credentials = GoogleCredentials.fromStream(stream).createScoped(SCOPE);
final AccessToken token = credentials.refreshAccessToken();
prefs.edit()
.putString(PREF_ACCESS_TOKEN_VALUE, token.getTokenValue())
.putLong(PREF_ACCESS_TOKEN_EXPIRATION_TIME, token.getExpirationTime().getTime())
.apply();
return token;
} catch (IOException e) {
Log.e(TAG, "Failed to obtain access token.", e);
}
return null;
}
#Override
protected void onPostExecute(AccessToken accessToken) {
mAccessTokenTask = null;
final ManagedChannel channel = new OkHttpChannelProvider()
.builderForAddress(GOOGLE_API_HOSTNAME, GOOGLE_API_PORT)
.nameResolverFactory(new DnsNameResolverProvider())
.intercept(new GoogleCredentialsInterceptor(new GoogleCredentials(accessToken)
.createScoped(SCOPE)))
.build();
mApi = SpeechGrpc.newStub(channel);
// Schedule access token refresh before it expires
if (mHandler != null) {
mHandler.postDelayed(mFetchAccessTokenRunnable,
Math.max(accessToken.getExpirationTime().getTime() - System.currentTimeMillis() - ACCESS_TOKEN_FETCH_MARGIN, ACCESS_TOKEN_EXPIRATION_TOLERANCE));
}
}
}
This code is the code that calls 'credential.json' file on Android and gets 'Access token'.
The server for this app is python and communicates via http.
https://github.com/GoogleCloudPlatform/android-docs-samples/tree/master/speech/Speech
The description in the link above tells you to delegate the authentication to the server.
I want to write that part with python code.
What should I do?
In the link you provided in the description, they suggest you to read first the basic authentication concepts document. In your case, use a service account for the Android application.
I understand that you have already been able to provide end user credentials to a Google Cloud Platform API, as for example Cloud Speech API.
If you want to authenticate multiple users to your application you should use instead Firebase authentication. The link contains a brief explanation and a tutorial.
There are several Python client libraries for GCP that you can use, depending on what operations do you want to perform on the server. And regarding Python authentication on the server side, this documentation shows how the authentication for Google Cloud Storage works (have this example in mind as a reference).
My server sends the list of videoID to Android. Now, I want to show Title, Thumbnail and Number of Comments on these videos in List View. I have done this in web using GET request to https://www.googleapis.com/youtube/v3/videos?part=snippet&id={VIDEO_ID}&key={YOUR_API_KEY} but how to do this in Android? Is there any YouTube SDK to initialize YouTube object? How do I retrieve this information from YouTube using VideoID?
EDIT: I have found a way to this using YouTube Data API Client Library for Java but It is giving runtime error without any explanation.
Here is the code I used
/**
* Define a global instance of a Youtube object, which will be used
* to make YouTube Data API requests.
*/
private static YouTube youtube;
youtube = new YouTube.Builder(new NetHttpTransport(), new JacksonFactory(), new HttpRequestInitializer(){
public void initialize(com.google.api.client.http.HttpRequest request) throws IOException {
}
}).setApplicationName("youtube-cmdline-search-sample").build();
// Call the YouTube Data API's videos.list method to retrieve videos.
VideoListResponse videoListResponse = youtube.videos().
list("snippet").setId(videoId).execute();
// Since the API request specified a unique video ID, the API
// response should return exactly one video. If the response does
// not contain a video, then the specified video ID was not found.
List<Video> videoList = videoListResponse.getItems();
if (videoList.isEmpty()) {
System.out.println("Can't find a video with ID: " + videoId);
return;
}
Video video = videoList.get(0)
// Print information from the API response.
}
YouTube provides (at least) two official libraries relevant to your question:
YouTube Android Player API
YouTube Data API Client Library for Java
As the name already suggests, the first library is specifically developed for the Android platform. Its focus is on enabling you to incorporate video playback functionality into an app by providing a player framework. If your goal is to enable users to simply play YouTube videos, then is probably easiest to implement. Do note that this library requires the official YouTube app to be installed on the device.
The second library is more generic (although there are separate instructions for using it on Android) and provides a wrapper around YouTube's Data API to make interfacing with it a little easier. Hence, it allows you to do basically everything you can also do with the web API. As such, it solves a different problem than the Android Player API and is more likely the way to go if you want full control over how you display video data in your own UI.
Your third option would be to do exactly what you did for your web-based solution: make the API call yourself, parse the response and bind up the relevant data to your UI components. Various networking libraries (i.e. Retrofit) can greatly simplify this process.
Refer my post here. I just tried this method for my project and it works very nicely. You don't need the above code or any google api jar imports. Just replace the HTTP request with your HTTP request.
Output is returned in JSON, for which you can use a JSON parser jar to retrieve the title,thumbnails and other details you may require, as I have described in my answer there.
Try this:
protected void requestYoutubeVideos(String text) {
try {
youtube = new YouTube.Builder(new NetHttpTransport(), new JacksonFactory(), new HttpRequestInitializer() {
public void initialize(HttpRequest request) throws IOException {
}
}).setApplicationName("My app name").build();
// Define the API request for retrieving search results.
YouTube.Search.List query = youtube.search().list("id");
// Set your developer key from the Google Cloud Console for
// non-authenticated requests. See:
// https://cloud.google.com/console
query.setKey(YOUTUBE_API_KEY);
query.setQ(text);
query.setMaxResults(NUMBER_OF_VIDEOS_RETURNED);
// To increase efficiency, only retrieve the fields that the
// application uses.
query.setFields("items(id)");
query.setOrder("viewCount");
// Restrict the search results to only include videos. See:
// https://developers.google.com/youtube/v3/docs/search/list#type
query.setType("video");
SearchListResponse searchResponse = query.execute();
List<SearchResult> list = searchResponse.getItems();
Log.e("Youtube search", "list ===> " + list);
//Get Info for each video id
for (SearchResult video: list) {
youtubeList.add(video);
YouTube.Videos.List query2 = youtube.videos().list("id,contentDetails,snippet,statistics").setId(video.getId().getVideoId());
query2.setKey(YOUTUBE_API_KEY);
query2.setMaxResults((long) 1);
query2.setFields("items(id,contentDetails,snippet,statistics)");
VideoListResponse searchResponse2 = query2.execute();
List<Video> listEachVideo = searchResponse2.getItems();
Video eachVideo = listEachVideo.get(0);
}
} catch (GoogleJsonResponseException e) {
Log.e("Youtube search", "There was a service error: " + e.getDetails().getCode() + " : "
+ e.getDetails().getMessage());
} catch (IOException e) {
Log.e("Youtube search", "There was an IO error: " + e.getCause() + " : " + e.getMessage());
} catch (Throwable t) {
t.printStackTrace();
}
}
and do not forget to call it from another thread:
new Thread(new Runnable() {
#Override
public void run() {
try {
requestYoutubeVideos("Harry el Sucio Potter");
} catch (Exception ex) {
ex.printStackTrace();
}
}
}).start();
I refer from this code
AccountManager am = AccountManager.get(activity);
am.getAuthToken(am.getAccounts())[0],
"oauth2:" + DriveScopes.DRIVE,
new Bundle(),
true,
new OnTokenAcquired(),
null);
private class OnTokenAcquired implements AccountManagerCallback<Bundle> {
#Override
public void run(AccountManagerFuture<Bundle> result) {
try {
final String token = result.getResult().getString(AccountManager.KEY_AUTHTOKEN);
HttpTransport httpTransport = new NetHttpTransport();
JacksonFactory jsonFactory = new JacksonFactory();
Drive.Builder b = new Drive.Builder(httpTransport, jsonFactory, null);
b.setJsonHttpRequestInitializer(new JsonHttpRequestInitializer() {
#Override
public void initialize(JSonHttpRequest request) throws IOException {
DriveRequest driveRequest = (DriveRequest) request;
driveRequest.setPrettyPrint(true);
driveRequest.setKey(CLIENT ID YOU GOT WHEN SETTING UP THE CONSOLE BEFORE YOU STARTED CODING)
driveRequest.setOauthToken(token);
}
});
final Drive drive = b.build();
final com.google.api.services.drive.model.File body = new com.google.api.services.drive.model.File();
body.setTitle("My Test File");
body.setDescription("A Test File");
body.setMimeType("text/plain");
final FileContent mediaContent = new FileContent("text/plain", an ordinary java.io.File you'd like to upload. Make it using a FileWriter or something, that's really outside the scope of this answer.)
new Thread(new Runnable() {
public void run() {
try {
com.google.api.services.drive.model.File file = drive.files().insert(body, mediaContent).execute();
alreadyTriedAgain = false; // Global boolean to make sure you don't repeatedly try too many times when the server is down or your code is faulty... they'll block requests until the next day if you make 10 bad requests, I found.
} catch (IOException e) {
if (!alreadyTriedAgain) {
alreadyTriedAgain = true;
AccountManager am = AccountManager.get(activity);
am.invalidateAuthToken(am.getAccounts()[0].type, null); // Requires the permissions MANAGE_ACCOUNTS & USE_CREDENTIALS in the Manifest
am.getAuthToken (same as before...)
} else {
// Give up. Crash or log an error or whatever you want.
}
}
}
}).start();
Intent launch = (Intent)result.getResult().get(AccountManager.KEY_INTENT);
if (launch != null) {
startActivityForResult(launch, 3025);
return; // Not sure why... I wrote it here for some reason. Might not actually be necessary.
}
} catch (OperationCanceledException e) {
// Handle it...
} catch (AuthenticatorException e) {
// Handle it...
} catch (IOException e) {
// Handle it...
}
}
}
In jsonHttpRequestInitializer i get an issues. [GoogleClient$Builder cannot be resolved. It is indirectly referenced from required .class files] please suggest me what i have to do...
You have two different APIs you can use on Android, the REST and the GDAA.
REST is the 'barebones' API that gives you the full functionality of Google Drive. You also have an interactive playground to test everything (see the bottom of this page). But you have to manage the network delays, failures, etc... yourself. Ideally you would delegate that work to sync adapter service.
GDAA is built on top of REST, resides in Google Play Services and behaves as a local API with delayed promotion of objects (folders/files) to the Drive. Has only limited functionality compared to REST (forget thumbnail link, etc...). Essentially, you talk to GDAA and GDAA talks to the Drive on it's own schedule. So, you don't have to worry about on-line / off-line situations. Be careful though, this may also cause synchronization issues, since you don't have direct control over object promotion timing. The demos for GDAA can be found here and here.
I've also created a simple CRUD demo app that you can step through. The upload you're asking resides in create() method there. It is not fully up-to-date, since GDAA has implemented the 'trash' functionality already (in Google Play Services 7.00 / Rev. 23).
Good Luck
I'm trying to do an Android app that needs to work with Google spreadsheet API. I'm new in this, so I'm starting with the version 3 of the api: https://developers.google.com/google-apps/spreadsheets/
I followed all the steps, downloaded all the jar files to lib subfolder in my project folder and then I added to the build path in Eclipse as usual. So although there is no Java example to perform Oauth 2.0, I just tried to declare:
SpreadsheetService service = new SpreadsheetService("v1");
but when I emulate this simple line it gives me an error:
java.lang.NoClassDefFoundError: com.google.gdata.client.spreadsheet.SpreadsheetService
I'm using all the jars included in the documentation and I have the import:
import com.google.gdata.client.spreadsheet.SpreadsheetService;
but I am totally lost. I dont know what else to do just to start, connect to Google APIs and work with the spreadsheets.
Sample code for you without OAuth 2.0. But its recommended to perform OAuth as its good for the security purpose. You also have to add below permissions.
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCOUNT_MANAGER"/>
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
Sample Code:-
try {
SpreadsheetEntry spreadsheet;
service = new SpreadsheetService("Spreadsheet");
service.setProtocolVersion(SpreadsheetService.Versions.V3);
service.setUserCredentials("username", "password");//permission required to add in Manifest
URL metafeedUrl = new URL("https://spreadsheets.google.com/feeds/spreadsheets/private/full");
feed = service.getFeed(metafeedUrl, SpreadsheetFeed.class);
List<SpreadsheetEntry> spreadsheets = feed.getEntries();
if (spreadsheets.size() > 0) {
spreadsheet = spreadsheets.get(i);//Get your Spreadsheet
}
} catch (Exception e) {
e.printStackTrace();
}
Thank you so so much Scorpion! It works!! I've been trying this for too long.
Ok here is my solution:
I started a new project and included these jars:
gdata-client-1.0
gdata-client-meta-1.0
gdata-core-1.0
gdata-spreadsheet-3.0
gdata-spreadsheet-meta-3.0
guava-13.0.1
and my code:
SpreadsheetService spreadsheet= new SpreadsheetService("v1");
spreadsheet.setProtocolVersion(SpreadsheetService.Versions.V3);
try {
spreadsheet.setUserCredentials("username", "password");
URL metafeedUrl = new URL("https://spreadsheets.google.com/feeds/spreadsheets/private/full");
SpreadsheetFeed feed = spreadsheet.getFeed(metafeedUrl, SpreadsheetFeed.class);
List<SpreadsheetEntry> spreadsheets = feed.getEntries();
for (SpreadsheetEntry service : spreadsheets) {
System.out.println(service.getTitle().getPlainText());
}
} catch (AuthenticationException e) {
e.printStackTrace();
}
of course this is executed in a different thread not in the main thread. There is no java documentation for OAuth 2.0 but I will try and if I can't do it I'll ask here.
Again, thank you very much and I hope to help you when I work on this time enough. :)
(Feb 2017) The question (and most answers) are now out-of-date as:
GData APIs are the previous generation of Google APIs. While
not all GData APIs have been deprecated, all modern Google
APIs do not use the Google Data protocol
Google released a new Google Sheets API (v4; not GData) in
2016, and
Android Studio is now the preferred IDE over Eclipse. In order
to use Google APIs, you need to get the Google APIs Client Library
for Android (or for more general Java, the Google APIs Client
Library for Java). Now you're set.
To start, the latest Sheets API is much more powerful than all older versions. The latest API provides features not available in older releases, namely giving developers programmatic access to a Sheet as if you were using the user interface (create frozen rows, perform cell formatting, resize rows/columns, add pivot tables, create charts, etc.).
That said, yeah, it's tough when there aren't enough good (working) examples floating around, right? In the official docs, we try to put "quickstart" examples in as many languages as possible to help get you going. In that spirit, here are the Android quickstart code sample as well as the more general Java Quickstart code sample. For convenience, here's the Sheets API JavaDocs reference.
Another answer suggested using OAuth2 for data authorization, which you can do with this auth snippet from the quickstart above, plus the right scope:
// Sheets RO scope
private static final String[] SCOPES = {SheetsScopes.SPREADSHEETS_READONLY};
:
// Initialize credentials and service object
mCredential = GoogleAccountCredential.usingOAuth2(
getApplicationContext(), Arrays.asList(SCOPES))
.setBackOff(new ExponentialBackOff());
If you're not "allergic" to Python, I've made several videos with more "real-world" examples using the Sheets API (non-mobile though):
Migrating SQL data to a Sheet (code deep dive post)
Formatting text using the Sheets API (code deep dive post)
Generating slides from spreadsheet data (code deep dive post)
Finally, note that the Sheets API performs document-oriented functionality as described above. For file-level access, i.e. import, export etc. you'd use the Google Drive API instead; specifically for mobile, use the Google Drive Android API. Hope this helps!
It's a complex process, but it can be done! I wrote a blog post on getting the basics up and running. And I've also published an open-source project that is actually useful, but still quite minimal. It uses OAuth, and therefore can pull the permission directly from Android's permission model (no hardcoded email/password!).
You need something to start the "Choose account intent":
View.OnTouchListener mDelayHideTouchListener = new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
Intent intent = AccountPicker.newChooseAccountIntent(null, null, new String[]{"com.google"},
false, null, null, null, null);
startActivityForResult(intent, 1);
if (AUTO_HIDE) {
delayedHide(AUTO_HIDE_DELAY_MILLIS);
}
return false;
}
};
And then when that intent returns, you can try to use the token that was returned (although note, if it's the first time the user may have to explicitly authorize your program; that's the UserRecoverableAuthException):
protected void onActivityResult(final int requestCode, final int resultCode,
final Intent data) {
if (requestCode == 1 && resultCode == RESULT_OK) {
final String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
System.err.println(accountName);
(new AsyncTask<String, String,String>(){
#Override
protected String doInBackground(String... arg0) {
try {
// Turn account name into a token, which must
// be done in a background task, as it contacts
// the network.
String token =
GoogleAuthUtil.getToken(
FullscreenActivity.this,
accountName,
"oauth2:https://spreadsheets.google.com/feeds https://docs.google.com/feeds");
System.err.println("Token: " + token);
// Now that we have the token, can we actually list
// the spreadsheets or anything...
SpreadsheetService s =
new SpreadsheetService("Megabudget");
s.setAuthSubToken(token);
// Define the URL to request. This should never change.
// (Magic URL good for all users.)
URL SPREADSHEET_FEED_URL = new URL(
"https://spreadsheets.google.com/feeds/spreadsheets/private/full");
// Make a request to the API and get all spreadsheets.
SpreadsheetFeed feed;
try {
feed = s.getFeed(SPREADSHEET_FEED_URL, SpreadsheetFeed.class);
List<SpreadsheetEntry> spreadsheets = feed.getEntries();
// Iterate through all of the spreadsheets returned
for (SpreadsheetEntry spreadsheet : spreadsheets) {
// Print the title of this spreadsheet to the screen
System.err.println(spreadsheet.getTitle().getPlainText());
}
} catch (ServiceException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (UserRecoverableAuthException e) {
// This is NECESSARY so the user can say, "yeah I want
// this app to have permission to read my spreadsheet."
Intent recoveryIntent = e.getIntent();
startActivityForResult(recoveryIntent, 2);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (GoogleAuthException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}}).execute();
} else if (requestCode == 2 && resultCode == RESULT_OK) {
// After the user YAYs or NAYs our permission request, we are
// taken here, so if we wanted to grab the token now we could.
}
}
I need to obtain OAuth2 authentication token to pass it to the server so it can fetch list of Google Reader feeds for the user. Server is .NET - I have no access to it or to it's code but most likely it is using unofficial Reader API
I was able to use Android Account manager to obtain valid token for this purpose with the following code (notice that authTokenType="reader")
Account account = accounts[0];
manager.getAuthToken(account, "reader", null, this, new AccountManagerCallback<Bundle>() {
public void run(AccountManagerFuture<Bundle> future) {
try {
// If the user has authorized your application to use the tasks API
// a token is available.
String token = future.getResult().getString(AccountManager.KEY_AUTHTOKEN);
// Now you can send the token to API...
cacheManager.putString(GOOGLE_AUTH, token);
GoogleReaderManager.startAddFeedActivity(AddGoogleReaderSourcesActivity.this);
finish();
} catch (OperationCanceledException e) {
Log.e(TAG, "User cancelled", e);
finish();
} catch (Exception e) {
Log.e(TAG, "Failed to obtain Google reader API_KEY", e);
}
}
}, null);
The code above works fine when I send token to the server side .Net app: the app is able to retrieve the list of Reader feeds.
The problem is that this only works for "Google inside" devices. On Nook I have no such luck since there's no way that I was able to find to add Google account to the account manager. So I'm trying to it using OAuth 2 protocol as described here
It works fine as far as obtaining the token: User approves the app from the mobile page which returns the code token which then mobile app exchanges for the Auth token. However this token will not work with the server process. I have a feeling that perhaps I'm using the wrong scope in this URL:
https://accounts.google.com/o/oauth2/auth?response_type=code&scope=https://www.google.com/reader/api/0/subscription/list&redirect_uri=http://localhost&approval_prompt=force&state=/ok&client_id={apps.client.id}
Scopes that I did try in various combinations:
https://www.google.com/reader/api
https://www.google.com/reader/api/0
https://www.google.com/reader/api/0/subscription/list
https://www.google.com/reader/api+https://www.google.com/reader/atom
Here's example of JSON that is returned from get token POST
{"expires_in":3600,
"token_type":"Bearer",
"access_token":"ya29.AHES6ZSEvuUb6Bvd2DNoMnnN_UnfxirZmf_RQjn7LptFLfI",
"refresh_token":"1\/bUwa5MyOtP6VyWqaIEKgfPh08LNdawJ5Qxz6-qZrHg0"}
Am I messing up scope or token type? Not sure how to change a token type. Any other ideas?
P.S. Google account login page asks: Manage your data in Google Reader, that's why I suspect that the scope is wrong
I got it working for https://www.google.com/reader/api/0/subscription/list. So thought of sharing with you.
I have valid access_token:
This is what i tried to resolve it (partially) :
Google provides OAuth 2.o playgound; where they actually simulate all aspects of OAuth 2.0 as well as final API call to fetch data.
I found this very helpful as it clearly shows what is being sent to request.
Here is the URL : https://developers.google.com/oauthplayground/
Using this, i tweaked my api call below and it works :)
public static String getReaderContent(String accessToken){
String url = "https://www.google.com/reader/api/0/subscription/list" ;
HttpClient client = new HttpClient();
GetMethod method = new GetMethod(url);
String response="";
method.setRequestHeader("Authorization", "OAuth "+accessToken);
try {
int statusCode = client.executeMethod(method);
String response= method.getResponseBodyAsString();
System.out.println("response " + responseStr);
} catch (HttpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return response;
}
So this works properly fine for getting subscription list; but have not been able to make it work for reader api which you have mentioned in your question.
Let me know if you have got way around google reader API.