I generated an access token to be able to make API calls for my own account without going through the authorization flow. I found this Dropbox files Get API but I don't know how to use it.
I tried this code, but it doesn't seem to work:
// Authentication with Token
AppKeyPair appKeys = new AppKeyPair(APP_KEY, APP_SECRET);
AndroidAuthSession session = new AndroidAuthSession(appKeys);
mDBApi = new DropboxAPI<AndroidAuthSession>(session);
mDBApi.getSession().setOAuth2AccessToken(ACCESS_TOKEN);
// Upload a file to Apps folder
File file = new File("working-draft.txt");
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(file);
DropboxAPI.Entry response = mDBApi.putFile("/magnum-opus.txt", inputStream,
file.length(), null, null);
Log.i("DbExampleLog", "The uploaded file's rev is: " + response.rev);
} catch (Exception e) {
e.printStackTrace();
}
How can I upload and download directly to the Apps folder using the token key?
Also is there a way to print the list of all the files in my Apps folder?
The docs are pretty poor. I found the following examples on Github which helped me:
https://github.com/dropbox/dropbox-sdk-java/tree/master/examples/android/src/main/java/com/dropbox/core/examples/android
In gradle
compile 'com.dropbox.core:dropbox-core-sdk:3.0.2' or whatever is the latest
The key and secret are written into a JSON file + there's an entry you need to add into the manifest with the app key. Just follow the example which shows placeholders.
Once you've done the handshake and got the access token back
DbxRequestConfig requestConfig = DbxRequestConfig.newBuilder("your identifier")
.withHttpRequestor(new
OkHttp3Requestor(OkHttp3Requestor.defaultOkHttpClient()))
.build();
dbxClient = new DbxClientV2(requestConfig, accessToken);
dbxClient.files().[operation e.g. upload\download\file listing]
Related
I need to get the credential of Google Drive API inside my mobile app to create a simple folder and upload a single file on logged in user Google drive.
I get an error from the highlighted code (AuthorizeAsync function call) when I try to implement it using Xamarin Forms in Visual Studio 2022.
The highlighted code fails because of FileDataStore function parameter when tested on a android tablet running API 24. In ideal situation (such as this code running on desktop app), the file token.json would have been created automatically if it does not exists. But when implemented in Xamarin Forms (used for mobile app development), it gives an error, whether the file exists in the allowed mobile folder path and it also gives an error if the file does not exists in the allowed mobile folder path. It never ever creates the file on its own, the way it does in desktop app. Here is the code:
//credjson is client id info in json format read from the downloadeded credentials.json
//I created via google cloud api enable
public static void DriveCreateFolder(string credjson)
{
try
{
byte[] byteArray = Encoding.ASCII.GetBytes(credjson);
UserCredential credential;
using (MemoryStream stream = new MemoryStream(byteArray))
{
string localPath =
System.Environment.GetFolderPath(
Environment.SpecialFolder.LocalApplicationData );
string credPath = Path.Combine(localPath, "token.json");
// ***THIS LINE THROWS AN ERROR BECAUSE OF FILE DATA STORE PARAMETER TOKEN.JSON***
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.FromStream(stream).Secrets,
Scopes,
"user",
CancellationToken.None, new FileDataStore(credPath, true)).Result;
Console.WriteLine("Credential file saved to: " + credPath);
}
// Create Drive API service.
var service = new DriveService(new BaseClientService.Initializer
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName
});
// File metadata
var fileMetadata = new Google.Apis.Drive.v3.Data.File()
{
Name = "MyAppFolder",
MimeType = "application/vnd.google-apps.folder"
};
// Create a new folder on drive.
var request = service.Files.Create(fileMetadata);
request.Fields = "id";
var file = request.Execute();
// Prints the created folder id.
Console.WriteLine("Folder ID: " + file.Id);
ApplicationFolder = file;
// return file.Id;
}
catch (Exception e)
{
// TODO(developer) - handle error appropriately
if (e is AggregateException)
{
Console.WriteLine("Credential Not found");
}
else
{
throw;
}
}
//return null;
}
Here are the test code, test errors I receive
Errors thrown in three different test cases:
Test Code 1:
string credPath = Path.Combine("token.json");
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.FromStream(stream).Secrets,
Scopes,
"user",
CancellationToken.None, new FileDataStore(credPath, true)).Result;
Test Result 1:
AuthorizeAsync line throws an error
System.IO.IOException: 'Read-only file system'
Test Code 2:
string localPath = System.Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
string credPath = Path.Combine(localPath, "token.json");
//ensure file does not exists
if (File.Exists(credPath))
File.Delete(credPath);
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.FromStream(stream).Secrets,
Scopes,
"user",
CancellationToken.None, new FileDataStore(credPath, true)).Result;
Test Result 2:
note: the packagename is not revealed on purpose in test result
credPath evaluates to "/data/user/0/mypackagename/files/.local/share/token.json"
First time when I run the code, it deletes the existing token.json and throws an error without any details. StackTrack points to “External code”.
Second time when I run the same code, the file does not exists any more and the following error shows up
System.ComponentModel.Win32Exception: 'Cannot find the specified file'
Test Code 3:
//ensure file exists this time
if (!File.Exists(credPath))
File.Create(credPath);
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.FromStream(stream).Secrets,
Scopes,
"user",
CancellationToken.None, new FileDataStore(credPath, true)).Result;
Test Result 3:
note: the packagename is not revealed on purpose in test result
The File.Create line throws an exception
System.UnauthorizedAccessException: 'Access to the path '/data/user/0/mypackagename/files/.local/share/token.json' is denied.'
Test Code 4:
string localPath = System.Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string credPath = Path.Combine(localPath, "token.json");
//ensure file exists
if (!File.Exists(credPath))
File.Create(credPath);
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.FromStream(stream).Secrets,
Scopes,
"user",
CancellationToken.None, new FileDataStore(credPath, true)).Result;
Test Result 4:
note: the packagename is not revealed on purpose in test result
credPath evaluates to "/data
/user/0/mypackagename/files/.config/token.json"
File gets created successfully this time
AuthorizeAsync line throws the error
System.IO.IOException: 'The file '/data/user/0/mypackagename/files/.config/token.json' already exists.'
I need to download my key.p12 file from https://console.cloud.google.com/ but I dont know how to do it now.
My Dashboard "Api & Services > Credentials" is like this:
I need this p12 file to connect to the PHP API Google_Service_AndroidPublisher with this code (I am using the same code in this Stackoverflow answer to the question Get android subscription status, failed with 403:
$service_account_name = 'testing#nootrictesting.iam.gserviceaccount.com'; //Your service account email
$key_file_location = ''; // p12 file (key.p12)
$client = new Google_Client();
$client->setApplicationName("My name app"); //This is the name of the linked application
$key = file_get_contents($key_file_location);
$cred = new Google_Auth_AssertionCredentials(
$service_account_name,
array('https://www.googleapis.com/auth/androidpublisher'),
$key
);
$client->setAssertionCredentials($cred);
if($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($cred);
}
$apiKey = ""; //API key
$client->setDeveloperKey($apiKey);
$service = new Google_Service_AndroidPublisher($client);
$results = $service->purchases_subscriptions->get("MY_ANDROID_APP_PACKAGE", $product_id, $purchase_token, array());
Any help will be useful.
Thanks!!!
DalmoTo linked the video in their comment that shows how/where to grab keys: youtu.be/asrCdWFrF0A?t=76
However, Google_Auth_AssertionCredentials looks like it shouldn't be used any longer (https://github.com/googleapis/google-api-php-client/blob/master/UPGRADING.md). Instead, use $client->setAuthConfig('/path/to/service-account.json'). Then you can use the json key file, not the p12 key file.
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);
Is it possible to use both the Core and Sync Api in one Android app?
It is possible to use them together. It's a 2 part setup.
Removing Project errors:
Add jar files both SDKs to your project
Now open Dropbox Core SDK jar file and remove the client2.Auth classes - anything that's causing a namespace collision. You will see errors until this is fixed
Authenticating the SDKs:
Setup dropbox linking for the Sync SDK - there are many docs on this
Get the oAuth credentials from Sync SDK for your Core SDK using:
AppKeyPair appKeyPair = new AppKeyPair(APP_KEY, APP_SECRET);
AndroidAuthSession session = new AndroidAuthSession(appKeyPair);
session.setOAuth2AccessToken(getTokenFromSyncAPI());
session.finishAuthentication();
And finally, the missing method:
String getTokenFromSyncAPI() {
String token = null;
String allTokens = getApplicationContext().getSharedPreferences("dropbox-credentials",
Context.MODE_PRIVATE).getString("accounts", null);
try {
JSONArray jsonAccounts = new JSONArray(allTokens);
if (jsonAccounts.length() > 0) {
String tmpToken = null;
tmpToken = jsonAccounts.getJSONObject(0).getString("userToken");
// We take only oAuth2 tokens
if (tmpToken.startsWith("|oa2|"))
token = tmpToken.substring(5);
}
} catch (JSONException e) {
e.printStackTrace();
}
return token;
}
Method courtesy : https://blogs.dropbox.com/developers/2015/05/migrating-sync-sdk-access-tokens-to-core-sdk/
PS : The method shown at the link has a bug. substring(6) instead of 5
I want to upload image on Google Cloud Storage from my android app. For that I searched and found that GCS JSON Api provides this feature. I did a lot of research for Android sample which demonstrates its use. On the developer site they have provided code example that only support java. I don't know how to use that API in Android. I referred this and this links but couldn't get much idea. Please guide me on how i can use this api with android app.
Ok guys so I solved it and got my images being uploaded in Cloud Storage all good.
This is how:
Note: I used the XML API it is pretty much the same.
First, you will need to download a lot of libraries.
The easiest way to do this is create a maven project and let it download all the dependencies required. From this sample project :
Sample Project
The libraries should be:
Second, you must be familiar with Cloud Storage using the api console
You must create a project, create a bucket, give the bucket permissions, etc.
You can find more details about that here
Third, once you have all those things ready it is time to start coding.
Lets say we want to upload an image:
Cloud storage works with OAuth, that means you must be an authenticated user to use the API. For that the best way is to authorize using Service Accounts. Dont worry about it, the only thing you need to do is in the API console get a service account like this:
We will use this service account on our code.
Fourth, lets write some code, lets say upload an image to cloud storage.
For this code to work you must put your key generated in step 3 in assets folder, i named it "key.p12".
I don't recommend you to do this on your production version, since you will be giving out your key.
try{
httpTransport= new com.google.api.client.http.javanet.NetHttpTransport();
//agarro la key y la convierto en un file
AssetManager am = context.getAssets();
InputStream inputStream = am.open("key.p12"); //you should not put the key in assets in prod version.
//convert key into class File. from inputstream to file. in an aux class.
File file = UserProfileImageUploadHelper.createFileFromInputStream(inputStream,context);
//Google Credentianls
GoogleCredential credential = new GoogleCredential.Builder().setTransport(httpTransport)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
.setServiceAccountScopes(Collections.singleton(STORAGE_SCOPE))
.setServiceAccountPrivateKeyFromP12File(file)
.build();
String URI = "https://storage.googleapis.com/" + BUCKET_NAME+"/"+imagename+".jpg";
HttpRequestFactory requestFactory = httpTransport.createRequestFactory(credential);
GenericUrl url = new GenericUrl(URI);
//byte array holds the data, in this case the image i want to upload in bytes.
HttpContent contentsend = new ByteArrayContent("image/jpeg", byteArray );
HttpRequest putRequest = requestFactory.buildPutRequest(url, contentsend);
com.google.api.client.http.HttpResponse response = putRequest.execute();
String content = response.parseAsString();
Log.d("debug", "response is:"+response.getStatusCode());
Log.d("debug", "response content is:"+content);} catch (Exception e) Log.d("debug", "Error in user profile image uploading", e);}
This will upload the image to your cloud bucket.
For more info on the api check this link Cloud XML API
Firstly, You should get the below information by registering your application in the GCP console.
private final String pkcsFile = "xxx.json";//private key file
private final String bucketName = "your_gcp_bucket_name";
private final String projectId = "your_gcp_project_id";
Once you get the credentials, you should put the private key (.p12 or .json) in your assets folder. I'm using JSON format private key file. Also, you should update the image location to upload.
#RequiresApi(api = Build.VERSION_CODES.O)
public void uploadImageFile(String srcFileName, String newName) {
Storage storage = getStorage();
File file = new File(srcFileName);//Your image loaction
byte[] fileContent;
try {
fileContent = Files.readAllBytes(file.toPath());
} catch (IOException e) {
e.printStackTrace();
return;
}
if (fileContent == null || fileContent.length == 0)
return;
BlobInfo.Builder newBuilder = Blob.newBuilder(BucketInfo.of(bucketName), newName);
BlobInfo blobInfo = newBuilder.setContentType("image/png").build();
Blob blob = storage.create(blobInfo, fileContent);
String bucket = blob.getBucket();
String contentType = blob.getContentType();
Log.e("TAG", "Upload File: " + contentType);
Log.e("File ", srcFileName + " uploaded to bucket " + bucket + " as " + newName);
}
private Storage getStorage() {
InputStream credentialsStream;
Credentials credentials;
try {
credentialsStream = mContext.getAssets().open(pkcsFile);
credentials = GoogleCredentials.fromStream(credentialsStream);
} catch (IOException e) {
e.printStackTrace();
return null;
}
return StorageOptions.newBuilder()
.setProjectId(projectId).setCredentials(credentials)
.build().getService();
}