How to find a google Drive file by ID? - android

I'm working on a project where I need to upload a file to google Drive, to download it with another app.
I wanted to use the Drive Id, which I get by creating a file, to find it later, but this seems not to work.
I used an example from Google to get the ID:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_CODE_CREATOR:
if (resultCode == RESULT_OK) {
driveId = data.getParcelableExtra(
OpenFileActivityBuilder.EXTRA_RESPONSE_DRIVE_ID);
showMessage("File created with ID: " + driveId);
}
break;
default:
super.onActivityResult(requestCode, resultCode, data);
break;
}
}
This seemed to work so far, I am getting the Drive ID.
After this, I wanted to test it by using the Example "Files: get" from the Google Developers-page, where I got the following error:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "notFound",
"message": "File not found: CAESABiCASCQ1OnN-VMoAA==",
"locationType": "other",
"location": "file"
}
],
"code": 404,
"message": "File not found: CAESABiCASCQ1OnN-VMoAA=="
}
}
It seems like this ID is not the id to find files.
There must be something I missed but i don't know what.
I am new to programming, especially to Google and Android and I would be very happy if any one can help me through their answers.
Thanks.

There are two problems with your approach.
1/ You can not use the DriveId for anything outside your Android App instance, you have to go for the ResourceId (see SO 32210970)
2/ The DriveId you're showing above is the 'preliminary' DriveId that is returned by GooPlaySvcs before the object is committed (uploaded) (see SO 22874657). Also, you can't get a valid ResourceId until it the object is committed.
See also SO 33355665, SO 29030110
If you intent to take the ResourceId 'outside' (to a different app), you'll be OK. If you decide to use this ResourceId in the same Android app, mixing the two Apis (GDAA and REST), you will potentially introduce latency issues, since GDAA is a 'buffering' layer between your app and the REST api (you've already run into one with your 'invalid' DriveId).
Good Luck

Related

Error while migrating to latest Google Drive API in Android - Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup

