Merge pull request #1425 from reicast/ac/dropbox
Update Dropbox API from 1.6 to 3.0
This commit is contained in:
commit
d436c30f3b
|
@ -39,8 +39,6 @@ android {
|
|||
ndk {
|
||||
moduleName "dc"
|
||||
abiFilters 'armeabi-v7a', 'x86'
|
||||
moduleName "sexplay"
|
||||
abiFilters 'armeabi-v7a', 'x86'
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,11 +54,13 @@ android {
|
|||
buildTypes {
|
||||
debug {
|
||||
debuggable true
|
||||
minifyEnabled true
|
||||
zipAlignEnabled true
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
|
||||
}
|
||||
release {
|
||||
debuggable false
|
||||
minifyEnabled false
|
||||
minifyEnabled true
|
||||
zipAlignEnabled true
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
|
||||
signingConfig signingConfigs.release
|
||||
|
@ -101,6 +101,7 @@ dependencies {
|
|||
implementation 'org.bouncycastle:bcprov-jdk16:1.46'
|
||||
implementation 'commons-io:commons-io:2.6'
|
||||
implementation 'org.apache.commons:commons-lang3:3.7'
|
||||
implementation 'com.dropbox.core:dropbox-core-sdk:3.0.9'
|
||||
implementation ('com.googlecode.json-simple:json-simple:1.1.1') {
|
||||
exclude module: 'junit'
|
||||
}
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,69 @@
|
|||
# This is a configuration file for ProGuard.
|
||||
# http://proguard.sourceforge.net/index.html#manual/usage.html
|
||||
# Optimizations: If you don't want to optimize, use the
|
||||
# proguard-android.txt configuration file instead of this one, which
|
||||
# turns off the optimization flags. Adding optimization introduces
|
||||
# certain risks, since for example not all optimizations performed by
|
||||
# ProGuard works on all versions of Dalvik. The following flags turn
|
||||
# off various optimizations known to have issues, but the list may not
|
||||
# be complete or up to date. (The "arithmetic" optimization can be
|
||||
# used if you are only targeting Android 2.0 or later.) Make sure you
|
||||
# test thoroughly if you go this route.
|
||||
-optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*
|
||||
-optimizationpasses 5
|
||||
-allowaccessmodification
|
||||
-dontpreverify
|
||||
# The remainder of this file is identical to the non-optimized version
|
||||
# of the Proguard configuration file (except that the other file has
|
||||
# flags to turn off optimization).
|
||||
-dontusemixedcaseclassnames
|
||||
-dontskipnonpubliclibraryclasses
|
||||
-verbose
|
||||
-keepattributes *Annotation*
|
||||
# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native
|
||||
-keepclasseswithmembernames class * {
|
||||
native <methods>;
|
||||
}
|
||||
# keep setters in Views so that animations can still work.
|
||||
# see http://proguard.sourceforge.net/manual/examples.html#beans
|
||||
-keepclassmembers public class * extends android.view.View {
|
||||
void set*(***);
|
||||
*** get*();
|
||||
}
|
||||
# We want to keep methods in Activity that could be used in the XML attribute onClick
|
||||
-keepclassmembers class * extends android.app.Activity {
|
||||
public void *(android.view.View);
|
||||
}
|
||||
# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
|
||||
-keepclassmembers enum * {
|
||||
public static **[] values();
|
||||
public static ** valueOf(java.lang.String);
|
||||
}
|
||||
-keepclassmembers class * implements android.os.Parcelable {
|
||||
public static final android.os.Parcelable$Creator CREATOR;
|
||||
}
|
||||
-keepclassmembers class **.R$* {
|
||||
public static <fields>;
|
||||
}
|
||||
|
||||
-keep class com.reicast.** {*;}
|
||||
-keepclassmembers class com.reicast.** {*;}
|
||||
|
||||
# The support library contains references to newer platform versions.
|
||||
# Don't warn about those in case this app is linking against an older
|
||||
# platform version. We know about them, and they are safe.
|
||||
-dontwarn android.support.**
|
||||
-dontwarn okio.**
|
||||
-dontwarn okhttp3.**
|
||||
-dontwarn com.squareup.okhttp.**
|
||||
-dontwarn com.google.appengine.**
|
||||
-dontwarn java.io.**
|
||||
-dontwarn java.nio.file.**
|
||||
-dontwarn javax.naming.**
|
||||
-dontwarn javax.servlet.**
|
||||
-dontwarn junit.textui.**
|
||||
|
||||
-keepattributes Signature
|
||||
-keepattributes InnerClasses
|
||||
|
||||
-keepattributes Exceptions,SourceFile,LineNumberTable
|
|
@ -101,11 +101,11 @@
|
|||
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
|
||||
</activity>
|
||||
<activity
|
||||
android:name="com.dropbox.client2.android.AuthActivity"
|
||||
android:name="com.dropbox.core.android.AuthActivity"
|
||||
android:configChanges="orientation|keyboard"
|
||||
android:launchMode="singleTask" >
|
||||
android:launchMode="singleTask">
|
||||
<intent-filter>
|
||||
<data android:scheme="db-7d7tw1t57sbzrj5" />
|
||||
<data android:scheme="db-lowa9ps6h5k7zbo" />
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
|
|
@ -1,350 +0,0 @@
|
|||
package com.reicast.emulator;
|
||||
|
||||
/*
|
||||
* File: CloudFragment.java
|
||||
* Author: Luca D'Amico (Luca91)
|
||||
* Last Edit: 11 May 2014
|
||||
*
|
||||
* Reference: http://forums.reicast.com/index.php?topic=160.msg422
|
||||
*/
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.Editor;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.dropbox.client2.DropboxAPI;
|
||||
import com.dropbox.client2.DropboxAPI.Entry;
|
||||
import com.dropbox.client2.android.AndroidAuthSession;
|
||||
import com.dropbox.client2.exception.DropboxException;
|
||||
import com.dropbox.client2.session.AccessTokenPair;
|
||||
import com.dropbox.client2.session.AppKeyPair;
|
||||
import com.dropbox.client2.session.TokenPair;
|
||||
import com.reicast.emulator.config.Config;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
|
||||
public class CloudFragment extends Fragment {
|
||||
|
||||
Button uploadBtn;
|
||||
Button downloadBtn;
|
||||
AlertDialog.Builder confirmDialog = null;
|
||||
boolean actionRequired=false;
|
||||
public String task = "";
|
||||
DropBoxClient client = null;
|
||||
private String home_directory;
|
||||
|
||||
String[] vmus = {"vmu_save_A1.bin","vmu_save_A2.bin",
|
||||
"vmu_save_B1.bin","vmu_save_B2.bin",
|
||||
"vmu_save_C1.bin","vmu_save_C2.bin",
|
||||
"vmu_save_D1.bin","vmu_save_D2.bin"};
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.cloud_fragment, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
|
||||
home_directory = mPrefs.getString(Config.pref_home,
|
||||
Environment.getExternalStorageDirectory().getAbsolutePath());
|
||||
buttonListener();
|
||||
confirmDialog = new AlertDialog.Builder(getActivity());
|
||||
setClient();
|
||||
}
|
||||
|
||||
public void setClient(){
|
||||
if(client==null)
|
||||
client = new DropBoxClient(getActivity());
|
||||
}
|
||||
|
||||
|
||||
public void buttonListener() {
|
||||
uploadBtn = (Button) getView().findViewById(R.id.uploadBtn);
|
||||
uploadBtn.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
confirmDialog.setMessage(R.string.uploadWarning);
|
||||
confirmDialog.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
setClient();
|
||||
task = "Upload";
|
||||
client.startLogin();
|
||||
actionRequired = true;
|
||||
}
|
||||
});
|
||||
confirmDialog.setNegativeButton(R.string.cancel, null);
|
||||
confirmDialog.show();
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
downloadBtn = (Button) getView().findViewById(R.id.downloadBtn);
|
||||
downloadBtn.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
confirmDialog.setMessage(R.string.downloadWarning);
|
||||
confirmDialog.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
setClient();
|
||||
task = "Download";
|
||||
client.startLogin();
|
||||
actionRequired = true;
|
||||
}
|
||||
});
|
||||
confirmDialog.setNegativeButton(R.string.cancel, null);
|
||||
confirmDialog.show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onResume(){
|
||||
super.onResume();
|
||||
if (client.mDBApi != null) {
|
||||
if (client.mDBApi.getSession().authenticationSuccessful()) {
|
||||
try {
|
||||
client.mDBApi.getSession().finishAuthentication();
|
||||
TokenPair tokens = client.mDBApi.getSession(). getAccessTokenPair();
|
||||
if(tokens == null)
|
||||
Toast.makeText(getActivity(), "Failed to save session token!", Toast.LENGTH_SHORT).show();
|
||||
else
|
||||
client.storeKeys(tokens.key, tokens.secret);
|
||||
} catch (IllegalStateException e) {
|
||||
Log.i("Dropbox", "Error authenticating", e);
|
||||
}
|
||||
}
|
||||
if(actionRequired){
|
||||
for(int k=0;k<vmus.length;k++){
|
||||
String result = "";
|
||||
try {
|
||||
String vmuPath = home_directory+"/"+vmus[k];
|
||||
File vmu = new File(vmuPath);
|
||||
if(vmu.exists() || task.equals("Download") ){
|
||||
result = new netOperation(client, home_directory).execute(
|
||||
task,vmuPath,vmus[k]).get();
|
||||
}
|
||||
else{
|
||||
result = "Ok"; // The result is still ok, because the vmu bin doesn't exist ;)
|
||||
Toast.makeText(getActivity(), vmus[k]+ " doesn't exist, skipping it!",
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if(result.equals("Ok"))
|
||||
Toast.makeText(getActivity(), "Task Completed!", Toast.LENGTH_SHORT).show();
|
||||
else
|
||||
Toast.makeText(getActivity(), "Task Failed!", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
actionRequired = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
class DropBoxClient {
|
||||
|
||||
Context context;
|
||||
|
||||
final static private String APP_KEY = "7d7tw1t57sbzrj5";
|
||||
final static private String APP_SECRET = "5xxqa2uctousyi2";
|
||||
|
||||
public DropboxAPI<AndroidAuthSession> mDBApi;
|
||||
AndroidAuthSession session;
|
||||
|
||||
public DropBoxClient(Context context){
|
||||
this.context = context;
|
||||
session = buildSession();
|
||||
mDBApi = new DropboxAPI<AndroidAuthSession>(session);
|
||||
}
|
||||
|
||||
public void startLogin(){
|
||||
mDBApi.getSession().startOAuth2Authentication(context);
|
||||
}
|
||||
|
||||
public String[] getKeys() {
|
||||
SharedPreferences prefs = context.getSharedPreferences("ReicastVMUUploader", 0);
|
||||
String key = prefs.getString("DBoxKey", null);
|
||||
String secret = prefs.getString("DBoxSecret", null);
|
||||
if (key != null && secret != null) {
|
||||
String[] ret = new String[2];
|
||||
ret[0] = key;
|
||||
ret[1] = secret;
|
||||
return ret;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void storeKeys(String key, String secret) {
|
||||
SharedPreferences prefs = context.getSharedPreferences("ReicastVMUUploader", 0);
|
||||
Editor edit = prefs.edit();
|
||||
edit.putString("DBoxKey", key);
|
||||
edit.putString("DBoxSecret", secret);
|
||||
edit.apply();
|
||||
}
|
||||
|
||||
private AndroidAuthSession buildSession() {
|
||||
AppKeyPair appKeyPair = new AppKeyPair(APP_KEY, APP_SECRET);
|
||||
AndroidAuthSession session;
|
||||
|
||||
String[] stored = getKeys();
|
||||
if (stored != null) {
|
||||
AccessTokenPair accessToken = new AccessTokenPair(stored[0], stored[1]);
|
||||
session = new AndroidAuthSession(appKeyPair, accessToken);
|
||||
} else {
|
||||
session = new AndroidAuthSession(appKeyPair);
|
||||
}
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class netOperation extends AsyncTask<String, Void, String> {
|
||||
|
||||
DropBoxClient client = null;
|
||||
private String home_directory;
|
||||
|
||||
public netOperation(DropBoxClient client, String home_directory){
|
||||
this.client = client;
|
||||
this.home_directory = home_directory;
|
||||
}
|
||||
|
||||
public boolean uploadFile(String filePath, String fileName) {
|
||||
File file = new File(filePath);
|
||||
FileInputStream inputStream = null;
|
||||
try {
|
||||
inputStream = new FileInputStream(file);
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
DropboxAPI.Entry response = null;
|
||||
try {
|
||||
response = client.mDBApi.putFileOverwrite("/"+fileName, inputStream, file.length(), null);
|
||||
} catch (DropboxException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Log.i("FileInfos", "The uploaded file's rev is: "+ response);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean downloadFile(String filePath, String fileName) {
|
||||
DropboxAPI.DropboxFileInfo info = null;
|
||||
try {
|
||||
Entry remoteFile = client.mDBApi.metadata("/"+fileName, 1, null, false, null);
|
||||
if((remoteFile.rev != null) && (remoteFile.bytes > 0)){ // Avoid to download 0 bytes vmus!
|
||||
File file = new File(filePath);
|
||||
if(file.exists())
|
||||
createBackupOfVmu(fileName);
|
||||
FileOutputStream out = null;
|
||||
try {
|
||||
out = new FileOutputStream(file);
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
info = client.mDBApi.getFile("/"+fileName,null,out,null);
|
||||
}
|
||||
} catch (DropboxException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Log.i("FileInfos", "The downloaded file's rev is: "+ info);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String result) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doInBackground(String... strings) {
|
||||
if(strings[0].equals("Upload")){
|
||||
if(uploadFile(strings[1],strings[2]))
|
||||
return "Ok";
|
||||
else
|
||||
return "No";
|
||||
}
|
||||
else if(strings[0].equals("Download")){
|
||||
if(downloadFile(strings[1],strings[2]))
|
||||
return "Ok";
|
||||
else
|
||||
return "No";
|
||||
}
|
||||
else
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {}
|
||||
|
||||
@Override
|
||||
protected void onProgressUpdate(Void... values) {}
|
||||
|
||||
|
||||
void createBackupOfVmu(String vmuName){
|
||||
File backupDir = new File(home_directory+"/VmuBackups/");
|
||||
if(!backupDir.exists()) {
|
||||
backupDir.mkdirs();
|
||||
}
|
||||
|
||||
File source = new File(home_directory+"/"+vmuName);
|
||||
File destination = new File(home_directory+"/VmuBackups/"+vmuName);
|
||||
if(!destination.exists()) {
|
||||
try {
|
||||
destination.createNewFile();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
try {
|
||||
InputStream in = new FileInputStream(source);
|
||||
OutputStream out = new FileOutputStream(destination);
|
||||
byte[] buffer = new byte[1024];
|
||||
int length;
|
||||
while ((length = in.read(buffer)) > 0){
|
||||
out.write(buffer, 0, length);
|
||||
}
|
||||
in.close();
|
||||
out.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -194,6 +194,11 @@ public class FileBrowser extends Fragment {
|
|||
if (buttons != null && buttons.exists()) {
|
||||
in = new FileInputStream(buttons);
|
||||
} else if (!file.exists() || file.length() == 0) {
|
||||
try {
|
||||
file.createNewFile();
|
||||
} catch (Exception e) {
|
||||
// N+ files be broken
|
||||
}
|
||||
in = getActivity().getAssets().open("buttons.png");
|
||||
}
|
||||
if (in != null) {
|
||||
|
@ -321,17 +326,7 @@ public class FileBrowser extends Fragment {
|
|||
((TextView) childview.findViewById(R.id.item_name)).setText(R.string.boot_bios);
|
||||
ImageView icon = (ImageView) childview.findViewById(R.id.item_icon);
|
||||
icon.setImageResource(R.mipmap.disk_bios);
|
||||
int app_theme = mPrefs.getInt(Config.pref_app_theme, 0);
|
||||
if (app_theme == 7) {
|
||||
ImageViewCompat.setImageTintList(icon, ColorStateList.valueOf(
|
||||
ContextCompat.getColor(getActivity(), R.color.colorDreamTint)));
|
||||
} else if (app_theme == 1) {
|
||||
ImageViewCompat.setImageTintList(icon, ColorStateList.valueOf(
|
||||
ContextCompat.getColor(getActivity(), R.color.colorBlueTint)));
|
||||
} else {
|
||||
ImageViewCompat.setImageTintList(icon, ColorStateList.valueOf(
|
||||
ContextCompat.getColor(getActivity(), R.color.colorDarkTint)));
|
||||
}
|
||||
configureTheme(childview, true);
|
||||
|
||||
childview.setTag(null);
|
||||
|
||||
|
@ -352,17 +347,7 @@ public class FileBrowser extends Fragment {
|
|||
((TextView) childview.findViewById(R.id.item_name)).setText(R.string.clear_search);
|
||||
ImageView icon = (ImageView) childview.findViewById(R.id.item_icon);
|
||||
icon.setImageResource(R.mipmap.disk_unknown);
|
||||
int app_theme = mPrefs.getInt(Config.pref_app_theme, 0);
|
||||
if (app_theme == 7) {
|
||||
ImageViewCompat.setImageTintList(icon, ColorStateList.valueOf(
|
||||
ContextCompat.getColor(getActivity(), R.color.colorDreamTint)));
|
||||
} else if (app_theme == 1) {
|
||||
ImageViewCompat.setImageTintList(icon, ColorStateList.valueOf(
|
||||
ContextCompat.getColor(getActivity(), R.color.colorBlueTint)));
|
||||
} else {
|
||||
ImageViewCompat.setImageTintList(icon, ColorStateList.valueOf(
|
||||
ContextCompat.getColor(getActivity(), R.color.colorDarkTint)));
|
||||
}
|
||||
configureTheme(childview, true);
|
||||
|
||||
childview.setTag(null);
|
||||
|
||||
|
@ -433,6 +418,7 @@ public class FileBrowser extends Fragment {
|
|||
}
|
||||
}
|
||||
});
|
||||
configureTheme(childview, false);
|
||||
list.addView(childview);
|
||||
xmlParser.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, game.getName());
|
||||
}
|
||||
|
@ -499,18 +485,6 @@ public class FileBrowser extends Fragment {
|
|||
final View childview = browser.get().getActivity().getLayoutInflater().inflate(
|
||||
R.layout.browser_fragment_item, null, false);
|
||||
|
||||
int app_theme = browser.get().mPrefs.getInt(Config.pref_app_theme, 0);
|
||||
if (app_theme == 7) {
|
||||
childview.findViewById(R.id.childview)
|
||||
.setBackgroundResource(R.drawable.game_selector_dream);
|
||||
} else if (app_theme == 1) {
|
||||
childview.findViewById(R.id.childview)
|
||||
.setBackgroundResource(R.drawable.game_selector_blue);
|
||||
} else {
|
||||
childview.findViewById(R.id.childview)
|
||||
.setBackgroundResource(R.drawable.game_selector_dark);
|
||||
}
|
||||
|
||||
if (file == null) {
|
||||
((TextView) childview.findViewById(R.id.item_name)).setText(R.string.folder_select);
|
||||
} else if (file == parent)
|
||||
|
@ -522,17 +496,7 @@ public class FileBrowser extends Fragment {
|
|||
icon.setImageResource(file == null
|
||||
? R.drawable.ic_settings: file.isDirectory()
|
||||
? R.drawable.ic_folder_black_24dp : R.drawable.disk_unknown);
|
||||
|
||||
if (app_theme == 7) {
|
||||
ImageViewCompat.setImageTintList(icon, ColorStateList.valueOf(
|
||||
ContextCompat.getColor(browser.get().getActivity(), R.color.colorDreamTint)));
|
||||
} else if (app_theme == 1) {
|
||||
ImageViewCompat.setImageTintList(icon, ColorStateList.valueOf(
|
||||
ContextCompat.getColor(browser.get().getActivity(), R.color.colorBlueTint)));
|
||||
} else {
|
||||
ImageViewCompat.setImageTintList(icon, ColorStateList.valueOf(
|
||||
ContextCompat.getColor(browser.get().getActivity(), R.color.colorDarkTint)));
|
||||
}
|
||||
browser.get().configureTheme(childview, true);
|
||||
|
||||
childview.setTag(file);
|
||||
|
||||
|
@ -616,6 +580,30 @@ public class FileBrowser extends Fragment {
|
|||
}
|
||||
}
|
||||
|
||||
private void configureTheme(View childview, boolean useTint) {
|
||||
int app_theme = mPrefs.getInt(Config.pref_app_theme, 0);
|
||||
ImageView icon = (ImageView) childview.findViewById(R.id.item_icon);
|
||||
if (app_theme == 7) {
|
||||
childview.findViewById(R.id.childview)
|
||||
.setBackgroundResource(R.drawable.game_selector_dream);
|
||||
if (useTint)
|
||||
ImageViewCompat.setImageTintList(icon, ColorStateList.valueOf(
|
||||
ContextCompat.getColor(getActivity(), R.color.colorDreamTint)));
|
||||
} else if (app_theme == 1) {
|
||||
childview.findViewById(R.id.childview)
|
||||
.setBackgroundResource(R.drawable.game_selector_blue);
|
||||
if (useTint)
|
||||
ImageViewCompat.setImageTintList(icon, ColorStateList.valueOf(
|
||||
ContextCompat.getColor(getActivity(), R.color.colorBlueTint)));
|
||||
} else {
|
||||
childview.findViewById(R.id.childview)
|
||||
.setBackgroundResource(R.drawable.game_selector_dark);
|
||||
if (useTint)
|
||||
ImageViewCompat.setImageTintList(icon, ColorStateList.valueOf(
|
||||
ContextCompat.getColor(getActivity(), R.color.colorDarkTint)));
|
||||
}
|
||||
}
|
||||
|
||||
private void showToastMessage(String message, int duration) {
|
||||
ConstraintLayout layout = (ConstraintLayout) getActivity().findViewById(R.id.mainui_layout);
|
||||
Snackbar snackbar = Snackbar.make(layout, message, duration);
|
||||
|
|
|
@ -20,7 +20,6 @@ import android.support.design.widget.NavigationView;
|
|||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.support.v4.view.GravityCompat;
|
||||
import android.support.v4.widget.DrawerLayout;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
|
@ -41,6 +40,7 @@ import com.reicast.emulator.config.InputFragment;
|
|||
import com.reicast.emulator.config.OptionsFragment;
|
||||
import com.reicast.emulator.config.PGConfigFragment;
|
||||
import com.reicast.emulator.debug.GenerateLogs;
|
||||
import com.reicast.emulator.cloud.CloudFragment;
|
||||
import com.reicast.emulator.emu.JNIdc;
|
||||
|
||||
import java.lang.Thread.UncaughtExceptionHandler;
|
||||
|
|
|
@ -227,12 +227,15 @@ public class XMLParser extends AsyncTask<String, Integer, String> {
|
|||
icon.setImageDrawable(game_icon);
|
||||
int app_theme = mPrefs.getInt(Config.pref_app_theme, 0);
|
||||
if (app_theme == 7) {
|
||||
childview.get().setBackgroundResource(R.drawable.game_selector_dream);
|
||||
ImageViewCompat.setImageTintList(icon, ColorStateList.valueOf(
|
||||
ContextCompat.getColor(mContext.get(), R.color.colorDreamTint)));
|
||||
} else if (app_theme == 1) {
|
||||
childview.get().setBackgroundResource(R.drawable.game_selector_blue);
|
||||
ImageViewCompat.setImageTintList(icon, ColorStateList.valueOf(
|
||||
ContextCompat.getColor(mContext.get(), R.color.colorBlueTint)));
|
||||
} else {
|
||||
childview.get().setBackgroundResource(R.drawable.game_selector_dark);
|
||||
ImageViewCompat.setImageTintList(icon, ColorStateList.valueOf(
|
||||
ContextCompat.getColor(mContext.get(), R.color.colorDarkTint)));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,432 @@
|
|||
package com.reicast.emulator.cloud;
|
||||
|
||||
/*
|
||||
* Author: Luca D'Amico (Luca91)
|
||||
* Rewrite: AbandonedCart
|
||||
* Last Edit: 02 Oct 2018
|
||||
* Reference: http://forums.reicast.com/index.php?topic=160.msg422
|
||||
*/
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.dropbox.core.DbxException;
|
||||
import com.dropbox.core.android.Auth;
|
||||
import com.dropbox.core.v2.DbxClientV2;
|
||||
import com.dropbox.core.v2.files.FileMetadata;
|
||||
import com.dropbox.core.v2.files.ListFolderResult;
|
||||
import com.dropbox.core.v2.files.Metadata;
|
||||
import com.dropbox.core.v2.files.WriteMode;
|
||||
import com.reicast.emulator.R;
|
||||
import com.reicast.emulator.config.Config;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
|
||||
public class CloudFragment extends Fragment {
|
||||
|
||||
private final static String APP_KEY = "lowa9ps6h5k7zbo";
|
||||
private String mPath = ""; // Dropbox folder
|
||||
|
||||
Button uploadBtn;
|
||||
Button downloadBtn;
|
||||
AlertDialog.Builder confirmDialog = null;
|
||||
private String home_directory;
|
||||
|
||||
String[] vmus = {"vmu_save_A1.bin", "vmu_save_A2.bin",
|
||||
"vmu_save_B1.bin", "vmu_save_B2.bin",
|
||||
"vmu_save_C1.bin", "vmu_save_C2.bin",
|
||||
"vmu_save_D1.bin", "vmu_save_D2.bin"};
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.cloud_fragment, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
|
||||
home_directory = mPrefs.getString(Config.pref_home,
|
||||
Environment.getExternalStorageDirectory().getAbsolutePath());
|
||||
buttonListener();
|
||||
confirmDialog = new AlertDialog.Builder(getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
|
||||
String accessToken = mPrefs.getString("access-token", null);
|
||||
if (accessToken == null) {
|
||||
accessToken = Auth.getOAuth2Token();
|
||||
if (accessToken != null) {
|
||||
mPrefs.edit().putString("access-token", accessToken).apply();
|
||||
DbxClientFactory.init(accessToken);
|
||||
}
|
||||
} else {
|
||||
DbxClientFactory.init(accessToken);
|
||||
}
|
||||
}
|
||||
|
||||
public void buttonListener() {
|
||||
Auth.startOAuth2Authentication(getActivity(), APP_KEY);
|
||||
uploadBtn = (Button) getView().findViewById(R.id.uploadBtn);
|
||||
uploadBtn.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
confirmDialog.setMessage(R.string.uploadWarning);
|
||||
confirmDialog.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
getPathForFiles("Upload");
|
||||
}
|
||||
});
|
||||
confirmDialog.setNegativeButton(R.string.cancel, null);
|
||||
confirmDialog.show();
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
downloadBtn = (Button) getView().findViewById(R.id.downloadBtn);
|
||||
downloadBtn.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
confirmDialog.setMessage(R.string.downloadWarning);
|
||||
confirmDialog.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
getPathForFiles("Download");
|
||||
}
|
||||
});
|
||||
confirmDialog.setNegativeButton(R.string.cancel, null);
|
||||
confirmDialog.show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void uploadFile(String filePath) {
|
||||
final ProgressDialog dialog = new ProgressDialog(getActivity());
|
||||
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
|
||||
dialog.setCancelable(false);
|
||||
dialog.setMessage("Uploading");
|
||||
dialog.show();
|
||||
|
||||
try {
|
||||
new UploadFileTask(getActivity(), DbxClientFactory.getClient(), new UploadFileTask.Callback() {
|
||||
@Override
|
||||
public void onUploadComplete(FileMetadata result) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Exception e) {
|
||||
dialog.dismiss();
|
||||
|
||||
Log.e(getActivity().getLocalClassName(), "Failed to upload file.", e);
|
||||
Toast.makeText(getActivity(),
|
||||
"Failed to upload file", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}).execute(filePath, mPath);
|
||||
} catch (IllegalStateException s) {
|
||||
dialog.dismiss();
|
||||
Log.e(getActivity().getLocalClassName(), "Failed to upload file.", s);
|
||||
Toast.makeText(getActivity(),
|
||||
"Failed to upload file", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
private void retrieveFiles(final String vmu) {
|
||||
final ProgressDialog dialog = new ProgressDialog(getActivity());
|
||||
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
|
||||
dialog.setCancelable(false);
|
||||
dialog.setMessage("Loading");
|
||||
dialog.show();
|
||||
|
||||
try {
|
||||
new ListFolderTask(DbxClientFactory.getClient(), new ListFolderTask.Callback() {
|
||||
@Override
|
||||
public void onDataLoaded(ListFolderResult result) {
|
||||
dialog.dismiss();
|
||||
for (Metadata item : result.getEntries()) {
|
||||
if (item.getName().equals(vmu)) {
|
||||
if (item instanceof FileMetadata) {
|
||||
downloadFile((FileMetadata) item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Exception e) {
|
||||
dialog.dismiss();
|
||||
|
||||
Log.e(getActivity().getLocalClassName(), "Failed to list folder.", e);
|
||||
Toast.makeText(getActivity(),
|
||||
"Failed to list folder", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}).execute(mPath);
|
||||
} catch (IllegalStateException s) {
|
||||
dialog.dismiss();
|
||||
Log.e(getActivity().getLocalClassName(), "Failed to list folder.", s);
|
||||
Toast.makeText(getActivity(),
|
||||
"Failed to list folder", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
private void downloadFile(FileMetadata file) {
|
||||
final ProgressDialog dialog = new ProgressDialog(getActivity());
|
||||
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
|
||||
dialog.setCancelable(false);
|
||||
dialog.setMessage("Downloading");
|
||||
dialog.show();
|
||||
|
||||
try {
|
||||
new DownloadFileTask(this, DbxClientFactory.getClient(), new DownloadFileTask.Callback() {
|
||||
@Override
|
||||
public void onDownloadComplete(File result) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Exception e) {
|
||||
dialog.dismiss();
|
||||
|
||||
Log.e(getActivity().getLocalClassName(), "Failed to download file.", e);
|
||||
Toast.makeText(getActivity(),
|
||||
"Failed to download file\n" + e, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}).execute(file);
|
||||
} catch (IllegalStateException s) {
|
||||
dialog.dismiss();
|
||||
Log.e(getActivity().getLocalClassName(), "Failed to download file.", s);
|
||||
Toast.makeText(getActivity(),
|
||||
"Failed to download file", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
static class UploadFileTask extends AsyncTask<String, Void, FileMetadata> {
|
||||
|
||||
private WeakReference<Context> mContext;
|
||||
private final DbxClientV2 mDbxClient;
|
||||
private final Callback mCallback;
|
||||
private Exception mException;
|
||||
|
||||
public interface Callback {
|
||||
void onUploadComplete(FileMetadata result);
|
||||
void onError(Exception e);
|
||||
}
|
||||
|
||||
UploadFileTask(Context context, DbxClientV2 dbxClient, Callback callback) {
|
||||
mContext = new WeakReference<>(context);
|
||||
mDbxClient = dbxClient;
|
||||
mCallback = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(FileMetadata result) {
|
||||
super.onPostExecute(result);
|
||||
if (mException != null) {
|
||||
mCallback.onError(mException);
|
||||
} else if (result == null) {
|
||||
mCallback.onError(null);
|
||||
} else {
|
||||
mCallback.onUploadComplete(result);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FileMetadata doInBackground(String... params) {
|
||||
File localFile = new File(params[0]);
|
||||
String remoteFolderPath = params[1];
|
||||
|
||||
// Note - does not verify a valid dropbox file name
|
||||
String remoteFileName = localFile.getName();
|
||||
|
||||
try {
|
||||
InputStream inputStream = new FileInputStream(localFile);
|
||||
return mDbxClient.files().uploadBuilder(
|
||||
remoteFolderPath + "/" + remoteFileName)
|
||||
.withMode(WriteMode.OVERWRITE)
|
||||
.uploadAndFinish(inputStream);
|
||||
} catch (DbxException | IOException e) {
|
||||
mException = e;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static class ListFolderTask extends AsyncTask<String, Void, ListFolderResult> {
|
||||
|
||||
private final DbxClientV2 mDbxClient;
|
||||
private final Callback mCallback;
|
||||
private Exception mException;
|
||||
|
||||
public interface Callback {
|
||||
void onDataLoaded(ListFolderResult result);
|
||||
void onError(Exception e);
|
||||
}
|
||||
|
||||
ListFolderTask(DbxClientV2 dbxClient, Callback callback) {
|
||||
mDbxClient = dbxClient;
|
||||
mCallback = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(ListFolderResult result) {
|
||||
super.onPostExecute(result);
|
||||
|
||||
if (mException != null) {
|
||||
mCallback.onError(mException);
|
||||
} else {
|
||||
mCallback.onDataLoaded(result);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ListFolderResult doInBackground(String... params) {
|
||||
try {
|
||||
return mDbxClient.files().listFolder(params[0]);
|
||||
} catch (DbxException e) {
|
||||
mException = e;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static class DownloadFileTask extends AsyncTask<FileMetadata, Void, File> {
|
||||
|
||||
private WeakReference<CloudFragment> mCloud;
|
||||
private final DbxClientV2 mDbxClient;
|
||||
private final Callback mCallback;
|
||||
private Exception mException;
|
||||
|
||||
public interface Callback {
|
||||
void onDownloadComplete(File result);
|
||||
void onError(Exception e);
|
||||
}
|
||||
|
||||
DownloadFileTask(CloudFragment context, DbxClientV2 dbxClient, Callback callback) {
|
||||
mCloud = new WeakReference<>(context);
|
||||
mDbxClient = dbxClient;
|
||||
mCallback = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(File result) {
|
||||
super.onPostExecute(result);
|
||||
if (mException != null) {
|
||||
mCallback.onError(mException);
|
||||
} else {
|
||||
mCallback.onDownloadComplete(result);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected File doInBackground(FileMetadata... params) {
|
||||
FileMetadata metadata = params[0];
|
||||
try {
|
||||
File path = new File(mCloud.get().home_directory);
|
||||
File file = new File(path, metadata.getName());
|
||||
|
||||
// Make sure the Downloads directory exists.
|
||||
if (!path.exists()) {
|
||||
if (!path.mkdirs()) {
|
||||
mException = new RuntimeException("Unable to create directory: " + path);
|
||||
}
|
||||
} else if (!path.isDirectory()) {
|
||||
mException = new IllegalStateException("Download path is not a directory: " + path);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Download the file.
|
||||
OutputStream outputStream = new FileOutputStream(file);
|
||||
mDbxClient.files().download(metadata.getPathLower(), metadata.getRev())
|
||||
.download(outputStream);
|
||||
|
||||
// Tell android about the file
|
||||
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
|
||||
intent.setData(Uri.fromFile(file));
|
||||
mCloud.get().getActivity().sendBroadcast(intent);
|
||||
|
||||
return file;
|
||||
} catch (DbxException | IOException e) {
|
||||
mException = e;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void getPathForFiles(String task) {
|
||||
for (String vmu : vmus) {
|
||||
File vmuFile = new File(home_directory, vmu);
|
||||
if (task.equals("Download")) {
|
||||
if (vmuFile.exists())
|
||||
createBackupOfVmu(vmuFile.getName());
|
||||
else
|
||||
retrieveFiles(vmuFile.getName());
|
||||
}
|
||||
if (task.equals("Upload")) {
|
||||
if (vmuFile.exists())
|
||||
uploadFile(vmuFile.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void createBackupOfVmu(String vmuName) {
|
||||
File backupDir = new File(home_directory, "vmu_backup");
|
||||
if (!backupDir.exists()) {
|
||||
backupDir.mkdirs();
|
||||
}
|
||||
|
||||
File source = new File(home_directory, vmuName);
|
||||
File destination = new File(home_directory, "vmu_backup/" + vmuName);
|
||||
if (!destination.exists()) {
|
||||
try {
|
||||
destination.createNewFile();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
try {
|
||||
InputStream in = new FileInputStream(source);
|
||||
OutputStream out = new FileOutputStream(destination);
|
||||
byte[] buffer = new byte[1024];
|
||||
int length;
|
||||
while ((length = in.read(buffer)) > 0) {
|
||||
out.write(buffer, 0, length);
|
||||
}
|
||||
in.close();
|
||||
out.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
retrieveFiles(vmuName);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package com.reicast.emulator.cloud;
|
||||
|
||||
import com.dropbox.core.DbxRequestConfig;
|
||||
import com.dropbox.core.http.StandardHttpRequestor;
|
||||
import com.dropbox.core.v2.DbxClientV2;
|
||||
|
||||
/**
|
||||
* Singleton instance of {@link DbxClientV2} and friends
|
||||
*/
|
||||
public class DbxClientFactory {
|
||||
|
||||
private static DbxClientV2 sDbxClient;
|
||||
|
||||
public static void init(String accessToken) {
|
||||
if (sDbxClient == null) {
|
||||
StandardHttpRequestor requestor = new StandardHttpRequestor(
|
||||
StandardHttpRequestor.Config.DEFAULT_INSTANCE);
|
||||
DbxRequestConfig requestConfig = DbxRequestConfig
|
||||
.newBuilder("ReicastCloud")
|
||||
.withHttpRequestor(requestor).build();
|
||||
|
||||
sDbxClient = new DbxClientV2(requestConfig, accessToken);
|
||||
}
|
||||
}
|
||||
|
||||
public static DbxClientV2 getClient() {
|
||||
if (sDbxClient == null) {
|
||||
throw new IllegalStateException("Client not initialized.");
|
||||
}
|
||||
return sDbxClient;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue