Manoj Pathak
Manoj Pathak

Reputation: 209

CloudRail implementation of GoogleDrive

Is there any CloudRail sample only for GoogleDrive upload/download? I followed this video and this tuorial and managed to make it working for authentication (Really great tutorials, even for newbies). Then I tried to use github sample for cloud storage, it is working when using the github project but when I try to integrate to my app then the app is not getting CloudRail initial screen and stopping suddenly.

Also the github project is old and using deprecated methods and API for example

setDrawerListener,

Fragment as per android documentation

It would be great if the CouldRail team provide more tutorials like that.

EDIT- below is the source code

MainActivity.java

package com.mpathak.driverail;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import com.cloudrail.si.CloudRail;

public class MainActivity extends AppCompatActivity {

    private static final String BROWSABLE = "android.intent.category.BROWSABLE";
    FileInputStream fileInputStream = null;
    File image = new File(Environment.getExternalStorageDirectory(),"/DCIM/Camera/someImage.jpg");
    CloudStorage googleDriveService = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

       int Service_Number = 1;
       Services.getInstance().prepare(this);
        googleDriveService = Services.getInstance().getService(Service_Number);

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    fileInputStream = new FileInputStream(image);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }

                String imagesavingPath = "/" + image.getName();

                if (fileInputStream != null)
                {
                    googleDriveService.upload(imagesavingPath, fileInputStream, image.length(), true);
                }
                fileInputStream = null;
            }
        });

        setContentView(R.layout.activity_main);
    }

    @Override
    protected void onNewIntent(Intent intent)
    {
        if(intent.getCategories().contains(BROWSABLE)){
            CloudRail.setAuthenticationResponse(intent);
        }

        super.onNewIntent(intent);
    }

    @Override
    protected void onStop() {
        Services.getInstance().storePersistent();
        super.onStop();
    }


}

Services.java

package com.mpathak.driverail;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;

import com.cloudrail.si.CloudRail;
import com.cloudrail.si.exceptions.ParseException;
import com.cloudrail.si.interfaces.CloudStorage;
import com.cloudrail.si.services.GoogleDrive;

import java.util.concurrent.atomic.AtomicReference;

/**
 * This class encapsulates the different services being used by the application. It also initializes
 * them and persists the authentication data.
 *
 */
public class Services {
    private final static String CLOUDRAIL_LICENSE_KEY = "MY_CLOUDRAIL_KEY";
    private final static Services ourInstance = new Services();

    private final AtomicReference<CloudStorage> googledrive = new AtomicReference<>();

    private Activity context = null;

    static Services getInstance() {
        return ourInstance;
    }

    private Services() {
    }

    private void initGoogleDrive() {
        googledrive.set(new GoogleDrive(context, "MY_GOOGLE_ID",
                "", "com.mpathak.driverail:/oauth2redirect", ""));

        try
        {
            ((GoogleDrive) googledrive.get()).useAdvancedAuthentication();
        }
        catch(Exception ex) {

        }
    }

    // --------- Public Methods -----------
    void prepare(Activity context) {
        this.context = context;

        CloudRail.setAppKey(CLOUDRAIL_LICENSE_KEY);

        this.initGoogleDrive();

        SharedPreferences sharedPreferences = context.getPreferences(Context.MODE_PRIVATE);

        try {
            String persistent = sharedPreferences.getString("googledrivePersistent", null);
            if (persistent != null)
            {
                googledrive.get().loadAsString(persistent);
            }

        } catch (ParseException e) {}
    }

    CloudStorage getService(int service) {
        AtomicReference<CloudStorage> ret = new AtomicReference<>();

        switch (service) {
            case 1:
                ret = this.googledrive;
                break;

            default:
                throw new IllegalArgumentException("Unknown service!");
        }

        return ret.get();
    }

    void storePersistent() {
        SharedPreferences sharedPreferences = context.getPreferences(Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();

        editor.putString("googledrivePersistent", googledrive.get().saveAsString());

        editor.apply();
    }
}

AndroidMenifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.mpathak.driverail">

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:launchMode="singleTask">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

             <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data android:scheme="com.mpathak.driverail" />
            </intent-filter>