An application is published on Play Store and it is using 'application data folder' for the backup-restore purpose using Drive API. Everything works fine. However, this API is about to be turned down on 6th December, 2019 according to Google's announcement. Therefore, in order to support existing users, I have been migrating to latest API according to migration guidlines and an official sample app.
I can successfully authenticate using the code (from the official link) below.
GoogleSignInOptions signInOptions = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.requestScopes(new Scope(DriveScopes.DRIVE_APPDATA))
.build();
GoogleSignInClient client = GoogleSignIn.getClient(this, signInOptions);
// The result of the sign-in Intent is handled in onActivityResult.
startActivityForResult(client.getSignInIntent(), REQUEST_CODE_SIGN_IN);
I am also using correct scope - DriveScopes.DRIVE_APPDATA as mentioned in the official documentation.
I am also seeing correct values of 'email' and 'granted scopes' inside onActivityResult()
if (requestCode == REQUEST_CODE_SIGN_IN && resultCode == RESULT_OK) {
GoogleSignIn.getSignedInAccountFromIntent(data).addOnSuccessListener(new OnSuccessListener<GoogleSignInAccount>() {
#Override
public void onSuccess(GoogleSignInAccount googleSignInAccount) {
Log.e("TAG", "Email - " + googleSignInAccount.getEmail()); // prints correct value
Log.e("TAG", "Granted scopes - " + googleSignInAccount.getGrantedScopes()); // prints correct value
GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2(getActivity(), Collections.singleton(DriveScopes.DRIVE_APPDATA));
credential.setSelectedAccount(googleSignInAccount.getAccount());
Drive googleDriveService = new Drive.Builder(
AndroidHttp.newCompatibleTransport(),
new GsonFactory(),
credential)
.setApplicationName("App Name") // Changed it for now
.build();
mDriveServiceHelper = new DriveServiceHelper(googleDriveService);
queryFiles();
}
});
}
However, whenever I try to access a backup file in queryFiles() using the code (from the official link) below,
FileList files = driveService.files().list()
.setSpaces("appDataFolder")
.setFields("nextPageToken, files(id, name)")
.setPageSize(10)
.execute();
for (File file : files.getFiles()) {
System.out.printf("Found file: %s (%s)\n",
file.getName(), file.getId());
}
It throws the following error
{
"errors": [
{
"domain": "usageLimits",
"reason": "dailyLimitExceededUnreg",
"message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup.",
"extendedHelp": "https://code.google.com/apis/console"
}
],
"code": 403,
"message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup."
}
Kindly help me fix the error. I believe that as everything is working fine with the published version, everything should be correct in terms of configuring on Google API console.
I probably can't find ALL threads with this problem but I can try to help in a few or so.
PRIMARY ANSWER
IF you're using ProGuard same as I am. ProGuard can cause this error to happen during query. I fixed it using the following.
# Fix OAuth Drive API failure for release builds
-keep class * extends com.google.api.client.json.GenericJson { *; }
-keep class com.google.api.services.drive.** { *; }
-keepclassmembers class * { #com.google.api.client.util.Key <fields>; }
SECONDARY ANSWER
Note that you DO NOT need to use keys/tokens using the Drive rest API with Android like you may find from other solutions (it may not hurt either, but it can). It doesn't match up here to what people talk about elsewhere (here they don't know what they're talking about).
See my notes here for further info: Google Drive via OAuth release version receives dailyLimitExceededUnreg
IF you have the problem however in debug build then you did not do everything correctly. My notes should get you on the right track.
If you need further help, I might assist because of how nuts it is.
EXAMPLE OF GETTING A FILE FROM DRIVE WITH THE NEW API USE
Just see from the following link
public Task<Pair<String, String>> readFile(String fileId)
https://github.com/gsuitedevs/android-samples/blob/master/drive/deprecation/app/src/main/java/com/google/android/gms/drive/sample/driveapimigration/DriveServiceHelper.java
The id comes from the query result where the id is part of that query info attached to that which is returned from the Drive query. The id is the file id for the file you want to retrieve. Pass that in to readFile and it gives you the file contents back that you can save locally to java.io.File eg fileOutputStream.write(contents.getBytes()); the contents of which is pair.second. You would then have your hopefully (because sometimes we have more work to do) identical java.io.File.
You can see a basic query if you need one in the the link sample as well but its missing some important info because depending on what you do you may need to check if trashed, get file size, modify time, md5, set order, etc. You may need to see https://developers.google.com/drive/api/v2/reference/files/list and https://developers.google.com/drive/api/v3/reference/files etc to figure that out. If enough files, there will be a paged requirement as well.
I know using Drive from code is a bit nuts (well, it is to me anyway lol) so hang in there =)
For Documentation purposes as a troubleshooting step:
Go to
https://console.developers.google.com/project/<project-id>/apiui/api
Or for Google Scripts:
https://script.google.com/home/usersettings
Replace with the ID of your application and check that the Google Drive API is turned on.
If it isn't - make sure to get a new token after turning it on if this is the case.

Google Play Services - which min sdk to use

