Somehow I managed to get AuthToken from Google in android but now I can't find that how could I use this token to connect with the Adsense management Service to get my Adsense account information.???
Please provide some example. I searched everywhere but cant find any example related to this.
When you construct your AdsenseApiClient in java, it takes three arguments - a transport, a jsonFactory, and a transportInitializer.
The initializer has the magic you're looking for; specifically, there's a GoogleAccessProtectedResource which is a type of transport initializer that takes an accessToken as an argument.
GoogleAccessProtectedResource transportInitializer = new GoogleAccessProtectedResource(authToken);
return ew AdsenseApiClient(transport, jsonFactory, transportInitializer);
My code, which is slightly more elaborate, looks like the following:
private ApiClient createClientForAccessToken(
final JsonHttpParser parser, HttpTransport transport, final String accessToken) {
final AccessProtectedResource accessProtectedResource =
new GoogleAccessProtectedResource(accessToken);
HttpRequestInitializer transportInitializer = new HttpRequestInitializer() {
#Override
public void initialize(HttpRequest request) throws IOException {
request.addParser(parser);
request.setConnectTimeout(CONNECTION_TIMEOUT_MILLIS);
request.setReadTimeout(SOCKET_TIMEOUT_MILLIS);
request.setEnableGZipContent(true);
request.setNumberOfRetries(0);
accessProtectedResource.initialize(request);
}
};
return new AdsenseApiClient(transport, parser.getJsonFactory(), transportInitializer);
}
The Google Api Java Client page has a number of samples including
Task sample for Andriod specifically TasksSample.java which gives examples of how to authenticate using the Google Api and OAuth2. For authentication this will be identical to how you should use the AdSense Management Api.
Related
I was creating the sample to get all the google calendar events and show the events with details on list. But it always throws the exception while fetching the data.
I tried to get events by follow the below link
https://www.c-sharpcorner.com/article/get-and-create-google-calendar-events-from-net/
and i also refer the google link also
https://developers.google.com/api-client-library/dotnet/get_started#simple
The issue was raised on make a request and i tried with both API key and client service.
I created the calendar credential by
GoogleCredential credential;
using(var stream = new FileStream(keyfilepath, FileMode.Open, FileAccess.Read)) {
credential = GoogleCredential.FromStream(stream)
.CreateScoped(Scopes).CreateWithUser("demo123#gmail.com");
}
var service = new CalendarService(new BaseClientService.Initializer() {
HttpClientInitializer = credential,
ApplicationName = "Calendar Sample",
});
EventsResource.ListRequest request = service.Events.List("primary");
Events events = request.Execute(); /// Makes crash
Android Crash : System.Net.WebException: 'Unable to resolve host "oauth2.googleapis.com": No address associated with hostname'
Windows : Google.Apis.Auth.OAuth2.Responses.TokenResponseException: 'Error:"unauthorized_client", Description:"Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested.", Uri:""'
Suggest me to resolve the problem.
I followed the "Android Quickstart" below.
https://developers.google.com/sheets/api/quickstart/android
Works great.
But the sample hard-codes a spreadsheetId to an existing spreadsheet.
String spreadsheetId = "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms";
I need to be able to find an existing spreadsheet, by name, and store the id (for later use).
I'd like to do something like this:
private com.google.api.services.sheets.v4.Sheets sheetsService = null;
HttpTransport transport = AndroidHttp.newCompatibleTransport();
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
sheetsService = new com.google.api.services.sheets.v4.Sheets.Builder(
transport, jsonFactory, credential)
.setApplicationName("My Application Name")
.build();
String spreadsheetId = null;
List<Spreadsheet> allSpreadsheets = sheetsService.spreadsheets().getAListOfAllSpreadsheets;
for (Spreadsheet spreadsheet : allSpreadsheets) {
if (spreadsheet.getName().equals("My Sheet")){
// found!
spreadsheetId = spreadsheet.getId();
}
}
Much thanks in advance!
It looks like this cannot be done with Sheets API v4.
However...it does look like it can be done with the compatible Google Drive API v3.
Note: the best part about this solution was that I could use the same method of authentication and credential gathering for both APIs. E.g., once I had the code for getting the credentials, I could use it for both API's interchangeably and consecutively.
Here's what I did:
Added this to my build.gradle (shown below my Sheets API declaration)
compile('com.google.apis:google-api-services-sheets:v4-rev468-1.22.0') {
exclude group: 'org.apache.httpcomponents'
}
compile('com.google.apis:google-api-services-drive:v3-rev69-1.22.0') {
exclude group: 'org.apache.httpcomponents'
}
I was already using the EasyPermissions method for getting account and credentials. Great example here.
Then...
import com.google.api.services.drive.Drive;
import com.google.api.services.sheets.v4.Sheets;
...
private static final String[] SCOPES = { SheetsScopes.SPREADSHEETS, DriveScopes.DRIVE_METADATA_READONLY };
...
credentials = GoogleAccountCredential.usingOAuth2(getApplicationContext(), Arrays.asList(SCOPES));
...
protected Drive driveService = new Drive.Builder(transport, jsonFactory, credential)
.setApplicationName("My Application Name")
.build();
protected Sheets sheetsService = new Sheets.Builder(transport, jsonFactory, credential)
.setApplicationName("My Application Name")
.build();
... async:
Drive.Files.List request = driveService.files().list()
.setPageSize(10)
// Available Query parameters here:
//https://developers.google.com/drive/v3/web/search-parameters
.setQ("mimeType = 'application/vnd.google-apps.spreadsheet' and name contains 'smith' and trashed = false")
.setFields("nextPageToken, files(id, name)");
FileList result = request.execute();
List<File> files = result.getFiles();
String spreadsheetId = null;
if (files != null) {
for (File file : files) {
// More code here to discriminate best result, if you want
spreadsheetId = file.getId();
}
}
Then you can directly use the id for the Sheets API:
ValueRange response = sheetsService.spreadsheets().values().get(spreadsheetId, "A1:B2").execute();
List<List<Object>> values = response.getValues();
It looks to me like you're confusing Spreadsheet and Sheet objects:
a Spreadsheet is a file with an Id, accessible by a URL such as https://docs.google.com/spreadsheets/d/yourSpreadsheetId; it is a document stored in a Google Drive folder (like an Excel workbook).
a Sheet is a tab in a Spreadsheet, with cells, like a page in your workbook. It has no Id and no direct URL. Well actually the API v4 reference indicate that Sheets also have Ids, but confusingly enough these are just reference numbers that you cannot even access in Google Apps Script, and wouldn't help you in your problem.
So you cannot access a range directly in a Spreadsheet, nor can you find a Sheet by Id.
Similarly enough to your answer, here is what I would suggest:
_ Browse through your Drive files (filter by mimeType == "application/vnd.google-apps.spreadsheet")
__For each Spreadsheet file, browse its Sheets (spreadsheet.sheets[])
___For each Sheet in the current Spreadsheet, check whether it's the one by looking at its name (sheet.title)
Once you found the right sheet, you can get its containing Spreadsheet's Id (spreadsheet.spreadsheetId).
One more thing: at the bottom of your answer, you wrote
ValueRange response = sheetsService.spreadsheets().values().get(spreadsheetId, "A1:B2").execute();
You wouldn't be able to access a cell range from a spreadsheet without first specifying the Sheet containing the range: so instead of "A1:B2", you would need "mySheetTitle!A1:B2".
I hope this is clearing up the confusion :)
I want to create a spreadsheet using the data stored in the local db. I have 5 columns and data in them. I want to create a spreadsheet having the same columns and data. I have tried using sheets api but I do not understand how to create one taking data from db
This is my code for fetching data from spreadsheet
private List<String> getDataFromApi() throws IOException {
String sheetId = "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms";
String range = "Class Data!A2:E";
List<String> results = new ArrayList<String>();
ValueRange response = this.mService.spreadsheets().values()
.get(sheetId, range)
.execute();
List<List<Object>> values = response.getValues();
if (values != null) {
results.add("Name, Major");
for (List row : values) {
results.add(row.get(0) + ", " + row.get(4));
}
}
return results;
}
This is my sheet
https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit
I did some research and found out that we can edit a spreadsheet using drive api but I am not able to find out how. I have implemented drive api and can create and edit files though
Please help
You need to use Google Sheets API, the Google Sheets API v3 (formerly called the Google Spreadsheets API) lets you develop client applications that read and modify worksheets and data in Google Sheets. To fulfill the equivalent functionality of original Sheets+Docs combination, you should use Drive API to perform file manipulations such as search/move/creation/deletion.
In addition to the scopes for Drive API, add the following scope to your grant:
https://spreadsheets.google.com/feeds
If you're using GData client library and Google OAuth client library, it will be quite easy to setup both services after OAuth 2.0 authorization.
// Acquire clientId, clientSecret and refreshToken
...
// Create shared credential
GoogleCredential credential = new GoogleCredential.Builder()
.setClientSecrets(clientId, clientSecret)
.setJsonFactory(jsonFactory)
.setTransport(transport)
.build().setRefreshToken(refreshToken);
// Setup both servives
Drive driveService = new Drive.Builder(transport, jsonFactory, credential).build();
SpreadsheetService sheetService = new SpreadsheetService(...);
sheetService.setOAuth2Credentials(credential); // only provided in newer releases
sheetService.useSsl();
Resource IDs in both APIs are identical, so you can search id of some file with Drive API methods and access worksheets in the file with Sheets API methods.
File file = driveService.files().get().setFields(...).execute();
String feedUrl = "https://spreadsheets.google.com/feeds/worksheets/"
+ file.getId + "/private/full";
WorksheetFeed feed = sheetService.getFeed(feedUrl, WorksheetFeed.class);
I just started Google Cloud Endpoints.
When running android app, I have the following warning in logcat:
Tag: AbstractGoogleClient
Text: Application name is not set. Call Builder#setApplicationName.
Where to set Application name? Is it in android or app engine/cloud endpoints?
The Class com.google.api.client.googleapis.services.AbstractGoogleClient has a function
public Builder setApplicationName(String applicationName) {
this.applicationName = applicationName;
return this;
}
When using Gradle to generate your client libraries using appengineEndpointsInstallClientLibs
You should be able to create an endpointbuilder for your endpoints:
private YourEndpoint.Builder endpointBuilder = new YourEndpoint.Builder(
AndroidHttp.newCompatibleTransport(), new JacksonFactory(),
new HttpRequestInitializer() {
public void initialize(HttpRequest httpRequest) {
}
}
);
then... to get rid of the warning:
endpointBuilder.setApplicationName("Some crazy App Name");
I'm trying to access a Purchase Status API from my ASP.NET web server using Google APIs .NET Client Library which is a recommended way for using Purchase API v1.1. However, the Authorization page of this API suggests direct web requests to Google's OAuth2 pages instead of using the corresponding client libraries.
OK, I tried both methods with all variations I could imagine and both of them lead to "The remote server returned an error: (400) Bad Request.".
Now what I've done to get to my point. First I've made all steps 1-8 under the Creating an APIs Console project of the Authorization page. Next I generated a refresh token as described there. During refresh token generation I chose the same Google account as I used to publish my Android application (which is in published beta state now).
Next I've created a console C# application for test purposes in Visual Studio (may be console app is the problem?)
and tried to call the Purchase API using this code (found in some Google API examples):
private static void Main(string[] args)
{
var provider =
new WebServerClient(GoogleAuthenticationServer.Description)
{
ClientIdentifier = "91....751.apps.googleusercontent.com",
ClientSecret = "wRT0Kf_b....ow"
};
var auth = new OAuth2Authenticator<WebServerClient>(
provider, GetAuthorization);
var service = new AndroidPublisherService(
new BaseClientService.Initializer()
{
Authenticator = auth,
ApplicationName = APP_NAME
});
var request = service.Inapppurchases.Get(
PACKAGE_NAME, PRODUCT_ID, PURCHASE_TOKEN);
var purchaseState = request.Execute();
Console.WriteLine(JsonConvert.SerializeObject(purchaseState));
}
private static IAuthorizationState GetAuthorization(WebServerClient client)
{
IAuthorizationState state =
new AuthorizationState(
new[] {"https://www.googleapis.com/auth/androidpublisher"})
{
RefreshToken = "4/lWX1B3nU0_Ya....gAI"
};
// below is my redirect URI which I used to get a refresh token
// I tried with and without this statement
state.Callback = new Uri("https://XXXXX.com/oauth2callback/");
client.RefreshToken(state); // <-- Here we have (400) Bad request
return state;
}
Then I tried this code to get the access token (I found it here: Google Calendar API - Bad Request (400) Trying To Swap Code For Access Token):
public static string GetAccessToken()
{
var request = WebRequest.Create(
"https://accounts.google.com/o/oauth2/token");
request.Method = "POST";
var postData =
string.Format(
#"code={0}&client_id={1}&client_secret={2}&redirect_uri={3}&grant_type=authorization_code",
// refresh token I got from browser
// also tried with Url encoded value
// 4%2FlWX1B3nU0_Yax....gAI
"4/lWX1B3nU0_Yax....gAI",
// ClientID from Google APIs Console
"919....1.apps.googleusercontent.com",
// Client secret from Google APIs Console
"wRT0Kf_bE....w",
// redirect URI from Google APIs Console
// also tried Url encoded value
// https%3A%2F%2FXXXXX.com%2Foauth2callback%2F
"https://XXXXX.com/oauth2callback/");
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteArray.Length;
using (var dataStream = request.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
}
try
{
// request.GetResponse() --> (400) Bad request again!
using (var response = request.GetResponse())
{
using (var dataStream = response.GetResponseStream())
{
using (var reader = new StreamReader(dataStream))
{
var responseFromServer = reader.ReadToEnd();
var jsonResponse = JsonConvert.DeserializeObject<OAuth2Response>(responseFromServer);
return jsonResponse.access_token;
}
}
}
}
catch (Exception ex) { var x = ex; }
return null;
}
So, to sum up all my long story:
Is it possible at all to pass OAuth2 authorization using either of methods above from a C# Console Application (without user interaction)?
I've double checked the redirect URI (since I saw a lot of discussed troubles because of it here on stackoverflow) and other parameters like ClientID and ClientSecret. What else I could do wrong in the code above?
Do I need to URL encode a slash in the refresh token (I saw that the first method using client library does it)?
What is the recommended way of achieving my final goal (Purchase API access from ASP.NET web server)?
I'll try to answer your last question. If you access your own data account, you dont need to use client id in oAuth2. Let's use service account to access Google Play API.
Create a service account in Google Developer Console > Your project > APIs and auth > Credentials > Create a new key. You will download a p12 key.
Create a C# project. You can choose console application.
Install google play api library from Google.Apis.androidpublisher. Nuget. You can find other library for dotnet in Google APIs Client Library for .NET
Link google api project with your google play account in API access
Authenticate and try to query information. I'll try with listing all inapp item. You can just change to get purchase's status
String serviceAccountEmail = "your-mail-in-developer-console#developer.gserviceaccount.com";
var certificate = new X509Certificate2(#"physical-path-to-your-key\key.p12", "notasecret", X509KeyStorageFlags.Exportable);
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = new[] { "https://www.googleapis.com/auth/androidpublisher" }
}.FromCertificate(certificate));
var service = new AndroidPublisherService(
new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "GooglePlay API Sample",
});
// try catch this function because if you input wrong params ( wrong token) google will return error.
var request = service.Inappproducts.List("your-package-name");
var purchaseState = request.Execute();
// var request = service.Purchases.Products.Get(
//"your-package-name", "your-inapp-item-id", "purchase-token"); get purchase'status
Console.WriteLine(JsonConvert.SerializeObject(purchaseState));
You should do the following in your
private static IAuthorizationState GetAuthorization(WebServerClient client) method:
private IAuthorizationState GetAuthorization(WebServerClient client)
{
IAuthorizationState state = AuthState;
if (state != null)
{
return state;
}
state = new AuthorizationState()
{
RefreshToken = "4/lWX1B3nU0_Ya....gAI",
Callback = new Uri(#"https://XXXXX.com/oauth2callback/")
};
client.RefreshToken(state);
// Store and return the credentials.
HttpContext.Current.Session["AUTH_STATE"] = _state = state;
return state;
}
Let me know if it works for you.
Be aware that we know that the whole OAuth2 flow is awkward today, and we are working to improve it.