I am facing the issue in uploading the list of audio to google drive.
I can upload the single audio file from a directory but i tried to upload the list of audio files is failed.
This is the path for the single audio file
final String path = new String(Environment.getExternalStorageDirectory() + "/CallLogs/Yaendi Yaendi.mp3");
How to upload the all the audio files in the CallLogs directory.
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();
final String path = new String(Environment.getExternalStorageDirectory() + "/CallLogs/Yaendi Yaendi.mp3");
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(new File(path));
} catch (FileNotFoundException e) {
showErrorDialog();
e.printStackTrace();
}
byte[] buf = new byte[1024];
int bytesRead;
try {
if (inputStream != null) {
while ((bytesRead = inputStream.read(buf)) > 0) {
outputStream.write(buf, 0, bytesRead);
}
}
} catch (IOException e) {
showErrorDialog();
e.printStackTrace();
}
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle("callLog")
.setMimeType("audio/mpeg")
.setStarred(true).build();
// create a file in root folder
Drive.DriveApi.getRootFolder(mGoogleApiClient)
.createFile(mGoogleApiClient, changeSet, driveContents).setResultCallback(fileCallback);
}
}.start();
Toast.makeText(getActivity(), "Created Successfully", Toast.LENGTH_SHORT).show();
}
The above code is for uploading the single audio file to google drive.
Please help me how to upload the all the files to the google drive.
Place your code inside AsyncTask's doInBackground() method.
I'm trying to solve this problem for a long time.
This part of code download image to GDrive.
public void UploadFileOnGoogleDrive(DriveContentsResult result){
final DriveContents driveContents=result.getDriveContents();
new Thread(){
#Override
public void run(){
OutputStream outputStream = driveContents.getOutputStream();
// Write the bitmap data from it.
String photo = "IMG23.jpg";
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM),photo);
Bitmap myBitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
ByteArrayOutputStream bitmapStream = new ByteArrayOutputStream();
int numOfbytes = myBitmap.getByteCount();
ByteBuffer buffer = ByteBuffer.allocate(numOfbytes);
myBitmap.copyPixelsToBuffer(buffer);
//imageInByte = buffer.array();
myBitmap.compress(Bitmap.CompressFormat.JPEG, 80, bitmapStream);
try {
outputStream.write(bitmapStream.toByteArray());
//outputStream.write(bitmapStream.toByteArray());
} catch (IOException e1) {
Log.i(TAG, "Unable to write file contents.");
}
MetadataChangeSet metadataChangeSet = new MetadataChangeSet.Builder()
.setMimeType("image/jpeg")
.setTitle(photo)
.setIndexableText(photo)
.build();
Log.d("Description",metadataChangeSet.getIndexableText());
Drive.DriveApi.getRootFolder(mGoogleApiClient)
.createFile(mGoogleApiClient, metadataChangeSet, driveContents).
setResultCallback(fileCallback);
//Drive.DriveApi.fetchDriveId(mGoogleApiClient,EXISTING_FILE_ID).setResultCallback(idfileCallback);
}
}.start();
}
Here I try to get file ID
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();
//DriveFile file = Drive.DriveApi.getFile(mGoogleApiClient, result.getDriveFile().getDriveId());
//file.getMetadata(mGoogleApiClient)
// .setResultCallback(metadataRetrievedCallback);
//String id=file.getDriveId().encodeToString();
Log.d("Fileidis",result.getDriveFile().getDriveId().encodeToString());
//final DriveId fileid = result.getDriveFile().getDriveId();
//DriveFile driveFile=Drive.DriveApi.getFile(mGoogleApiClient,fileid);
}
return;
}
};
But we find not fully ID in logs
07-06 15:15:50.939 19899-19899/valery.pankov.gdriveapp D/Fileidis: DriveId:CAESABj4XSCG9Oqbt1EoAA==
I thought set idResultCallback on UploadFileOnGoogleDrive but it was not successfull.
Thanks in advance
I have followed the Drive API guide (https://developer.android.com/google/play-services/drive.html) and my app now uploads photos smoothly, but I am now trying to upload videos (mp4) without success.
Does anyone know how to achieve this? The video is a newly generated mp4 file and I have the path to where it is stored on the device.
For pictures its done like this:
Drive.DriveApi.newDriveContents(mDriveClient).setResultCallback(
new ResultCallback<DriveContentsResult>() {
#Override
public void onResult(DriveContentsResult result) {
if (!result.getStatus().isSuccess()) {
Log.i(TAG, "Failed to create new contents.");
return;
}
OutputStream outputStream = result.getDriveContents().getOutputStream();
// Write the bitmap data from it.
ByteArrayOutputStream bitmapStream = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 80, bitmapStream);
try {
outputStream.write(bitmapStream.toByteArray());
} catch (IOException e1) {
Log.i(TAG, "Unable to write file contents.");
}
image.recycle();
outputStream = null;
String title = Shared.getOutputMediaFile(Shared.MEDIA_TYPE_IMAGE).getName();
MetadataChangeSet metadataChangeSet = new MetadataChangeSet.Builder()
.setMimeType("image/jpeg").setTitle(title)
.build();
Log.i(TAG, "Creating new pic on Drive (" + title + ")");
Drive.DriveApi.getFolder(mDriveClient,
mPicFolderDriveId).createFile(mDriveClient,
metadataChangeSet, result.getDriveContents());
}
});
}
What I am interested in is an alternative for a File, in this case pointing to a "video/mp4".
Without getting into much detail, just a few pointers:
Anything you want to upload (image, text, video,...) consists from
creating a file
setting metadata (title, MIME type, description,...)
setting content (byte stream)
The demo you mention does it with an image (JPEG bytestream) and you need to do it with video. So, the changes you need to implement are:
replace the "image/jpeg" MIME type with the one you need for your
video
copy your video stream (outputStream.write(bitmapStream.toByteArray())...)
to the content.
These are the only changes you need to make. Google Drive Android API doesn't care what is your content and metadata, it just grabs it a shoves it up to Google Drive.
In Google Drive, apps (web, android,...) read the metadata and content, and treat it accordingly.
So this my complete code how I achieved uploading a video.
Steps:
Fetch video file from uri(as in my case).
Get the byte array from bytearray outputstream as mentioned in the code
write the byte array to the ouputStream
the api will upload the file in the background
public class UploadVideo extends AppCompatActivity {
DriveClient mDriveClient;
DriveResourceClient mDriveResourceClient;
GoogleSignInAccount googleSignInAccount;
String TAG = "Drive";
private final int REQUEST_CODE_CREATOR = 2013;
Task<DriveContents> createContentsTask;
String uri;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_upload_video);
//Fetching uri or path from previous activity.
uri = getIntent().getStringExtra("uriVideo");
//Get previously signed in account.
googleSignInAccount = GoogleSignIn.getLastSignedInAccount(this);
if (googleSignInAccount != null) {
mDriveClient = Drive.getDriveClient(getApplicationContext(), googleSignInAccount);
mDriveResourceClient =
Drive.getDriveResourceClient(getApplicationContext(), googleSignInAccount);
}
else Toast.makeText(this, "Login again and retry", Toast.LENGTH_SHORT).show();
createContentsTask = mDriveResourceClient.createContents();
findViewById(R.id.uploadVideo).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
createFile();
}
});
}
private void createFile() {
// [START create_file]
final Task<DriveFolder> rootFolderTask = mDriveResourceClient.getRootFolder();
final Task<DriveContents> createContentsTask = mDriveResourceClient.createContents();
Tasks.whenAll(rootFolderTask, createContentsTask)
.continueWithTask(new Continuation<Void, Task<DriveFile>>() {
#Override
public Task<DriveFile> then(#NonNull Task<Void> task) throws Exception {
DriveFolder parent = rootFolderTask.getResult();
DriveContents contents = createContentsTask.getResult();
File file = new File(uri);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
FileInputStream fis = new FileInputStream(file);
for (int readNum; (readNum = fis.read(buf)) != -1;) {
baos.write(buf, 0, readNum);
}
OutputStream outputStream = contents.getOutputStream();
outputStream.write(baos.toByteArray());
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle("MyVideo.mp4") // Provide you video name here
.setMimeType("video/mp4") // Provide you video type here
.build();
return mDriveResourceClient.createFile(parent, changeSet, contents);
}
})
.addOnSuccessListener(this,
new OnSuccessListener<DriveFile>() {
#Override
public void onSuccess(DriveFile driveFile) {
Toast.makeText(Upload.this, "Upload Started", Toast.LENGTH_SHORT).show();
finish();
}
})
.addOnFailureListener(this, new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.e(TAG, "Unable to create file", e);
finish();
}
});
// [END create_file]
}
}
If you want to upload any file to Google Drive, then use the below code with Synchronization task, it will upload your file to Drive.
AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>()
{
#Override
protected String doInBackground(Void... params)
{
String file_type="video/mp4"; //write your file type
File body = new File();
File FileRtr = null;
body.setTitle(myfile.getName());
body.setMimeType(file_type);
body.setParents(Arrays.asList(new ParentReference().setId(LocationID))); //LocationID means the path in the drive e where you want to upload it
try
{
FileContent mediaContent = new FileContent(file_type, myfile);
FileRtr = mService.files().insert(body, mediaContent).execute();
if ( FileRtr != null)
{
System.out.println("File uploaded: " + FileRtr.getTitle());
}
}
catch (IOException e)
{
System.out.println("An error occurred: " + e.getMessage());
}
return null;
}
protected void onPostExecute(String token)
{
Toast.makeText(mContext, "Uploaded Successfuly",Toast.LENGTH_LONG).show();
}
};
task.execute();
Solution by OP.
Thanks to seanpj, turns out I was overestimating the difficulty of this, I now use this method to upload both images and videos:
/**
* Create a new file and save it to Drive.
*/
private void saveFiletoDrive(final File file, final String mime) {
// Start by creating a new contents, and setting a callback.
Drive.DriveApi.newDriveContents(mDriveClient).setResultCallback(
new ResultCallback<DriveContentsResult>() {
#Override
public void onResult(DriveContentsResult result) {
// If the operation was not successful, we cannot do
// anything
// and must
// fail.
if (!result.getStatus().isSuccess()) {
Log.i(TAG, "Failed to create new contents.");
return;
}
Log.i(TAG, "Connection successful, creating new contents...");
// Otherwise, we can write our data to the new contents.
// Get an output stream for the contents.
OutputStream outputStream = result.getDriveContents()
.getOutputStream();
FileInputStream fis;
try {
fis = new FileInputStream(file.getPath());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int n;
while (-1 != (n = fis.read(buf)))
baos.write(buf, 0, n);
byte[] photoBytes = baos.toByteArray();
outputStream.write(photoBytes);
outputStream.close();
outputStream = null;
fis.close();
fis = null;
} catch (FileNotFoundException e) {
Log.w(TAG, "FileNotFoundException: " + e.getMessage());
} catch (IOException e1) {
Log.w(TAG, "Unable to write file contents." + e1.getMessage());
}
String title = file.getName();
MetadataChangeSet metadataChangeSet = new MetadataChangeSet.Builder()
.setMimeType(mime).setTitle(title).build();
if (mime.equals(MIME_PHOTO)) {
if (VERBOSE)
Log.i(TAG, "Creating new photo on Drive (" + title
+ ")");
Drive.DriveApi.getFolder(mDriveClient,
mPicFolderDriveId).createFile(mDriveClient,
metadataChangeSet,
result.getDriveContents());
} else if (mime.equals(MIME_VIDEO)) {
Log.i(TAG, "Creating new video on Drive (" + title
+ ")");
Drive.DriveApi.getFolder(mDriveClient,
mVidFolderDriveId).createFile(mDriveClient,
metadataChangeSet,
result.getDriveContents());
}
if (file.delete()) {
if (VERBOSE)
Log.d(TAG, "Deleted " + file.getName() + " from sdcard");
} else {
Log.w(TAG, "Failed to delete " + file.getName() + " from sdcard");
}
}
});
}
There is one more way to upload file to Google Drive without using Drive API. Using Intent you can implement this. (Tested on Android 12)
String your_file_path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath()
+ "/XYZ/Database/"+FILE_NAME+"_");
Intent intent = new Intent(android.content.Intent.ACTION_SEND);
intent.setType("*/*");
Uri photoURI = FileProvider.getUriForFile(this, "authorities_from_manifest_file_of_provider_tag",new File(your_file_path));
intent.setPackage("com.google.android.apps.docs"); //Google Drive
intent.putExtra(Intent.EXTRA_STREAM,photoURI);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(Intent.createChooser(intent, "Save Backup"));
You must have added working File Provider in your Manifest before implementing of this.
Note: "authorities_from_manifest_file_of_provider_tag" is the attribute value of android:authorities this from manifest. i.e -
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.your.packageName.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths" />
</provider>
File albumF = getVideoAlbumDir();
String path = albumF.getAbsolutePath();
// path =/storage/emulated/0/Pictures/.MyImages (Hidden folder)
// fileSelected.fileName()=IMG_20140417_113847.jpg
File localFile = new File(path + "/" + fileSelected.fileName());
Log.v("", "file exist===" + localFile.exists());
if (!localFile.exists()) {
Log.v("", "inside if===");
Log.v("", "Parent Filet===" + localFile.getParentFile());
localFile.getParentFile().mkdirs();
// localFile.createNewFile();
copy(fileSelected, localFile);
} else {
Log.v("", "inside else===");
mCurrentPhotoPath = localFile.getAbsolutePath();
uploadMediaFile();
}
This copy method copies data from dropbox file to my local storage.
private void copy(final Entry fileSelected, final File localFile) {
final ProgressDialog pd = ProgressDialog.show(ChatActivity.this,
"Downloading...", "Please wait...");
new Thread(new Runnable() {
#Override
public void run() {
BufferedInputStream br = null;
BufferedOutputStream bw = null;
DropboxInputStream fd;
try {
fd = mDBApi.getFileStream(fileSelected.path,
localFile.getAbsolutePath());
br = new BufferedInputStream(fd);
bw = new BufferedOutputStream(new FileOutputStream(
localFile));
byte[] buffer = new byte[4096];
int read;
while (true) {
read = br.read(buffer);
if (read <= 0) {
break;
}
bw.write(buffer, 0, read);
}
pd.dismiss();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
android.os.Message msg = new android.os.Message();
msg.arg1 = 100;
if (msg.arg1 >= 100) {
progressHandler.sendMessage(msg);
mCurrentPhotoPath = localFile.getAbsolutePath();
}
} catch (DropboxException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bw != null) {
try {
bw.close();
if (br != null) {
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}).start();
I am creating file in a folder using localFile.getParentFile().mkdirs();
I got above error when I upload this file to server.
how to fix this?
If you've tried all other options - and problem still persists - then maybe you have a case when the file you want to create matches name of already existing directory.(which might be earlier created my some call to mkdirs() maybe accidentally).
Example:
You want to save file Test\test.pdf but you already have folder Test\Test.pdf\
Could someone look at this snippet of code please and let me know what I'm doing wrong? It's a simple function that takes a string as parameter which it uses as a file name, adding ".txt" to the end of it.
The function checks if the file exists, creating it if it doesn't and then writes two lines of text to the file. Everything appears to be working and the file is created successfully on the sd card. However, after everything is done, the file is empty (and has a size of 0 bytes).
I suspect it's something obvious that I'm overlooking.
public void writeFile(String fileName) {
String myPath = new File(Environment.getExternalStorageDirectory(), "SubFolderName");
myPath.mkdirs();
File file = new File(myPath, fileName+".txt");
try {
if (!file.exists()) {
if (!file.createNewFile()) {
Toast.makeText(this, "Error Creating File", Toast.LENGTH_LONG).show();
return;
}
}
OutputStreamWriter writer = new OutputStreamWriter(openFileOutput(file.getName(), Context.MODE_PRIVATE));
writer.append("First line").append('\n');
writer.append("Second line").append('\n');
writer.close();
}
catch (IOException e) {
// Do whatever
}
}
Hi I will show you the full code I use, works perfect.
I don't use
new OutputStreamWriter()
i use
new BufferedWriter()
here is my Snippet
public void writeToFile(Context context, String fileName, String data) {
Writer mwriter;
File root = Environment.getExternalStorageDirectory();
File dir = new File(root.getAbsolutePath() + File.separator + "myFolder");
if (!dir.isDirectory()) {
dir.mkdir();
}
try {
if (!dir.isDirectory()) {
throw new IOException(
"Unable to create directory myFolder. SD card mounted?");
}
File outputFile = new File(dir, fileName);
mwriter = new BufferedWriter(new FileWriter(outputFile));
mwriter.write(data); // DATA WRITE TO FILE
Toast.makeText(context.getApplicationContext(),
"successfully saved to: " + outputFile.getAbsolutePath(), Toast.LENGTH_LONG).show();
mwriter.close();
} catch (IOException e) {
Log.w("write log", e.getMessage(), e);
Toast.makeText(context, e.getMessage() + " Unable to write to external storage.",Toast.LENGTH_LONG).show();
}
}
-- Original Code --
That one took a while to find out. The javadocs
here brought me on the right track.
It says:
Parameters
name The name of the file to open; can not contain path separators.
mode Operating mode. Use 0 or MODE_PRIVATE for the default operation, MODE_APPEND to append to an existing file, MODE_WORLD_READABLE and MODE_WORLD_WRITEABLE to control permissions.
The file is created, if it does not exist, but it is created in the private app space. You create the file somewhere on the sd card using File.createNewFile() but when you do context.openFileOutput() it creates always a private file in the private App space.
EDIT: Here's my code. I've expanded your method by writing and reading the lines and print what I got to logcat.
<pre>
public void writeFile(String fileName) {
try {
OutputStreamWriter writer = new OutputStreamWriter(
getContext().openFileOutput(fileName + ".txt", Context.MODE_PRIVATE));
writer.append("First line").append('\n');
writer.append("Second line").append('\n');
writer.close();
}
catch (IOException e) {
Log.e("STACKOVERFLOW", e.getMessage(), e);
return;
// Do whatever
}
// Now read the file
try {
BufferedReader is = new BufferedReader(
new InputStreamReader(
getContext().openFileInput(fileName + ".txt")));
for(String line = is.readLine(); line != null; line = is.readLine())
Log.d("STACKOVERFLOW", line);
is.close();
} catch (IOException e) {
Log.e("STACKOVERFLOW", e.getMessage(), e);
return;
// Do whatever
}
}
Change the mode from Context.MODE_PRIVATE to Context.MODE_APPEND in openFileOutput()
MODE_APPEND
MODE_PRIVATE
Instead of
OutputStreamWriter writer = new OutputStreamWriter(openFileOutput(file.getName(), Context.MODE_PRIVATE));
Use
OutputStreamWriter writer = new OutputStreamWriter(openFileOutput(file.getName(), Context.MODE_APPEND));
UPDATE :
1.
FileOutputStream osr = new FileOutputStream(file.getName(), true); // this will set append flag to true
OutputStreamWriter writer = new OutputStreamWriter(osr);
BufferedWriter fbw = new BufferedWriter(writer);
fbw.write("First line");
fbw.newLine();
fbw.write("Second line");
fbw.newLine();
fbw.close();
Or 2.
private void writeFileToInternalStorage() {
FileOutputStream osr = new FileOutputStream(file.getName(), true); // this will set append flag to true
String eol = System.getProperty("line.separator");
BufferedWriter fbw = null;
try {
OutputStreamWriter writer = new OutputStreamWriter(osr);
fbw = new BufferedWriter(writer);
fbw.write("First line" + eol);
fbw.write("Second line" + eol);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fbw != null) {
try {
fbw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}