I have an SplashActivity class that logins to drive API:
private void handleSignInIntent(Intent data) {
GoogleSignIn.getSignedInAccountFromIntent(data).addOnSuccessListener(new OnSuccessListener<GoogleSignInAccount>() {
#Override
public void onSuccess(GoogleSignInAccount googleSignInAccount) {
GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2(SplashActivity.this, Collections.singleton(DriveScopes.DRIVE_FILE));
credential.setSelectedAccount(googleSignInAccount.getAccount());
Drive googleDriveService = new Drive.Builder(
AndroidHttp.newCompatibleTransport(),
new GsonFactory(), credential)
.setApplicationName("MyApp")
.build();
DriveServiceHelper driveServiceHelper = new DriveServiceHelper(googleDriveService); //Need the driveServiceHelper
startApp(); //Goes to Main Activity
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
}
});
}
Which creates DriveServiceHelper instance. I need to use this instance in the MainActivity like so:
private void uploadFile()
{
String filePath = "path";
driveServiceHelper.createFile(filePath).addOnSuccessListener(new OnSuccessListener<String>() { //Need to use the driveServiceHelper instance
#Override
public void onSuccess(String s) {
Toast.makeText(getApplicationContext(),"Success",Toast.LENGTH_LONG).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(getApplicationContext(),"Error",Toast.LENGTH_LONG).show();
});
}
I cannot make class DriveServiceHelper Serializable and pass it trough intent, and I am not sure that I can make function createFile static and use it from anywhere because mDriveService in DriveServiceHelper may be null.
DriveServiceHelper:
public class DriveServiceHelper
{
private final Executor mExecutor = Executors.newSingleThreadExecutor();
private Drive mDriveService;
public DriveServiceHelper(Drive mDriveService)
{
this.mDriveService = mDriveService;
}
public Task<String> createFile(String filePath) {
return Tasks.call(mExecutor, () -> {
String fileId = "------------------------------------";
File gDriveFile = mDriveService.files().get(fileId).execute();
java.io.File fileContent = new java.io.File(filePath);
FileContent mediaContent = new FileContent("text/plain", fileContent);
File fileObjectWithUpdates = new File();
File updatedFile = mDriveService.files().update(gDriveFile.getId(), fileObjectWithUpdates, mediaContent).execute();
if (updatedFile == null) {
throw new IOException("Null result");
}
return updatedFile.getId();
});
}
}
What is the best approach for this?
Have you tried to wrap the Drive object in wrapper class and use a singleton pattern to use it else where in your application. Something like this solution link
Related
I am looking for a solution for uploading data to Firebase without having the user wait for the data to upload, so that the user can use the app in offline mode.
Let's suppose that the app is about places. In this app, the user can upload an image and an object containing address, city, state, country, latitude, longitude, description, etc. Let's say a big POJO.
Firebase Realtime Database and Firebase Firestore can wait for (I do not know for how long) a stable internet connection to send the data. But Firebase Storage do not have this feature.
So I've found WorkManager. It seemed to solve the problem, but I had to serialize my POJO into small primitive variable types in order to send the POJO to Worker class.
The result I want to achieve is:
1) upload image to Firebase Storage
2) download URL of the image
3) send the POJO to Firebase Firestore with the ImageUrl in it.
QUESTIONS
1) Is WorkManager best suited for this kind of purpose?
2) How many times can an user trigger this background job without causing any issue to the app in offline mode?
3) How to propperly send the POJO to the Worker class?
Here is what I've done so far:
Get pushKey for the new place, start the background job and keep navigating through activities:
savePlaceData.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DocumentReference docRef = DatabaseRouter.getPlaceCollectionRef().document();
String key = docRef.getId();
uploadPlaceDataInBackground(key)
Intent intent = new Intent(PlaceActivity.this, OtherActivity.class);
startActivity(intent);
}
});
Set the request for the background job:
private void uploadPlaceDataInBackground(String placeKey) {
// TESTING WORKMANAGER FOR UPLOADING IMAGES TO FIREBASE STORAGE
// Create a Constraints object that defines when the task should run
Constraints constraints = new Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build();
// Passing data to the worker class
Data.Builder uploadBuilder = new Data.Builder();
uploadBuilder.putString("image_uri", placeImageUri.toString());
uploadBuilder.putString("image_pushkey", placeKey);
Data ImageUriInputData = uploadBuilder.build();
// ...then create a OneTimeWorkRequest that uses those constraints
OneTimeWorkRequest uploadWorkRequest = new OneTimeWorkRequest
.Builder(UploadImageWorker.class)
.setConstraints(constraints)
.setInputData(ImageUriInputData)
.build();
OneTimeWorkRequest downloadWorkRequest = new OneTimeWorkRequest
.Builder(DownloadImageUrlWorker.class)
.setConstraints(constraints)
.build();
// Converting placeObject into Map
Data.Builder uploadPlaceBuilder = new Data.Builder();
Map<String, Object> placeMap = convertPlaceObjectIntoMap();
uploadPlaceBuilder.putAll(placeMap);
Data placeInfoInputData = uploadPlaceBuilder.build();
OneTimeWorkRequest uploadPlaceWorkRequest = new OneTimeWorkRequest
.Builder(UploadPlaceWorker.class)
.setConstraints(constraints)
.setInputData(placeInfoInputData)
.build();
// Execute and Manage the background service
WorkManager workManager = WorkManager.getInstance(getActivity());
workManager.beginWith(uploadWorkRequest)
.then(downloadWorkRequest)
.then(uploadPlaceWorkRequest)
.enqueue();
}
Below are the Worker classes:
public class UploadImageWorker extends Worker {
public UploadImageWorker(#NonNull Context context, #NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
#NonNull
#Override
public Result doWork() {
String imageUriInput = getInputData().getString("image_uri");
String imagePushKey = getInputData().getString("image_pushkey");
final Result[] result = {Result.retry()};
CountDownLatch countDownLatch = new CountDownLatch(1);
StorageReference storageRef = DatabaseRouter.getPlaceStorageRef(imagePushKey).child(imagePushKey+".jpg");
storageRef.putFile(Uri.parse(imageUriInput)).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
#Override
public void onComplete(#NonNull Task<UploadTask.TaskSnapshot> task) {
if (task.isSuccessful()) {
result[0] = Result.success(getInputData());
} else {
Log.i(TAG, "onComplete: image NOT uploaded - RETRYING");
result[0] = Result.retry();
}
countDownLatch.countDown();
}
});
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
return result[0];
}
}
public class DownloadImageUrlWorker extends Worker {
public DownloadImageUrlWorker(#NonNull Context context, #NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
#NonNull
#Override
public Result doWork() {
String imageUriInput = getInputData().getString("image_uri");
String imagePushKey = getInputData().getString("image_pushkey");
final Result[] result = {Result.retry()};
CountDownLatch countDownLatch = new CountDownLatch(1);
StorageReference storageRef = DatabaseRouter.getPlaceStorageRef(imagePushKey).child(imagePushKey+".jpg");
storageRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
String imageUrl = uri.toString();
Data.Builder outputBuilder = new Data.Builder();
outputBuilder.putString("image_url", imageUrl);
outputBuilder.putString("image_pushkey", imagePushKey);
Data outputData = outputBuilder.build();
result[0] = Result.success(outputData);
countDownLatch.countDown();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.i(TAG, "onFailure: imageUrl NOT downloaded - RETRYING");
result[0] = Result.retry();
countDownLatch.countDown();
}
});
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
return result[0];
}
}
public class UploadPlaceWorker extends Worker {
public UploadPlaceWorker(#NonNull Context context, #NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
#NonNull
#Override
public Result doWork() {
String imageUrl = getInputData().getString("image_url");
String imagePushKey = getInputData().getString("image_pushkey");
Map<String, Object> placeObject = getInputData().getKeyValueMap();
PlaceModel placeModel = convertMapIntoPlaceObject(placeObject, imageUrl, imagePushKey);
final Result[] result = {Result.retry()};
CountDownLatch countDownLatch = new CountDownLatch(1);
DocumentReference docRef = DatabaseRouter.getPlaceCollectionRef().document(imagePushKey);
docRef.set(placeModel).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
result[0] = Result.success();
} else {
Log.i(TAG, "onComplete: place NOT uploaded - RETRYING");
result[0] = Result.retry();
}
countDownLatch.countDown();
}
});
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
return result[0];
}
private PlaceModel convertMapIntoPlaceObject(Map<String, Object> placeMap, String imageUrl, String placeKey) {
PlaceModel place = new PlaceModel();
place.setAddress(placeMap.get("a").toString());
place.setCity(placeMap.get("b").toString());
place.setCountry(placeMap.get("c").toString());
place.setDistrict(placeMap.get("d").toString());
place.setG(placeMap.get("e").toString());
place.setId(placeMap.get("f").toString());
place.setImage(imageUrl);
place.setKey(placeKey);
GeoPoint geoPoint = new GeoPoint((Double) placeMap.get("h"), (Double) placeMap.get("i"));
place.setL(geoPoint);
place.setDescription(placeMap.get("j").toString());
return place;
}
}
I appreciate any help!
I checked this article but observe the response changes in MainActivity.
Here is my code for LoginRepo
public MutableLiveData<LoginResponseModel> checkLogin(LoginRequestModel loginRequestModel) {
final MutableLiveData<LoginResponseModel> data = new MutableLiveData<>();
Map<String, String> params = new HashMap<>();
params.put("email", loginRequestModel.getEmail());
params.put("password", loginRequestModel.getPassword());
apiService.checkLogin(params)
.enqueue(new Callback<LoginResponseModel>() {
#Override
public void onResponse(Call<LoginResponseModel> call, Response<LoginResponseModel> response) {
if (response.isSuccessful()) {
data.setValue(response.body());
Log.i("Response ", response.body().getMessage());
}
}
#Override
public void onFailure(Call<LoginResponseModel> call, Throwable t) {
data.setValue(null);
}
});
return data;
}
Here is my Code LoginViewModel
public class LoginViewModel extends ViewModel {
public MutableLiveData<String> emailAddress = new MutableLiveData<>();
public MutableLiveData<String> password = new MutableLiveData<>();
Map<String, String> params = new HashMap<>();
LoginRepo loginRepo;
private MutableLiveData<LoginResponseModel> loginResponseModelMutableLiveData;
public LiveData<LoginResponseModel> getUser() {
if (loginResponseModelMutableLiveData == null) {
loginResponseModelMutableLiveData = new MutableLiveData<>();
loginRepo = LoginRepo.getInstance();
}
return loginResponseModelMutableLiveData;
}
//This method is using Retrofit to get the JSON data from URL
private void checkLogin(LoginRequestModel loginRequestModel) {
loginResponseModelMutableLiveData = loginRepo.checkLogin(loginRequestModel);
}
public void onLoginClick(View view) {
LoginRequestModel loginRequestModel = new LoginRequestModel();
loginRequestModel.setEmail(emailAddress.getValue());
loginRequestModel.setPassword(password.getValue());
params.put("email", loginRequestModel.getEmail());
params.put("password", loginRequestModel.getPassword());
checkLogin(loginRequestModel);
}
}
Here is my code for LoginActivity
private LoginViewModel loginViewModel;
private ActivityMainBinding binding;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
loginViewModel = ViewModelProviders.of(this).get(LoginViewModel.class);
binding = DataBindingUtil.setContentView(LoginActivity.this, R.layout.activity_main);
binding.setLifecycleOwner(this);
binding.setLoginViewModel(loginViewModel);
loginViewModel.getUser().observe(this, new Observer<LoginResponseModel>() {
#Override
public void onChanged(#Nullable LoginResponseModel loginUser) {
if (loginUser != null) {
binding.lblEmailAnswer.setText(loginUser.getUser().getId());
Toast.makeText(getApplicationContext(), loginUser.getUser().getId(), Toast.LENGTH_SHORT).show();
}
}
});
}
onLoginClick method used in LoginViewModel is using LiveData.
The Response coming from api is okay. But onchange() it is not shown, how to use LiveData using MVVM pattern in simple Login Example. Please help!
Here is what i have tried using your classes just altering retrofit to background thread to wait 5 seconds and then setting the data (you need to confirm the response being successful as you don't change the data if it's failing and hence if the loginResponseModel is null then it will enter the onChanged Method but it won't do anything as you don't have a condition if it is equals to null) here is what i did
in Main Activity -> onCreate() i just created the viewmodel and observed on the mutableLiveData
myViewModel.onLoginClick(null);
myViewModel.simpleModelMutableLiveData.observe(this, new Observer<String>() {
#Override
public void onChanged(#Nullable String s) {
if(s==null)
Log.v("testinggg","test - onChanged --- Null " );
else
Log.v("testinggg","test - onChanged --- s -> "+s );
}
});
Then here is the ViewModel -> in which you will have the MutableLiveData itself named simpleModelMutableLiveData
MutableLiveData<String> simpleModelMutableLiveData;
public LiveData<String> getUser() {
if (simpleModelMutableLiveData == null) {
simpleModelMutableLiveData = new MutableLiveData<>();
}
return simpleModelMutableLiveData;
}
// this method will return Object of MutableLiveData<String> and let the simpleModelMutableLiveData be the returned object
private void checkLogin(String placeholder) {
simpleModelMutableLiveData = MyRepo.checkLogin(placeholder);
}
public void onLoginClick(View view) {
checkLogin("test");
}
and at last the Repo method in which i will return the MutableLiveData and let the simpleModelMutableLiveData to be the return and initiate a background thread using runnable that will wait 5 seconds before it sets the value using a handler (in your case you will need to set the value of the data after enqueue inside the Overridden Methods onResponse and onFailure)
as follows
public static MutableLiveData<String> checkLogin(String test) {
final MutableLiveData<String> data = new MutableLiveData<>();
Runnable r = new Runnable() {
public void run() {
runYourBackgroundTaskHere(data);
}
};
new Thread(r).start();
return data;
}
private static void runYourBackgroundTaskHere(final MutableLiveData<String> data) {
try {
Thread.sleep(5000);
// Handler handler = new Handler();
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
// things to do on the main thread
/* Here i set the data to sss and then null and when
you check the logcat and type the keyword used for
logging which is "testinggg"
you will find it show sss and then null which means
it has entered the onChanged and showed you the log */
data.setValue("sss");
data.setValue(null);
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
in fact I am in the process of preparing an android application that makes the upload of an image on a server thanks to a REST API.
I tested lapi with POSTMAN and I have no errors.
but have an error in this part: I that the crash app before intent
this is my source codes:
public class FileShooser extends AppCompatActivity {
private static final int INTENT_REQUEST_CODE = 100;
private String name ;
private CompositeSubscription mSubscriptions;
ProgressDialog progressdialog ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSubscriptions = new CompositeSubscription();
// get name from last activity
name= getIntent().getStringExtra("Name");
// start file shooser intent
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
try {
startActivityForResult(intent, INTENT_REQUEST_CODE );
} catch (ActivityNotFoundException e) {
e.printStackTrace();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode==INTENT_REQUEST_CODE)
{
if(resultCode==RESULT_OK){
uploadImage( data.getData());
}
}
}
public byte[] getBytes(InputStream is) throws IOException {
ByteArrayOutputStream byteBuff = new ByteArrayOutputStream();
int buffSize = 1024;
byte[] buff = new byte[buffSize];
int len = 0;
while ((len = is.read(buff)) != -1) {
byteBuff.write(buff, 0, len);
}
return byteBuff.toByteArray();
}
private void uploadImage(Uri fileUri) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constants.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitInterface retrofitInterface = retrofit.create(RetrofitInterface.class);
// use the FileUtils to get the actual file by uri
File file = new File(fileUri.getPath());
showSnackBarMessage("name:"+file.getName());
// create RequestBody instance from file
RequestBody requestFile =
RequestBody.create(
MediaType.parse(getContentResolver().getType(fileUri)),
file
);
// MultipartBody.Part is used to send also the actual file name
MultipartBody.Part body =
MultipartBody.Part.createFormData("image", file.getName(), requestFile);
// progress dialog
progressdialog = new ProgressDialog(getApplicationContext());
progressdialog.setMessage("Please wait ...");
progressdialog.show();
retrofitInterface.upload(name,body).observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(this::handleResponse,this::handleError);
}
private void handleError(Throwable error) {
progressdialog.dismiss();
if (error instanceof HttpException) {
Gson gson = new GsonBuilder().create();
try {
String errorBody = ((HttpException) error).response().errorBody().string();
Response response = gson.fromJson(errorBody,Response.class);
showSnackBarMessage(response.getMessage());
} catch (IOException e) {
e.printStackTrace();
}
} else {
showSnackBarMessage("Network Error !");
}
}
private void handleResponse(Response response) {
progressdialog.dismiss();
showSnackBarMessage(response.getMessage());
}
private void showSnackBarMessage(String message) {
Toast.makeText(getApplicationContext(),message,Toast.LENGTH_LONG).show();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
return true;
}
}
thank you very much for your answers
I'm trying to create a file on google drive through android, I successfully sign in google but when I try to create a drive content I don't receive the OnResult.
This is my code:
public class GoogleDrive: Java.Lang.Object, IResultCallback
{
GoogleApiClient GAClient;
public GoogleDrive(Android.Content.Res.Resources res,GoogleApiClient gac)
{
GAClient=gac;
DriveClass.DriveApi.NewDriveContents(GAClient).SetResultCallback(this);
}
void IResultCallback.OnResult(Java.Lang.Object result)
{
var contentResults = (result).JavaCast<IDriveApiDriveContentsResult>();
Statuses a=contentResults.Status;
if (!contentResults.Status.IsSuccess) // handle the error
return;
Task.Run(() =>
{
var writer = new OutputStreamWriter(contentResults.DriveContents.OutputStream);
writer.Write("Stack Overflow");
writer.Close();
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.SetTitle("test.txt")
.SetMimeType("text/plain")
.Build();
DriveClass.DriveApi
.GetRootFolder(GAClient)
.CreateFile(GAClient, changeSet, contentResults.DriveContents);
});
}
public IDriveContents DriveContents
{
get
{
throw new NotImplementedException();
}
}
public Statuses Status
{
get
{
throw new NotImplementedException();
}
}
public void Dispose()
{
}
Nothing happen after the line DriveClass.DriveApi.NewDriveContents(GAClient).SetResultCallback(this); And the program never goes in OnResult. Is there a OnFailed method that can help me ?
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.