Skip to content

Commit e00a1cd

Browse files
committed
Add sdome improvements for files storage. Add context menu in transfers to show the absolute file path for a transfer
1 parent c57442c commit e00a1cd

File tree

15 files changed

+213
-42
lines changed

15 files changed

+213
-42
lines changed

android/jdonkey/AndroidManifest.xml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
xmlns:tools="http://schemas.android.com/tools"
44
package="org.dkf.jmule"
55
android:installLocation="auto"
6-
android:versionCode="34"
7-
android:versionName="34">
6+
android:versionCode="35"
7+
android:versionName="35">
88

99
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
1010
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
@@ -27,7 +27,8 @@
2727
<activity
2828
android:name="org.dkf.jmule.activities.SplashActivity"
2929
android:label="@string/app_name"
30-
android:theme="@style/SplashTheme">
30+
android:theme="@style/SplashTheme"
31+
android:exported="true">
3132
<intent-filter>
3233
<action android:name="android.intent.action.MAIN" />
3334
<category android:name="android.intent.category.LAUNCHER" />
@@ -36,7 +37,8 @@
3637

3738
<activity
3839
android:name="org.dkf.jmule.activities.MainActivity"
39-
android:label="@string/app_name" >
40+
android:label="@string/app_name"
41+
android:exported="true">
4042
<intent-filter>
4143
<action android:name="org.dkf.jmule.android.ACTION_SHOW_TRANSFERS" />
4244
<action android:name="org.dkf.jmule.android.ACTION_REQUEST_SHUTDOWN" />
@@ -96,7 +98,7 @@
9698
android:resource="@xml/provider_paths" />
9799
</provider>
98100

99-
<service android:name="org.dkf.jmule.ED2KService">
101+
<service android:name="org.dkf.jmule.ED2KService" android:exported="false">
100102
<intent-filter>
101103
<action android:name="org.dkf.jmule.INTENT_OPEN"/>
102104
<action android:name="org.dkf.jmule.INTENT_CLOSE"/>

android/jdonkey/build.gradle

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ buildscript {
1010
}
1111

1212
dependencies {
13-
classpath 'com.android.tools.build:gradle:7.0.4'
13+
classpath 'com.android.tools.build:gradle:7.2.1'
1414
}
1515
}
1616

