I am trying to use Google Drive Android API to read a file from Google drive, and I was trying to understand the example Google gives below. What I am confused about is that what is Drveid and EXISTING_FILE_ID? How do I get them? If I want to open a file by its name, how do I do that? Thanks!
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);
}
public class EditContentsAsyncTask extends ApiClientAsyncTask<DriveFile, Void, Boolean> {
public EditContentsAsyncTask(Context context) {
super(context);
}
#Override
protected Boolean doInBackgroundConnected(DriveFile... args) {
DriveFile file = args[0];
try {
DriveContentsResult driveContentsResult = file.open(
getGoogleApiClient(), DriveFile.MODE_WRITE_ONLY, null).await();
if (!driveContentsResult.getStatus().isSuccess()) {
return false;
}
DriveContents driveContents = driveContentsResult.getDriveContents();
OutputStream outputStream = driveContents.getOutputStream();
outputStream.write("Hello world".getBytes());
com.google.android.gms.common.api.Status status =
driveContents.commit(getGoogleApiClient(), null).await();
return status.getStatus().isSuccess();
} catch (IOException e) {
Log.e(TAG, "IOException while appending to the output stream", e);
}
return false;
}
#Override
protected void onPostExecute(Boolean result) {
if (!result) {
showMessage("Error while editing contents");
return;
}
showMessage("Successfully edited contents");
}
}
DriveId is defined here as: A canonical identifier for a Drive resource. The identifier can be converted to a String representation for storage using encodeToString() and then later converted back to the ID representation using decodeFromString(String). equals(Object) can be used to see if two different identifiers refer to the same resource.
EXISTING_FILE_ID in Google's drive api demo code refers to the saved file id of an existing file in drive. file Id is auto-generated.
check this SO link for more on how to get driveId/file id to use that file
You can get a file by its name but its better to use driveId as its unique.
Ok, here is how I did it. FileID is auto-generated when file was created. Once we have fileId. Below can be used to get the file.
Drive.DriveApi.fetchDriveId(getGoogleApiClient(), fileId).setResultCallback(idCallback);
Query can be used to get the FileId of files.
Query query = new Query.Builder().addFilter(Filters.eq(SearchableField.TITLE, fileName)).build();
Drive.DriveApi.query(getGoogleApiClient(), query).setResultCallback(metadataCallback);
At least the codes above were what Google did in its demo app.
Related
I am facing the issue in creating the file inside a folder , i created the separate file and separate folder in google drive but i can't create the file inside a folder in google drive
I have used the for creating the file inside the folder in google drive is posted below
public void onClickFolderInRootFlder(View view)
{
MetadataChangeSet changeSet = new MetadataChangeSet.Builder().setTitle("New CallLog folders").build();
Drive.DriveApi.getRootFolder(mGoogleApiClient).createFolder(
mGoogleApiClient, changeSet).setResultCallback(callback);
}
final ResultCallback<DriveFolder.DriveFolderResult> callback = new ResultCallback<DriveFolder.DriveFolderResult>() {
#Override
public void onResult(DriveFolder.DriveFolderResult result) {
if (!result.getStatus().isSuccess()) {
Toast.makeText(MainActivity.this,"Error while trying to create the folder",Toast.LENGTH_SHORT).show();
return;
}
Toast.makeText(MainActivity.this,"Created a folder with content: " +
result.getDriveFolder().getDriveId(),Toast.LENGTH_SHORT).show();
Drive.DriveApi.fetchDriveId(mGoogleApiClient, String.valueOf(result.getDriveFolder().getDriveId()))
.setResultCallback(idCallback);
}
};
final private ResultCallback<DriveApi.DriveIdResult> idCallback = new ResultCallback<DriveApi.DriveIdResult>() {
#Override
public void onResult(DriveApi.DriveIdResult result) {
if (!result.getStatus().isSuccess()) {
// showMessage("Cannot find DriveId. Are you authorized to view this file?");
Toast.makeText(MainActivity.this,"Cannot find DriveId. Are you authorized to view this file?",Toast.LENGTH_SHORT).show();
return;
}
DriveId mFolderDriveId = result.getDriveId();
Drive.DriveApi.newDriveContents(mGoogleApiClient)
.setResultCallback(driveContentsCallback);
}
};
final ResultCallback<DriveApi.DriveContentsResult> driveContentsCallback =
new ResultCallback<DriveApi.DriveContentsResult>() {
#Override
public void onResult(DriveApi.DriveContentsResult result) {
if (!result.getStatus().isSuccess()) {
// display an error saying file can't be opened
return;
}
else{
CreateFileOnGoogleDrive(result);
}
// DriveContents object contains pointers
// to the actual byte stream
DriveContents contents = result.getDriveContents();
}
};
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 World");
writer.close();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle("prabha")
.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(MainActivity.this,"Error while trying to create the file",Toast.LENGTH_SHORT).show();
return;
}
Toast.makeText(MainActivity.this,"Created a file with content: " +
result.getDriveFile().getDriveId(),Toast.LENGTH_SHORT).show();
}
};
I tried this method but the issue is occurring in the line
final private ResultCallback<DriveApi.DriveIdResult> idCallback = new ResultCallback<DriveApi.DriveIdResult>() {
#Override
public void onResult(DriveApi.DriveIdResult result) {
if (!result.getStatus().isSuccess()) {
// showMessage("Cannot find DriveId. Are you authorized to view this file?");
Toast.makeText(MainActivity.this,"Cannot find DriveId. Are you authorized to view this file?",Toast.LENGTH_SHORT).show();
return;
}
DriveId mFolderDriveId = result.getDriveId();
Drive.DriveApi.newDriveContents(mGoogleApiClient)
.setResultCallback(driveContentsCallback);
}
};
The result.getStatus.isSuccess is false is returning .Please help me how to create the file inside a folder in google drive.
You are calling
Drive.DriveApi.getRootFolder(mGoogleApiClient).createFile
which (unsurprisingly) creates a file in the Root Folder.
Instead you should call
DriveFolder.createFile
as described at https://developers.google.com/android/reference/com/google/android/gms/drive/DriveFolder.html#createFile(com.google.android.gms.common.api.GoogleApiClient,com.google.android.gms.drive.MetadataChangeSet,com.google.android.gms.drive.DriveContents)
Using the bellow snippet I am able to access folder which I have already created with the same app. I am using 'com.google.android.gms:play-services-drive:9.0.0' library and referring google drive sample on github. using the sample CreateFolderInFolderActivity.java I am able to create folder inside an existing folder. Instead of creating folder I need to create a file inside existing folder.
public class CreateFileInsideFolderActivity extends BaseDemoActivity {
private static final String TAG = "CreateFileActivity";
#Override
public void onConnected(Bundle connectionHint) {
super.onConnected(connectionHint);
Drive.DriveApi
.fetchDriveId(getGoogleApiClient(), "0B_cMuo4-XwcAZ3IzSG1jajFlWk0")
.setResultCallback(idCallback);
}
final ResultCallback<DriveApi.DriveIdResult> idCallback = new ResultCallback<DriveApi.DriveIdResult>() {
#Override
public void onResult(DriveApi.DriveIdResult result) {
if (!result.getStatus().isSuccess()) {
showMessage("Cannot find DriveId. Are you authorized to view this file?");
return;
}
DriveId driveId = result.getDriveId();
//showMessage("driveid" + driveId.getResourceId());
final DriveFolder folder = driveId.asDriveFolder();
//
// How to upload a file to this folder
//
}
Thanks #pinoyyid
I fount an example from wiki.workassis that I am sharing here. If anyone have better solution please share with me
#Override
public void onConnected(Bundle connectionHint) {
super.onConnected(connectionHint);
Drive.DriveApi.newDriveContents(getGoogleApiClient()).setResultCallback(driveContentsCallback);
}
In result call back
final private ResultCallback<DriveApi.DriveContentsResult> driveContentsCallback = new ResultCallback<DriveApi.DriveContentsResult>() {
#Override
public void onResult(DriveApi.DriveContentsResult result) {
if (!result.getStatus().isSuccess()) {
showMessage("Error while trying to create new file contents");
return;
}
final DriveContents driveContents = result.getDriveContents();
// Perform I/O off the UI thread.
new Thread() {
#Override
public void run() {
OutputStream outputStream = driveContents.getOutputStream();
try {
InputStream inputStream = getContentResolver().openInputStream(imageUri);
if (inputStream != null) {
byte[] data = new byte[1024];
while (inputStream.read(data) != -1) {
outputStream.write(data);
}
inputStream.close();
}
outputStream.close();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle("New file")
.setMimeType("image/jpg")
.setStarred(true).build();
DriveApi.DriveIdResult exFolderResult = Drive.DriveApi
.fetchDriveId(getGoogleApiClient(), ExistingFolderID)
.await();
if (!exFolderResult.getStatus().isSuccess()) {
showMessage("Cannot find DriveId. Are you authorized to view this file?");
return;
}
DriveId driveId = exFolderResult.getDriveId();
//showMessage("driveid" + driveId.getResourceId());
final DriveFolder folder = driveId.asDriveFolder();
// create a file on root folder
folder.createFile(getGoogleApiClient(), changeSet, driveContents)
.setResultCallback(fileCallback);
}
}.start();
}
};
I am using the default file picker for getting Image url
refer : http://wiki.workassis.com/google-drive-android-api-upload-file-to-existing-folder/
for file picker : http://wiki.workassis.com/android-create-a-file-picker/
i am building an android app using google drive api.First i get resourceId of a folder ("shared with me with edit access") using files:list rest api.i get Folder
Id="0B6DwkfjCNXHYflJVOGdnbFU0QkxfU25NbHV5UjNfVmNlNWhhcllnbktmNDNReEhuMm83X0E"
public class MainActivity extends BaseDemoActivity {
#Override
public void onConnected(Bundle connectionHint) {
super.onConnected(connectionHint);
Drive.DriveApi.fetchDriveId(getGoogleApiClient(),"0B6DwkfjCNXHYflJVOGdnbFU0QkxfU25NbHV5UjNfVmNlNWhhcllnbktmNDNReEhuMm83X0E")
.setResultCallback(idCallback);
}
final private 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;
}
Log.i("driveId is: ", result.toString());
showMessage("Drive Id is: "+result.toString());
DriveId driveId = result.getDriveId();
Log.i("drive Id is",driveId.toString());
//showMessage("Drive Id is: " + driveId.toString());
/* DriveFile ff = driveId.asDriveFile();
ff.getMetadata(getGoogleApiClient()).setResultCallback(metadataRetrievedCallback);
*/
/* DriveFolder folder = driveId.asDriveFolder();
Query query = new Query.Builder()
.addFilter(Filters.eq(SearchableField.MIME_TYPE, "text/plain"))
.build();
folder.queryChildren(getGoogleApiClient(), query)
.setResultCallback(metadataCallback);*/
}
};
ResultCallback<DriveResource.MetadataResult> metadataRetrievedCallback = new
ResultCallback<DriveResource.MetadataResult>() {
#Override
public void onResult(DriveResource.MetadataResult result) {
if (!result.getStatus().isSuccess()) {
showMessage("Problem while trying to fetch metadata");
return;
}
Metadata metadata = result.getMetadata();
showMessage("Metadata succesfully fetched. Title: " + metadata.getTitle());
}
};
}
i set up the project as described in google drive android api.but when i run my code i am getting in callback error "Cannot find DriveId. Are you authorized to view this file?"
I have spent too much time on this so I would like to ask about it. I want to create and upload google spreadsheet using android. I know that I should use Drive API to do this. I know how to create file using this API(even excel file) but when setMimeType is set to application/vnd.google-apps.spreadsheet I receive an error on the device: Error while trying to create the file.
#Override
public void onConnected(Bundle connectionHint) {
super.onConnected(connectionHint);
// create new contents resource
Drive.DriveApi.newDriveContents(getGoogleApiClient())
.setResultCallback(driveContentsCallback);
}
final private ResultCallback<DriveContentsResult> driveContentsCallback = new
ResultCallback<DriveContentsResult>() {
#Override
public void onResult(DriveContentsResult result) {
if (!result.getStatus().isSuccess()) {
showMessage("Error while trying to create new file contents");
return;
}
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 World!");
writer.write("Hello World!");
writer.close();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle("Orders")
.setMimeType("application/vnd.google-apps.spreadsheet")
.setStarred(true).build();
// create a file on root folder
Drive.DriveApi.getRootFolder(getGoogleApiClient())
.createFile(getGoogleApiClient(), changeSet, driveContents)
.setResultCallback(fileCallback);
}
}.start();
}
};
final private ResultCallback<DriveFileResult> fileCallback = new
ResultCallback<DriveFileResult>() {
#Override
public void onResult(DriveFileResult result) {
if (!result.getStatus().isSuccess()) {
showMessage("Error while trying to create the file");
return;
}
showMessage("Created a file with content: " + result.getDriveFile().getDriveId());
storeId(result.getDriveFile().getDriveId());
kill_activity();
}
};v
The GDAA does not currently support creation Google Docs files. You will have to use the Google Drive REST API in your Android application to do this.
#user3212019, You can upload a excel spread sheet in google drive from your android app, just follow as below.
I think you aware of Quick Start on Google Android site.
Now create a excel sheet by using jxl jar library
Now follow the Start Integrating Google Sign-In and Integrate Google SignIn with Drive scope (Drive.SCOPE_FILE) in your app.
Now final and last copy paste below activity code in your activity and then give a excel sheet path in saveFileToDrive(file_path) method.
public class UploadFileInGoogleDriveActivity extends Activity {
private static final String TAG = "tejadroid-quickstart";
private static final int REQUEST_CODE_SIGN_IN = 0;
private GoogleSignInClient mGoogleSignInClient;
private DriveClient mDriveClient;
private DriveResourceClient mDriveResourceClient;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
signIn();
}
/**
* Start sign in activity.
*/
private void signIn() {
Log.i(TAG, "Start sign in");
mGoogleSignInClient = buildGoogleSignInClient();
startActivityForResult(mGoogleSignInClient.getSignInIntent(), REQUEST_CODE_SIGN_IN);
}
/**
* Build a Google SignIn client.
*/
private GoogleSignInClient buildGoogleSignInClient() {
GoogleSignInOptions signInOptions =
new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestScopes(Drive.SCOPE_FILE)
.build();
return GoogleSignIn.getClient(this, signInOptions);
}
#Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQUEST_CODE_SIGN_IN:
Log.i(TAG, "Sign in request code");
// Called after user is signed in.
if (resultCode == RESULT_OK) {
Log.i(TAG, "Signed in successfully.");
// Use the last signed in account here since it already have a Drive scope.
mDriveClient = Drive.getDriveClient(this, GoogleSignIn.getLastSignedInAccount(this));
// Build a drive resource client.
mDriveResourceClient =
Drive.getDriveResourceClient(this, GoogleSignIn.getLastSignedInAccount(this));
// Excel Sheet path from SD card
final String filePath = "/storage/emulated/0/Expense Manager/ExpenseReport/ExpenseDiary.xls";
saveFileToDrive(filePath);
}
break;
}
}
/**
* Create a new file and save it to Drive.
*/
private void saveFileToDrive(final String filePath) {
// Start by creating a new contents, and setting a callback.
Log.i(TAG, "Creating new contents.");
mDriveResourceClient
.createContents()
.continueWithTask(
new Continuation<DriveContents, Task<Void>>() {
#Override
public Task<Void> then(#NonNull Task<DriveContents> task) throws Exception {
return createFileIntentSender(task.getResult(), new File(filePath));
}
})
.addOnFailureListener(
new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.w(TAG, "Failed to create new contents.", e);
}
});
}
/**
* Creates an {#link IntentSender} to start a dialog activity with configured {#link
* CreateFileActivityOptions} for user to create a new photo in Drive.
*/
private Task<Void> createFileIntentSender(DriveContents driveContents, File file) throws Exception {
Log.i(TAG, "New contents created.");
OutputStream outputStream = driveContents.getOutputStream();
InputStream in = new FileInputStream(file);
try {
try {
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
outputStream.write(buf, 0, len);
}
} finally {
outputStream.close();
}
} finally {
in.close();
}
// Create the initial metadata - MIME type and title.
// Note that the user will be able to change the title later.
MetadataChangeSet metadataChangeSet =
new MetadataChangeSet.Builder()
.setMimeType("application/vnd.ms-excel")
.setTitle("ExcelSheet.xls")
.build();
// Set up options to configure and display the create file activity.
CreateFileActivityOptions createFileActivityOptions =
new CreateFileActivityOptions.Builder()
.setInitialMetadata(metadataChangeSet)
.setInitialDriveContents(driveContents)
.build();
return mDriveClient
.newCreateFileActivityIntentSender(createFileActivityOptions)
.continueWith(
new Continuation<IntentSender, Void>() {
#Override
public Void then(#NonNull Task<IntentSender> task) throws Exception {
startIntentSenderForResult(task.getResult(), REQUEST_CODE_CREATOR, null, 0, 0, 0);
return null;
}
});
}
}
Just debug app and look in to Google Drive there your file exist in root folder of drive.
I want to read the i have written on a file in Appfolder.but i am not able to read that my app is crashes when i try to read that from file.i have created the file in App folder successfully.i am using the below code so please tell if i am doing anything wrong.The error which is coming while i run this code is invalid drive id.i am getting that drive id by this:
result.getDriveFile().getDriveId().encodeToString()
where result is drivefileresult. May I know what is the correct way to achieve my objective?
public class Fifth extends BaseDemoActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fifth);
}
#Override
public void onConnected(Bundle connectionHint) {
super.onConnected(connectionHint);
// create new contents resource
Drive.DriveApi.newContents(getGoogleApiClient())
.setResultCallback(contentsCallback);
}
final private ResultCallback<ContentsResult> contentsCallback = new
ResultCallback<ContentsResult>() {
#Override
public void onResult(ContentsResult result) {
if (!result.getStatus().isSuccess()) {
showMessage("Error while trying to create new file contents");
return;
}
// Get an output stream for the contents.
OutputStream outputStream = result.getContents().getOutputStream();
// Write the bitmap data from it.
String data="hello world. this is sample";
byte[] bytes = data.getBytes();
// ByteArrayOutputStream bitmapStream = new ByteArrayOutputStream();
// image.compress(Bitmap.CompressFormat.PNG, 100, bitmapStream);
try {
Log.i("Success", "able to write file contents.");
outputStream.write(bytes);
} catch (IOException e1) {
Log.i("Failier", "Unable to write file contents.");
}
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle("appdatafolder.txt")
.setMimeType("text/plain")
.build();
Drive.DriveApi.getAppFolder(getGoogleApiClient())
.createFile(getGoogleApiClient(), changeSet, result.getContents())
.setResultCallback(fileCallback);
}
};
final private ResultCallback<DriveFileResult> fileCallback = new
ResultCallback<DriveFileResult>() {
#Override
public void onResult(DriveFileResult result) {
if (!result.getStatus().isSuccess()) {
showMessage("Error while trying to create the file");
return;
}
showMessage("Created a file in App Folder: "
+ result.getDriveFile().getDriveId());
Log.i("Drioved_ID", result.getDriveFile().getDriveId().encodeToString());
}
};
}
Unfortunately I don't have time to analyze your code but can offer a segment that does essentially the same. Try it.
GoogleApiClient gac = getGoogleApiClient();
DriveFolder dfl = Drive.DriveApi.getAppFolder(gac)
String title = "appdatafolder.txt";
String mime = "text/plain";
byte[] buff = ("hello world. this is sample").getBytes();
createFile(gac, dfl, title, mime, buff);
void createFile(final GoogleApiClient gac, final DriveFolder fldr,
final String name, final String mime, final byte[] buff) {
Thread t = new Thread(new Runnable() {
#Override public void run() {
try {
ContentsResult rslt = Drive.DriveApi.newContents(gac).await();
if (rslt.getStatus().isSuccess()) {
Contents cont = rslt.getContents();
cont.getOutputStream().write(buff);
MetadataChangeSet meta =
new MetadataChangeSet.Builder().setTitle(name).setMimeType(mime).build();
DriveFile df = fldr.createFile(gac, meta, cont).await().getDriveFile();
Log.i("X", ""+ df.getDriveId().encodeToString());
}
} catch (Exception e) {}
}
});
t.start();
}
... and here is how you read it back:
void getFileIs(final GoogleApiClient gac, final DriveId drvId) {
Thread t = new Thread(new Runnable() {
#Override public void run() {
try {
DriveFile df = Drive.DriveApi.getFile(gac, drvId);
ContentsResult rslt = df.openContents(gac, DriveFile.MODE_READ_ONLY, null).await();
if (rslt.getStatus().isSuccess()){
InputStream is = rslt.getContents().getInputStream();
}
} catch (Exception e) {}
}
});
t.start();
}
After days of searching for a good example, I found the Google I/O app on GitHub has excellent utility methods to create, update and read files from Drive. They use the AppFolder as well.