I'm trying to make my Android app to upload a Video format file to my Google Drive account. The whole code:
import android.Manifest;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.fragment.app.Fragment;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.ExponentialBackOff;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.FileList;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URLConnection;
import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static net.fortuna.ical4j.util.ResourceLoader.getResourceAsStream;
public class ManagerUploadFragment extends Fragment {
private final static int APP_PERMISSION_REQUEST = 100;
private final static int ACTIVITY_CHOOSE_FILE = 1;
private static final String APPLICATION_NAME = "Google Drive API Java Quickstart";
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
private static final String TOKENS_DIRECTORY_PATH = "tokens";
private static final List<String> SCOPES = Collections.singletonList(DriveScopes.DRIVE_METADATA_READONLY);
private static final String CREDENTIALS_FILE_PATH = "/credentials.json";
private View fragmentView;
private Button uploadButton;
private Drive driveService;
// Required empty public constructor for fragments
public ManagerUploadFragment() {}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
fragmentView = inflater.inflate(R.layout.fragment_manager_upload, container, false);
uploadButton = (Button) fragmentView.findViewById(R.id.upload_view_browse_button);
// Set upload button
uploadButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
uploadImage();
}
});
// Connect to drive
try {
driveService = createService();
} catch (GeneralSecurityException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return fragmentView;
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == APP_PERMISSION_REQUEST) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
for (int grantResult : grantResults) {
if (grantResult != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(getActivity(), R.string.enable_required_permissions, Toast.LENGTH_LONG).show();
return; // Permissions were not granted
}
}
}
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == AppCompatActivity.RESULT_OK) {
if (requestCode == ACTIVITY_CHOOSE_FILE && getActivity() != null) {
Uri uri = data.getData();
System.out.println("URI " + uri.toString());
if (!(isVideoFile(uri))) {
Toast.makeText(getActivity(), "File is not in a valid video format", Toast.LENGTH_LONG).show();
return;
}
if (getFileSizeInMB(uri.getPath()) > 1) {
Toast.makeText(getActivity(), "File size is bigger than 20MB", Toast.LENGTH_LONG).show();
return;
}
}
}
}
private static long getFileSizeInMB(final String file_path) {
final File file = new File(file_path);
long sizeInBytes = file.length();
return sizeInBytes / (1024 * 1024);
}
private boolean isVideoFile(Uri uri) {
ContentResolver cR = getContext().getContentResolver();
String type = cR.getType(uri);
return type != null && (type.equals("video/mp4") || type.equals("video/avi"));
}
private void uploadImage() {
if (getActivity() != null) {
final int writeStoragePermission = ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE);
final int readStoragePermission = ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE);
if (writeStoragePermission != PackageManager.PERMISSION_GRANTED || readStoragePermission != PackageManager.PERMISSION_GRANTED) {
final String[] permissions = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE};
ActivityCompat.requestPermissions(getActivity(), permissions, APP_PERMISSION_REQUEST);
return;
}
Intent chooseFile;
Intent intent;
chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
chooseFile.addCategory(Intent.CATEGORY_OPENABLE);
chooseFile.setType("*/*");
intent = Intent.createChooser(chooseFile, "Choose a file");
startActivityForResult(intent, ACTIVITY_CHOOSE_FILE);
}
}
private Drive createService() throws GeneralSecurityException, IOException {
final NetHttpTransport HTTP_TRANSPORT = new com.google.api.client.http.javanet.NetHttpTransport();
Drive mService = new Drive.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(getContext(), HTTP_TRANSPORT))
.setApplicationName(APPLICATION_NAME)
.build();
// Print the names and IDs for up to 10 files.
FileList result = mService.files().list()
.setPageSize(10)
.setFields("nextPageToken, files(id, name)")
.execute();
List<com.google.api.services.drive.model.File> files = result.getFiles();
if (files == null || files.isEmpty()) {
System.out.println("No files found.");
} else {
System.out.println("Files:");
for (com.google.api.services.drive.model.File file : files) {
System.out.printf("%s (%s)\n", file.getName(), file.getId());
}
}
return mService;
}
private static Credential getCredentials(final Context context, final NetHttpTransport HTTP_TRANSPORT) throws IOException {
// Load client secrets.
InputStream in = context.getClass().getResourceAsStream(CREDENTIALS_FILE_PATH);
if (in == null) {
throw new FileNotFoundException("Resource not found: " + CREDENTIALS_FILE_PATH);
}
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
// Build flow and trigger user authorization request.
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
.setDataStoreFactory(new FileDataStoreFactory(new java.io.File(TOKENS_DIRECTORY_PATH)))
.setAccessType("offline")
.build();
LocalServerReceiver receiver = new LocalServerReceiver.Builder().setPort(8888).build();
return new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");
}
}
In order to upload the video to the Dirve, I need to connect to the Drive first. I followed the steps on how to create to use the API (docs). Then I followed this example, which should show how to connect to the Google Drive and list the content.
But, before even pressing the "upload" button, I get an error to connect to the Google Drive:
java.io.IOException: unable to create directory: /tokens
On line:
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
.setDataStoreFactory(new FileDataStoreFactory(new java.io.File(TOKENS_DIRECTORY_PATH)))
.setAccessType("offline")
.build();
Please correct me if I'm wrong, but as I understand, it tries to create the token directory locally and not in the remote - but why does it need it? I just want to be able to push the video I got from the user to the Drive. How can I connect to the Google Drive and push the video to the Drive (if you will take a look into a code, I have the uri of the file, that should be pushed to the Drive).
from How to push a video format file to the Google Drive from an Android app?
No comments:
Post a Comment