diff --git a/.idea/assetWizardSettings.xml b/.idea/assetWizardSettings.xml
index 62a2e14..f6dbe7c 100644
--- a/.idea/assetWizardSettings.xml
+++ b/.idea/assetWizardSettings.xml
@@ -29,8 +29,8 @@
diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser
index b914f54..349c0a1 100644
Binary files a/.idea/caches/build_file_checksums.ser and b/.idea/caches/build_file_checksums.ser differ
diff --git a/app/build.gradle b/app/build.gradle
index 81693f1..d5fda8b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -6,8 +6,8 @@ android {
applicationId "ca.pkay.rcloneexplorer"
minSdkVersion 21
targetSdkVersion 27
- versionCode 10
- versionName "1.2.1"
+ versionCode 11
+ versionName "1.2.2"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
diff --git a/app/src/main/assets/changelog.md b/app/src/main/assets/changelog.md
index 0da0e2e..6ea286b 100644
--- a/app/src/main/assets/changelog.md
+++ b/app/src/main/assets/changelog.md
@@ -1,3 +1,11 @@
+### 1.2.2
+* **Update:** Rclone to version 1.41
+* **New:** App shortcuts
+* **Fix:** Color picker not working on sdk 21
+* **Fix:** Rclone not getting updated
+
+***
+
### 1.2.1
* **New:** Dark theme!
* **Fix:** Crash when starting app for the first time
diff --git a/app/src/main/assets/rclone-arm32 b/app/src/main/assets/rclone-arm32
index 5b2abb3..c8ac16c 100644
Binary files a/app/src/main/assets/rclone-arm32 and b/app/src/main/assets/rclone-arm32 differ
diff --git a/app/src/main/assets/rclone-arm64 b/app/src/main/assets/rclone-arm64
index cb3c3fc..6e84659 100644
Binary files a/app/src/main/assets/rclone-arm64 and b/app/src/main/assets/rclone-arm64 differ
diff --git a/app/src/main/assets/rclone-x86_32 b/app/src/main/assets/rclone-x86_32
index be3bfa5..92b46ee 100644
Binary files a/app/src/main/assets/rclone-x86_32 and b/app/src/main/assets/rclone-x86_32 differ
diff --git a/app/src/main/java/ca/pkay/rcloneexplorer/Dialogs/ColorPickerDialog.java b/app/src/main/java/ca/pkay/rcloneexplorer/Dialogs/ColorPickerDialog.java
index 9d85dfb..0493733 100644
--- a/app/src/main/java/ca/pkay/rcloneexplorer/Dialogs/ColorPickerDialog.java
+++ b/app/src/main/java/ca/pkay/rcloneexplorer/Dialogs/ColorPickerDialog.java
@@ -3,6 +3,7 @@
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
+import android.content.res.ColorStateList;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
@@ -11,6 +12,7 @@
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
+import android.widget.ImageView;
import android.widget.LinearLayout;
import ca.pkay.rcloneexplorer.R;
@@ -70,8 +72,8 @@ private void createLayout(View view) {
int i = 0;
for (final int color : colorChoices) {
View item = layoutInflater.inflate(R.layout.color_picker_item, null);
- View colorOption = item.findViewById(R.id.color_option);
- colorOption.getBackground().setTint(color);
+ ImageView colorOption = item.findViewById(R.id.color_option);
+ colorOption.setColorFilter(color);
if (color == defaultColor) {
(item.findViewById(R.id.checkmark)).setVisibility(View.VISIBLE);
@@ -104,10 +106,10 @@ public void onClick(View v) {
while (i < 5) { // add dummy items so that layout is even
View item = layoutInflater.inflate(R.layout.color_picker_item, null);
- View colorOption = item.findViewById(R.id.color_option);
+ ImageView colorOption = item.findViewById(R.id.color_option);
TypedValue typedValue = new TypedValue();
context.getTheme().resolveAttribute(R.attr.cardColor, typedValue, true);
- colorOption.getBackground().setTint(typedValue.data);
+ colorOption.setColorFilter(typedValue.data);
rowLayout.addView(item);
i++;
}
diff --git a/app/src/main/java/ca/pkay/rcloneexplorer/Fragments/FileExplorerFragment.java b/app/src/main/java/ca/pkay/rcloneexplorer/Fragments/FileExplorerFragment.java
index 21fbd01..24490ce 100644
--- a/app/src/main/java/ca/pkay/rcloneexplorer/Fragments/FileExplorerFragment.java
+++ b/app/src/main/java/ca/pkay/rcloneexplorer/Fragments/FileExplorerFragment.java
@@ -128,7 +128,7 @@ public void onCreate(@Nullable Bundle savedInstanceState) {
setHasOptionsMenu(true);
SharedPreferences sharedPreferences = context.getSharedPreferences(MainActivity.SHARED_PREFS_TAG, Context.MODE_PRIVATE);
- sortOrder = sharedPreferences.getInt(SHARED_PREFS_SORT_ORDER, -1);
+ sortOrder = sharedPreferences.getInt(SHARED_PREFS_SORT_ORDER, SortDialog.ALPHA_ASCENDING);
//networkStateReceiver = ((MainActivity)context).getNetworkStateReceiver();
rclone = new Rclone(getContext());
@@ -440,7 +440,9 @@ private void showSortMenu() {
.setListener(new SortDialog.OnClickListener() {
@Override
public void onPositiveButtonClick(int sortById, int sortOrderId) {
- sortSelected(sortById, sortOrderId);
+ if (directoryContent != null && !directoryContent.isEmpty()) {
+ sortSelected(sortById, sortOrderId);
+ }
}
})
.setSortOrder(sortOrder)
@@ -590,6 +592,7 @@ public void onDirectoryClicked(FileItem fileItem) {
}
path = fileItem.getPath();
recyclerViewAdapter.clear();
+ directoryContent.clear();
fetchDirectoryTask = new FetchDirectoryContent().execute();
}
diff --git a/app/src/main/java/ca/pkay/rcloneexplorer/MainActivity.java b/app/src/main/java/ca/pkay/rcloneexplorer/MainActivity.java
index 15656ae..85ca4ba 100644
--- a/app/src/main/java/ca/pkay/rcloneexplorer/MainActivity.java
+++ b/app/src/main/java/ca/pkay/rcloneexplorer/MainActivity.java
@@ -10,8 +10,11 @@
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
+import android.content.pm.ShortcutInfo;
+import android.content.pm.ShortcutManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
+import android.graphics.drawable.Icon;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.AsyncTask;
@@ -37,6 +40,9 @@
import java.io.File;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import ca.pkay.rcloneexplorer.BroadcastReceivers.NetworkStateReceiver;
import ca.pkay.rcloneexplorer.Dialogs.InputDialog;
@@ -54,6 +60,8 @@ public class MainActivity extends AppCompatActivity
private static final int READ_REQUEST_CODE = 42; // code when opening rclone config file
private static final int REQUEST_PERMISSION_CODE = 62; // code when requesting permissions
private static final int SETTINGS_CODE = 71; // code when coming back from settings
+ private final String APP_SHORTCUT_REMOTE_NAME = "arg_remote_name";
+ private final String APP_SHORTCUT_REMOTE_TYPE = "arg_remote_type";
private NavigationView navigationView;
private Rclone rclone;
private Fragment fragment;
@@ -94,10 +102,26 @@ public void onClick(View v) {
}
});
+ Intent intent = getIntent();
+ Bundle bundle = intent.getExtras();
+
+ SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
+ int lastVersionCode = sharedPreferences.getInt(getString(R.string.pref_key_version_code), -1);
+ int currentVersionCode = BuildConfig.VERSION_CODE;
+
if (!rclone.isRcloneBinaryCreated()) {
new CreateRcloneBinary().execute();
+ } else if (lastVersionCode < currentVersionCode) {
+ new CreateRcloneBinary().execute();
+ SharedPreferences.Editor editor = sharedPreferences.edit();
+ editor.putInt(getString(R.string.pref_key_version_code), currentVersionCode);
+ editor.apply();
} else if (rclone.isConfigEncrypted()) {
askForConfigPassword();
+ } else if (bundle != null && bundle.containsKey(APP_SHORTCUT_REMOTE_NAME) && bundle.containsKey(APP_SHORTCUT_REMOTE_TYPE)) {
+ String remoteName = bundle.getString(APP_SHORTCUT_REMOTE_NAME);
+ String remoteType = bundle.getString(APP_SHORTCUT_REMOTE_TYPE);
+ startRemote(remoteName, remoteType);
} else {
startRemotesFragment();
}
@@ -269,14 +293,129 @@ public void requestPermissions() {
}
}
+ private void addRemotesToShortcutList() {
+ if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.N_MR1) {
+ return;
+ }
+ ShortcutManager shortcutManager = getSystemService(ShortcutManager.class);
+ if (shortcutManager == null) {
+ return;
+ }
+ shortcutManager.removeAllDynamicShortcuts();
+
+ List remoteItemList = rclone.getRemotes();
+ List shortcutInfoList = new ArrayList<>();
+
+ for (RemoteItem remoteItem : remoteItemList) {
+ String id = remoteItem.getName().replaceAll(" ", "_");
+
+ Intent intent = new Intent(Intent.ACTION_MAIN, Uri.EMPTY, this, MainActivity.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ intent.putExtra(APP_SHORTCUT_REMOTE_NAME, remoteItem.getName());
+ intent.putExtra(APP_SHORTCUT_REMOTE_TYPE, remoteItem.getType());
+
+ ShortcutInfo shortcut = new ShortcutInfo.Builder(this, id)
+ .setShortLabel(remoteItem.getName())
+ .setIcon(Icon.createWithResource(context, getRemoteIcon(remoteItem.getType())))
+ .setIntent(intent)
+ .build();
+ shortcutInfoList.add(shortcut);
+ if (shortcutInfoList.size() == 4) {
+ break;
+ }
+ }
+ shortcutManager.setDynamicShortcuts(shortcutInfoList);
+ }
+
+ private void addRemoteToShortcutList(RemoteItem remoteItem) {
+ if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.N_MR1) {
+ return;
+ }
+ ShortcutManager shortcutManager = getSystemService(ShortcutManager.class);
+ if (shortcutManager == null) {
+ return;
+ }
+
+ String id = remoteItem.getName().replaceAll(" ", "_");
+
+ List shortcutInfoList = shortcutManager.getDynamicShortcuts();
+ for (ShortcutInfo shortcutInfo : shortcutInfoList) {
+ if (shortcutInfo.getId().equals(id)) {
+ shortcutManager.reportShortcutUsed(id);
+ return;
+ }
+ }
+
+ Intent intent = new Intent(Intent.ACTION_MAIN, Uri.EMPTY, this, MainActivity.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ intent.putExtra(APP_SHORTCUT_REMOTE_NAME, remoteItem.getName());
+ intent.putExtra(APP_SHORTCUT_REMOTE_TYPE, remoteItem.getType());
+
+ ShortcutInfo shortcut = new ShortcutInfo.Builder(this, id)
+ .setShortLabel(remoteItem.getName())
+ .setIcon(Icon.createWithResource(context, getRemoteIcon(remoteItem.getType())))
+ .setIntent(intent)
+ .build();
+
+ if (shortcutInfoList.size() >= 4) {
+ ShortcutInfo removeId = shortcutInfoList.get(0);
+ shortcutManager.removeDynamicShortcuts(Collections.singletonList(removeId.getId()));
+ }
+ shortcutManager.addDynamicShortcuts(Collections.singletonList(shortcut));
+ shortcutManager.reportShortcutUsed(id);
+ }
+
+ private int getRemoteIcon(String remoteType) {
+ switch (remoteType) {
+ case "crypt":
+ return R.drawable.ic_lock_black;
+ case "amazon cloud drive":
+ return R.drawable.ic_amazon;
+ case "b2":
+ return R.drawable.ic_b2;
+ case "drive":
+ return R.drawable.ic_google_drive;
+ case "dropbox":
+ return R.drawable.ic_dropbox;
+ case "google cloud storage":
+ return R.drawable.ic_google;
+ case "onedrive":
+ return R.drawable.ic_onedrive;
+ case "s3":
+ return R.drawable.ic_amazon;
+ case "yandex":
+ return R.drawable.ic_yandex;
+ case "box":
+ return R.drawable.ic_box;
+ case "sftp":
+ return R.drawable.ic_terminal;
+ default:
+ return R.drawable.ic_cloud;
+ }
+ }
+
@Override
public void onRemoteClick(RemoteItem remote) {
+ startRemote(remote);
+ }
+
+ private void startRemote(RemoteItem remote) {
fragment = FileExplorerFragment.newInstance(remote.getName(), remote.getType());
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.flFragment, fragment);
transaction.addToBackStack(null);
transaction.commit();
+ addRemoteToShortcutList(remote);
+ navigationView.getMenu().getItem(0).setChecked(false);
+ }
+
+ private void startRemote(String remoteName, String remoteType) {
+ fragment = FileExplorerFragment.newInstance(remoteName, remoteType);
+ FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+ transaction.replace(R.id.flFragment, fragment);
+ transaction.commit();
+
navigationView.getMenu().getItem(0).setChecked(false);
}
@@ -356,6 +495,7 @@ protected void onPostExecute(Boolean success) {
if (rclone.isConfigEncrypted()) {
askForConfigPassword();
} else {
+ addRemotesToShortcutList();
startRemotesFragment();
}
}
@@ -390,6 +530,7 @@ protected void onPostExecute(Boolean success) {
askForConfigPassword();
} else {
findViewById(R.id.locked_config).setVisibility(View.GONE);
+ addRemotesToShortcutList();
startRemotesFragment();
}
}
diff --git a/app/src/main/java/ca/pkay/rcloneexplorer/SettingsActivity.java b/app/src/main/java/ca/pkay/rcloneexplorer/SettingsActivity.java
index 368886f..e87dbcd 100644
--- a/app/src/main/java/ca/pkay/rcloneexplorer/SettingsActivity.java
+++ b/app/src/main/java/ca/pkay/rcloneexplorer/SettingsActivity.java
@@ -13,6 +13,7 @@
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.CompoundButton;
+import android.widget.ImageView;
import android.widget.Switch;
import android.widget.TextView;
@@ -21,9 +22,9 @@
public class SettingsActivity extends AppCompatActivity {
private View primaryColorElement;
- private View primaryColorPreview;
+ private ImageView primaryColorPreview;
private View accentColorElement;
- private View accentColorPreview;
+ private ImageView accentColorPreview;
private Switch darkThemeSwitch;
private View darkThemeElement;
private View notificationsElement;
@@ -194,7 +195,7 @@ private void onPrimaryColorSelected(int color) {
editor.putInt(getString(R.string.pref_key_color_primary), color);
editor.apply();
- primaryColorPreview.getBackground().setTint(color);
+ primaryColorPreview.setColorFilter(color);
showSnackBar();
}
@@ -204,7 +205,7 @@ private void onAccentColorSelected(int color) {
editor.putInt(getString(R.string.pref_key_color_accent), color);
editor.apply();
- accentColorPreview.getBackground().setTint(color);
+ accentColorPreview.setColorFilter(color);
showSnackBar();
}
diff --git a/app/src/main/res/drawable/grey_circle.xml b/app/src/main/res/drawable/grey_circle.xml
deleted file mode 100644
index 0a4701e..0000000
--- a/app/src/main/res/drawable/grey_circle.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_circle.xml b/app/src/main/res/drawable/ic_circle.xml
new file mode 100644
index 0000000..101b3b2
--- /dev/null
+++ b/app/src/main/res/drawable/ic_circle.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/layout/color_picker_item.xml b/app/src/main/res/layout/color_picker_item.xml
index 1a19a58..232a8fc 100644
--- a/app/src/main/res/layout/color_picker_item.xml
+++ b/app/src/main/res/layout/color_picker_item.xml
@@ -6,12 +6,12 @@
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:paddingTop="12dp">
-
+ android:src="@drawable/ic_circle"
+ android:contentDescription="@string/content_description_circle" />
-
+ android:src="@drawable/ic_circle"
+ android:contentDescription="@string/content_description_circle"
+ android:tint="?attr/colorPrimary" />
@@ -106,14 +107,15 @@
android:textStyle="bold"
android:text="@string/accent_color"/>
-
+ android:tint="?attr/colorAccent"
+ android:src="@drawable/ic_circle"
+ android:contentDescription="@string/content_description_circle"/>
diff --git a/app/src/main/res/layout/empty_directory_state.xml b/app/src/main/res/layout/empty_directory_state.xml
index 8864709..0050409 100644
--- a/app/src/main/res/layout/empty_directory_state.xml
+++ b/app/src/main/res/layout/empty_directory_state.xml
@@ -13,14 +13,16 @@
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_centerInParent="true">
-
-
+
+
+
-
+
-
-
-
-
-
+
-
-
-
+
+ android:layout_height="76dp"
+ android:src="@drawable/ic_file"
+ android:contentDescription="@string/file_icon" />
+
+
+ android:layout_toEndOf="@id/icons"
+ android:orientation="vertical"
+ android:layout_marginStart="16dp"
+ android:layout_marginEnd="16dp"
+ android:layout_centerVertical="true">
+ android:textAppearance="?attr/textAppearanceListItem"
+ android:fontFamily="sans-serif"
+ android:textSize="16sp"
+ android:textColor="?attr/textColorPrimary"
+ android:ellipsize="middle"
+ android:singleLine="true"
+ tools:text="Test File"/>
-
+ android:orientation="horizontal"
+ android:paddingTop="4dp" >
-
+
+
+
+
+
+
-
-
-
\ No newline at end of file
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/no_internet_state.xml b/app/src/main/res/layout/no_internet_state.xml
index e6ade3b..7b1b349 100644
--- a/app/src/main/res/layout/no_internet_state.xml
+++ b/app/src/main/res/layout/no_internet_state.xml
@@ -11,14 +11,16 @@
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_centerInParent="true">
-
-
+
+
+
-
+
pref_key_color_primary
pref_key_color_accent
pref_key_dark_theme
+ pref_key_version_code
Look and Feel
Primary color
Primary Color
@@ -156,4 +157,5 @@
Select accent color
Notifications
Open system settings
+ circle
diff --git a/build.gradle b/build.gradle
index f76b4f9..8fd7939 100644
--- a/build.gradle
+++ b/build.gradle
@@ -7,7 +7,7 @@ buildscript {
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.1.1'
+ classpath 'com.android.tools.build:gradle:3.1.2'
// NOTE: Do not place your application dependencies here; they belong