├── .gitignore
├── .idea
├── codeStyles
│ └── Project.xml
├── misc.xml
├── modules.xml
├── runConfigurations.xml
└── vcs.xml
├── LICENSE
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── tejpratapsingh
│ │ └── googledriverestandroid
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── tejpratapsingh
│ │ │ └── googledriverestandroid
│ │ │ └── MainActivity.java
│ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ └── ic_launcher_background.xml
│ │ ├── layout
│ │ └── activity_main.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── tejpratapsingh
│ └── googledriverestandroid
│ └── ExampleUnitTest.java
├── build.gradle
├── cover_big.png
├── googledriverest
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── tejpratapsingh
│ │ └── googledriverest
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── tejpratapsingh
│ │ │ └── googledriverest
│ │ │ ├── Helper
│ │ │ ├── GDConstants.java
│ │ │ ├── GDException.java
│ │ │ ├── GDFileManager.java
│ │ │ └── GDUtilities.java
│ │ │ ├── api
│ │ │ └── GDApiManager.java
│ │ │ ├── auth
│ │ │ ├── GDAuthConfig.java
│ │ │ └── GDAuthManager.java
│ │ │ └── modal
│ │ │ ├── GDAuthResponse.java
│ │ │ ├── GDDeleteFileResponse.java
│ │ │ ├── GDDownloadFileResponse.java
│ │ │ ├── GDUploadFileResponse.java
│ │ │ └── GDUserInfo.java
│ └── res
│ │ └── values
│ │ └── strings.xml
│ └── test
│ └── java
│ └── com
│ └── tejpratapsingh
│ └── googledriverest
│ └── ExampleUnitTest.java
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── icons8-cloud-checked-512.png
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | *.apk
3 | *.ap_
4 |
5 | # Files for the ART/Dalvik VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # Generated files
12 | bin/
13 | gen/
14 | out/
15 |
16 | # Gradle files
17 | .gradle/
18 | build/
19 |
20 | # Local configuration file (sdk path, etc)
21 | local.properties
22 |
23 | # Proguard folder generated by Eclipse
24 | proguard/
25 |
26 | # Log Files
27 | *.log
28 |
29 | # Android Studio Navigation editor temp files
30 | .navigation/
31 |
32 | # Android Studio captures folder
33 | captures/
34 |
35 | # IntelliJ
36 | *.iml
37 | .idea/workspace.xml
38 | .idea/tasks.xml
39 | .idea/gradle.xml
40 | .idea/assetWizardSettings.xml
41 | .idea/dictionaries
42 | .idea/libraries
43 | .idea/caches
44 |
45 | # Keystore files
46 | # Uncomment the following line if you do not want to check your keystore files in.
47 | #*.jks
48 |
49 | # External native build folder generated in Android Studio 2.2 and later
50 | .externalNativeBuild
51 |
52 | # Google Services (e.g. APIs or Firebase)
53 | google-services.json
54 |
55 | # Freeline
56 | freeline.py
57 | freeline/
58 | freeline_project_description.json
59 |
60 | # fastlane
61 | fastlane/report.xml
62 | fastlane/Preview.html
63 | fastlane/screenshots
64 | fastlane/test_output
65 | fastlane/readme.md
66 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | xmlns:android
11 |
12 | ^$
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | xmlns:.*
22 |
23 | ^$
24 |
25 |
26 | BY_NAME
27 |
28 |
29 |
30 |
31 |
32 |
33 | .*:id
34 |
35 | http://schemas.android.com/apk/res/android
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | .*:name
45 |
46 | http://schemas.android.com/apk/res/android
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | name
56 |
57 | ^$
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | style
67 |
68 | ^$
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 | .*
78 |
79 | ^$
80 |
81 |
82 | BY_NAME
83 |
84 |
85 |
86 |
87 |
88 |
89 | .*
90 |
91 | http://schemas.android.com/apk/res/android
92 |
93 |
94 | ANDROID_ATTRIBUTE_ORDER
95 |
96 |
97 |
98 |
99 |
100 |
101 | .*
102 |
103 | .*
104 |
105 |
106 | BY_NAME
107 |
108 |
109 |
110 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Tej Pratap Sngh
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://jitpack.io/#tejpratap46/Google-Drive-REST-Android)
2 |
3 | # Google-Drive-REST-Android
4 | Google Drive REST API for android
5 | 
6 | This is a simple wrapper of around Google Drive REST API using OKHTTP.
7 |
8 | # Install via Gradle
9 | Step 1. Add the JitPack repository to your build file
10 | Add it in your root build.gradle at the end of repositories:
11 | ```
12 | allprojects {
13 | repositories {
14 | ...
15 | maven { url 'https://jitpack.io' }
16 | }
17 | }
18 | ```
19 | Step 2. Add the dependency
20 | ```
21 | dependencies {
22 | implementation 'com.github.tejpratap46:Google-Drive-REST-Android:VERSION'
23 | }
24 | ```
25 |
26 | ## Auth
27 | Before you can do any request, you need to authenticate your app with google drive, Best way is to use [Google Sign In For Android](https://developers.google.com/identity/sign-in/android/) with [Offline Access](https://developers.google.com/identity/sign-in/android/offline-access)
28 |
29 | ### Auth Steps
30 | 1. Goto [Google Console Credentials](https://console.developers.google.com/apis/credentials). Make sure Your Google Drive API is turned on for your Google Project.
31 | 2. Create first Auth for Android App (For Google Sign In)
32 | 3. Create another Auth for Web browser App (For Google Drive Rest API)
33 |
34 | In Your Android App code, Auth using offline access, code:
35 | ```java
36 | String serverClientId = "CLIENT_ID_OF_WEB_BROWSER_API";
37 | GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
38 | .requestScopes(new Scope(Scopes.DRIVE_APPFOLDER))
39 | .requestServerAuthCode(serverClientId)
40 | .requestEmail()
41 | .build();
42 |
43 | GoogleSignInClient mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
44 | startActivityForResult(mGoogleSignInClient.getSignInIntent(), REQUEST_CODE_GOOGLE_SIGN_IN);
45 | ```
46 | 4. In your ```onActivityResult(Intent data)```
47 | ```java
48 | Task task = GoogleSignIn.getSignedInAccountFromIntent(data);
49 | try {
50 | GoogleSignInAccount account = task.getResult(ApiException.class);
51 | String authCode = account.getServerAuthCode();
52 |
53 | ArrayList scopes = new ArrayList<>();
54 | scopes.add(GDAuthConfig.SCOPES.EMAIL);
55 | scopes.add(GDAuthConfig.SCOPES.DRIVE);
56 | scopes.add(GDAuthConfig.SCOPES.APP_FOLDER);
57 |
58 | final GDAuthConfig gdAuthConfig = new GDAuthConfig(REDIRECT_URI, CLIENT_ID, CLIENT_SECRET, scopes);
59 |
60 | // Use auth code to get AccessToken
61 | GDApiManager.getInstance().getAuthFromCodeAsync(authCode, gdAuthConfig, new GDAuthResponse.OnAuthResponseListener() {
62 | @Override
63 | public void onSuccess(final GDAuthResponse gdAuthResponse) {
64 | boolean isAuthDataSaved = GDAuthManager.getInstance().setAuthData(MainActivity.this, gdAuthResponse);
65 | }
66 |
67 | @Override
68 | public void onError(GDException exception) {
69 |
70 | }
71 | });
72 | } catch (ApiException e) {
73 | Log.w(TAG, "Sign-in failed", e);
74 | updateUI(null);
75 | }
76 | ```
77 |
78 | ## Available API
79 | 1. ```GDAuthResponse gdAuthResponse = getAuthFromCode(authCode, gdAuthConfig);```
80 | 2. ```GDAuthResponse gdAuthResponse = getAuthFromRefreshToken(context, authCode, previousAuthResponse);```
81 | 3. ```GDUserInfo gdUserInfo = getUserInfo(context, gdAuthResponse, gdAuthConfig);```
82 | 4. ```GDUploadFileResponse fileUploadResponse = uploadFile(context, gdAuthResponse, gdAuthConfig, fileToUpload, fileMime, uploadToAppFolder);```
83 | 5. ```File downloadedFile = downloadFile(context, gdAuthResponse, gdAuthConfig, gdResourceId, fileName)```
84 | 6. ```boolnea isFileDeleted = deleteFile(context, gdAuthResponse, gdAuthConfig, gdResourceId)```
85 |
86 | ### All API's are abailable as Async Requests.
87 |
88 | Fo example, look into [MainActivity](https://github.com/tejpratap46/Google-Drive-REST-Android/blob/master/app/src/main/java/com/tejpratapsingh/googledriverestandroid/MainActivity.java) of app module
89 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 28
5 | defaultConfig {
6 | applicationId "com.tejpratapsingh.googledriverestandroid"
7 | minSdkVersion 14
8 | targetSdkVersion 28
9 | versionCode 1
10 | versionName "1.0"
11 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 | }
20 |
21 | dependencies {
22 | implementation fileTree(dir: 'libs', include: ['*.jar'])
23 | implementation 'androidx.appcompat:appcompat:1.1.0'
24 | implementation 'com.google.android.gms:play-services-auth:17.0.0'
25 | testImplementation 'junit:junit:4.12'
26 | androidTestImplementation 'androidx.test:runner:1.2.0'
27 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
28 |
29 | implementation project(path: ':googledriverest')
30 | }
31 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/tejpratapsingh/googledriverestandroid/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.tejpratapsingh.googledriverestandroid;
2 |
3 | import android.content.Context;
4 |
5 | import androidx.test.platform.app.InstrumentationRegistry;
6 | import androidx.test.ext.junit.runners.AndroidJUnit4;
7 |
8 | import org.junit.Test;
9 | import org.junit.runner.RunWith;
10 |
11 | import static org.junit.Assert.*;
12 |
13 | /**
14 | * Instrumented test, which will execute on an Android device.
15 | *
16 | * @see Testing documentation
17 | */
18 | @RunWith(AndroidJUnit4.class)
19 | public class ExampleInstrumentedTest {
20 | @Test
21 | public void useAppContext() {
22 | // Context of the app under test.
23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
24 |
25 | assertEquals("com.tejpratapsingh.googledriverestandroid", appContext.getPackageName());
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
17 |
18 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tejpratapsingh/googledriverestandroid/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.tejpratapsingh.googledriverestandroid;
2 |
3 | import androidx.appcompat.app.AppCompatActivity;
4 |
5 | import android.app.AlertDialog;
6 | import android.app.ProgressDialog;
7 | import android.content.DialogInterface;
8 | import android.content.Intent;
9 | import android.net.Uri;
10 | import android.os.Bundle;
11 | import android.util.Log;
12 | import android.webkit.WebView;
13 | import android.widget.ArrayAdapter;
14 | import android.widget.Toast;
15 |
16 | import com.google.android.gms.auth.api.signin.GoogleSignIn;
17 | import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
18 | import com.google.android.gms.auth.api.signin.GoogleSignInClient;
19 | import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
20 | import com.google.android.gms.common.api.ApiException;
21 | import com.google.android.gms.common.api.Scope;
22 | import com.google.android.gms.tasks.Task;
23 | import com.tejpratapsingh.googledriverest.Helper.GDException;
24 | import com.tejpratapsingh.googledriverest.Helper.GDFileManager;
25 | import com.tejpratapsingh.googledriverest.api.GDApiManager;
26 | import com.tejpratapsingh.googledriverest.auth.GDAuthConfig;
27 | import com.tejpratapsingh.googledriverest.auth.GDAuthManager;
28 | import com.tejpratapsingh.googledriverest.modal.GDAuthResponse;
29 | import com.tejpratapsingh.googledriverest.modal.GDDownloadFileResponse;
30 | import com.tejpratapsingh.googledriverest.modal.GDUploadFileResponse;
31 |
32 | import java.io.File;
33 | import java.util.ArrayList;
34 |
35 | public class MainActivity extends AppCompatActivity {
36 |
37 | private static final String TAG = "MainActivity";
38 | private GDAuthConfig gdAuthConfig;
39 |
40 | public static final int REQUEST_CODE_GOOGLE_SIGN_IN = 1;
41 |
42 | private final String CLIENT_ID = "CLIENT_ID";
43 | private final String CLIENT_SECRET = "CLIENT_SECRET";
44 | private final String REDIRECT_URI = "https://httpbin1.appspot.com/get";
45 |
46 | ArrayList scopes = new ArrayList<>();
47 |
48 | ProgressDialog loadingDialog = null;
49 |
50 | @Override
51 | protected void onCreate(Bundle savedInstanceState) {
52 | super.onCreate(savedInstanceState);
53 | setContentView(R.layout.activity_main);
54 |
55 | scopes.add(GDAuthConfig.SCOPES.EMAIL);
56 | scopes.add(GDAuthConfig.SCOPES.DRIVE);
57 | scopes.add(GDAuthConfig.SCOPES.APP_FOLDER);
58 |
59 | showAuthOptions();
60 | }
61 |
62 | private void showAuthOptions() {
63 | String[] authOptionList = {"Auth Using Web View", "Auth Using Google Sign In"};
64 | ArrayAdapter authListAdapter = new ArrayAdapter(getApplicationContext(), android.R.layout.simple_list_item_1, authOptionList);
65 |
66 | new AlertDialog.Builder(MainActivity.this)
67 | .setTitle("Choose Auth Method")
68 | .setAdapter(authListAdapter, new DialogInterface.OnClickListener() {
69 | @Override
70 | public void onClick(DialogInterface dialog, int which) {
71 | switch (which) {
72 | case 0:
73 | startGoogleWithWebView();
74 | break;
75 | case 1:
76 | startGoogleSignInAuth();
77 | break;
78 | }
79 | }
80 | })
81 | .create()
82 | .show();
83 | }
84 |
85 | private void startGoogleWithWebView() {
86 | WebView webViewGoogleDrive = (WebView) findViewById(R.id.webViewGoogleDrive);
87 |
88 | GDAuthManager gdAuthManager = GDAuthManager.getInstance();
89 |
90 | try {
91 |
92 | this.gdAuthConfig = new GDAuthConfig("https://httpbin1.appspot.com/get",
93 | CLIENT_ID,
94 | CLIENT_SECRET,
95 | scopes);
96 |
97 | loadingDialog = new ProgressDialog(this); // this = YourActivity
98 | loadingDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
99 | loadingDialog.setTitle("Loading");
100 | loadingDialog.setMessage("Loading. Please wait...");
101 | loadingDialog.setIndeterminate(true);
102 | loadingDialog.setCanceledOnTouchOutside(false);
103 |
104 | gdAuthManager.startGoogleDriveAuth(MainActivity.this, webViewGoogleDrive, this.gdAuthConfig, new GDAuthManager.OnGoogleAuthCompleteListener() {
105 | @Override
106 | public void onLoadingStart() {
107 | // Show loading alert
108 | loadingDialog.show();
109 | }
110 |
111 | @Override
112 | public void onLoadingFinish() {
113 | loadingDialog.dismiss();
114 | }
115 |
116 | @Override
117 | public void onSuccess(final GDAuthResponse gdAuthResponse) {
118 | // Upload a file
119 | showToast("Google Drive Authenticated");
120 |
121 | testGoogleDriveUpload(gdAuthResponse);
122 | }
123 |
124 | @Override
125 | public void onError(GDException exception) {
126 | exception.printStackTrace();
127 | showToast("Error: " + exception.getMessage());
128 | }
129 | });
130 | } catch (GDException e) {
131 | e.printStackTrace();
132 | showToast("Error: " + e.getMessage());
133 | }
134 | }
135 |
136 | private void signOutGoogleSignInUser() {
137 | if (GoogleSignIn.getLastSignedInAccount(getApplicationContext()) != null) {
138 | GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
139 | .requestEmail()
140 | .requestScopes(new Scope(GDAuthConfig.SCOPES.APP_FOLDER.getStringValue()))
141 | .build();
142 |
143 | GoogleSignInClient mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
144 |
145 | mGoogleSignInClient.signOut();
146 | }
147 | }
148 |
149 | private void startGoogleSignInAuth() {
150 | signOutGoogleSignInUser();
151 | final GDAuthManager gdAuthManager = GDAuthManager.getInstance();
152 | gdAuthManager.clearCachedAuthData(getApplicationContext());
153 | try {
154 | final GDAuthConfig gdAuthConfig = new GDAuthConfig(REDIRECT_URI, CLIENT_ID, CLIENT_SECRET, scopes);
155 |
156 | GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
157 | .requestServerAuthCode(gdAuthConfig.getClientId(), true)
158 | .requestEmail()
159 | .requestScopes(new Scope(GDAuthConfig.SCOPES.DRIVE.getStringValue()))
160 | .requestScopes(new Scope(GDAuthConfig.SCOPES.APP_FOLDER.getStringValue()))
161 | .build();
162 |
163 | GoogleSignInClient mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
164 | startActivityForResult(mGoogleSignInClient.getSignInIntent(), REQUEST_CODE_GOOGLE_SIGN_IN);
165 | } catch (GDException e) {
166 | e.printStackTrace();
167 | }
168 | }
169 |
170 | @Override
171 | public void onActivityResult(int requestCode, int resultCode, Intent data) {
172 | Log.d(TAG, "onActivityResult: ");
173 | super.onActivityResult(requestCode, resultCode, data);
174 |
175 | // Result returned from launching the Intent from GoogleSignInClient.getSignInIntent(...);
176 | if (requestCode == REQUEST_CODE_GOOGLE_SIGN_IN) {
177 | // The Task returned from this call is always completed, no need to attach
178 | // a listener.
179 | Task task = GoogleSignIn.getSignedInAccountFromIntent(data);
180 | handleSignInResult(task);
181 | }
182 | }
183 |
184 | private void handleSignInResult(Task completedTask) {
185 | try {
186 | final GDAuthConfig gdAuthConfig = new GDAuthConfig(REDIRECT_URI, CLIENT_ID, CLIENT_SECRET, scopes);
187 | GoogleSignInAccount account = completedTask.getResult(ApiException.class);
188 |
189 | // Get Auth from access code
190 | GDApiManager.getInstance().getAuthFromCodeAsync(account.getServerAuthCode(), gdAuthConfig, new GDAuthResponse.OnAuthResponseListener() {
191 | @Override
192 | public void onSuccess(final GDAuthResponse gdAuthResponse) {
193 |
194 | runOnUiThread(new Runnable() {
195 | @Override
196 | public void run() {
197 | // Save auth data to preferences, call: GDAuthManager.getInstance().getAuthData(MainActivity.this) to read it anytime
198 | boolean isAuthDataSaved = GDAuthManager.getInstance().setAuthData(MainActivity.this, gdAuthResponse);
199 | if (isAuthDataSaved == false) {
200 | return;
201 | }
202 |
203 | testGoogleDriveUpload(gdAuthResponse);
204 | }
205 | });
206 | }
207 |
208 | @Override
209 | public void onError(GDException exception) {
210 |
211 | }
212 | });
213 | } catch (ApiException e) {
214 | // The ApiException status code indicates the detailed failure reason.
215 | // Please refer to the GoogleSignInStatusCodes class reference for more information.
216 | e.printStackTrace();
217 | Log.w(TAG, "signInResult:failed code=" + e.getStatusCode());
218 | showToast("Error while connecting to Google");
219 | } catch (GDException e) {
220 | e.printStackTrace();
221 | }
222 | }
223 |
224 | private void testGoogleDriveUpload(final GDAuthResponse gdAuthResponse) {
225 | File tempFile = GDFileManager.getInstance().createTempFile(getApplicationContext(), "txt", false);
226 | try {
227 | // Create a temp Text file
228 | GDFileManager.getInstance().saveStringToFile(tempFile, "This is a test file Created by Google_Drive_REST_Android Library");
229 |
230 | // Upload this file to google drive.
231 | GDApiManager.getInstance().uploadFileAsync(getApplicationContext(), gdAuthResponse, MainActivity.this.gdAuthConfig, tempFile, GDFileManager.getInstance().getMimeType(getApplicationContext(), tempFile), false, new GDUploadFileResponse.OnUploadFileCompleteListener() {
232 | @Override
233 | public void onSuccess(GDUploadFileResponse uploadFileResponse) {
234 | showToast("File Uploaded Successfully");
235 |
236 | // Download just uploaded file
237 | GDApiManager.getInstance().downloadFileAsync(getApplicationContext(), gdAuthResponse, MainActivity.this.gdAuthConfig, uploadFileResponse.getId(), "downloaded_file.txt", new GDDownloadFileResponse.OnDownloadFileCompleteListener() {
238 | @Override
239 | public void onSuccess(File downloadedFile) {
240 | // Check for a download file in your private files
241 | // In here: Internal Storage > Android > data > com.tejpratapsingh.com > files
242 | showToast("File Downloaded Successfully");
243 | showAlert("Sample Text file is successfully Uploaded and Downloaded from Google Drive. Check you Google Drive.");
244 | }
245 |
246 | @Override
247 | public void onError(GDException exception) {
248 | showToast("Error: " + exception.getMessage());
249 | showAlert("Sample Text file is successfully Uploaded to Google Drive. But failed to Download it.");
250 | }
251 | });
252 | }
253 |
254 | @Override
255 | public void onError(GDException exception) {
256 | showToast("Error: " + exception.getMessage());
257 | showAlert("Sample Text file is Failed to Upload to Google Drive.");
258 | }
259 | });
260 | } catch (GDException e) {
261 | e.printStackTrace();
262 | showToast("Error: " + e.getMessage());
263 | }
264 | }
265 |
266 | private void showToast(final String message) {
267 | runOnUiThread(new Runnable() {
268 | @Override
269 | public void run() {
270 | Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show();
271 | }
272 | });
273 | }
274 |
275 | private void showAlert(final String text) {
276 |
277 | runOnUiThread(new Runnable() {
278 | @Override
279 | public void run() {
280 | new AlertDialog.Builder(MainActivity.this)
281 | .setTitle(R.string.app_name)
282 | .setMessage(text)
283 | .setPositiveButton(R.string.text_retry, new DialogInterface.OnClickListener() {
284 | @Override
285 | public void onClick(DialogInterface dialog, int which) {
286 | showAuthOptions();
287 | }
288 | })
289 | .setNegativeButton(R.string.text_cancel, new DialogInterface.OnClickListener() {
290 | @Override
291 | public void onClick(DialogInterface dialog, int which) {
292 | finish();
293 | }
294 | })
295 | .setNeutralButton(R.string.text_icon8, new DialogInterface.OnClickListener() {
296 | @Override
297 | public void onClick(DialogInterface dialog, int which) {
298 | String url = "http://www.icon8.com";
299 | Intent i = new Intent(Intent.ACTION_VIEW);
300 | i.setData(Uri.parse(url));
301 | startActivity(i);
302 | }
303 | })
304 | .create()
305 | .show();
306 | }
307 | });
308 | }
309 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tejpratap46/Google-Drive-REST-Android/f336dcfe1cf485e5a87ced81dc51bbf377e67e08/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tejpratap46/Google-Drive-REST-Android/f336dcfe1cf485e5a87ced81dc51bbf377e67e08/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tejpratap46/Google-Drive-REST-Android/f336dcfe1cf485e5a87ced81dc51bbf377e67e08/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tejpratap46/Google-Drive-REST-Android/f336dcfe1cf485e5a87ced81dc51bbf377e67e08/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tejpratap46/Google-Drive-REST-Android/f336dcfe1cf485e5a87ced81dc51bbf377e67e08/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tejpratap46/Google-Drive-REST-Android/f336dcfe1cf485e5a87ced81dc51bbf377e67e08/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tejpratap46/Google-Drive-REST-Android/f336dcfe1cf485e5a87ced81dc51bbf377e67e08/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tejpratap46/Google-Drive-REST-Android/f336dcfe1cf485e5a87ced81dc51bbf377e67e08/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tejpratap46/Google-Drive-REST-Android/f336dcfe1cf485e5a87ced81dc51bbf377e67e08/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tejpratap46/Google-Drive-REST-Android/f336dcfe1cf485e5a87ced81dc51bbf377e67e08/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #008577
4 | #00574B
5 | #D81B60
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Google Drive Rest Android
3 | Web View
4 | Auth Using Web Browser
5 | Auth Using Google Sign In
6 | Retry
7 | Cancel
8 | Icons from icon8.com
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/test/java/com/tejpratapsingh/googledriverestandroid/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.tejpratapsingh.googledriverestandroid;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | google()
6 | jcenter()
7 |
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:3.5.0'
11 |
12 | // NOTE: Do not place your application dependencies here; they belong
13 | // in the individual module build.gradle files
14 | }
15 | }
16 |
17 | allprojects {
18 | repositories {
19 | google()
20 | jcenter()
21 |
22 | }
23 | }
24 |
25 | task clean(type: Delete) {
26 | delete rootProject.buildDir
27 | }
28 |
--------------------------------------------------------------------------------
/cover_big.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tejpratap46/Google-Drive-REST-Android/f336dcfe1cf485e5a87ced81dc51bbf377e67e08/cover_big.png
--------------------------------------------------------------------------------
/googledriverest/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/googledriverest/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 28
5 |
6 | defaultConfig {
7 | minSdkVersion 14
8 | targetSdkVersion 28
9 | versionCode 1
10 | versionName "1.0"
11 |
12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
13 |
14 | }
15 |
16 | buildTypes {
17 | release {
18 | minifyEnabled false
19 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
20 | }
21 | }
22 |
23 | }
24 |
25 | dependencies {
26 | implementation fileTree(dir: 'libs', include: ['*.jar'])
27 |
28 | implementation 'com.squareup.okhttp3:okhttp:4.2.0'
29 | }
30 |
--------------------------------------------------------------------------------
/googledriverest/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/googledriverest/src/androidTest/java/com/tejpratapsingh/googledriverest/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.tejpratapsingh.googledriverest;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.tejpratapsingh.googledriverest.test", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/googledriverest/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/googledriverest/src/main/java/com/tejpratapsingh/googledriverest/Helper/GDConstants.java:
--------------------------------------------------------------------------------
1 | package com.tejpratapsingh.googledriverest.Helper;
2 |
3 | public class GDConstants {
4 |
5 | public static final String GD_PREFS_NAME = "GD_PREFS";
6 | public static final String GD_PREFS_ACCESS_TOKEN = "GD_PREF_ACCESS_TOKEN";
7 | public static final String GD_PREFS_REFRESH_TOKEN = "GD_PREF_REFRESH_TOKEN";
8 | public static final String GD_PREFS_TOKEN_EXPIRES_AT = "GD_PREFS_TOKEN_EXPIRES_AT";
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/googledriverest/src/main/java/com/tejpratapsingh/googledriverest/Helper/GDException.java:
--------------------------------------------------------------------------------
1 | package com.tejpratapsingh.googledriverest.Helper;
2 |
3 | public class GDException extends Exception {
4 | public GDException(String message) {
5 | super(message);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/googledriverest/src/main/java/com/tejpratapsingh/googledriverest/Helper/GDFileManager.java:
--------------------------------------------------------------------------------
1 | package com.tejpratapsingh.googledriverest.Helper;
2 |
3 | import android.content.Context;
4 | import android.database.Cursor;
5 | import android.net.Uri;
6 | import android.provider.OpenableColumns;
7 | import android.webkit.MimeTypeMap;
8 |
9 | import java.io.File;
10 | import java.io.FileOutputStream;
11 | import java.io.FileWriter;
12 | import java.io.IOException;
13 | import java.io.InputStream;
14 | import java.net.URLConnection;
15 | import java.util.Date;
16 |
17 | public class GDFileManager {
18 | private static final GDFileManager ourInstance = new GDFileManager();
19 |
20 | public static GDFileManager getInstance() {
21 | return ourInstance;
22 | }
23 |
24 | private GDFileManager() {
25 | }
26 |
27 | private final String tempDirectoryName = "temp";
28 | private final String tempDuplicateFileNameSuffix = "dup";
29 |
30 |
31 |
32 | /**
33 | * Write file from InputStream, file will be overwritten if exist
34 | *
35 | * @param context context
36 | * @param inputStream input stream reader of data (file)
37 | * @param fileName name of file which has to saved
38 | * @param overWriteIfExist if true, file will be overwritten if exist
39 | * @return saved file
40 | * @throws IOException
41 | */
42 | public File saveFileToPrivateStorageFromInputStream(Context context, InputStream inputStream, String fileName, boolean overWriteIfExist) throws GDException, IOException {
43 | // Start referencing a new file
44 | File fileToSave = new File(context.getExternalFilesDir(null), fileName);
45 | if (overWriteIfExist == false) {
46 | // Check if file already exist or not, return if exist
47 | boolean isFileAlreadyExist = hasExternalStoragePrivateFile(context, fileName);
48 | if (isFileAlreadyExist) {
49 | throw new GDException("File Already Exists, make it overWritable to replace.");
50 | }
51 | }
52 | FileOutputStream fileOutput = new FileOutputStream(fileToSave);
53 |
54 | byte[] buffer = new byte[1024];
55 | int bufferLength = 0;
56 |
57 | while ((bufferLength = inputStream.read(buffer)) > 0) {
58 | fileOutput.write(buffer, 0, bufferLength);
59 | }
60 | fileOutput.flush();
61 | fileOutput.close();
62 | inputStream.close();
63 | return fileToSave;
64 | }
65 |
66 | /**
67 | * Check if file is available in private storage
68 | *
69 | * @param context context
70 | * @param fileName Name of file in external private storage to be checked
71 | * @return boolean is file exist or not
72 | */
73 | public boolean hasExternalStoragePrivateFile(Context context, String fileName) {
74 | // Get path for the file on external storage.
75 | // If external storage is not currently mounted this will fail.
76 | File file = new File(context.getExternalFilesDir(null), fileName);
77 | if (file != null) {
78 | return file.exists();
79 | }
80 | return false;
81 | }
82 |
83 | private boolean makeDirectoryInPrivateStorage(Context context, String directoryName) {
84 | File randomDirectory = new File(context.getExternalFilesDir(null) + File.separator + directoryName);
85 | if (!randomDirectory.exists()) {
86 | System.out.println("creating directory: " + directoryName);
87 | randomDirectory.mkdir();
88 | }
89 | return true;
90 | }
91 |
92 | /**
93 | * Save a string in file
94 | *
95 | * @param fileToWrite
96 | * @param dataToWrite
97 | * @return
98 | * @throws GDException
99 | */
100 | public File saveStringToFile(File fileToWrite, String dataToWrite) throws GDException {
101 | try {
102 | FileWriter fw = new FileWriter(fileToWrite);
103 | fw.write(dataToWrite);
104 | fw.close();
105 | return fileToWrite;
106 | } catch (IOException e) {
107 | e.printStackTrace();
108 | throw new GDException(e.getMessage());
109 | }
110 | }
111 |
112 | /**
113 | * Get Temp folder from private storage (create one if not exist)
114 | *
115 | * @param context current context
116 | * @return temp folder location (path)
117 | */
118 | public String getTempFolder(Context context) {
119 | File tempDirectory = new File(context.getExternalFilesDir(null) + File.separator + tempDirectoryName);
120 | if (!tempDirectory.exists()) {
121 | System.out.println("creating directory: temp");
122 | tempDirectory.mkdir();
123 | }
124 |
125 | return tempDirectory.getAbsolutePath();
126 | }
127 |
128 | /**
129 | * Create a temporary file in temp folder
130 | *
131 | * @param context current context
132 | * @param withExtension specify file extension
133 | * @param withDuplicate create a duplicate of temp file (used in case of image processing), DUPLICATE FILES ARE JUST A EMPTY FILE PATH, ALL FILE MANAGEMENT HAS TO BE DONE BY YOU.
134 | * @return created temp file
135 | */
136 | public File createTempFile(Context context, String withExtension, boolean withDuplicate) {
137 | // Actual temp file
138 | String tempFileName = Long.toString(new Date().getTime());
139 | if (withExtension != null && withExtension.isEmpty() == false) {
140 | tempFileName = tempFileName + "." + withExtension;
141 | }
142 | File tempFile = new File(getTempFolder(context), tempFileName);
143 | if (withDuplicate) {
144 | // Duplicate of temp file
145 | File tempDuplicateFile = new File(getTempFolder(context), tempFileName + tempDuplicateFileNameSuffix);
146 | }
147 |
148 | return tempFile;
149 | }
150 |
151 | /**
152 | * Create a temporary file in temp folder with user given name, file will be overwritten if name is collapsed
153 | *
154 | * @param context current context
155 | * @param withDuplicate create a duplicate of temp file (used in case of image processing), DUPLICATE FILES ARE JUST A EMPTY FILE PATH, ALL FILE MANAGEMENT HAS TO BE DONE BY YOU.
156 | * @return created temp file
157 | */
158 | public File createTempFileWithName(Context context, String tempFileName, boolean withDuplicate) {
159 | // Actual temp file
160 | File tempFile = new File(getTempFolder(context), tempFileName);
161 | if (withDuplicate) {
162 | // Duplicate of temp file
163 | File tempDuplicateFile = new File(getTempFolder(context), tempFileName + tempDuplicateFileNameSuffix);
164 | }
165 |
166 | return tempFile;
167 | }
168 |
169 | /**
170 | * Get Mime type from a file
171 | *
172 | * @param file file whose mime type has to find
173 | * @return mime type of string
174 | */
175 | public String getMimeType(Context context, File file) {
176 | String type = null;
177 | String extension = MimeTypeMap.getFileExtensionFromUrl(file.getAbsolutePath());
178 | if (extension != null) {
179 | type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
180 | }
181 | if (type == null) {
182 | try {
183 | type = file.toURI().toURL().openConnection().getContentType();
184 | } catch (IOException e) {
185 | e.printStackTrace();
186 | }
187 | }
188 | if (type == null) {
189 | type = context.getContentResolver().getType(Uri.fromFile(file));
190 | }
191 | if (type == null) {
192 | type = URLConnection.guessContentTypeFromName(file.getName());
193 | }
194 | if (type == null) {
195 | // If nothing worked, just set mime type to empty string
196 | type = "";
197 | }
198 | return type;
199 | }
200 |
201 | public File getFileFromURI(Context context, Uri contentUri) {
202 | try {
203 | InputStream inputStream = context.getContentResolver().openInputStream(contentUri);
204 | File fileToSave = createTempFile(context, getFileExtension(new File(getFileName(context, contentUri))), false);
205 | FileOutputStream fileOutput = new FileOutputStream(fileToSave);
206 |
207 | byte[] buffer = new byte[1024];
208 | int bufferLength = 0;
209 |
210 | while ((bufferLength = inputStream.read(buffer)) > 0) {
211 | fileOutput.write(buffer, 0, bufferLength);
212 | }
213 | fileOutput.flush();
214 | fileOutput.close();
215 | inputStream.close();
216 | return fileToSave;
217 | } catch (IOException e) {
218 | e.printStackTrace();
219 | return null;
220 | }
221 | }
222 |
223 | /**
224 | * Gte file's extension without "."
225 | *
226 | * @param sourceFile whole extension has to be found
227 | * @return file extension without "."
228 | */
229 | public String getFileExtension(File sourceFile) {
230 | if (sourceFile == null || sourceFile.getName().lastIndexOf(".") <= 0) {
231 | return null;
232 | }
233 | String[] fileNameParts = sourceFile.getName().split("\\.");
234 | return fileNameParts[fileNameParts.length - 1];
235 | }
236 |
237 | public String getFileName(Context context, Uri uri) {
238 | String result = null;
239 | if (uri.getScheme().equals("content")) {
240 | Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
241 | try {
242 | if (cursor != null && cursor.moveToFirst()) {
243 | result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
244 | }
245 | } finally {
246 | cursor.close();
247 | }
248 | }
249 | if (result == null) {
250 | result = uri.getPath();
251 | int cut = result.lastIndexOf('/');
252 | if (cut != -1) {
253 | result = result.substring(cut + 1);
254 | }
255 | }
256 | return result;
257 | }
258 | }
259 |
--------------------------------------------------------------------------------
/googledriverest/src/main/java/com/tejpratapsingh/googledriverest/Helper/GDUtilities.java:
--------------------------------------------------------------------------------
1 | package com.tejpratapsingh.googledriverest.Helper;
2 |
3 | import java.io.UnsupportedEncodingException;
4 | import java.net.URL;
5 | import java.net.URLDecoder;
6 | import java.util.LinkedHashMap;
7 | import java.util.Map;
8 |
9 | public class GDUtilities {
10 | public static Map splitQuery(URL url) throws UnsupportedEncodingException {
11 | Map query_pairs = new LinkedHashMap();
12 | String query = url.getQuery();
13 | String[] pairs = query.split("&");
14 | for (String pair : pairs) {
15 | int idx = pair.indexOf("=");
16 | query_pairs.put(URLDecoder.decode(pair.substring(0, idx), "UTF-8"), URLDecoder.decode(pair.substring(idx + 1), "UTF-8"));
17 | }
18 | return query_pairs;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/googledriverest/src/main/java/com/tejpratapsingh/googledriverest/api/GDApiManager.java:
--------------------------------------------------------------------------------
1 | package com.tejpratapsingh.googledriverest.api;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 | import android.os.AsyncTask;
6 |
7 | import com.tejpratapsingh.googledriverest.Helper.GDConstants;
8 | import com.tejpratapsingh.googledriverest.Helper.GDException;
9 | import com.tejpratapsingh.googledriverest.Helper.GDFileManager;
10 | import com.tejpratapsingh.googledriverest.auth.GDAuthConfig;
11 | import com.tejpratapsingh.googledriverest.modal.GDAuthResponse;
12 | import com.tejpratapsingh.googledriverest.modal.GDDeleteFileResponse;
13 | import com.tejpratapsingh.googledriverest.modal.GDDownloadFileResponse;
14 | import com.tejpratapsingh.googledriverest.modal.GDUploadFileResponse;
15 | import com.tejpratapsingh.googledriverest.modal.GDUserInfo;
16 |
17 | import org.json.JSONException;
18 | import org.json.JSONObject;
19 |
20 | import java.io.File;
21 | import java.io.IOException;
22 | import java.io.InputStream;
23 | import java.util.Locale;
24 |
25 | import okhttp3.MediaType;
26 | import okhttp3.OkHttpClient;
27 | import okhttp3.Request;
28 | import okhttp3.RequestBody;
29 | import okhttp3.Response;
30 |
31 | import static android.content.Context.MODE_PRIVATE;
32 |
33 | public class GDApiManager {
34 | private static final String TAG = "GDApiManager";
35 |
36 | private OkHttpClient client;
37 |
38 | private static final GDApiManager ourInstance = new GDApiManager();
39 |
40 | public static GDApiManager getInstance() {
41 | return ourInstance;
42 | }
43 |
44 | private GDApiManager() {
45 | this.client = new OkHttpClient();
46 | }
47 |
48 | public void getAuthFromCodeAsync(final String code, final GDAuthConfig config, final GDAuthResponse.OnAuthResponseListener onAuthResponseListener) {
49 | AsyncTask.execute(new Runnable() {
50 | @Override
51 | public void run() {
52 | try {
53 | onAuthResponseListener.onSuccess(getInstance().getAuthFromCode(code, config));
54 | } catch (GDException e) {
55 | onAuthResponseListener.onError(e);
56 | }
57 | }
58 | });
59 | }
60 |
61 | public GDAuthResponse getAuthFromCode(final String code, final GDAuthConfig config) throws GDException {
62 | String requestBody = String.format("code=%s&client_id=%s&client_secret=%s&redirect_uri=%s&grant_type=authorization_code", code, config.getClientId(), config.getClientSecret(), config.getRedirectURI());
63 |
64 | MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
65 | RequestBody body = RequestBody.create(mediaType, requestBody);
66 | Request request = new Request.Builder()
67 | .url("https://www.googleapis.com/oauth2/v4/token")
68 | .post(body)
69 | .addHeader("content-type", "application/x-www-form-urlencoded")
70 | .build();
71 |
72 | try {
73 | Response response = getInstance().client.newCall(request).execute();
74 | try {
75 | JSONObject responseJSON = new JSONObject(response.body().string());
76 |
77 | GDAuthResponse gdAuthResponse = new GDAuthResponse(
78 | responseJSON.getString("access_token"),
79 | responseJSON.getString("refresh_token"),
80 | (System.currentTimeMillis() / 1000) + responseJSON.getLong("expires_in")
81 | );
82 |
83 | return gdAuthResponse;
84 |
85 | } catch (JSONException e) {
86 | e.printStackTrace();
87 | throw new GDException(e.getMessage());
88 | }
89 |
90 | } catch (IOException e) {
91 | e.printStackTrace();
92 | throw new GDException(e.getMessage());
93 | }
94 | }
95 |
96 | public void getAuthFromRefreshTokenAsync(final Context context, final GDAuthResponse previousAuthResponse, final GDAuthConfig config, final GDAuthResponse.OnAuthResponseListener onAuthResponseListener) {
97 | AsyncTask.execute(new Runnable() {
98 | @Override
99 | public void run() {
100 | try {
101 | onAuthResponseListener.onSuccess(getInstance().getAuthFromRefreshToken(context, previousAuthResponse, config));
102 | } catch (GDException e) {
103 | onAuthResponseListener.onError(e);
104 | }
105 | }
106 | });
107 | }
108 |
109 | public GDAuthResponse getAuthFromRefreshToken(final Context context, final GDAuthResponse previousAuthResponse, final GDAuthConfig config) throws GDException {
110 | MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
111 | RequestBody body = RequestBody.create(
112 | mediaType, String.format(Locale.getDefault(), "client_id=%s&client_secret=%s&redirect_uri=%s&grant_type=refresh_token&refresh_token=%s", config.getClientId(), config.getClientSecret(), config.getRedirectURI(), previousAuthResponse.getRefreshToken())
113 | );
114 | Request request = new Request.Builder()
115 | .url("https://www.googleapis.com/oauth2/v4/token")
116 | .post(body)
117 | .addHeader("cache-control", "no-cache")
118 | .addHeader("content-type", "application/x-www-form-urlencoded")
119 | .build();
120 |
121 | try {
122 | Response response = getInstance().client.newCall(request).execute();
123 | try {
124 | JSONObject responseJSON = new JSONObject(response.body().string());
125 |
126 | GDAuthResponse gdAuthResponse = new GDAuthResponse(
127 | responseJSON.getString("access_token"),
128 | previousAuthResponse.getRefreshToken(),
129 | (System.currentTimeMillis() / 1000) + responseJSON.getInt("expires_in")
130 | );
131 |
132 | SharedPreferences.Editor editor = context.getSharedPreferences(GDConstants.GD_PREFS_NAME, MODE_PRIVATE).edit();
133 | editor.putString(GDConstants.GD_PREFS_ACCESS_TOKEN, gdAuthResponse.getAccessToken());
134 | editor.putString(GDConstants.GD_PREFS_REFRESH_TOKEN, gdAuthResponse.getRefreshToken());
135 | editor.putLong(GDConstants.GD_PREFS_TOKEN_EXPIRES_AT, gdAuthResponse.getExpiresAtTimestamp());
136 | editor.apply();
137 |
138 | return gdAuthResponse;
139 |
140 | } catch (JSONException e) {
141 | e.printStackTrace();
142 | throw new GDException(e.getMessage());
143 | }
144 | } catch (IOException e) {
145 | e.printStackTrace();
146 | throw new GDException(e.getMessage());
147 | }
148 | }
149 |
150 | /**
151 | * Get user information if you asked for SCOPE: EMAIL
152 | * in BACKGROUND
153 | *
154 | * @param gdAuthResponse Auth credentials
155 | * @param onUserInfoReceivedListener onComplete event listener
156 | */
157 | public void getUserInfoAsync(final Context context, final GDAuthResponse gdAuthResponse, final GDAuthConfig authConfig, final GDUserInfo.OnUserInfoReceivedListener onUserInfoReceivedListener) {
158 | AsyncTask.execute(new Runnable() {
159 | @Override
160 | public void run() {
161 | try {
162 | onUserInfoReceivedListener.onSuccess(getInstance().getUserInfo(context, gdAuthResponse, authConfig));
163 | } catch (GDException e) {
164 | e.printStackTrace();
165 | onUserInfoReceivedListener.onError(e);
166 | }
167 | }
168 | });
169 | }
170 |
171 | /**
172 | * Get user information if you asked for SCOPE: EMAIL
173 | * in CURRENT thread
174 | *
175 | * @param gdAuthResponse Auth credentials
176 | * @return user info
177 | * @throws GDException if any error occurred
178 | */
179 | public GDUserInfo getUserInfo(final Context context, GDAuthResponse gdAuthResponse, final GDAuthConfig authConfig) throws GDException {
180 |
181 | if (gdAuthResponse.isExpired()) {
182 | // Get access token again from refresh token
183 | gdAuthResponse = this.getAuthFromRefreshToken(context, gdAuthResponse, authConfig);
184 | }
185 | Request request = new Request.Builder()
186 | .url("https://www.googleapis.com/oauth2/v3/userinfo?access_token=" + gdAuthResponse.getAccessToken())
187 | .get()
188 | .build();
189 |
190 | try {
191 | Response response = getInstance().client.newCall(request).execute();
192 |
193 | try {
194 | JSONObject userJSONObject = new JSONObject(response.body().string());
195 |
196 | return new GDUserInfo(userJSONObject.has("name") ? userJSONObject.getString("name") : "",
197 | userJSONObject.getString("email"), // Email is not optional
198 | userJSONObject.has("profile") ? userJSONObject.getString("profile") : "",
199 | userJSONObject.has("picture") ? userJSONObject.getString("picture") : "");
200 |
201 | } catch (JSONException e) {
202 | e.printStackTrace();
203 | throw new GDException(e.getMessage());
204 | }
205 | } catch (IOException e) {
206 | e.printStackTrace();
207 | throw new GDException(e.getMessage());
208 | }
209 | }
210 |
211 | /**
212 | * Upload file to google drive in BACKGROUND thread
213 | *
214 | * @param gdAuthResponse auth credentials from google response
215 | * @param fileToUpload file to upload to google drive
216 | * @param fileMime mime type of file, can be fetched from GDFileManager.getMimeType
217 | * @param uploadToAppFolder true if you want to use app folder in google drive (files won't be visible to user)
218 | * @param uploadFileListener listener for success or exception
219 | */
220 | public void uploadFileAsync(final Context context, final GDAuthResponse gdAuthResponse, final GDAuthConfig authConfig, final File fileToUpload, final String fileMime, final boolean uploadToAppFolder, final GDUploadFileResponse.OnUploadFileCompleteListener uploadFileListener) {
221 | AsyncTask.execute(new Runnable() {
222 | @Override
223 | public void run() {
224 | try {
225 | GDUploadFileResponse gdUploadFileResponse = getInstance().uploadFile(context, gdAuthResponse, authConfig, fileToUpload, fileMime, uploadToAppFolder);
226 | uploadFileListener.onSuccess(gdUploadFileResponse);
227 | } catch (GDException e) {
228 | uploadFileListener.onError(e);
229 | }
230 | }
231 | });
232 | }
233 |
234 | /**
235 | * Upload file to google drive in CURRENT thread
236 | *
237 | * @param gdAuthResponse auth credentials from google response
238 | * @param fileToUpload file to upload to google drive
239 | * @param fileMime mime type of file, can be fetched from GDFileManager.getMimeType
240 | * @param uploadToAppFolder true if you want to use app folder in google drive (files won't be visible to user)
241 | * @return GDUploadFileResponse object with fileId and name
242 | * @throws GDException if any error occurred
243 | */
244 | public GDUploadFileResponse uploadFile(final Context context, GDAuthResponse gdAuthResponse, final GDAuthConfig authConfig, final File fileToUpload, final String fileMime, final boolean uploadToAppFolder) throws GDException {
245 |
246 | if (gdAuthResponse.isExpired()) {
247 | // Get access token again from refresh token
248 | gdAuthResponse = this.getAuthFromRefreshToken(context, gdAuthResponse, authConfig);
249 | }
250 | MediaType mediaType = MediaType.parse("application/json");
251 | RequestBody body = RequestBody.create("{\"name\": \"" + fileToUpload.getName() + "\"}", mediaType);
252 | if (uploadToAppFolder) {
253 | body = RequestBody.create("{\"name\": \"" + fileToUpload.getName() + "\", \"parents\":[\"appDataFolder\"]}", mediaType);
254 | }
255 | Request fileCreateRequest = new Request.Builder()
256 | .url("https://www.googleapis.com/drive/v3/files")
257 | .post(body)
258 | .addHeader("Authorization", "Bearer " + gdAuthResponse.getAccessToken())
259 | .addHeader("accept", "application/json")
260 | .addHeader("content-type", "application/json")
261 | .build();
262 |
263 | try {
264 | Response fileCreateResponse = getInstance().client.newCall(fileCreateRequest).execute();
265 |
266 | JSONObject fileCreteResponseJSONObject = new JSONObject(fileCreateResponse.body().string());
267 |
268 | MediaType mediaMimeType = MediaType.parse(fileMime);
269 |
270 | Request fileUploadRequest = new Request.Builder()
271 | .url("https://www.googleapis.com/upload/drive/v3/files/" + fileCreteResponseJSONObject.getString("id") + "?uploadType=media")
272 | .patch(RequestBody.create(mediaMimeType, fileToUpload))
273 | .addHeader("Authorization", "Bearer " + gdAuthResponse.getAccessToken())
274 | .addHeader("Content-Type", fileMime)
275 | .addHeader("Content-Length", "" + fileToUpload.length())
276 | .build();
277 |
278 | try {
279 | Response fileUploadResponse = getInstance().client.newCall(fileUploadRequest).execute();
280 |
281 | JSONObject fileUploadResponseJSONObject = new JSONObject(fileUploadResponse.body().string());
282 |
283 | return new GDUploadFileResponse(
284 | fileUploadResponseJSONObject.getString("id"),
285 | fileUploadResponseJSONObject.getString("name"),
286 | fileUploadResponseJSONObject.getString("mimeType")
287 | );
288 | } catch (IOException | JSONException e) {
289 | e.printStackTrace();
290 | throw new GDException(e.getMessage());
291 | }
292 | } catch (IOException | JSONException e) {
293 | e.printStackTrace();
294 | throw new GDException(e.getMessage());
295 | }
296 | }
297 |
298 |
299 | /**
300 | * Download file in BACKGROUND thread
301 | *
302 | * @param context to get local folder of application
303 | * @param gdAuthResponse Auth credentials
304 | * @param gdFileId fileId to download
305 | * @param fileName name of saved file
306 | * @param downloadFileCompleteListener on complete event
307 | */
308 | public void downloadFileAsync(final Context context, final GDAuthResponse gdAuthResponse, final GDAuthConfig authConfig, final String gdFileId, final String fileName, final GDDownloadFileResponse.OnDownloadFileCompleteListener downloadFileCompleteListener) {
309 | AsyncTask.execute(new Runnable() {
310 | @Override
311 | public void run() {
312 | try {
313 | downloadFileCompleteListener.onSuccess(getInstance().downloadFile(context, gdAuthResponse, authConfig, gdFileId, fileName));
314 | } catch (GDException e) {
315 | downloadFileCompleteListener.onError(e);
316 | }
317 | }
318 | });
319 | }
320 |
321 |
322 | /**
323 | * Download file in CURRENT thread
324 | *
325 | * @param context to get local folder of application
326 | * @param gdAuthResponse Auth credentials
327 | * @param gdFileId fileId to download
328 | * @param fileName name of saved file
329 | * @return saved File
330 | * @throws GDException if any error occurred
331 | */
332 | public File downloadFile(final Context context, GDAuthResponse gdAuthResponse, final GDAuthConfig authConfig, final String gdFileId, final String fileName) throws GDException {
333 |
334 | if (gdAuthResponse.isExpired()) {
335 | // Get access token again from refresh token
336 | gdAuthResponse = this.getAuthFromRefreshToken(context, gdAuthResponse, authConfig);
337 | }
338 | Request request = new Request.Builder()
339 | .url("https://www.googleapis.com/drive/v3/files/" + gdFileId + "?alt=media")
340 | .get()
341 | .addHeader("authorization", "Bearer " + gdAuthResponse.getAccessToken())
342 | .build();
343 |
344 | try {
345 | Response response = getInstance().client.newCall(request).execute();
346 | if (response.isSuccessful()) {
347 | InputStream fileInputStream = response.body().byteStream();
348 |
349 | File savedFile = GDFileManager.getInstance().saveFileToPrivateStorageFromInputStream(context, fileInputStream, fileName, true);
350 |
351 | return savedFile;
352 | } else {
353 | throw new GDException("File not found on Google Drive");
354 | }
355 | } catch (IOException | GDException e) {
356 | e.printStackTrace();
357 | throw new GDException(e.getMessage());
358 | }
359 |
360 | }
361 |
362 |
363 | /**
364 | * Download file in BACKGROUND thread
365 | *
366 | * @param context to get local folder of application
367 | * @param gdAuthResponse Auth credentials
368 | * @param gdFileId fileId to delete
369 | * @param deleteFileCompleteListener on complete event
370 | */
371 | public void deleteFileAsync(final Context context, final GDAuthResponse gdAuthResponse, final GDAuthConfig authConfig, final String gdFileId, final GDDeleteFileResponse.OnDeleteFileListener deleteFileCompleteListener) {
372 | AsyncTask.execute(new Runnable() {
373 | @Override
374 | public void run() {
375 | try {
376 | Boolean isFileDeleted = getInstance().deleteFile(context, gdAuthResponse, authConfig, gdFileId);
377 | if (isFileDeleted) {
378 | deleteFileCompleteListener.onSucess();
379 | } else {
380 | deleteFileCompleteListener.onError(null);
381 | }
382 | } catch (GDException e) {
383 | deleteFileCompleteListener.onError(e);
384 | }
385 | }
386 | });
387 | }
388 |
389 |
390 | /**
391 | * Download file in CURRENT thread
392 | *
393 | * @param context to get local folder of application
394 | * @param gdAuthResponse Auth credentials
395 | * @param gdFileId fileId to delete
396 | * @return true if file deleted
397 | * @throws GDException if any error occurred
398 | */
399 | public Boolean deleteFile(final Context context, GDAuthResponse gdAuthResponse, final GDAuthConfig authConfig, final String gdFileId) throws GDException {
400 |
401 | if (gdAuthResponse.isExpired()) {
402 | // Get access token again from refresh token
403 | gdAuthResponse = this.getAuthFromRefreshToken(context, gdAuthResponse, authConfig);
404 | }
405 | Request request = new Request.Builder()
406 | .url("https://www.googleapis.com/drive/v3/files/" + gdFileId)
407 | .delete()
408 | .addHeader("authorization", "Bearer " + gdAuthResponse.getAccessToken())
409 | .build();
410 |
411 | try {
412 | Response response = getInstance().client.newCall(request).execute();
413 |
414 | return response.isSuccessful();
415 | } catch (IOException e) {
416 | e.printStackTrace();
417 | throw new GDException(e.getMessage());
418 | }
419 |
420 | }
421 | }
422 |
--------------------------------------------------------------------------------
/googledriverest/src/main/java/com/tejpratapsingh/googledriverest/auth/GDAuthConfig.java:
--------------------------------------------------------------------------------
1 | package com.tejpratapsingh.googledriverest.auth;
2 |
3 | import android.text.TextUtils;
4 |
5 | import java.util.ArrayList;
6 | import java.util.Locale;
7 |
8 | import com.tejpratapsingh.googledriverest.Helper.GDException;
9 |
10 | public class GDAuthConfig {
11 |
12 | private String redirectURI, clientId, clientSecret;
13 | private ArrayList scopes;
14 |
15 | public enum SCOPES {
16 |
17 | EMAIL("email"),
18 | APP_FOLDER("https://www.googleapis.com/auth/drive.appfolder"),
19 | DRIVE("https://www.googleapis.com/auth/drive.file"),
20 | DRIVE_FULL("https://www.googleapis.com/auth/drive"),
21 | READ_ONLY("https://www.googleapis.com/auth/drive.readonly"),
22 | MATADATA("https://www.googleapis.com/auth/drive.metadata"),
23 | APP_SCRIPT("https://www.googleapis.com/auth/drive.scripts");
24 |
25 | private String stringValue;
26 |
27 | SCOPES(String stringValue) {
28 | this.stringValue = stringValue;
29 | }
30 |
31 | public String getStringValue() {
32 | return stringValue;
33 | }
34 | }
35 |
36 | public GDAuthConfig(String redirectURI, String clientId, String clientSecret, ArrayList scopes) throws GDException {
37 |
38 | if (redirectURI == null || redirectURI.isEmpty()) {
39 | throw new GDException("redirectURI cannot be null");
40 | } else if (clientId == null || clientId.isEmpty()) {
41 | throw new GDException("clientId cannot be null");
42 | } else if (scopes == null || scopes.size() == 0) {
43 | throw new GDException("scopes cannot be empty");
44 | }
45 |
46 | this.redirectURI = redirectURI;
47 | this.clientId = clientId;
48 | this.clientSecret = clientSecret;
49 | this.scopes = scopes;
50 | }
51 |
52 | public String getRedirectURI() {
53 | return redirectURI;
54 | }
55 |
56 | public String getClientId() {
57 | return clientId;
58 | }
59 |
60 | public String getClientSecret() {
61 | return clientSecret;
62 | }
63 |
64 | public String getAuthURL() {
65 |
66 | ArrayList scopesStringArray = new ArrayList<>();
67 | for (SCOPES scope : this.scopes) {
68 | scopesStringArray.add(scope.getStringValue());
69 | }
70 |
71 | String scopesCSV = TextUtils.join("%20", scopesStringArray);
72 |
73 | return String.format(Locale.getDefault(), "https://accounts.google.com/o/oauth2/v2/auth?scope=%s&access_type=offline&prompt=consent&include_granted_scopes=true&state=state_parameter_passthrough_value&redirect_uri=%s&response_type=code&client_id=%s",
74 | scopesCSV, this.redirectURI, this.clientId);
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/googledriverest/src/main/java/com/tejpratapsingh/googledriverest/auth/GDAuthManager.java:
--------------------------------------------------------------------------------
1 | package com.tejpratapsingh.googledriverest.auth;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.content.SharedPreferences;
6 | import android.os.Build;
7 | import android.util.Log;
8 | import android.webkit.WebChromeClient;
9 | import android.webkit.WebSettings;
10 | import android.webkit.WebView;
11 | import android.webkit.WebViewClient;
12 |
13 | import com.tejpratapsingh.googledriverest.Helper.GDConstants;
14 | import com.tejpratapsingh.googledriverest.Helper.GDException;
15 | import com.tejpratapsingh.googledriverest.Helper.GDUtilities;
16 | import com.tejpratapsingh.googledriverest.api.GDApiManager;
17 | import com.tejpratapsingh.googledriverest.modal.GDAuthResponse;
18 |
19 | import java.io.UnsupportedEncodingException;
20 | import java.net.MalformedURLException;
21 | import java.net.URL;
22 |
23 | import static android.content.Context.MODE_PRIVATE;
24 |
25 | public class GDAuthManager {
26 |
27 | private static final String TAG = "GDAuthManager";
28 |
29 | public interface OnGoogleAuthCompleteListener {
30 | // Web browser is loading page
31 | void onLoadingStart();
32 | // Web browser finished loading page
33 | void onLoadingFinish();
34 | // Finished with success
35 | void onSuccess(GDAuthResponse gdAuthResponse);
36 | // Finished with error
37 | void onError(GDException exception);
38 | }
39 |
40 | private static final GDAuthManager ourInstance = new GDAuthManager();
41 |
42 | public static GDAuthManager getInstance() {
43 | return ourInstance;
44 | }
45 |
46 | private GDAuthManager() {
47 | }
48 |
49 | public void startGoogleDriveAuth(final Activity activity, final WebView webView, final GDAuthConfig config, final OnGoogleAuthCompleteListener onGoogleAuthCompleteListener) {
50 |
51 | try {
52 | GDAuthResponse gdAuthResponse = getAuthData(activity.getApplicationContext());
53 | if (gdAuthResponse.isExpired() == false) {
54 | onGoogleAuthCompleteListener.onSuccess(gdAuthResponse);
55 | Log.d(TAG, "startGoogleDriveAuth: OLD AUTH IS NOT EXPIRED, USE it");
56 | return;
57 | }
58 | } catch (GDException e) {
59 | e.printStackTrace();
60 | }
61 |
62 | webView.getSettings().setJavaScriptEnabled(true);
63 | webView.getSettings().setSupportMultipleWindows(true);
64 | webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
65 | String userAgent = String.format("%s", webView.getSettings().getUserAgentString().replace("; wv)", ")"));
66 | Log.d(TAG, "onCreateWindow: userAgent: " + userAgent);
67 | webView.getSettings().setUserAgentString(userAgent);
68 | webView.getSettings().setGeolocationEnabled(true);
69 | webView.getSettings().setUseWideViewPort(true);
70 | webView.getSettings().setLoadWithOverviewMode(true);
71 | webView.getSettings().setAllowContentAccess(true);
72 | webView.getSettings().setDatabaseEnabled(true);
73 | webView.getSettings().setLoadsImagesAutomatically(true);
74 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
75 | webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
76 | }
77 | webView.setWebChromeClient(new MyWebChromeClient());
78 | enableHTML5AppCache(webView);
79 |
80 | webView.loadUrl(config.getAuthURL());
81 | onGoogleAuthCompleteListener.onLoadingStart();
82 | webView.setWebViewClient(new WebViewClient() {
83 | public void onPageFinished(WebView view, String url) {
84 | onGoogleAuthCompleteListener.onLoadingFinish();
85 | // do your stuff here
86 | Log.d(TAG, "onPageFinished: Current URL: " + url);
87 | Log.d(TAG, "onPageFinished: url.matched: " + url.toLowerCase().startsWith(config.getRedirectURI().toLowerCase()));
88 | if (url.toLowerCase().startsWith(config.getRedirectURI().toLowerCase())) {
89 | // DO Auth API CALLS
90 | try {
91 | URL urlObject = new URL(url);
92 | try {
93 | String code = GDUtilities.splitQuery(urlObject).get("code");
94 | Log.d(TAG, "onPageFinished: Auth Finished with code: " + code);
95 | Log.d(TAG, "onPageFinished: Getting access code from request code");
96 |
97 | GDApiManager gdApiManager = GDApiManager.getInstance();
98 | gdApiManager.getAuthFromCodeAsync(code, config, new GDAuthResponse.OnAuthResponseListener() {
99 | @Override
100 | public void onSuccess(final GDAuthResponse gdAuthResponse) {
101 | Log.d(TAG, "onSuccess: Auth Finished: " + gdAuthResponse.toString());
102 | activity.runOnUiThread(new Runnable() {
103 | @Override
104 | public void run() {
105 | SharedPreferences.Editor editor = activity.getSharedPreferences(GDConstants.GD_PREFS_NAME, MODE_PRIVATE).edit();
106 | editor.putString(GDConstants.GD_PREFS_ACCESS_TOKEN, gdAuthResponse.getAccessToken());
107 | editor.putString(GDConstants.GD_PREFS_REFRESH_TOKEN, gdAuthResponse.getRefreshToken());
108 | editor.putLong(GDConstants.GD_PREFS_TOKEN_EXPIRES_AT, gdAuthResponse.getExpiresAtTimestamp());
109 | if (editor.commit()) {
110 | onGoogleAuthCompleteListener.onSuccess(gdAuthResponse);
111 | }
112 | }
113 | });
114 | }
115 |
116 | @Override
117 | public void onError(GDException exception) {
118 | onGoogleAuthCompleteListener.onError(exception);
119 | }
120 | });
121 | } catch (UnsupportedEncodingException e) {
122 | e.printStackTrace();
123 | onGoogleAuthCompleteListener.onError(new GDException(e.getMessage()));
124 | }
125 | } catch (MalformedURLException e) {
126 | e.printStackTrace();
127 | onGoogleAuthCompleteListener.onError(new GDException(e.getMessage()));
128 | }
129 |
130 | }
131 | }
132 | });
133 | }
134 |
135 | public GDAuthResponse getAuthData(Context context) throws GDException {
136 | SharedPreferences preferences = context.getSharedPreferences(GDConstants.GD_PREFS_NAME, MODE_PRIVATE);
137 |
138 | if (preferences.contains(GDConstants.GD_PREFS_ACCESS_TOKEN) == false
139 | || preferences.contains(GDConstants.GD_PREFS_REFRESH_TOKEN) == false
140 | || preferences.contains(GDConstants.GD_PREFS_TOKEN_EXPIRES_AT) == false) {
141 | throw new GDException("You did not use GDAuthResponse.getInstance().setAuthData() [to persist auth data.]");
142 | }
143 |
144 | return new GDAuthResponse(
145 | preferences.getString(GDConstants.GD_PREFS_ACCESS_TOKEN, null),
146 | preferences.getString(GDConstants.GD_PREFS_REFRESH_TOKEN, null),
147 | preferences.getLong(GDConstants.GD_PREFS_TOKEN_EXPIRES_AT, 0)
148 | );
149 | }
150 |
151 | public Boolean setAuthData(Activity activity, GDAuthResponse authData) {
152 | SharedPreferences.Editor editor = activity.getSharedPreferences(GDConstants.GD_PREFS_NAME, MODE_PRIVATE).edit();
153 | editor.putString(GDConstants.GD_PREFS_ACCESS_TOKEN, authData.getAccessToken());
154 | editor.putString(GDConstants.GD_PREFS_REFRESH_TOKEN, authData.getRefreshToken());
155 | editor.putLong(GDConstants.GD_PREFS_TOKEN_EXPIRES_AT, authData.getExpiresAtTimestamp());
156 | return editor.commit();
157 | }
158 |
159 | public void clearCachedAuthData(Context context) {
160 | SharedPreferences preferences = context.getSharedPreferences(GDConstants.GD_PREFS_NAME, MODE_PRIVATE);
161 | SharedPreferences.Editor editor = preferences.edit();
162 | editor.remove(GDConstants.GD_PREFS_ACCESS_TOKEN);
163 | editor.remove(GDConstants.GD_PREFS_REFRESH_TOKEN);
164 | editor.remove(GDConstants.GD_PREFS_TOKEN_EXPIRES_AT);
165 | editor.commit();
166 | }
167 |
168 | private void enableHTML5AppCache(WebView mWebView) {
169 |
170 | mWebView.getSettings().setDomStorageEnabled(true);
171 |
172 | // Set cache size to 8 mb by default. should be more than enough
173 | mWebView.getSettings().setAppCacheMaxSize(1024 * 1024 * 8);
174 |
175 | // This next one is crazy. It's the DEFAULT location for your app's cache
176 | // But it didn't work for me without this line
177 | mWebView.getSettings().setAppCachePath("/data/data/" + mWebView.getContext().getPackageName() + "/cache");
178 | mWebView.getSettings().setAllowFileAccess(true);
179 | mWebView.getSettings().setAppCacheEnabled(true);
180 |
181 | mWebView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
182 | }
183 |
184 | private class MyWebChromeClient extends WebChromeClient {
185 |
186 | @Override
187 | public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, android.os.Message resultMsg) {
188 | WebView newWebView = new WebView(view.getContext());
189 |
190 | newWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
191 | newWebView.getSettings().setLoadWithOverviewMode(true);
192 | newWebView.getSettings().setAllowContentAccess(true);
193 | newWebView.getSettings().setDatabaseEnabled(true);
194 | newWebView.getSettings().setLoadsImagesAutomatically(true);
195 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
196 | newWebView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
197 | }
198 | enableHTML5AppCache(newWebView);
199 | newWebView.setWebChromeClient(new WebChromeClient() {
200 | @Override
201 | public void onCloseWindow(WebView window) {
202 | }
203 | });
204 | view.addView(newWebView);
205 | WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
206 | transport.setWebView(newWebView);
207 | resultMsg.sendToTarget();
208 | return true;
209 | }
210 |
211 | @Override
212 | public void onCloseWindow(WebView window) {
213 | }
214 | }
215 | }
216 |
--------------------------------------------------------------------------------
/googledriverest/src/main/java/com/tejpratapsingh/googledriverest/modal/GDAuthResponse.java:
--------------------------------------------------------------------------------
1 | package com.tejpratapsingh.googledriverest.modal;
2 |
3 | import android.util.Log;
4 |
5 | import com.tejpratapsingh.googledriverest.Helper.GDException;
6 |
7 | import java.util.Locale;
8 |
9 | public class GDAuthResponse {
10 |
11 | public interface OnAuthResponseListener {
12 | void onSuccess(GDAuthResponse gdAuthResponse);
13 |
14 | void onError(GDException exception);
15 | }
16 |
17 | private String accessToken, refreshToken;
18 | private long expiresAtTimestamp;
19 |
20 | public GDAuthResponse(String accessToken, String refreshToken, long expiresAtTimestamp) {
21 | this.accessToken = accessToken;
22 | this.refreshToken = refreshToken;
23 | this.expiresAtTimestamp = expiresAtTimestamp;
24 |
25 | Log.d("", "GDAuthResponse: " + this.toString());
26 | System.out.println("isExpired: " + this.isExpired());
27 | }
28 |
29 | public String getAccessToken() {
30 | return this.accessToken;
31 | }
32 |
33 | public String getRefreshToken() {
34 | return this.refreshToken;
35 | }
36 |
37 | public long getExpiresAtTimestamp() {
38 | return this.expiresAtTimestamp;
39 | }
40 |
41 | public boolean isExpired() {
42 | if ((System.currentTimeMillis() / 1000) > this.expiresAtTimestamp - 90) {
43 | return true;
44 | }
45 | return false;
46 | }
47 |
48 | @Override
49 | public String toString() {
50 | return String.format(Locale.getDefault(),
51 | "accessToken: %s,\nrefreshToken: %s,\nexpiresAtTimestamp: %d,\ntimeRemaining: %d",
52 | this.accessToken, this.refreshToken, this.expiresAtTimestamp, this.expiresAtTimestamp - (System.currentTimeMillis() / 1000));
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/googledriverest/src/main/java/com/tejpratapsingh/googledriverest/modal/GDDeleteFileResponse.java:
--------------------------------------------------------------------------------
1 | package com.tejpratapsingh.googledriverest.modal;
2 |
3 | public class GDDeleteFileResponse {
4 | public interface OnDeleteFileListener {
5 | void onSucess();
6 | void onError(Exception e);
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/googledriverest/src/main/java/com/tejpratapsingh/googledriverest/modal/GDDownloadFileResponse.java:
--------------------------------------------------------------------------------
1 | package com.tejpratapsingh.googledriverest.modal;
2 |
3 | import com.tejpratapsingh.googledriverest.Helper.GDException;
4 |
5 | import java.io.File;
6 |
7 | public class GDDownloadFileResponse {
8 | public interface OnDownloadFileCompleteListener {
9 | void onSuccess(File downloadedFile);
10 | void onError(GDException exception);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/googledriverest/src/main/java/com/tejpratapsingh/googledriverest/modal/GDUploadFileResponse.java:
--------------------------------------------------------------------------------
1 | package com.tejpratapsingh.googledriverest.modal;
2 |
3 | import com.tejpratapsingh.googledriverest.Helper.GDException;
4 |
5 | public class GDUploadFileResponse {
6 |
7 | public interface OnUploadFileCompleteListener {
8 | void onSuccess(GDUploadFileResponse uploadFileResponse);
9 | void onError(GDException exception);
10 | }
11 |
12 | private String id, name, mimeType;
13 |
14 | public GDUploadFileResponse(String id, String name, String mimeType) {
15 | this.id = id;
16 | this.name = name;
17 | this.mimeType = mimeType;
18 | }
19 |
20 | public String getId() {
21 | return id;
22 | }
23 |
24 | public String getName() {
25 | return name;
26 | }
27 |
28 | public String getMimeType() {
29 | return mimeType;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/googledriverest/src/main/java/com/tejpratapsingh/googledriverest/modal/GDUserInfo.java:
--------------------------------------------------------------------------------
1 | package com.tejpratapsingh.googledriverest.modal;
2 |
3 | import com.tejpratapsingh.googledriverest.Helper.GDException;
4 |
5 | public class GDUserInfo {
6 |
7 | public interface OnUserInfoReceivedListener {
8 | void onSuccess(GDUserInfo userInfo);
9 | void onError(GDException exception);
10 | }
11 |
12 | private String name, email, profile, picture;
13 |
14 | public GDUserInfo(String name, String email, String profile, String picture) {
15 | this.name = name;
16 | this.email = email;
17 | this.profile = profile;
18 | this.picture = picture;
19 | }
20 |
21 | public String getName() {
22 | return name;
23 | }
24 |
25 | public String getEmail() {
26 | return email;
27 | }
28 |
29 | public String getProfile() {
30 | return profile;
31 | }
32 |
33 | public String getPicture() {
34 | return picture;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/googledriverest/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Google Drive Rest
3 |
4 |
--------------------------------------------------------------------------------
/googledriverest/src/test/java/com/tejpratapsingh/googledriverest/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.tejpratapsingh.googledriverest;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app's APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Automatically convert third-party libraries to use AndroidX
19 | android.enableJetifier=true
20 |
21 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tejpratap46/Google-Drive-REST-Android/f336dcfe1cf485e5a87ced81dc51bbf377e67e08/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Sep 13 20:54:53 IST 2019
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/icons8-cloud-checked-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tejpratap46/Google-Drive-REST-Android/f336dcfe1cf485e5a87ced81dc51bbf377e67e08/icons8-cloud-checked-512.png
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':googledriverest'
2 | rootProject.name='GoogleDriveRestAndroid'
3 |
--------------------------------------------------------------------------------