I have created an app but when I tried to test it on my minsdk which is API 21, google play services won't work.
The error I get is com.google.android.gms.common.api.ApiException: 4:.
I followed the setup guide, which means I have set my Google Play Services libs to version 11.8.0, it says I just have to use Android 4.2.2 which is API 17.
My compileSdkVersion is set to 27.
Is there something big I am misunderstanding here on how the compiling works? The app works fine on API 26 and 25, but fails when I try using it on API 24, with the same error as with API 21.
My build.gradle file looks like this.
https://gist.github.com/uruloke/f2f71dd6318d365cd53d74c274cd8523
When using the GoogleSignInClient.silentSignIn() from the addOnFailureListener, I get the following exception
com.google.android.gms.common.api.ApiException: 4:
at com.google.android.gms.common.internal.zzb.zzy(Unknown Source)
at com.google.android.gms.common.internal.zzbk.zzz(Unknown Source)
at com.google.android.gms.common.internal.zzbl.zzr(Unknown Source)
at com.google.android.gms.common.api.internal.BasePendingResult.zzc(Unknown Source)
at com.google.android.gms.common.api.internal.BasePendingResult.setResult(Unknown Source)
at com.google.android.gms.auth.api.signin.internal.zzg.zza(Unknown Source)
at com.google.android.gms.auth.api.signin.internal.zzt.onTransact(Unknown Source)
at android.os.Binder.execTransact(Binder.java:565)
Also if I try to use the GoogleSignInClient.getSignInIntent(), no intent is shown when starting it, but in my onActivityResult, I get an result which is non-successful, but with an empty status message
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SIGN_IN) {
GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
Log.d(TAG, result.getStatus().toString());
if (result.isSuccess()) {
// The signed in account is stored in the result.
GoogleSignInAccount signedInAccount = result.getSignInAccount();
menuFragment.updateUi(signedInAccount);
} else {
String message = result.getStatus().getStatusMessage();
if (message == null || message.isEmpty()) {
message = "Failed to sign in to Play Games. Maybe try updating it?";
}
new AlertDialog.Builder(this).setMessage(message)
.setNeutralButton(android.R.string.ok, null).show();
}
}
}
public static final int SIGN_IN_REQUIRED
The client attempted to connect to the service but the user is not signed in. The client may choose to continue without using the API. Alternately, if hasResolution() returns true the client may call startResolutionForResult(Activity, int) to prompt the user to sign in. After the sign in activity returns with RESULT_OK further attempts should succeed.
Constant Value: 4
Source: CommonStatusCodes, emphasis mine
It looks like silentSignIn only works if you're signed in to Google on the device, to be precise:
We attempt to sign users in if:
There is one and only one matching account on the device that has previously signed in to your application, and
the user previously granted all of the scopes your app is requesting for this sign in.
Source: GoogleSignInApi#silentSignIn

Facebook Chatbot: Animated GIFs in Generic Templates

With the generic templates for Facebook chatbots it is possible to use animated GIF images. This works perfectly for the desktop version. With the messenger app on iOS or Android the animation is not playing and only the first frame is displayed instead.
Is there something I can do to make it also work in the messenger app?
Here is the documention about the generic templates for the Facebook chatbot: https://developers.facebook.com/docs/messenger-platform/send-api-reference/generic-template
I tried it too, but the answer is what you knew. Animated Gifs works as single picture, but doesn't work in any templates. I've read all reference by FB and checked all news they've published. But they haven't mentioned about it and there is just the true by my hand below.
o single picture on browser
o single picture on app
o picture of template on browser
x picture of template on app
o -> animating
x -> stop and just first frame is shown
I had the same issue when I posted a valid GIF URL in the generic template. You can see a question I posted and the answer I add after a couple of hours of searching.
Unfortunately, animated GIF images cannot be printed through the generic template yet.
The solution you can do is you create two payloads and not a template. The first payload will post a GIF Image and the second your buttons like,
code
def thanks(req):
your_welcome_gif=[ "https://media3.giphy.com/media/KCw6QUxe9zBO6QNrFe/giphy.gif",
"https://media1.giphy.com/media/H21d4avBXs8B9X0NLj/giphy.gif",
"https://media1.tenor.com/images/15bafc0b414757acab81650a6ff21963/tenor.gif?itemid=11238673"]
greeding = req.get('queryResult').get('parameters').get('greeding')
if greeding == 'Thank you' or greeding == 'thank you' or greeding == 'Thanks' or greeding == 'thanks' or greeding == 'Nice' or greeding == 'nice':
return {"fulfillmentMessages": [
{
'payload': {
"facebook": {
"attachment": {
"type": "image",
"payload":{
"url":random.choice(your_welcome_gif)
}
}
}
}
},
{
'payload': {
"facebook": {
"attachment": {
"type": "template",
"payload": {
"template_type": "button",
"text": "You're welcome :) \nWould you like to choose another movie?",
"buttons": [
{
"type": "postback",
"title":"Yes",
"payload":"Yes"
},
{
"type": "postback",
"title":"No",
"payload":"No"
}
]
}
}
}
}
}
]}
Here is my question with code uploaded.
Yes you also send a gif message but int the url section you have to give a valid url of that gif...you can do it by uploading on git first and then at the last of url you have to type.....=> ?raw=true
because in git it stored in raw format...
You may see all the details here on my link this chatbot is handling almost every feature in the described in the documents