        </activity>        
    </application>

</manifest>

Upvotes: 1

Views: 267

Answers (1)

Don Wilson
Don Wilson

Reputation: 156

I show below the methods I use for upload and download. They show both the coding I use for Google Drive and for other Storage (One Drive, DropBox, Box). I only upload and download photos and filter accordingly. I found I needed to upload the metadata and the photo inputStream separately. I then read the time stamp. You should find the variable names I self-evident.

I hope this helps, even if it is a bit late.

public Response upload(Photo_Record photo_record, String folder_id, InputStream input_stream, Long size) throws Throwable {
    if (service != null) {
        switch (type) {
            case My_Sources.SOURCE_GOOGLE_DRIVE:
            case My_Sources.SOURCE_GOOGLE_PHOTOS:
                AdvancedRequestSpecification specification = new AdvancedRequestSpecification
                    ("https://www.googleapis.com/upload/drive/v3/files?spaces=drive&uploadType=resumable");
                specification.setMethod("POST");
                specification.disableBaseUrl();
                Map<String, String> params = new HashMap<>();
                params.put("X-Upload-Content-Type", "image/jpeg");
                params.put("X-Upload-Content-Length", Long.toString(size));
                params.put("Content-Type", "application/json; charset=UTF-8");
                specification.setHeaders(params);
                Map<String, Object> content = new HashMap<>();
                content.put("mimeType", "image/jpeg");
                content.put("name", My_Utils.getName(photo_record.getPhoto()));
                content.put("description", photo_record.getDescription(true));
                content.put("parents", Collections.singletonList(folder_id));
                specification.setBodyStringifyJson(content);
                AdvancedRequestResponse response = ((GoogleDrive) service).advancedRequest(specification);
                @SuppressWarnings("unchecked")
                Map<String, String> headersObjectMap = response.getHeaders();
                String location = headersObjectMap.get("Location");
                specification = new AdvancedRequestSpecification(location);
                specification.setMethod("PUT");
                specification.disableBaseUrl();
                params = new HashMap<>();
                params.put("Content-Length", Long.toString(size));
                specification.setHeaders(params);
                specification.setBodyAsStream(input_stream);
                response = ((GoogleDrive) service).advancedRequest(specification);
                @SuppressWarnings("unchecked")
                Map<String, Object> resultObjectMap = (Map<String, Object>) response.getBodyJsonParsed();
                String source_id = (String) resultObjectMap.get("id");
                return new Response(folder_id, source_id, getModifiedTime(source_id));
            default:
                source_id = getSourceIdFromPhoto(photo_record.getPhoto());
                service.upload(source_id, input_stream, size, true);
                return new Response(getParentId(source_id), source_id, getModifiedTime(source_id));
        }
    }
    return new Response("", "", 0L);
}

public InputStream download(String source_id) throws Exception {
    if (service != null) {
        switch (type) {
            case My_Sources.SOURCE_GOOGLE_DRIVE:
            case My_Sources.SOURCE_GOOGLE_PHOTOS:
                AdvancedRequestSpecification specification =
                    new AdvancedRequestSpecification("/files/" + source_id + "?spaces=drive&alt=media");
                AdvancedRequestResponse response = ((GoogleDrive) service).advancedRequest(specification);
                return response.getBodyAsStream();
            default:
                return service.download(source_id);
        }
    }
    return null;
}

private Long getModifiedTime(String source_id) throws Exception {
    if (service != null) {
        try {
            switch (type) {
                case My_Sources.SOURCE_GOOGLE_DRIVE:
                case My_Sources.SOURCE_GOOGLE_PHOTOS:
                    AdvancedRequestSpecification specification = new AdvancedRequestSpecification("/files/" + source_id +
                        "?spaces=drive&fields=modifiedTime");
                    AdvancedRequestResponse response = ((GoogleDrive) service).advancedRequest(specification);
                    @SuppressWarnings("unchecked")
                    Map<String, Object> resultObjectMap = (Map<String, Object>) response.getBodyJsonParsed();
                    return (new org.joda.time.DateTime(resultObjectMap.get("modifiedTime"), DateTimeZone.UTC)).getMillis();
                default:
                    return service.getMetadata(source_id).getModifiedAt();
            }
        } catch (Exception e) {
            My_Utils.logW(this.getClass(), "getModifiedTime() source id %s exception %s",
                source_id, e.toString());
            Crashlytics.logException(e);
        }
    }
    return 0L;
}

Upvotes: 0

Related Questions