@@ -66,13 +66,13 @@ def changeApkOutput(variant) {
6666
boolean isAssembleRelease = gradle.startParameter.taskNames.contains("assembleRelease") || gradle.startParameter.taskNames.contains("assembleBasicRelease")
6767

6868
android {
69-
compileSdkVersion 31
69+
compileSdkVersion 32
7070

7171
defaultConfig {
7272
applicationId 'org.dkf.jmule'
7373
versionName project.ext.versionName
7474
minSdkVersion 16
75-
targetSdkVersion 30
75+
targetSdkVersion 32
7676
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
7777
}
7878

@@ -100,9 +100,6 @@ android {
100100
}
101101
}
102102

103-
lintOptions {
104-
abortOnError false
105-
}
106103

107104
signingConfigs {
108105
release {
@@ -154,6 +151,9 @@ android {
154151
resValue "string", "application_label", "Mule"
155152
}
156153
}
154+
lint {
155+
abortOnError false
156+
}
157157

158158
applicationVariants.all { variant ->
159159
changeApkOutput(variant)
@@ -170,9 +170,9 @@ dependencies {
170170
implementation 'androidx.documentfile:documentfile:1.0.1'
171171
implementation 'com.google.android.material:material:1.4.0'
172172
implementation 'androidx.preference:preference:1.1.1'
173-
debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.5'
174-
releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'
175-
testImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'
173+
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.9.1'
174+
//releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:2.9.1'
175+
//testImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:2.9.1'
176176
testImplementation 'org.robolectric:robolectric:4.6'
177177
androidTestImplementation 'androidx.test:core:' + project.ext.coreVersion
178178
androidTestImplementation 'androidx.test.ext:junit:' + project.ext.extJUnitVersion

android/jdonkey/src/main/java/org/dkf/jmule/AndroidPaths.java

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,27 +40,34 @@
4040
*/
4141
public final class AndroidPaths {
4242
private static final boolean USE_EXTERNAL_STORAGE_DIR_ON_OR_AFTER_ANDROID_10 = true;
43-
private final Context context;
43+
private final Application app;
4444

4545
private static final Map<Byte, String> fileTypeFolders = new HashMap<>();
4646
private static final Object fileTypeFoldersLock = new Object();
4747

48-
public AndroidPaths(Context app) {
49-
this.context = app;
48+
public AndroidPaths(Application app) {
49+
this.app = app;
5050
}
5151

5252
public File data() {
5353
if (SystemUtils.hasAndroid10OrNewer()) {
54-
File externalDir = context.getExternalFilesDir(null);
55-
return USE_EXTERNAL_STORAGE_DIR_ON_OR_AFTER_ANDROID_10 ? externalDir : context.getFilesDir();
54+
if (SystemUtils.hasAndroid10()) {
55+
return app.getExternalFilesDir(null);
56+
}
57+
58+
// On Android 11 and up, they finally let us use File objects in the public download directory as long as we have permission from the user
59+
return android11AndUpStorage();
60+
}
5661

62+
if (SystemUtils.hasAndroid10OrNewer()) {
63+
File externalDir = app.getExternalFilesDir(null);
64+
return USE_EXTERNAL_STORAGE_DIR_ON_OR_AFTER_ANDROID_10 ? externalDir : app.getFilesDir();
5765
}
5866

5967
/* For Older versions of Android where we used to have access to write to external storage
60-
* <externalStoragePath>
68+
* <externalStoragePath>/Download/FrostWire/
6169
*/
62-
String path = ConfigurationManager.instance().getStoragePath();
63-
return new File(ConfigurationManager.instance().getStoragePath());
70+
return new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath());
6471
}
6572

6673
public static byte getFileType(String filePath, boolean returnTorrentsAsDocument) {
@@ -79,6 +86,10 @@ public static byte getFileType(String filePath, boolean returnTorrentsAsDocument
7986
return result;
8087
}
8188

89+
public static File android11AndUpStorage() {
90+
return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
91+
}
92+
8293

8394
/**
8495
* FILE_TYPE_AUDIO -> "Music"

android/jdonkey/src/main/java/org/dkf/jmule/AndroidPlatform.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
package org.dkf.jmule;
2020

21+
import android.app.Application;
2122
import android.content.Context;
2223
import android.os.Build;
2324
import android.os.Looper;
@@ -88,7 +89,7 @@ enum NetworkType {
8889

8990
private final int sdk;
9091

91-
public AndroidPlatform(Context app) {
92+
public AndroidPlatform(Application app) {
9293
fileSystem = buildFileSystem(app);
9394
systemPaths = new AndroidPaths(app);
9495
appSettings = new AndroidSettings();

android/jdonkey/src/main/java/org/dkf/jmule/MainApplication.java

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
package org.dkf.jmule;
2020

2121
import android.app.Application;
22-
import com.squareup.leakcanary.LeakCanary;
2322
import org.slf4j.Logger;
2423
import org.slf4j.LoggerFactory;
2524

@@ -40,14 +39,6 @@ public void onTerminate() {
4039
public void onCreate() {
4140
super.onCreate();
4241

43-
if (LeakCanary.isInAnalyzerProcess(this)) {
44-
// This process is dedicated to LeakCanary for heap analysis.
45-
// You should not init your app in this process.
46-
return;
47-
}
48-
49-
LeakCanary.install(this);
50-
5142
try {
5243

5344
Platforms.set(new AndroidPlatform(this));

android/jdonkey/src/main/java/org/dkf/jmule/Platforms.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,15 @@
1919
package org.dkf.jmule;
2020

2121
import java.io.File;
22+
import org.slf4j.Logger;
23+
import org.slf4j.LoggerFactory;
2224

2325
/**
2426
* @author gubatron
2527
* @author aldenml
2628
*/
2729
public final class Platforms {
30+
private static final Logger LOG = LoggerFactory.getLogger(Platforms.class);
2831

2932
private static AndroidPlatform platform;
3033

@@ -64,6 +67,8 @@ public static AndroidSettings appSettings() {
6467
}
6568

6669
public static File data() {
67-
return get().systemPaths().data();
70+
File f = get().systemPaths().data();
71+
LOG.warn("PLATFORM FILE " + f.getAbsolutePath());
72+
return f;
6873
}
6974
}

android/jdonkey/src/main/java/org/dkf/jmule/adapters/TransferListAdapter.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ private String populateTransferDownloadMenuAction(Transfer download, List<MenuAc
257257
R.string.transfers_context_menu_copy_link_copied, download.toLink()));
258258

259259
items.add(new CancelMenuAction(context.get(), download, !download.isComplete()));
260+
items.add(new ShowThePathMenuAction(context.get(), download));
260261
return title;
261262
}
262263

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package org.dkf.jmule.adapters.menu;
2+
3+
import android.app.Activity;
4+
import android.app.Dialog;
5+
import android.content.Context;
6+
import android.os.Bundle;
7+
import android.view.View;
8+
import android.widget.Button;
9+
import android.widget.TextView;
10+
11+
import org.dkf.jmule.Platforms;
12+
import org.dkf.jmule.R;
13+
import org.dkf.jmule.transfers.Transfer;
14+
import org.dkf.jmule.util.Ref;
15+
import org.dkf.jmule.views.AbstractDialog;
16+
import org.dkf.jmule.views.MenuAction;
17+
18+
import java.lang.ref.WeakReference;
19+
20+
public class ShowThePathMenuAction extends MenuAction {
21+
private final Transfer transfer;
22+
23+
@SuppressWarnings("WeakerAccess")
24+
public final static class ShowThePathDialog extends AbstractDialog {
25+
Context context;
26+
String filename;
27+
28+
public static ShowThePathDialog newInstance(Context context, String filename) {
29+
return new ShowThePathDialog(context, filename);
30+
}
31+
32+
// Important to keep this guy 'public', even if IntelliJ thinks you shouldn't.
33+
// otherwise, the app crashes when you turn the screen and the dialog can't
34+
public ShowThePathDialog(Context contex, String filename) {
35+
super(R.layout.dialog_default_info);
36+
this.context = contex;
37+
this.filename = filename;
38+
}
39+
40+
@Override
41+
protected void initComponents(Dialog dlg, Bundle savedInstanceState) {
42+
TextView title = findView(dlg, R.id.dialog_default_info_title);
43+
title.setText(R.string.transfers_context_menu_show_path_title);
44+
TextView text = findView(dlg, R.id.dialog_default_info_text);
45+
String pathsTemplate = context.getResources().getString(R.string.transfers_context_menu_show_path_body);
46+
String pathsStr = String.format(pathsTemplate, Platforms.data().getAbsolutePath(), filename);
47+
text.setText(pathsStr);
48+
Button okButton = findView(dlg, R.id.dialog_default_info_button_ok);
49+
okButton.setText(android.R.string.ok);
50+
okButton.setOnClickListener(new OkButtonOnClickListener(dlg));
51+
}
52+
}
53+
54+
private final static class OkButtonOnClickListener implements View.OnClickListener {
55+
private final WeakReference<Dialog> dialogPtr;
56+
57+
OkButtonOnClickListener(Dialog newNoWifiInformationDialog) {
58+
this.dialogPtr = Ref.weak(newNoWifiInformationDialog);
59+
}
60+
61+
@Override
62+
public void onClick(View view) {
63+
if (Ref.alive(dialogPtr)) {
64+
dialogPtr.get().dismiss();
65+
}
66+
}
67+
}
68+
69+
public ShowThePathMenuAction(Context context
70+
, Transfer transfer) {
71+
super(context, R.drawable.ic_search_black_24dp, R.string.transfers_context_menu_show_path_title);
72+
this.transfer = transfer;
73+
}
74+
75+
@Override
76+
protected void onClick(Context context) {
77+
if (transfer != null) {
78+
ShowThePathDialog dialog = ShowThePathDialog.newInstance(context, transfer.getFilePath());
79+
dialog.show(((Activity)context).getFragmentManager());
80+
}
81+
}
82+
}
83+

android/jdonkey/src/main/java/org/dkf/jmule/util/SystemUtils.java

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ public final class SystemUtils {
5050

5151
private static final int VERSION_CODE_KITKAT = 19;
5252
private static final int VERSION_SDK_NOUGAT_7_0 = 24;
53+
private static final int VERSION_SDK_NOUGAT_7_0_N = 24;
54+
private static final int VERSION_SDK_ANDROID_10_Q = 29;
55+
private static final int VERSION_SDK_ANDROID_11_R = 30;
56+
private static final int VERSION_SDK_ANDROID_12_S = 31;
5357

5458
private SystemUtils() {
5559
}
@@ -195,6 +199,23 @@ private static boolean hasSdkOrNewer(int versionCode) {
195199
return Build.VERSION.SDK_INT >= versionCode;
196200
}
197201

202+
@SuppressWarnings("SameParameterValue")
203+
private static boolean hasSdk(int versionCode) {
204+
return Build.VERSION.SDK_INT == versionCode;
205+
}
206+
207+
208+
public static boolean hasAndroid10() {
209+
return hasSdk(VERSION_SDK_ANDROID_10_Q);
210+
}
211+
212+
/**
213+
* Used to determine if the device is running Android11 or greater
214+
*/
215+
public static boolean hasAndroid11OrNewer() {
216+
return hasSdkOrNewer(VERSION_SDK_ANDROID_11_R);
217+
}
218+
198219
/**
199220
* Used to determine if the device is running
200221
* KitKat (Android 4.4) or greater
@@ -226,12 +247,6 @@ public static boolean hasNougatOrNewer() {
226247
return hasSdkOrNewer(VERSION_SDK_NOUGAT_7_0);
227248
}
228249

229-
/**
230-
* Used to determine if the device is running Android11 or greater
231-
*/
232-
public static boolean hasAndroid11OrNewer() {
233-
return hasSdkOrNewer(30); //Build.VERSION_CODES.R
234-
}
235250

236251
/**
237252
* We call it "safe" because if any exceptions are thrown,

0 commit comments

Comments
 (0)