Skip to content

Commit

Permalink
Android support (npomfret#5)
Browse files Browse the repository at this point in the history
* Update build.gradle

* Delete CopyToGoogleDriveTask.java

* Create DriveServiceHelper.java

* Delete GoogleDriveApiClient.java

* Update RNCloudFsModule.java

* bump to v2
  • Loading branch information
brunobar79 authored Sep 23, 2020
1 parent 7c84944 commit f80180e
Show file tree
Hide file tree
Showing 6 changed files with 426 additions and 742 deletions.
24 changes: 19 additions & 5 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ buildscript {
apply plugin: 'com.android.library'

android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
compileSdkVersion 28
buildToolsVersion "28.0.3"

defaultConfig {
minSdkVersion 16
targetSdkVersion 22
minSdkVersion 19
targetSdkVersion 28
versionCode 1
versionName "1.0"
ndk {
Expand All @@ -25,6 +25,10 @@ android {
lintOptions {
warning 'InvalidPackage'
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}

allprojects {
Expand All @@ -35,5 +39,15 @@ allprojects {

dependencies {
provided 'com.google.android.gms:play-services-drive:+'
implementation ('com.google.android.gms:play-services-auth:18.1.0') {
force = true;
}
implementation 'com.google.http-client:google-http-client-gson:1.26.0'
implementation('com.google.api-client:google-api-client-android:1.26.0') {
exclude group: 'org.apache.httpcomponents'
}
implementation('com.google.apis:google-api-services-drive:v3-rev136-1.25.0') {
exclude group: 'org.apache.httpcomponents'
}
provided 'com.facebook.react:react-native:+'
}
}
73 changes: 0 additions & 73 deletions android/src/main/java/org/rncloudfs/CopyToGoogleDriveTask.java

This file was deleted.

214 changes: 214 additions & 0 deletions android/src/main/java/org/rncloudfs/DriveServiceHelper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
package org.rncloudfs;

/**
* Copyright 2018 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import android.content.ContentResolver;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.provider.OpenableColumns;
import android.util.Log;

import androidx.core.util.Pair;

import com.google.android.gms.tasks.Task;
import com.google.android.gms.tasks.Tasks;

import com.google.api.client.http.FileContent;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.model.File;
import com.google.api.services.drive.model.FileList;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicReference;

/**
* A utility for performing read/write operations on Drive files via the REST API and opening a
* file picker UI via Storage Access Framework.
*/
public class DriveServiceHelper {
private final Executor mExecutor = Executors.newSingleThreadExecutor();
private final Drive mDriveService;

public DriveServiceHelper(Drive driveService) {
mDriveService = driveService;
}

public Task<String> saveFile(String sourcePath, String destinationPath, String mimeType, Boolean useDocumentsFolder) throws ExecutionException, InterruptedException {
String existingFileId = null;
FileList fileList = Tasks.await(queryFiles(useDocumentsFolder));
for (File file : fileList.getFiles()) {
if(file.getName().equalsIgnoreCase(destinationPath)){
existingFileId = file.getId();
}
}
return createFile(sourcePath, destinationPath, mimeType, useDocumentsFolder, existingFileId);
}

/**
* Creates a text file in the user's My Drive folder and returns its file ID.
*/
public Task<String> createFile(String sourcePath, String destinationPath, String mimeType, Boolean useDocumentsFolder, String fileId) {

return Tasks.call(mExecutor, () -> {
try{
java.io.File sourceFile = new java.io.File(sourcePath);
FileContent mediaContent = new FileContent(mimeType, sourceFile);
List<String> parentFolder = Collections.singletonList(useDocumentsFolder ? "root" : "appDataFolder");
File metadata = new File()
.setMimeType(mimeType)
.setName(destinationPath);
if(fileId == null){
metadata.setParents(parentFolder);
}

File googleFile = null;
if(fileId != null){
googleFile = mDriveService.files().update(fileId, metadata, mediaContent).execute();
} else{
googleFile = mDriveService.files().create(metadata, mediaContent).execute();
}

if (googleFile == null) {
throw new IOException("Null result when requesting file creation.");
}

return googleFile.getId();
} catch(Exception e){
Log.e("WTF", e.toString());
throw e;
}

});
}


public Task<Boolean> checkIfFileExists(String fileId) {
return Tasks.call(mExecutor, () -> {
// Retrieve the metadata as a File object.
File metadata = mDriveService.files().get(fileId).execute();
if(metadata != null){
return true;
}
return false;
});
}

public Task<Boolean> deleteFile(String fileId) {
return Tasks.call(mExecutor, () -> {
// Retrieve the metadata as a File object.
mDriveService.files().delete(fileId).execute();
return true;
});
}

/**
* Opens the file identified by {@code fileId} and returns a {@link Pair} of its name and
* contents.
*/
public Task<String> readFile(String fileId) {
return Tasks.call(mExecutor, () -> {
// Retrieve the metadata as a File object.
File metadata = mDriveService.files().get(fileId).execute();
String name = metadata.getName();

// Stream the file contents to a String.
try (InputStream is = mDriveService.files().get(fileId).executeMediaAsInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is))) {
StringBuilder stringBuilder = new StringBuilder();
String line;

while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
}
String contents = stringBuilder.toString();

return contents;
}
});
}

/**
* Returns a {@link FileList} containing all the visible files in the user's My Drive.
*
* <p>The returned list will only contain files visible to this app, i.e. those which were
* created by this app. To perform operations on files not created by the app, the project must
* request Drive Full Scope in the <a href="https://play.google.com/apps/publish">Google
* Developer's Console</a> and be submitted to Google for verification.</p>
*/
public Task<FileList> queryFiles(Boolean useDocumentsFolder) {
return Tasks.call(mExecutor, () ->
mDriveService.files().list().
setSpaces(useDocumentsFolder ? "drive" : "appDataFolder")
.setFields("nextPageToken, files(id, name, modifiedTime)")
.setPageSize(100)
.execute()
);
}

/**
* Returns an {@link Intent} for opening the Storage Access Framework file picker.
*/
public Intent createFilePickerIntent() {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("text/plain");

return intent;
}

/**
* Opens the file at the {@code uri} returned by a Storage Access Framework {@link Intent}
* created by {@link #createFilePickerIntent()} using the given {@code contentResolver}.
*/
public Task<Pair<String, String>> openFileUsingStorageAccessFramework(
ContentResolver contentResolver, Uri uri) {
return Tasks.call(mExecutor, () -> {
// Retrieve the document's display name from its metadata.
String name;
try (Cursor cursor = contentResolver.query(uri, null, null, null, null)) {
if (cursor != null && cursor.moveToFirst()) {
int nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
name = cursor.getString(nameIndex);
} else {
throw new IOException("Empty cursor returned for file.");
}
}

// Read the document's contents as a String.
String content;
try (InputStream is = contentResolver.openInputStream(uri);
BufferedReader reader = new BufferedReader(new InputStreamReader(is))) {
StringBuilder stringBuilder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
}
content = stringBuilder.toString();
}

return Pair.create(name, content);
});
}
}
Loading

0 comments on commit f80180e

Please sign in to comment.