App invites using Firebase not working

Developing an App which has Firebase as backend. Currently, was stuck while implementing Firebase App Invite . Just looking to send invites ( not currently trying to implement the clicking of the dynamic link by the installed new user) but the onActivityResult returns wrong result_code
Steps followed
Integrated FireBase SDK and authenticating successfully.
Enabled Firebase Dynamic link and referred in the app
Clicking on the invite button shows the inbuilt Firebase Activity with option to select users to invite and sent ( SMS or Email Invites )
the app returns back to the invite screen as expected.
Code Snippet
InviteActivity
btnInvite.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new AppInviteInvitation.IntentBuilder(INVITATION_TITLE)
.setMessage(INVITATION_MESSAGE)
.setDeepLink(Uri.parse("https://ewyc6.app.goo.gl/eNh4"))
.setCallToActionText(INVITATION_CALL_TO_ACTION)
.build();
startActivityForResult(intent, REQUEST_INVITE);
}
});
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.d(TAG, "onActivityResult: requestCode=" + requestCode + ", resultCode=" + resultCode + "result_ok ="+RESULT_OK);
if (requestCode == REQUEST_INVITE) {
if (resultCode == RESULT_OK) {
// You successfully sent the invite,
// we can dismiss the button.
btnInvite.setVisibility(View.GONE);
String[] ids = AppInviteInvitation.getInvitationIds(resultCode, data);
StringBuilder sb = new StringBuilder();
sb.append("Sent ").append(Integer.toString(ids.length)).append(" invitations: ");
for (String id : ids) sb.append("[").append(id).append("]");
Toast.makeText(getApplicationContext(),"Invited!!!",Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(),"Sorry, unable to send invite.",Toast.LENGTH_SHORT).show();
}
}
}
//result_code is 3 and the RESULT_OK is -1 on debugging
New to Firebase stuff , would appreciate if point out what I m doing wrong.
After hours of struggle found the issue and fixed it, posting it here since it might be helpful to others too.
The initial hint was "Create invitations failed to error code: 3" Had a similar issue here in SO
Get suggested invitees failed due to error code: 3
But in my case the SHA1 certificate was already added, but the package name in Firebase turned out to be a case sensitive issue.
One more point worth taking note of, "api_key" in google-services.json downloaded from Firebase and Web Api Key are not related. I tried to copy and paste the web api key to the json file manually from dashboard to api_key under the misconception that might be the issue lead to the error.
Log onto Firebase Console: https://console.firebase.google.com
You will need to click on the "Add Fingerprint" button and then add on your SHA1 key. You do not need to redownload your google-services.json, you just need to add the SHA1 key.
Try sending an app invite from your app. It will now work.

Get userInfo from Instagram in android

I am integrating Instagram in my android app. I am able to get authetication and token from Instagram API. Now what I am looking for is userinfo. As soon as user is authenticated I want his userinfo like username,name etc. Any idea how to get it ? I tried several ways but didnt able to achieve it.
I tried this example https://github.com/poller/instagram-demo-for-android
Get basic information about a user. To get information about the owner of the access token, you can use self instead of the user-id.
Link for Documentation is :
https://instagram.com/developer/endpoints/users/
Use this API :
https://api.instagram.com/v1/users/{user-id}/?access_token=ACCESS-TOKEN
Response contains information about that particular user requested by passing ID :
{
"data": {
"id": "1574083",
"username": "snoopdogg",
"full_name": "Snoop Dogg",
"profile_picture": "url of picture",
"bio": "This is my bio",
"website": "website of that user",
"counts": {
"media": 1320,
"follows": 420,
"followed_by": 3410
}
}
Simply pass your access token to this url. And you will get the logged user information of the Instagram.
[https://api.instagram.com/v1/users/self/?access_token=YOUR-ACCESS-TOKEN]
this will return the user information like the above #Heena Arora mentioned.
And also she mentioned about retrieving the user information for the particular user by id.

Categories

Resources