I wanted to download file from google drive.
For this I have implemented in Google Drive SDk and used the following method.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_CODE_OPENER:
if (resultCode == RESULT_OK) {
DriveId driveId = (DriveId) data.getParcelableExtra(
OpenFileActivityBuilder.EXTRA_RESPONSE_DRIVE_ID);
}
finish();
break;
default:
super.onActivityResult(requestCode, resultCode, data);
}
}
I also tried using output stream but not able to save data to a file.
I have tried searching around this, but couldn't find any useful link which can guide me how to download and store file.
IMO, you should read some useful links below:
Google Drive APIs Android - Guides - Working with File Contents
Google Drive Android API Demos at GitHub
Then, please refer to the following snippets, of course when getting the input stream, you can save it to a file in your device instead of printing to Logcat.
public class GoogleDriveActivity extends AppCompatActivity
implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
...
#Override
protected void onCreate(Bundle savedInstanceState) {
...
mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
mProgressBar.setMax(100);
}
#Override
protected void onResume() {
super.onResume();
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
mGoogleApiClient.connect();
}
#Override
protected void onPause() {
if (mGoogleApiClient != null) {
mGoogleApiClient.disconnect();
}
super.onPause();
}
#Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
if (requestCode == RC_OPENER && resultCode == RESULT_OK) {
mSelectedFileDriveId = data.getParcelableExtra(
OpenFileActivityBuilder.EXTRA_RESPONSE_DRIVE_ID);
}
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult result) {
// Called whenever the API client fails to connect.
// Do something...
}
#Override
public void onConnected(#Nullable Bundle bundle) {
// If there is a selected file, open its contents.
if (mSelectedFileDriveId != null) {
open();
return;
}
// Let the user pick a file...
IntentSender intentSender = Drive.DriveApi
.newOpenFileActivityBuilder()
.setMimeType(new String[]{"video/mp4", "image/jpeg", "text/plain"})
.build(mGoogleApiClient);
try {
startIntentSenderForResult(intentSender, RC_OPENER, null, 0, 0, 0);
} catch (IntentSender.SendIntentException e) {
Log.e(TAG, "Unable to send intent", e);
}
}
#Override
public void onConnectionSuspended(int i) {
}
private void open() {
mProgressBar.setProgress(0);
DriveFile.DownloadProgressListener listener = new DriveFile.DownloadProgressListener() {
#Override
public void onProgress(long bytesDownloaded, long bytesExpected) {
// Update progress dialog with the latest progress.
int progress = (int) (bytesDownloaded * 100 / bytesExpected);
Log.d(TAG, String.format("Loading progress: %d percent", progress));
mProgressBar.setProgress(progress);
}
};
DriveFile driveFile = mSelectedFileDriveId.asDriveFile();
driveFile.open(mGoogleApiClient, DriveFile.MODE_READ_ONLY, listener)
.setResultCallback(driveContentsCallback);
mSelectedFileDriveId = null;
}
private final ResultCallback<DriveApi.DriveContentsResult> driveContentsCallback =
new ResultCallback<DriveApi.DriveContentsResult>() {
#Override
public void onResult(#NonNull DriveApi.DriveContentsResult result) {
if (!result.getStatus().isSuccess()) {
Log.w(TAG, "Error while opening the file contents");
return;
}
Log.i(TAG, "File contents opened");
// Read from the input stream an print to LOGCAT
DriveContents driveContents = result.getDriveContents();
BufferedReader reader = new BufferedReader(new InputStreamReader(driveContents.getInputStream()));
StringBuilder builder = new StringBuilder();
String line;
try {
while ((line = reader.readLine()) != null) {
builder.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
String contentsAsString = builder.toString();
Log.i(TAG, contentsAsString);
// Close file contents
driveContents.discard(mGoogleApiClient);
}
};
}
Related
I have implemented Google Drive with my Android application. I am able to view all my files in the app. Now I want to implement delete and update of google drive files.
This is my current code:
public void OpenFileFromGoogleDrive() {
IntentSender intentSender = Drive.DriveApi
.newOpenFileActivityBuilder()
.setMimeType(new String[]{"text/plain", "text/html"})
.build(mGoogleApiClient);
try {
startIntentSenderForResult(
intentSender, REQUEST_CODE_OPENER, null, 0, 0, 0);
}
catch (SendIntentException e) {
Log.w(TAG, "Unable to send intent", e);
}
}
final ResultCallback<DriveContentsResult> driveContentsCallback =
new ResultCallback<DriveContentsResult>() {
#Override
public void onResult(DriveContentsResult result) {
if (result.getStatus().isSuccess()) {
OpenFileFromGoogleDrive();
}
}
};
#Override
protected void onActivityResult(final int requestCode,
final int resultCode, final Intent data) {
switch (requestCode) {
case REQUEST_CODE_OPENER:
if (resultCode == RESULT_OK) {
mFileId = (DriveId) data.getParcelableExtra(
OpenFileActivityBuilder.EXTRA_RESPONSE_DRIVE_ID);
Log.e("file id", mFileId.getResourceId() + ""); // 0B-KGM98PVf2SdkdYTFRXZlNjSjg
/*String url = "https://drive.google.com/open?id="+ mFileId.getResourceId();
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);*/
options();
}
break;
default:
super.onActivityResult(requestCode, resultCode, data);
break;
}
}
How to delete and update files using DriveId?
You can achieve this doing:
driveFile = Drive.DriveApi.getFile(mGoogleApiClient,
DriveId.decodeFromString(driveIdStr));
// Call to delete file.
driveFile.delete(mGoogleApiClient).setResultCallback(deleteCallback);
Check google drive documentation for more info https://developers.google.com/drive/android/trash?hl=es-419
In addition to #AndroidRuntimeException's answer, you may want to check this Working with File Contents documentation and this Google Drive Android API Demos.
To edit a file:
/**
* An activity to illustrate how to edit contents of a Drive file.
*/
public class EditContentsActivity extends BaseDemoActivity {
private static final String TAG = "EditContentsActivity";
#Override
public void onConnected(Bundle connectionHint) {
super.onConnected(connectionHint);
final ResultCallback<DriveIdResult> idCallback = new ResultCallback<DriveIdResult>() {
#Override
public void onResult(DriveIdResult result) {
if (!result.getStatus().isSuccess()) {
showMessage("Cannot find DriveId. Are you authorized to view this file?");
return;
}
DriveId driveId = result.getDriveId();
DriveFile file = driveId.asDriveFile();
new EditContentsAsyncTask(EditContentsActivity.this).execute(file);
}
};
Drive.DriveApi.fetchDriveId(getGoogleApiClient(), EXISTING_FILE_ID)
.setResultCallback(idCallback);
}
To delete a file:
/**
* An activity to illustrate how to delete contents of a Drive file.
*/
driveFile = Drive.DriveApi.getFile(mGoogleApiClient,
DriveId.decodeFromString(driveIdStr));
// Call to delete file.
driveFile.delete(mGoogleApiClient).setResultCallback(deleteCallback);
Hope this helps!
Main task is to get users Age and Gender on current device (for ads targeting).
I knew that this question could be possible duplicate, but none of posted answers didn't help me.
From my code i'm getting correct users Name but birthday = null, gender = 0.
Tested on my test device with valid Google Account with public Birthday and Gender.
private static final int RC_SIGN_IN = 1009;
private GoogleApiClient googleApiClient;
private int connectionFailedCounter;
private void googleSignIn() {
googleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addScope(Plus.SCOPE_PLUS_LOGIN)
.addScope(Plus.SCOPE_PLUS_PROFILE)
.addApi(Plus.API)
.build();
googleApiClient.connect();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
//...
googleSignIn();
}
#Override
protected void onStart() {
super.onStart();
if (googleApiClient == null)
googleSignIn();
else if (!googleApiClient.isConnecting())
googleApiClient.connect();
}
#Override
protected void onStop() {
if (googleApiClient != null && googleApiClient.isConnected())
googleApiClient.disconnect();
super.onStop();
}
#Override
public void onConnected(#Nullable Bundle bundle) {
Toast.makeText(this, "google+ connected", Toast.LENGTH_LONG).show();
Person currentPerson = Plus.PeopleApi.getCurrentPerson(googleApiClient);
if (currentPerson != null) {
//NotificationManager is my own class,
//sendNotification(Context context, Class classToOpenOnClick, String title, String message)
NotificationManager.sendNotification(this, null, currentPerson.getName().getFamilyName(),
String.format(Locale.getDefault(), "bir = %s, gen = %d", currentPerson.getBirthday(), currentPerson.getGender()));
}
else Toast.makeText(this, "getCurrentPerson = null", Toast.LENGTH_LONG).show();
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Log.e(TAG, "connection failed (" + connectionResult.getErrorCode() + ")");
Toast.makeText(this, "google+ failed", Toast.LENGTH_LONG).show();
if (connectionResult.hasResolution()) {
try {
connectionFailedCounter++;
if (connectionFailedCounter < 2)
connectionResult.startResolutionForResult(this, RC_SIGN_IN);
} catch (IntentSender.SendIntentException e) {
}
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == RC_SIGN_IN) {
Person currentPerson = Plus.PeopleApi.getCurrentPerson(googleApiClient);
NotificationManager.sendNotification(this, null, currentPerson.getName().getFamilyName(),
String.format(Locale.getDefault(), "bir = %s, gen = %d", currentPerson.getBirthday(), currentPerson.getGender()));
if (!googleApiClient.isConnected())
googleApiClient.connect();
}
}
}
I'm making an app that'll allows me to get a google drive files to my app. I have managed to open the google drive and to download a file to my phone but that's not the point to this app. I'm trying to open the files from the app, not to open the Google Drive. Any help?
Note: I've already registered my app at Google cloud console and all of the stuff there.
Here's the code. But as i said i don't need to open the Google Drive, i need to get files from there in my app.
#Override
protected void onResume() {
super.onResume();
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
.addConnectionCallbacks((GoogleApiClient.ConnectionCallbacks) this)
.addOnConnectionFailedListener((GoogleApiClient.OnConnectionFailedListener) this)
.build();
}
mGoogleApiClient.connect();
}
#Override
protected void onStop() {
super.onStop();
if (mGoogleApiClient != null) {
// disconnect Google API client connection
mGoogleApiClient.disconnect();
}
super.onPause();
}
public void onConnectionFailed(ConnectionResult result) {
// Called whenever the API client fails to connect.
Log.i(TAG, "GoogleApiClient connection failed: " + result.toString());
if (!result.hasResolution()) {
// show the localized error dialog.
GoogleApiAvailability.getInstance().getErrorDialog(this, result.getErrorCode(), 0).show();
return;
}
try {
result.startResolutionForResult(this, REQUEST_CODE_RESOLUTION);
} catch (IntentSender.SendIntentException e) {
Log.e(TAG, "Exception while starting resolution activity", e);
}
}
public void onConnected(Bundle connectionHint) {
Toast.makeText(getApplicationContext(), "Connected", Toast.LENGTH_LONG).show();
}
public void onConnectionSuspended(int cause) {
Log.i(TAG, "GoogleApiClient connection suspended");
}
public void onClickCreateMethod(View view){
fileOperation = true;
// create new contents resource
Drive.DriveApi.newDriveContents(mGoogleApiClient)
.setResultCallback(driveContentsCallback);
}
public void onClickOpenFileMethod(View view){
fileOperation = false;
// create new contents resource
Drive.DriveApi.newDriveContents(mGoogleApiClient)
.setResultCallback(driveContentsCallback);
}
/**
* Open list of folder and file of the Google Drive
*/
public void OpenFileFromGoogleDrive(){
IntentSender intentSender = Drive.DriveApi
.newOpenFileActivityBuilder()
.setMimeType(new String[] { "text/plain", "text/html" })
.build(mGoogleApiClient);
try {
startIntentSenderForResult(
intentSender, REQUEST_CODE_OPENER, null, 0, 0, 0);
} catch (IntentSender.SendIntentException e) {
Log.w(TAG, "Unable to send intent", e);
}
}
final ResultCallback<DriveApi.DriveContentsResult> driveContentsCallback =
new ResultCallback<DriveApi.DriveContentsResult>() {
#Override
public void onResult(DriveApi.DriveContentsResult result) {
if (result.getStatus().isSuccess()) {
if (fileOperation == true) {
CreateFileOnGoogleDrive(result);
} else {
OpenFileFromGoogleDrive();
}
}
}
};
public void CreateFileOnGoogleDrive(DriveApi.DriveContentsResult result){
final DriveContents driveContents = result.getDriveContents();
// Perform I/O off the UI thread.
new Thread() {
#Override
public void run() {
// write content to DriveContents
OutputStream outputStream = driveContents.getOutputStream();
Writer writer = new OutputStreamWriter(outputStream);
try {
writer.write("Hello abhay!");
writer.close();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle("abhaytest2")
.setMimeType("text/plain")
.setStarred(true).build();
// create a file in root folder
Drive.DriveApi.getRootFolder(mGoogleApiClient)
.createFile(mGoogleApiClient, changeSet, driveContents)
.setResultCallback(fileCallback);
}
}.start();
}
final private ResultCallback<DriveFolder.DriveFileResult> fileCallback = new
ResultCallback<DriveFolder.DriveFileResult>() {
#Override
public void onResult(DriveFolder.DriveFileResult result) {
if (result.getStatus().isSuccess()) {
Toast.makeText(getApplicationContext(), "file created: "+""+
result.getDriveFile().getDriveId(), Toast.LENGTH_LONG).show();
}
return;
}
};
#Override
protected void onActivityResult(final int requestCode,
final int resultCode, final Intent data) {
switch (requestCode) {
case REQUEST_CODE_OPENER:
if (resultCode == RESULT_OK) {
mFileId = (DriveId) data.getParcelableExtra(
OpenFileActivityBuilder.EXTRA_RESPONSE_DRIVE_ID);
Log.e("file id", mFileId.getResourceId() + "");
String url = "https://drive.google.com/open?id=" + mFileId.getResourceId();
new DownloadFileFromURL().execute(url);
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
DriveFile googleDriveFile = Drive.DriveApi.getFile(mGoogleApiClient, driveId);
DriveResource.MetadataResult mdRslt = googleDriveFile.getMetadata(mGoogleApiClient).await();
if(mdRslt!= null && mdRslt.getStatus().isSuccess()){
mdRslt.getMetadata().getTitle();
System.out.println("The title is : " + driveId);
}
}
break;
default:
super.onActivityResult(requestCode, resultCode, data);
break;
}
}
public Context getAppContext() {
return appContext;
}
So, before android 6 marshmallow release, google + sign in worked perfectly. After release, Im having issues like permissions, onConnectionFailed, etc... Does anybody has a solution how to fix this? Im calling google sign in methods from fragment. Here is the code:
Fragment:
#Override
public void onConnected(Bundle bundle) {
Log.d("GoogleApiClient", "onConnected");
mShouldResolve = false;
new RetrieveTokenTask().execute(Plus.AccountApi.getAccountName(mGoogleApiClient));
}
#Override
public void onConnectionSuspended(int i) {
Log.d("GoogleApiClient", "onConnectionSuspended " + String.valueOf(i));
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.d("GoogleApiClient", "onConnectionFailed");
Log.d("GoogleApiCLient", connectionResult.toString());
ViewUtils.hideProgressDialog();
if (!mIsResolving && mShouldResolve) {
if (connectionResult.hasResolution()) {
try {
connectionResult.startResolutionForResult(getActivity(), RC_SIGN_IN);
mIsResolving = true;
} catch (IntentSender.SendIntentException e) {
Log.e("LoginFragment", "Could not resolve ConnectionResult.", e);
mIsResolving = false;
mGoogleApiClient.connect();
}
}
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.i("RequestCode", String.valueOf(requestCode));
Log.i("ResultCode", String.valueOf(resultCode));
try {
Log.i("Intent", data.getAction());
} catch (Exception e) {
}
if (requestCode == RC_SIGN_IN) {
// If the error resolution was not successful we should not resolve further.
ViewUtils.showProgressDialog(getActivity(), getActivity().getResources().getString(R.string.loading_dialog_str));
if (resultCode != getActivity().RESULT_OK) {
mShouldResolve = false;
}
mIsResolving = false;
mGoogleApiClient.connect();
if (mGoogleApiClient.isConnected()) {
new RetrieveTokenTask().execute(Plus.AccountApi.getAccountName(mGoogleApiClient));
}
} else {
//facebook
Log.d("Login", "FaceBook");
mCallbackManagerFacebook.onActivityResult(requestCode, resultCode, data);
}
}
private class RetrieveTokenTask extends AsyncTask<String, Void, String> {
private static final String TAG = "RetrieveAccessToken";
private static final int REQ_SIGN_IN_REQUIRED = 55664;
#Override
protected String doInBackground(String... params) {
String accountName = params[0];
String scopes = "oauth2:profile";
String token = null;
try {
token = GoogleAuthUtil.getToken(getActivity(), accountName, scopes);
} catch (IOException e) {
Log.e(TAG, e.getMessage());
} catch (UserRecoverableAuthException e) {
startActivityForResult(e.getIntent(), REQ_SIGN_IN_REQUIRED);
} catch (GoogleAuthException e) {
Log.e(TAG, e.getMessage());
}
return token;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Log.d("Token", "Token Value: " + s);
if (s == null) {
ViewUtils.hideProgressDialog();
ViewUtils.showToastMessage(getActivity(), getActivity().getResources().getString(R.string.login_error));
} else {
loginGoogleUser(s);
}
if (mGoogleApiClient.isConnected()) {
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
mGoogleApiClient.disconnect();
}
}
}
and activities on result:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
LoginFragment loginFragment = (LoginFragment) getSupportFragmentManager().findFragmentByTag("MyProfileFragment");
if (loginFragment != null) {
loginFragment.onActivityResult(requestCode, resultCode, data);
}
}
Ok, so, first of all, you need to change all of your dependencies of google play services to 8.1.0, also, build.gradle to the newest version, targeted sdk 23, comiled version 23, etc. So, basicaly, check your gradle. After that, you need to change your mGoogleApiClient to :
mGoogleApiClient = new GoogleApiClient.Builder(getActivity()).addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Plus.API)
.addScope(new Scope(Scopes.PROFILE))
.addScope(new Scope(Scopes.EMAIL))
.addScope(new Scope(Scopes.PLUS_LOGIN))
.addScope(new Scope(Scopes.PLUS_ME))
.build();
mGoogleApiClient.connect();
And finally, you need to include permissions you need for sdk>= 23. To do that, create
private static String ACCOUNT_PERMISSIONS[] = new String[]{
Manifest.permission.GET_ACCOUNTS
};
Here is a good tutorial on how to get permissions for sdk >= 23:
https://github.com/googlesamples/android-RuntimePermissions
I am working on an android app, which should be able to read a spreadsheet from google drive. However, every time when I try to open a file from google drive I get following message from the DriveContentsResult: "No content is available for this file".
Here is my code, after I got the authorization for google drive via the GoogleApiClient:
private static final int REQUEST_RESOLVE_ERROR = 1001;
public static final int REQUEST_CODE_OPENER = 1002;
private DriveId mSelectedFileDriveId;
public GoogleApiClient mGoogleApiClient;
public void getGoogleDriveFile(View view){
if(mGoogleApiClient.isConnected()){
IntentSender intentSender = Drive.DriveApi
.newOpenFileActivityBuilder()
.setMimeType(new String[] {"application/vnd.google-apps.spreadsheet"})
.build(mGoogleApiClient);
try {
startIntentSenderForResult(intentSender, REQUEST_CODE_OPENER, null, 0, 0, 0);
} catch (SendIntentException e) {
Log.d(TAG, "Unable to send intent" + e);
}
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d(TAG, "onActivityResult");
if (requestCode == REQUEST_RESOLVE_ERROR) {
...
} else if(requestCode == REQUEST_CODE_OPENER){
if(resultCode == RESULT_OK){
mSelectedFileDriveId = (DriveId) data.getParcelableExtra(OpenFileActivityBuilder.EXTRA_RESPONSE_DRIVE_ID);
if(mSelectedFileDriveId != null){
open();
}
}
}
}
private void open() {
Drive.DriveApi.getFile(mGoogleApiClient, mSelectedFileDriveId)
.open(mGoogleApiClient, DriveFile.MODE_READ_ONLY, null)
.setResultCallback(driveContentsCallback);
}
private ResultCallback<DriveContentsResult> driveContentsCallback =
new ResultCallback<DriveContentsResult>() {
#Override
public void onResult(DriveContentsResult result) {
if (!result.getStatus().isSuccess()) {
Log.d(TAG, "Error while opening the file contents " + result.getStatus().getStatusMessage());
return;
}
DriveContents contents = result.getDriveContents();
}
};
Content here refers to binary content. Google Spreadsheets (and the other Google Docs types) are not stored as binary content. The Android-specific API doesn't currently support reading Spreadsheet contents.
Using the RESTful API, you can get it in a binary format like csv using the ExportLinks.
use the "google spreadsheets api" (REST) not drive api.