I am working on an Android app that records video and allows the user to upload it directly to YouTube using the YouTube Data API v3.
I have set up my app in Google's API console. Under services, I have YouTube Data API v3 enabled. Under API access I have both a section "Client ID for installed applications" (including a Client ID and Client Secret) and a section "Simple API Access" -> "Key for Android apps (with certificates)" (which includes an API key and an "Android Apps" section, which is left blank for now, i.e. allow all Android apps, but I have tried it with setting my android key).
I have based my code from a number of places, primarily:
https://developers.google.com/youtube/v3/code_samples/java#upload_a_video
and
https://code.google.com/p/google-api-java-client/source/browse/tasks-android-sample/src/main/java/com/google/api/services/samples/tasks/android/TasksSample.java?repo=samples
The upload initialises OK, starts the AsyncTask, but then I get an IOException thrown saying:
{
"code": 403,
"errors": [
{
"domain": "usageLimits",
"message": "Access Not Configured",
"reason": "accessNotConfigured"
}
],
"message": "Access Not Configured"
}
Similar SO posts suggest it is to do with my Google API console settings, but I can't find anything wrong. Any suggestions? I wonder if it is because I am not providing my client ID or secret anywhere ...
Thanks.
My code runs from a fragment containing a list of videos. The relevant sections are:
-- Init
public class UploadFragment extends Fragment {
private static GoogleAccountCredential credential;
private static final HttpTransport transport = AndroidHttp.newCompatibleTransport();
private static final JsonFactory jsonFactory = new GsonFactory();
public YouTube youtube;
List<String> scopes = Lists.newArrayList(YouTubeScopes.YOUTUBE_UPLOAD);
private static String VIDEO_FILE_FORMAT = "video/*";
static final int REQUEST_GOOGLE_PLAY_SERVICES = 0;
static final int REQUEST_AUTHORIZATION = 1;
static final int REQUEST_ACCOUNT_PICKER = 2;
-- Setup credential and youtube
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
...
credential = googleAccountCredential(scopes);
youtube = new YouTube.Builder(transport, jsonFactory, credential)
.setApplicationName("MyAppName")
.build();
...
}
-- On button click, initiate upload
#Override void onClick(View v) {
...
if (hasGooglePlayServices()) {
uploadYouTubeVideos();
...
}
-- Build credential
/**
* Get the credential to authorize the installed application to access user's protected data.
*
* #param scopes list of scopes needed to run YouTube upload.
*/
private static GoogleAccountCredential googleAccountCredential(List<String> scopes) throws Exception {
credential = GoogleAccountCredential.usingOAuth2(context, scopes)
.setSelectedAccountName(PreferenceManager.getAccountName());
return credential;
}
-- Request an account from the user
/**
* Fire intent to get user to choose account
* Return to onActivityResult
*/
private void chooseAccount() {
startActivityForResult(credential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
}
-- On return from the user choosing and account
-- / requesting authorization
/**
* Returns from chooseAccount and from request authorization
*/
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQUEST_AUTHORIZATION:
if (resultCode == Activity.RESULT_OK) {
uploadYouTubeVideos();
} else {
chooseAccount();
}
break;
case REQUEST_ACCOUNT_PICKER:
if (resultCode == Activity.RESULT_OK && data != null && data.getExtras() != null) {
String accountName = data.getExtras().getString(AccountManager.KEY_ACCOUNT_NAME);
if (accountName != null) {
credential.setSelectedAccountName(accountName);
PreferenceManager.setAccountName(accountName);
uploadYouTubeVideos();
}
}
break;
}
}
-- Called multiple times depending on what information we have
-- account, authorization, etc.
/**
* Uploads user selected video to the user's YouTube account using OAuth2
* for authentication.
*
* #param videoFile file to be uploaded
*/
public void uploadYouTubeVideos() {
if (credential.getSelectedAccountName() == null) {
chooseAccount();
} else {
File videoFile = getVideoFile();
Insert videoInsert = prepareUpload(videoFile);
new VideoUploadAsyncTask().execute(videoInsert);
}
}
-- Prepare the upload
-- Puts everything together
/**
* Prepare upload. Just leaves execute to be run in AsyncTask.
*
* #param videoFile file to be uploaded
* #return
*/
public Insert prepareUpload( File videoFile ) {
try {
// Add extra information to the video before uploading.
Video videoObjectDefiningMetadata = new Video();
// Set the video to public (default).
VideoStatus status = new VideoStatus();
status.setPrivacyStatus("public");
videoObjectDefiningMetadata.setStatus(status);
// We set a majority of the metadata with the VideoSnippet object.
VideoSnippet snippet = new VideoSnippet();
// Video file name.
snippet.setTitle(videoFile.getName());
snippet.setDescription("Test description");
// Set keywords.
List<String> tags = new ArrayList<String>();
tags.add("test");
snippet.setTags(tags);
// Set completed snippet to the video object.
videoObjectDefiningMetadata.setSnippet(snippet);
InputStreamContent mediaContent = new InputStreamContent(
VIDEO_FILE_FORMAT, new BufferedInputStream(new FileInputStream(videoFile)));
mediaContent.setLength(videoFile.length());
/*
* The upload command includes: 1. Information we want returned after file is successfully
* uploaded. 2. Metadata we want associated with the uploaded video. 3. Video file itself.
*/
YouTube.Videos.Insert videoInsert = youtube.videos()
.insert("snippet,statistics,status", videoObjectDefiningMetadata, mediaContent);
// Set the upload type and add event listener.
MediaHttpUploader uploader = videoInsert.getMediaHttpUploader();
/*
* Sets whether direct media upload is enabled or disabled. True = whole media content is
* uploaded in a single request. False (default) = resumable media upload protocol to upload
* in data chunks.
*/
uploader.setDirectUploadEnabled(false);
MediaHttpUploaderProgressListener progressListener = new MediaHttpUploaderProgressListener() {
public void progressChanged(MediaHttpUploader uploader) throws IOException {
switch (uploader.getUploadState()) {
case INITIATION_STARTED:
Log.d(TAG, "Upload file: Initiation Started");
break;
case INITIATION_COMPLETE:
Log.d(TAG, "Upload file: Initiation Completed");
break;
case MEDIA_IN_PROGRESS:
Log.d(TAG, "Upload file: Upload in progress");
Log.d(TAG, "Upload file: Upload percentage: " + uploader.getProgress());
break;
case MEDIA_COMPLETE:
Log.d(TAG, "Upload file: Upload Completed!");
break;
case NOT_STARTED:
Log.d(TAG, "Upload file: Upload Not Started!");
break;
}
}
};
uploader.setProgressListener(progressListener);
return videoInsert;
} catch (FileNotFoundException e) {
Log.e(TAG, "File not found: " + e.getMessage());
return null;
} catch (IOException e) {
Log.e(TAG, "IOException: " + e.getMessage());
return null;
}
}
-- Require Google play services
/**
* Pop up dialog requesting user to download Google Play Services.
* Returns to onActivityResult
*/
void showGooglePlayServicesAvailabilityErrorDialog(final int connectionStatusCode) {
getActivity().runOnUiThread(new Runnable() {
public void run() {
Dialog dialog =
GooglePlayServicesUtil.getErrorDialog(connectionStatusCode, getActivity(),
REQUEST_GOOGLE_PLAY_SERVICES);
dialog.show();
}
});
}
-- AsyncTask that runs execute on the upload
public class VideoUploadAsyncTask extends AsyncTask<Insert, Void, Void> {
#Override
protected Void doInBackground( Insert... inserts ) {
Insert videoInsert = inserts[0];
try {
Video returnVideo = videoInsert.execute();
} catch (final GooglePlayServicesAvailabilityIOException availabilityException) {
showGooglePlayServicesAvailabilityErrorDialog(
availabilityException.getConnectionStatusCode());
} catch (UserRecoverableAuthIOException userRecoverableException) {
startActivityForResult(
userRecoverableException.getIntent(), UploadFragment.REQUEST_AUTHORIZATION);
} catch (IOException e) {
Log.e(TAG, "IOException: " + e.getMessage());
}
return null;
}
}
}
The answer provided by #Ibrahim was almost correct for me. What I needed to do was edit my API configuration. However, it was not the "Simple API access" section I needed to edit, it was the settings after clicking the button "Create another client Id".
Then I could select "Installed application" -> "Android". After inputting my package name and SHA1, and waiting 15 minutes, my app worked as expect. I also have the "Simple API access" set up. I am not sure if you need both or not.
Yes, YouTube Direct Lite for Android is similar. You have to configure simple API access with your SHA1 key. Explains here.
Related
How to attach PDF file to post API with two parameter? I am using Fast android networking library.
I am able to call API but I when user touched button my API called in my API have three parameters like this:
message = "Test"
receiver_Email = "#gmail.com"
File = text.PDF;
Sy API allows only PDF form met with message and email. I am using Fast android networking library. I try to call API but I am not able to do it.
I also looked at some examples but it couldn't help me out.
just call this method from your onCreate this is the easy way to call API with file and parameter I hope it helps you
//method used to call API to send email
enter code here
#RequiresApi(API = Build.VERSION_CODES.LOLLIPOP_MR1)
public void call_Api()
{
final String key = "file";
final File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), "/test.pdf");
AndroidNetworking.initialize(this);
AndroidNetworking.upload("your API")
.setPriority(Priority.HIGH)
.addMultipartParameter("message", "test")
.addMultipartParameter("receiverEmail","testrg0017#gmail.com")
.addMultipartFile(key, file)
.setPriority(Priority.HIGH)
.build()
.getAsJSONObject(new JSONObjectRequestListener()
{
#Override
public void onResponse(JSONObject response)
{
Log.d("res ",response.toString());
if(file.exists())
{
Toast.makeText(PdfGeneration.this, "API call successfully",
Toast.LENGTH_SHORT).show();
}
}
#Override
public void onError(ANError anError)
{
anError.printStackTrace();
Log.d("res12 ",anError.toString());
if(!file.exists())
{
Toast.makeText(PdfGeneration.this, "file not available",
Toast.LENGTH_SHORT).show();
}
}
});
}
I'm new with zoom integration.
I wants user login and create meeting in their account. I've done login user part using loginWithZoom method but now wants to create meeting for that auth token needed.
How can I get token when user login in zoom without OAuth?
I've found but not getting much idea. I tried with JWT token it works with
https://api.zoom.us/v2/users/me/meetings api. I gave Authorization token and content-type in
headers. it gives me all meetings of that specific user. but problem to get different authorization token for different users. I don't have idea is it possible or not.
Suggest if anyone knows
Code I've used for Login:
public void initializeSdk(Context context) {
ZoomSDK sdk = ZoomSDK.getInstance();
// TODO: Do not use hard-coded values for your key/secret in your app in production!
ZoomSDKInitParams params = new ZoomSDKInitParams();
params.appKey = "a...t4.."; // TODO: Retrieve your SDK key and enter it here
params.appSecret = "y...19"; // TODO: Retrieve your SDK secret and enter it here
params.domain = "zoom.us";
params.enableLog = true;
// TODO: Add functionality to this listener (e.g. logs for debugging)
ZoomSDKInitializeListener listener = new ZoomSDKInitializeListener() {
/**
* #param errorCode {#link us.zoom.sdk.ZoomError#ZOOM_ERROR_SUCCESS} if the SDK has been initialized successfully.
*/
#Override
public void onZoomSDKInitializeResult(int errorCode, int internalErrorCode) {
Log.i("","onZoomSDKInitializeResult Error code"+errorCode);
Toast.makeText(getApplicationContext()," error code : " + errorCode,Toast.LENGTH_LONG).show();
}
#Override
public void onZoomAuthIdentityExpired() {
System.out.println(" identity expired..");
}
};
sdk.initialize(context, listener, params);
}
findViewById(R.id.login_button).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(getApplicationContext(), "onclick of login", Toast.LENGTH_LONG).show();
Log.i(" ","onclick of login : "+ ZoomSDK.getInstance().isLoggedIn());
if (ZoomSDK.getInstance().isLoggedIn()) {
//wants to create meeting
} else {
createLoginDialog();
}
}
});
private void createLoginDialog() {
new AlertDialog.Builder(this)
.setView(R.layout.dialog_login)
.setPositiveButton("Log in", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
AlertDialog dialog = (AlertDialog) dialogInterface;
TextInputEditText emailInput = dialog.findViewById(R.id.email_input);
TextInputEditText passwordInput = dialog.findViewById(R.id.pw_input);
if (emailInput != null && emailInput.getText() != null && passwordInput != null && passwordInput.getText() != null) {
String email = emailInput.getText().toString();
String password = passwordInput.getText().toString();
if (email.trim().length() > 0 && password.trim().length() > 0) {
login(email, password);
}
}
dialog.dismiss();
}
})
.show();
}
public void login(String username, String password) {
int result = ZoomSDK.getInstance().loginWithZoom(username, password);
if (result == ZoomApiError.ZOOM_API_ERROR_SUCCESS) {
// Request executed, listen for result to start meeting
ZoomSDK.getInstance().addAuthenticationListener(authListener);
}
}
public void onZoomSDKLoginResult(long result) {
if (result == ZoomAuthenticationError.ZOOM_AUTH_ERROR_SUCCESS) {
// Once we verify that the request was successful, we may start the meeting
Toast.makeText(getApplicationContext(), "Login successfully", Toast.LENGTH_SHORT).show();
} else if(result == ZoomAuthenticationError.ZOOM_AUTH_ERROR_USER_NOT_EXIST || result == ZoomAuthenticationError.ZOOM_AUTH_ERROR_WRONG_PASSWORD){
Toast.makeText(getApplicationContext(),"Invalid username or password",Toast.LENGTH_LONG).show();
}
}
Thanks in advance.
I tried with JWT token it works with
https://api.zoom.us/v2/users/me/meetings api. I gave Authorization
token and content-type in headers. it gives me all meetings of that
specific user. but problem to get different authorization token for
different users. I don't have idea is it possible or not.
Assuming these users are not part of the same Zoom account, then no, it is not possible as of 2021-08-28. JWT-based authentication is only for Zoom integration in internal applications/services:
Note: JWT may only be used for internal applications and processes. All apps created for third-party usage must use our OAuth app type.
In this context, "internal" means "only to be used with a single Zoom account." Note that there can be many users under one account (e.g., all employees of Corporation XYZ are part of XYZ's Zoom account). Put differently, you can use a JWT issued for the XYZ Zoom account to access information for all users under the XYZ Zoom account, but if you need data for users that are not part of the XYZ Zoom account, then you need an API Key and API Secret for their Zoom account(s) as well to generate JWTs that you can use to retrieve their data.
If you are building an integration/service that you want to make available to the general public, then you need to use OAuth:
This app can either be installed and managed across an account by
account admins (account-level app) or by users individually
(user-managed app).
I am attempting to communicate with a Pi header using Android Things Developer Preview 5. Below is the class I have created to communicate with the header as per the official Android Things documentation:
public class UartComm {
private static final String UART_DEVICE_NAME = "UART1";
private UartDevice mDevice;
private void configureUartFrame(UartDevice uart) throws IOException {
// Configure the UART port
uart.setBaudrate(115200);
}
public void onCreate() {
try {
PeripheralManagerService manager = new PeripheralManagerService();
List<String> deviceList = manager.getUartDeviceList();
if (deviceList.isEmpty()) {
Log.i(TAG, "No UART port available on this device.");
} else {
Log.i(TAG, "List of available devices: " + deviceList);
}
mDevice = manager.openUartDevice(UART_DEVICE_NAME);
configureUartFrame(mDevice);
mDevice.registerUartDeviceCallback(mUartCallback);
} catch (Exception e) {
Log.w(TAG, "Unable to access UART device", e);
}
}
public void readUartBuffer(UartDevice uart) throws IOException {
// Maximum amount of data to read at one time
final int maxCount = 40;
byte[] buffer = new byte[maxCount];
uart.read(buffer, maxCount);
String data = new String(buffer, "UTF-8");
Log.d(TAG, data);
}
private UartDeviceCallback mUartCallback = new UartDeviceCallback() {
#Override
public boolean onUartDeviceDataAvailable(UartDevice uart) {
// Read available data from the UART device
try {
readUartBuffer(uart);
} catch (IOException e) {
Log.w(TAG, "Unable to access UART device", e);
}
// Continue listening for more interrupts
return true;
}
#Override
public void onUartDeviceError(UartDevice uart, int error) {
Log.w(TAG, uart + ": Error event " + error);
}
};
}
In my MainActivity I create an instance of UartComm by doing UartComm device = new UartComm() and the proceed to call device.onCreate()
I have also modified /boot/cmdline.txt and removed the console=serial0,115200 and replaced it with console=tty0, I have also tried just removing the console line without adding console=tty0. In /boot/config.txt I have also removed enable_uart=1 and core-freq=400 and also added dtoverlay=pi3-miniuart-bt I have also tried to remove Bluetooth support altogether by doing dtoverlay=pi3-disable-bt to no avail.
I have tested that the header works and is configured correctly in Rapsbian, where I swapped /dev/ttyAMA0 and /dev/ttyS0 and it worked correctly. I was able to run the screen command on Raspbian with a default baud rate of 115200 and was able to get the desired information.
I would like to do the same in Android Things Developer Preview 5 and have the Bluetooth run over the mini-uart ttyS0 and the header run over ttyAMA0. My desired result is for the header to be accessible over UART0.
An older USB serial device that has the same functionality works, but I would prefer the UART device be physically on top of the Pi, so that is not an option.
Might be wrong but shouldn't:
private static final String UART_DEVICE_NAME = "UART1";
be UART0 i.e.
private static final String UART_DEVICE_NAME = "UART0";
I did a UART example here https://github.com/blundell/androidthings-uart/blob/master/app/src/main/java/com/blundell/tut/MainActivity.java (obviously different hardware) But it's connected to raspberry pi pins in the same way like so:
I created an application to upload certain custom thumbnails to YouTube videos and it works fine but, I revoked access to my application from my YouTube account to test some things and my application no longer asks for access. Now whenever I attempt to use my application it only responds with:
IOException: 400 Bad Request
{
"error" : "invalid_grant",
"error_description" : "Token has been expired or revoked."
}
com.google.api.client.auth.oauth2.TokenResponseException: 400 Bad Request
{
"error" : "invalid_grant",
"error_description" : "Token has been expired or revoked."
}
I used the thumbnails set example from the YouTube page : https://developers.google.com/youtube/v3/docs/thumbnails/set
I was wondering what I could change in my following code to get the login page to show up again so I can give access to my application again, my code is here:
private void uploadThumbnail(String videoId, BufferedImage thumbnail){
YouTube youtube;
String IMAGE_FILE_FORMAT = "image/png";
// This OAuth 2.0 access scope allows for full read/write access to the
// authenticated user's account.
ArrayList<String> scopes = new ArrayList<>();
scopes.add("https://www.googleapis.com/auth/youtube");
try {
// Authorize the request.
Credential credential = Auth.authorize(scopes, "uploadthumbnail");
// This object is used to make YouTube Data API requests.
youtube = new YouTube.Builder(Auth.HTTP_TRANSPORT, Auth.JSON_FACTORY, credential).setApplicationName(
"youtube-cmdline-uploadthumbnail-sample").build();
get.saveImg(thumbnail,"./Screens/screenshot0t.png");
File imageFile = new File("./Screens/screenshot0t.png");
// Create an object that contains the thumbnail image file's
// contents.
InputStreamContent mediaContent = new InputStreamContent(
IMAGE_FILE_FORMAT, new BufferedInputStream(new FileInputStream(imageFile)));
mediaContent.setLength(imageFile.length());
// Create an API request that specifies that the mediaContent
// object is the thumbnail of the specified video.
Set thumbnailSet = youtube.thumbnails().set(videoId, mediaContent);
// Set the upload type and add an event listener.
MediaHttpUploader uploader = thumbnailSet.getMediaHttpUploader();
// Indicate whether direct media upload is enabled. A value of
// "True" indicates that direct media upload is enabled and that
// the entire media content will be uploaded in a single request.
// A value of "False," which is the default, indicates that the
// request will use the resumable media upload protocol, which
// supports the ability to resume an upload operation after a
// network interruption or other transmission failure, saving
// time and bandwidth in the event of network failures.
uploader.setDirectUploadEnabled(false);
// Set the upload state for the thumbnail image.
MediaHttpUploaderProgressListener progressListener = new MediaHttpUploaderProgressListener() {
#Override
public void progressChanged(MediaHttpUploader uploader) throws IOException {
switch (uploader.getUploadState()) {
// This value is set before the initiation request is
// sent.
case INITIATION_STARTED:
System.out.println("Initiation Started");
break;
// This value is set after the initiation request
// completes.
case INITIATION_COMPLETE:
System.out.println("Initiation Completed");
break;
// This value is set after a media file chunk is
// uploaded.
case MEDIA_IN_PROGRESS:
System.out.println("Upload in progress");
System.out.println("Upload percentage: " + uploader.getProgress());
break;
// This value is set after the entire media file has
// been successfully uploaded.
case MEDIA_COMPLETE:
System.out.println("Upload Completed!");
break;
// This value indicates that the upload process has
// not started yet.
case NOT_STARTED:
System.out.println("Upload Not Started!");
break;
}
}
};
uploader.setProgressListener(progressListener);
// Upload the image and set it as the specified video's thumbnail.
ThumbnailSetResponse setResponse = thumbnailSet.execute();
// Print the URL for the updated video's thumbnail image.
System.out.println("\n================== Uploaded Thumbnail ==================\n");
System.out.println(" - Url: " + setResponse.getItems().get(0).getDefault().getUrl());
get.deleteFile(imageFile.getPath());
} catch (GoogleJsonResponseException e) {
System.err.println("GoogleJsonResponseException code: " + e.getDetails().getCode() + " : "
+ e.getDetails().getMessage());
e.printStackTrace();
} catch (IOException e) {
System.err.println("IOException: " + e.getMessage());
e.printStackTrace();
}
}
I had the exact same issue with Gmail API, everything went back to normal after removing the stored credentials.
e.g. rm ~/.credentials/gmail-java-quickstart/StoredCredential
I use the new Google drive api and I can't get All folders from my google drive, I only get the folders that I create with the google drive api...
Anybody know why happens this?
this is my code:
#Override
protected void onResume() {
super.onResume();
if (mGoogleApiClient == null) {
// Create the API client and bind it to an instance variable.
// We use this instance as the callback for connection and connection
// failures.
// Since no account name is passed, the user is prompted to choose.
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
// Connect the client. Once connected, the camera is launched.
mGoogleApiClient.connect();
}
/**
* Handles resolution callbacks.
*/
#Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_RESOLUTION && resultCode == RESULT_OK) {
mGoogleApiClient.connect();
}
}
/**
* Called when activity gets invisible. Connection to Drive service needs to
* be disconnected as soon as an activity is invisible.
*/
#Override
protected void onPause() {
if (mGoogleApiClient != null) {
mGoogleApiClient.disconnect();
}
super.onPause();
}
/**
* Called when {#code mGoogleApiClient} is connected.
*/
#Override
public void onConnected(Bundle connectionHint) {
Log.i(TAG, "GoogleApiClient connected");
rootFolder = Drive.DriveApi.getRootFolder(mGoogleApiClient);
rootFolder.listChildren(getGoogleApiClient()).setResultCallback(pruebaChildren);
}
ResultCallback<DriveApi.MetadataBufferResult> pruebaChildren = new
ResultCallback<DriveApi.MetadataBufferResult>() {
#Override
public void onResult(DriveApi.MetadataBufferResult metadataBufferResult) {
if (!metadataBufferResult.getStatus().isSuccess()) {
showMessage("Problem while retrieving files");
return;
}
Log.i(TAG,"got root folder");
MetadataBuffer buffer = metadataBufferResult.getMetadataBuffer();
Log.i(TAG,"Buffer count " + buffer.getCount());
if(buffer.getCount() == 0){
createFolderApp();
}
else{
for(Metadata m : buffer){
Log.i(TAG,"Metadata name " + m.getTitle() + "(" + (m.isFolder() ? "folder" : "file") + ")");
if (m.isFolder() && m.getTitle().equals(TAG)){
Log.i(TAG,"APP FOLDER FOUND");
Drive.DriveApi.getFolder(mGoogleApiClient, m.getDriveId())
.listChildren(mGoogleApiClient)
.setResultCallback(foreachAppAplication);
}
}
}
return;
}
};
And now I want see all folders in rootFolder Drive, I try the requestSync() but the result is same... I need help please!
And another question: How I can set the AppFolder? I only see getAppFolder but How I can set ??
Thanks
By design, GDAA supports only the FILE scope, i.e. it will find / list only folders / files created by the Android app.
There are 2 ways around it:
Use one of the intents of the GDAA, basically letting the user pick the file / folder. That way it will become available to your app.
Use a different API, the REST Api, which supports the DRIVE scope, giving your app full set of files / folders.
In case you want to study how the two APIs behave, I've put two different demos on the Github (the REST and the GDAA CRUD demo wrappers).
The second part of your question does not have answer. You don't set the app folder, you can only get it's DriveFolder id. You use it to create / retrieve objects.
DriveFolder appFldr = Drive.DriveApi.getAppFolder(mGooleApiClient);
appFldr.createFile(...);
appFldr.createFolder(...);
appFldr.listChildren(...);
appFldr.queryChildren(...);
... and don't forget to add the SCOPE_APPFOLDER scope
Good Luck