I am new to android, I am trying to implement YouTube's search by keyword in my android app.But I am not able to get response from API (I think).I think there is some problem in search.execute().I looked some other answers too but not able to find any solution.
Here's the class (I modified it a little bit):
class Search {
private static final long NUMBER_OF_VIDEOS_RETURNED = 2;
/**
* Define a global instance of a Youtube object, which will be used
* to make YouTube Data API requests.
*/
private YouTube youtube;
/**
* Initialize a YouTube object to search for videos on YouTube. Then
* display the name and thumbnail image of each video in the result set.
*
*
*/
private void Hakuna() {
// Read the developer key from the properties file.
try {
// This object is used to make YouTube Data API requests. The last
// argument is required, but since we don't need anything
// initialized when the HttpRequest is initialized, we override
// the interface and provide a no-op function.
youtube = new YouTube.Builder(new NetHttpTransport(), new JacksonFactory(), new HttpRequestInitializer() {
public void initialize(HttpRequest request) throws IOException {
}
}).setApplicationName("youtube-cmdline-search-sample").build();
// Prompt the user to enter a query term.
String queryTerm = getInputQuery();
// Define the API request for retrieving search results.
YouTube.Search.List search = youtube.search().list("id,snippet");
// Set your developer key from the {{ Google Cloud Console }} for
// non-authenticated requests. See:
// {{ https://cloud.google.com/console }}
String apiKey = "HERE_I_PUT_MY_APIKEY";
search.setKey(apiKey);
search.setQ(queryTerm);
// Restrict the search results to only include videos. See:
// https://developers.google.com/youtube/v3/docs/search/list#type
search.setType("video");
// To increase efficiency, only retrieve the fields that the
// application uses.
search.setFields("items(id/kind,id/videoId,snippet/title,snippet/thumbnails/default/url)");
search.setMaxResults(NUMBER_OF_VIDEOS_RETURNED);
// Call the API and print results.
SearchListResponse searchResponse = search.execute();
mResult.setText("hello");
List<SearchResult> searchResultList = searchResponse.getItems();
if (searchResultList != null) {
prettyPrint(searchResultList.iterator(), queryTerm);
}
} catch (GoogleJsonResponseException e) {
System.err.println("There was a service error: " + e.getDetails().getCode() + " : "
+ e.getDetails().getMessage());
} catch (IOException e) {
System.err.println("There was an IO error: " + e.getCause() + " : " + e.getMessage());
} catch (Throwable t) {
t.printStackTrace();
}
}
/*
* Prompt the user to enter a query term and return the user-specified term.
*/
private String getInputQuery() throws IOException {
String inputQuery = "";
inputQuery = mSearchtext.getText().toString();
if (inputQuery.length() < 1) {
// Use the string "YouTube Developers Live" as a default.
inputQuery = "YouTube Developers Live";
}
return inputQuery;
}
/*
* Prints out all results in the Iterator. For each result, print the
* title, video ID, and thumbnail.
*
* #param iteratorSearchResults Iterator of SearchResults to print
*
* #param query Search query (String)
*/
private void prettyPrint(Iterator<SearchResult> iteratorSearchResults, String query) {
mResult.setText("hello");
System.out.println("\n=============================================================");
System.out.println(
" First " + NUMBER_OF_VIDEOS_RETURNED + " videos for search on \"" + query + "\".");
System.out.println("=============================================================\n");
if (!iteratorSearchResults.hasNext()) {
System.out.println(" There aren't any results for your query.");
}
while (iteratorSearchResults.hasNext()) {
SearchResult singleVideo = iteratorSearchResults.next();
ResourceId rId = singleVideo.getId();
// Confirm that the result represents a video. Otherwise, the
// item will not contain a video ID.
if (rId.getKind().equals("youtube#video")) {
Thumbnail thumbnail = singleVideo.getSnippet().getThumbnails().getDefault();
System.out.println(" Video Id" + rId.getVideoId());
System.out.println(" Title: " + singleVideo.getSnippet().getTitle());
System.out.println(" Thumbnail: " + thumbnail.getUrl());
System.out.println("\n-------------------------------------------------------------\n");
}
}
}
}
Here are the dependencies that I added:
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
implementation 'com.google.apis:google-api-services-youtube:v3-rev181-1.22.0'
There may be some redundant lines of code, please ignore them.
Related
My Referee watch creates a Google Fit Session using the following code:
private void insertFitSession(final Game currentGame, final Period period,
final long periodStartTime, final long periodEndTime) {
//add the detailed Sensor data (using History API) if available
boolean activityWasInserted = false;
if (!RefWatchUtil.isRefWatchFree()) {
//If there are speeds then we will insert an activity
//4.5.09: Unfortunately mFitnessDataSets[] can have leftover data from a period where you did track fitness
//So we had to replace with period-by-period dataSets
activityWasInserted = (period.getFitnessDataSet(SPEED_LISTENER_IDX) != null)
&& !period.getFitnessDataSet(SPEED_LISTENER_IDX).isEmpty();
}
//create a Session in Google Fit for the period that just completed
//(this happens even for Free)
try {
String sessionBaseName = currentGame.getTitle();
if (sessionBaseName.isEmpty()) sessionBaseName = currentGame.getLocation();
if (sessionBaseName.isEmpty()) sessionBaseName = RefWatchUtil.timeMillisToDefaultShortDateTime(currentGame.getStartTimeMillis());
final String sessionName = sessionBaseName + ": " + String.format(getResources().getString(R.string.fitness_period_label), period.getPeriodNum());
final Session.Builder fitnessSessionBuilder = new Session.Builder();
fitnessSessionBuilder
.setName(sessionName)
.setIdentifier(sessionName)
.setDescription(mCurrentGame.getDescription())
.setStartTime(periodStartTime, TimeUnit.MILLISECONDS)
.setEndTime(periodEndTime, TimeUnit.MILLISECONDS);
//If we're Free, then we don't have real fitness session data and just guess at Jogging
// (also if we have no Activity data in Pro)
if (RefWatchUtil.isRefWatchFree() || !activityWasInserted) {
fitnessSessionBuilder.setActivity(FitnessActivities.RUNNING_JOGGING);
}
final Session fitSession = fitnessSessionBuilder.build();
SessionInsertRequest insertRequest = new SessionInsertRequest.Builder()
.setSession(fitSession)
.build();
Fitness.SessionsApi.insertSession(mFitnessApiClient, insertRequest)
.setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(#NonNull Status status) {
if (status.isSuccess()) {
Log.d(TAG, "Successfully inserted Session " + sessionName);
} else {
Log.d(TAG, "There was a problem inserting the session " + sessionName
+ ": " + status.getStatusCode() + " " + status.getStatusMessage());
}
}
});
} catch (RuntimeException e){
Log.e(TAG, "There was a runtime exception inserting the session: " + e.getLocalizedMessage());
}
}
Note the sessionName defaults to either Title, Location, or Time appended with the current Period. This has been working great.
Recently (last month or so?) the Fit session is correctly inserted (I can track it in the log) but the Name doesn't stick. Instead I get "25 min running" for some, but not all, of them.
Has anybody else experienced this type of override by Fit?
I am trying to use a Developer Authenticated Provider to login to my android app basing it loosely off of this demo: https://github.com/awslabs/aws-sdk-android-samples/tree/master/CognitoSyncDemo. I successfully logged in through our own backend got the idToken and subsequently got session credentials to access our AWS database. I then used those credentials to make a POST to the db.
But this only worked once, now I cannot get through again, without having changed any code. I am also using a generated SDK through http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-generate-sdk.html. I'm not sure if this is causing any errors.
Here is my DeveloperAuthenticationProvider:
public class AuthenticationProvider extends
AWSAbstractCognitoDeveloperIdentityProvider {
private static final String TAG = AuthenticationProvider.class.getSimpleName();
private static SocializeClient mSocializeClient;
private static final String developerProvider = Constants.AWS_PROVIDER_NAME;
private static final String cognitoSampleDeveloperAuthenticationAppEndpoint = UrlEndpoints.URL_DOMAIN;
public AuthenticationProvider(Context context, String accountId, String identityPoolId, Regions region) {
super(accountId, identityPoolId, region);
/*
* Initialize the client using which you will communicate with your
* backend for user authentication.
*/
AWSCredentialsProvider awsCredentialsProvider = new CognitoCachingCredentialsProvider(
context,
this,
region
);
ApiClientFactory factory = new ApiClientFactory()
.endpoint(cognitoSampleDeveloperAuthenticationAppEndpoint)
.credentialsProvider(awsCredentialsProvider);
mSocializeClient = factory.build(SocializeClient.class);
}
/*Only refreshes the login info, when it has expired*/
/*
* (non-Javadoc)
* #see com.amazonaws.auth.AWSCognitoIdentityProvider#refresh() In refresh
* method, you will have two flows:
*/
/*
* 1. When the app user uses developer authentication. In this case, make
* the call to your developer backend, from where call the
* GetOpenIdTokenForDeveloperIdentity API of Amazon Cognito service. Be sure to call update(), so as to
* set the identity id and the token received.
*/
/*
* 2.When the app user is not using the developer authentication, just call
* the refresh method of the AWSAbstractCognitoDeveloperIdentityProvider
* class which actually calls GetId and GetOpenIDToken API of Amazon
* Cognito.
*/
#Override
public String refresh() {
Log.i(TAG, "refresh");
// If there is a key with developer provider name in the logins map, it
// means the app user has used developer credentials
if (!loginsMap.isEmpty()
&& loginsMap.containsKey(developerProvider)) {
Log.i(TAG, "contains provider");
} else {
Log.i(TAG, "does not contain developer provider");
Map<String, String> logins = new HashMap<>();
logins.put(developerProvider, UserSingleton.imei);
setLogins(logins);
}
// TODO:: Temp code to login. Once available, need to add code to GetToken from SocializeClient
Login login = new Login();
login.setImei(UserSingleton.imei);
login.setPassword(UserSingleton.password);
LoginReponse loginReponse = mSocializeClient.socializeAuthLoginPost(login);
Log.i(TAG, "login response: " + loginReponse.getIdentityId() + " - token: " + loginReponse.getToken());
update(loginReponse.getIdentityId(), loginReponse.getToken());
Log.i(TAG, "updated");
return loginReponse.getToken();
}
/*
* (non-Javadoc)
* #see com.amazonaws.auth.AWSBasicCognitoIdentityProvider#getIdentityId()
*/
/*
* This method again has two flows as mentioned above depending on whether
* the app user is using developer authentication or not. When using
* developer authentication system, the identityId should be retrieved from
* the developer backend. In the other case the identityId will be retrieved
* using the getIdentityId() method which in turn calls Cognito GetId and
* GetOpenIdToken APIs.
*/
#Override
public String getIdentityId() {
Log.i(TAG, "getIdentityId");
identityId = CognitoSyncClientManager.credentialsProvider.getCachedIdentityId();
if (identityId == null) {
Log.i(TAG, "identityId is null");
if (!loginsMap.isEmpty()
&& loginsMap.containsKey(developerProvider)) {
Log.i(TAG, "grabbing identityId using logins map");
// TODO:: Temp code to login. Once available, need to add code to GetToken from SocializeClient
Login login = new Login();
login.setImei(loginsMap.get(developerProvider));
login.setPassword(UserSingleton.password);
LoginReponse loginReponse = mSocializeClient.socializeAuthLoginPost(login);
Log.i(TAG, "login response: " + loginReponse.getIdentityId() + " - token: " + loginReponse.getToken());
update(loginReponse.getIdentityId(), loginReponse.getToken());
return loginReponse.getIdentityId();
} else {
return super.getIdentityId();
}
} else {
return identityId;
}
}
/*
* (non-Javadoc)
* #see
* com.amazonaws.auth.AWSAbstractCognitoIdentityProvider#getProviderName()
* Return the developer provider name which you chose while setting up the
* identity pool in the Amazon Cognito Console
*/
#Override
public String getProviderName() {
return developerProvider;
}
/**
* This function validates the user credentials against the sample Cognito
* developer authentication application. After that it stores the key and
* token received from sample Cognito developer authentication application
* for all further communication with the application.
*
* #param imei
* #param password
*/
public void login(String imei, String password, Context context) {
Log.i(TAG, "login");
Login login = new Login();
login.setImei(imei);
login.setPassword(password);
new AuthenticationTask(context).execute(login);
}
public void publishProfile(Context context, Profile profile){
Log.i(TAG, "publishProfile");
ProfileKey profileKey = new ProfileKey();
profileKey.setUserID(identityId);
profile.setKey(profileKey);
new UploadProfileTask(context).execute(profile);
}
protected static SocializeClient getSocializeClientInstance() {
if (mSocializeClient == null) {
throw new IllegalStateException(
"Dev Auth Client not initialized yet");
}
return mSocializeClient;
}
}
Here is my AuthenticationTask as well where I attempt to login, then grab credentials to access the AWS database:
public class AuthenticationTask extends
AsyncTask<Login, Void, Void> {
private static final String TAG = AuthenticationTask.class.getSimpleName();
// The user name or the developer user identifier you will pass to the
// Amazon Cognito in the GetOpenIdTokenForDeveloperIdentity API
private String mImei;
private String mPassword;
private GetCredentialsForIdentityResult credentialsForIdentityResult;
private boolean isSuccessful;
private final Context context;
public AuthenticationTask(Context context) {
this.context = context;
}
#Override
protected Void doInBackground(Login... params) {
Log.i(TAG, "doInBackground get refreshing threshold: " + CognitoCachingCredentialsProvider.DEFAULT_THRESHOLD_SECONDS);
mImei = params[0].getImei();
mPassword = params[0].getPassword();
Login login = params[0];
// if(mPassword == null){
// Log.i(TAG, "register");
// mPassword = Utils.generateRandomString();
// final Register register = new Register();
// register.setImei(mImei);
// register.setPassword(mPassword);
// login.setPassword(mPassword);
// RegisterResponse registerResponse = AuthenticationProvider.getSocializeClientInstance().socializeAuthRegisterPost(register);
// Log.i(TAG, "registerResponse: " + registerResponse.getCreated());
UserSingleton.password = mPassword;
UserSingleton.getInstance().saveRegistrationInfo();
Log.i(TAG, "imei: " + mImei);
// }
Log.i(TAG, "calling login post");
LoginReponse loginReponse = AuthenticationProvider.getSocializeClientInstance().socializeAuthLoginPost(login);
Log.i(TAG, "login response: " + loginReponse.getIdentityId() + " - token: " + loginReponse.getToken());
// Set up the loginsMap to send with the credentials request
Map<String, String> loginsMap = new HashMap<>();
loginsMap.put(CognitoSyncClientManager.developerIdentityProvider.getProviderName(), loginReponse.getToken());
// get AWS credentials to access DB
GetCredentialsForIdentityRequest credentialsForIdentityRequest = new GetCredentialsForIdentityRequest();
credentialsForIdentityRequest.setIdentityId(loginReponse.getIdentityId());
credentialsForIdentityRequest.setLogins(loginsMap);
Log.i(TAG, "credentials request: " + credentialsForIdentityRequest.getIdentityId() + credentialsForIdentityRequest.getLogins());
AmazonCognitoIdentityClient cognitoIdentityClient = new AmazonCognitoIdentityClient(CognitoSyncClientManager.credentialsProvider);
credentialsForIdentityResult = cognitoIdentityClient
.getCredentialsForIdentity(credentialsForIdentityRequest);
isSuccessful = credentialsForIdentityResult != null;
return null;
}
#Override
protected void onPostExecute(Void result) {
if (isSuccessful) {
Log.i(TAG, "accessKeyId: " + credentialsForIdentityResult.getCredentials().getAccessKeyId()
+ "\nsecretKey: " + credentialsForIdentityResult.getCredentials().getSecretKey()
+ "\nsessionToken: " + credentialsForIdentityResult.getCredentials().getSessionToken());
CognitoSyncClientManager
.addLogins(
((AuthenticationProvider) CognitoSyncClientManager.credentialsProvider
.getIdentityProvider()).getProviderName(),
mImei);
} else {
Log.i(TAG, "login error: " + result);
}
}
}
In my refresh call I am just relogging in. I'm not sure if that is correct.
The biggest issue now is upon startup when I attempt to login using, mSocializeClient.socializeAuthLoginPost(login) it seems to call refresh every time, before it even logs in. Refresh then attempts to login again and it keeps calling itself endlessly.
Any help/explanations would be greatly appreciated.
The way the dev auth sample works is as follows:
The DeveloperAuthenticationTask.login() is supposed to login to the server and get a session key.
It sets up the logins map and calls DeveloperAuthenticationProvider.refresh()
Refresh exchanges the session key with the server for a valid cognito token and identity id and calls update with the token and identity id.
In your case, you don't have this session key, just username and password. So you don't need the AuthenticationTask. All you need is:
a login() in your AuthenticationProvider, that puts the username/password in a secure location, sets up the login map and calls refresh (it shouldn't actually attempt to login to your service).
In refresh() you retrieve the username/pass from the secure location, call your service and then call update with the token and identity id returned from your service.
Can you simplify your code to this flow?
According to the documentation it should be possible to register a notification channel for changes to the app folder of my app, using setSpaces("appDataFolder").
However, I only get an initial sync notification when setting up the channel, but no change notifications when I change something in the app folder.
If I use setSpaces("drive") or omit the setSpaces() altogether and change something in regular drive space, I receive change notifications alright.
I didn't find anything about watching for changes in the app folder, so I hope someone here can help me.
This is how I set up the channel, where mDrive is a fully initialized and authorized instance of com.google.api.services.drive.Drive
channelId = UUID.randomUUID().toString();
channelExpiration = System.currentTimeMillis() + CHANNEL_LIVETIME_MILLIS;
Channel channel = new Channel();
channel.setType("web_hook");
channel.setId(channelId);
channel.setAddress(DRIVE_API_CALLBACK_RECEIVER_URL);
channel.setToken("...");
channel.setExpiration(channelExpiration);
Channel result = mDrive.changes().watch(channel).setSpaces("appDataFolder").execute();
Is there a scope where you set this up? Make sure you have a broad enough scope to include 'appDataFolder'. By this I mean you should be able to get some results from this (from here):
/**
* Print metadata for the Application Data folder.
*
* #param service Drive API service instance.
*/
private static void printApplicationDataFolderMetadata(Drive service) {
try {
File file = service.files().get("appfolder").execute();
System.out.println("Id: " + file.getId());
System.out.println("Title: " + file.getTitle());
} catch (IOException e) {
System.out.println("An error occured: " + e);
}
}
I think the above might be your problem. Whereever you are setting scope make sure to include the drive.appfolder or more formally
https://www.googleapis.com/auth/drive.appfolder
Furthermore, are you checking if result is null? You really should put the Channel result =... line in a try {} catch(IOExeption e) {} and print the error if there is one like in this example (from here).
/**
* Watch for all changes to a user's Drive.
*
* #param service Drive API service instance.
* #param channelId Unique string that identifies this channel.
* #param channelType Type of delivery mechanism used for this channel.
* #param channelAddress Address where notifications are delivered.
* #return The created channel if successful, {#code null} otherwise.
*/
private static Channel watchChange(Drive service, String channelId,
String channelType, String channelAddress) {
Channel channel = new Channel();
channel.setId(channelId);
channel.setType(channelType);
channel.setAddress(channelAddress);
try {
return service.changes().watch(channel).execute();
} catch (IOException e) {
e.printStackTrace();
// ADD A LOG OR PRINT STATEMENT HERE
Log.e("DRIVEAPI", "Error: " + e.toString())
}
return null;
}
Which for you code should look like this:
channelId = UUID.randomUUID().toString();
channelExpiration = System.currentTimeMillis() + CHANNEL_LIVETIME_MILLIS;
Channel channel = new Channel();
channel.setType("web_hook");
channel.setId(channelId);
channel.setAddress(DRIVE_API_CALLBACK_RECEIVER_URL);
channel.setToken("...");
channel.setExpiration(channelExpiration);
try {
Channel result = mDrive.changes().watch(channel).setSpaces("appDataFolder").execute();
if(result != null) {
// do whatever you want with result Channel
} else {
Log.e("DRIVEAPI", "Error: result is null for some reason!");
}
} catch (IOException e) {
e.printStackTrace()
Log.e("DRIVEAPI", "Error: " + e.toString());
}
I'm trying to search youtube video based on given keyword. So that I can list all found video to display in a list with video thumbnail. I don't find a way to do so. After searching I found this https://developers.google.com/youtube/v3/docs/videos/list#examples.
Can I use save for my android application? Or how do I search in Android application?
You can use the Youtube API code samples in your app on the following conditions:
1. Your app is a free app.
2. If your app is monetized (paid, ads, and/or in app purchases) then your app has to contain more content and features than just a feature searching Youtube.
Full details here:
https://developers.google.com/youtube/creating_monetizable_applications
That being said, you can fully use code samples from Youtube API. I have done so myself to create an Android app to help people find all my favorite cat videos (shameless promotion): Cat Roulette
Anyhow, here is a specific Java code example for searching Youtube videos:
https://developers.google.com/youtube/v3/code_samples/java#search_by_keyword
/*
* Copyright (c) 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.api.services.samples.youtube.cmdline.data;
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.samples.youtube.cmdline.Auth;
import com.google.api.services.youtube.YouTube;
import com.google.api.services.youtube.model.ResourceId;
import com.google.api.services.youtube.model.SearchListResponse;
import com.google.api.services.youtube.model.SearchResult;
import com.google.api.services.youtube.model.Thumbnail;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
/**
* Print a list of videos matching a search term.
*
* #author Jeremy Walker
*/
public class Search {
/**
* Define a global variable that identifies the name of a file that
* contains the developer's API key.
*/
private static final String PROPERTIES_FILENAME = "youtube.properties";
private static final long NUMBER_OF_VIDEOS_RETURNED = 25;
/**
* Define a global instance of a Youtube object, which will be used
* to make YouTube Data API requests.
*/
private static YouTube youtube;
/**
* Initialize a YouTube object to search for videos on YouTube. Then
* display the name and thumbnail image of each video in the result set.
*
* #param args command line args.
*/
public static void main(String[] args) {
// Read the developer key from the properties file.
Properties properties = new Properties();
try {
InputStream in = Search.class.getResourceAsStream("/" + PROPERTIES_FILENAME);
properties.load(in);
} catch (IOException e) {
System.err.println("There was an error reading " + PROPERTIES_FILENAME + ": " + e.getCause()
+ " : " + e.getMessage());
System.exit(1);
}
try {
// This object is used to make YouTube Data API requests. The last
// argument is required, but since we don't need anything
// initialized when the HttpRequest is initialized, we override
// the interface and provide a no-op function.
youtube = new YouTube.Builder(Auth.HTTP_TRANSPORT, Auth.JSON_FACTORY, new HttpRequestInitializer() {
public void initialize(HttpRequest request) throws IOException {
}
}).setApplicationName("youtube-cmdline-search-sample").build();
// Prompt the user to enter a query term.
String queryTerm = getInputQuery();
// Define the API request for retrieving search results.
YouTube.Search.List search = youtube.search().list("id,snippet");
// Set your developer key from the Google Developers Console for
// non-authenticated requests. See:
// https://console.developers.google.com/
String apiKey = properties.getProperty("youtube.apikey");
search.setKey(apiKey);
search.setQ(queryTerm);
// Restrict the search results to only include videos. See:
// https://developers.google.com/youtube/v3/docs/search/list#type
search.setType("video");
// To increase efficiency, only retrieve the fields that the
// application uses.
search.setFields("items(id/kind,id/videoId,snippet/title,snippet/thumbnails/default/url)");
search.setMaxResults(NUMBER_OF_VIDEOS_RETURNED);
// Call the API and print results.
SearchListResponse searchResponse = search.execute();
List<SearchResult> searchResultList = searchResponse.getItems();
if (searchResultList != null) {
prettyPrint(searchResultList.iterator(), queryTerm);
}
} catch (GoogleJsonResponseException e) {
System.err.println("There was a service error: " + e.getDetails().getCode() + " : "
+ e.getDetails().getMessage());
} catch (IOException e) {
System.err.println("There was an IO error: " + e.getCause() + " : " + e.getMessage());
} catch (Throwable t) {
t.printStackTrace();
}
}
/*
* Prompt the user to enter a query term and return the user-specified term.
*/
private static String getInputQuery() throws IOException {
String inputQuery = "";
System.out.print("Please enter a search term: ");
BufferedReader bReader = new BufferedReader(new InputStreamReader(System.in));
inputQuery = bReader.readLine();
if (inputQuery.length() < 1) {
// Use the string "YouTube Developers Live" as a default.
inputQuery = "YouTube Developers Live";
}
return inputQuery;
}
/*
* Prints out all results in the Iterator. For each result, print the
* title, video ID, and thumbnail.
*
* #param iteratorSearchResults Iterator of SearchResults to print
*
* #param query Search query (String)
*/
private static void prettyPrint(Iterator<SearchResult> iteratorSearchResults, String query) {
System.out.println("\n=============================================================");
System.out.println(
" First " + NUMBER_OF_VIDEOS_RETURNED + " videos for search on \"" + query + "\".");
System.out.println("=============================================================\n");
if (!iteratorSearchResults.hasNext()) {
System.out.println(" There aren't any results for your query.");
}
while (iteratorSearchResults.hasNext()) {
SearchResult singleVideo = iteratorSearchResults.next();
ResourceId rId = singleVideo.getId();
// Confirm that the result represents a video. Otherwise, the
// item will not contain a video ID.
if (rId.getKind().equals("youtube#video")) {
Thumbnail thumbnail = singleVideo.getSnippet().getThumbnails().getDefault();
System.out.println(" Video Id" + rId.getVideoId());
System.out.println(" Title: " + singleVideo.getSnippet().getTitle());
System.out.println(" Thumbnail: " + thumbnail.getUrl());
System.out.println("\n-------------------------------------------------------------\n");
}
}
}
}
FYI you have to also obtain a Youtube API key as explained here:
https://developers.google.com/youtube/registering_an_application?hl=en
I'm trying to create a spreadsheet via my android app. So far I've been only successful in creating an empty text document. Google's Spreadsheet API instructs me to follow Google Documents List API in order to create a spreadsheet document in Google Drive. In Google Documents List API it says:
To create a new, empty spreadsheet, follow the instructions in
Creating a new document or file with metadata only. When doing so, use
a category term of http://schemas.google.com/docs/2007#spreadsheet.
In the link above I've found the next .NET code:
using System;
using Google.GData.Client;
using Google.GData.Documents;
namespace MyDocumentsListIntegration
{
class Program
{
static void Main(string[] args)
{
DocumentsService service = new DocumentsService("MyDocumentsListIntegration-v1");
// TODO: Authorize the service object for a specific user (see Authorizing requests)
// Instantiate a DocumentEntry object to be inserted.
DocumentEntry entry = new DocumentEntry();
// Set the document title
entry.Title.Text = "Legal Contract";
// Add the document category
entry.Categories.Add(DocumentEntry.DOCUMENT_CATEGORY);
// Make a request to the API and create the document.
DocumentEntry newEntry = service.Insert(
DocumentsListQuery.documentsBaseUri, entry);
}
}
}
I've used this code to try and create a spreadsheet, but only the third variant worked (using DocsService, without adding Category and using feedUrl URL object).
Here's part of my working code (upload() is being called when user clicks a button):
private void upload() {
SpreadSheetAsyncTask sprdSheetAsyncTsk = new SpreadSheetAsyncTask();
sprdSheetAsyncTsk.execute();
}
public class SpreadSheetAsyncTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
spreadSheetService = new SpreadsheetService("Salary_Calculator");
docService = new DocsService("Salary_Calculator");
try {
spreadSheetService.setUserCredentials(USERNAME, PASSWORD);
docService.setUserCredentials(USERNAME, PASSWORD);
URL feedUrl = new URL(
"https://docs.google.com/feeds/default/private/full/");
URL tmpFeedUrl = new URL(
"https://spreadsheets.google.com/feeds/worksheets/key/private/full");
DocumentEntry entry = new DocumentEntry();
Calendar timeRightNow = GregorianCalendar.getInstance();
entry.setTitle(new PlainTextConstruct(
"Salary Calculator Spreadsheet "
+ timeRightNow.get(Calendar.DAY_OF_MONTH) + "/"
+ (timeRightNow.get(Calendar.MONTH) + 1) + "/"
+ timeRightNow.get(Calendar.YEAR)));
// Category object = new Category("spreadsheet",
// "http://schemas.google.com/docs/2007#spreadsheet");
//
//
// entry.getCategories().add(object);
/*
* TODO TEST AREA
*/
entry = docService.insert(feedUrl, entry);
/*
* TODO TEST AREA
*/
} catch (AuthenticationException e) {
cancel(true);
loginDialog("Wrong username or password");
} catch (IOException e) {
e.printStackTrace();
return null;
} catch (ServiceException e) {
cancel(true);
loginDialog("Wrong username or password");
} catch (Exception e) {
loginDialog("Wrong username or password");
}
return null;
}
}
The non working code uses the category object object (as shown in the code comment) above and uses entry = spreadSheetService.insert(feedUrl, entry);
My question is - what did they want me to do when they wrote use a category term of http://schemas.google.com/docs/2007#spreadsheet?