Skip to content

Commit c87bc18

Browse files
committed
app: Add support for local sync provider
1 parent 53ec163 commit c87bc18

File tree

4 files changed

+95
-1
lines changed

4 files changed

+95
-1
lines changed

app/src/main/AndroidManifest.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@
88
<!-- 运行前台服务 -->
99
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
1010

11+
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
12+
tools:ignore="ScopedStorage" />
13+
14+
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
15+
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
16+
1117
<!--
1218
Fix the problem that notifications cannot be allowed on Android 13
1319
https://github.com/siyuan-note/siyuan/issues/7960
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package org.b3log.siyuan;
2+
3+
import android.content.Context;
4+
import android.net.Uri;
5+
import android.os.Environment;
6+
import android.provider.DocumentsContract;
7+
8+
public class AndroidFileUtils {
9+
public static String getPath(final Context context, final Uri uri) {
10+
if (DocumentsContract.isDocumentUri(context, uri)) {
11+
if (isExternalStorageDocument(uri)) {
12+
final String docId = DocumentsContract.getDocumentId(uri);
13+
final String[] split = docId.split(":");
14+
if (split.length != 2) return null;
15+
16+
final String type = split[0];
17+
18+
if ("primary".equalsIgnoreCase(type))
19+
return Environment.getExternalStorageDirectory() + "/" + split[1];
20+
}
21+
}
22+
23+
return null;
24+
}
25+
26+
/**
27+
* @param uri The Uri to check.
28+
* @return Whether the Uri authority is ExternalStorageProvider.
29+
*/
30+
public static boolean isExternalStorageDocument(Uri uri) {
31+
return "com.android.externalstorage.documents".equals(uri.getAuthority());
32+
}
33+
}

app/src/main/java/org/b3log/siyuan/JSAndroid.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,13 @@ public void changeStatusBarColor(final String color, final int appearanceMode) {
199199
});
200200
}
201201

202+
@JavascriptInterface
203+
public String getLocalFileSystemPath() {
204+
activity.getStoragePermissions();
205+
activity.pickLocalFileSystemFolder();
206+
return activity.getLocalSyncPath();
207+
}
208+
202209
private int parseColor(String str) {
203210
try {
204211
str = str.trim();

app/src/main/java/org/b3log/siyuan/MainActivity.java

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,21 @@
2323
import android.content.ClipData;
2424
import android.content.ContentValues;
2525
import android.content.Intent;
26+
import android.content.SharedPreferences;
2627
import android.content.pm.PackageManager;
2728
import android.graphics.Bitmap;
2829
import android.graphics.Color;
2930
import android.net.Uri;
3031
import android.os.Build;
3132
import android.os.Bundle;
33+
import android.os.Environment;
3234
import android.os.Handler;
3335
import android.os.LocaleList;
3436
import android.os.Looper;
3537
import android.os.Message;
38+
import android.provider.DocumentsContract;
3639
import android.provider.MediaStore;
40+
import android.provider.Settings;
3741
import android.util.Log;
3842
import android.view.DragEvent;
3943
import android.view.View;
@@ -105,6 +109,8 @@ public class MainActivity extends AppCompatActivity implements com.blankj.utilco
105109
private ValueCallback<Uri[]> uploadMessage;
106110
private static final int REQUEST_SELECT_FILE = 100;
107111
private static final int REQUEST_CAMERA = 101;
112+
private static final int REQUEST_MANAGE_ALL_CODE = 200;
113+
private static final int FOLDER_PICKER_CODE = 202;
108114

109115
@Override
110116
public void onNewIntent(final Intent intent) {
@@ -156,6 +162,32 @@ protected void onCreate(final Bundle savedInstanceState) {
156162
AndroidBug5497Workaround.assistActivity(this);
157163
}
158164

165+
public String getLocalSyncPath() {
166+
SharedPreferences prefs = getSharedPreferences("app_prefs", MODE_PRIVATE);
167+
return prefs.getString("localSyncPath", null);
168+
}
169+
170+
public void getStoragePermissions() {
171+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !Environment.isExternalStorageManager()) {
172+
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
173+
Uri uri = Uri.fromParts("package", getPackageName(), null);
174+
intent.setData(uri);
175+
startActivityForResult(intent, REQUEST_MANAGE_ALL_CODE);
176+
}
177+
}
178+
179+
public void pickLocalFileSystemFolder() {
180+
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
181+
startActivityForResult(intent, FOLDER_PICKER_CODE);
182+
}
183+
184+
private void saveLocalSyncPath(String path) {
185+
SharedPreferences prefs = getSharedPreferences("app_prefs", MODE_PRIVATE);
186+
SharedPreferences.Editor editor = prefs.edit();
187+
editor.putString("localSyncPath", path);
188+
editor.apply();
189+
}
190+
159191
private void initUIElements() {
160192
bootLogo = findViewById(R.id.bootLogo);
161193
bootProgressBar = findViewById(R.id.progressBar);
@@ -573,8 +605,24 @@ private void openCamera() {
573605

574606
@Override
575607
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
608+
super.onActivityResult(requestCode, resultCode, intent);
609+
if (requestCode == FOLDER_PICKER_CODE && resultCode == RESULT_OK) {
610+
if (intent != null) {
611+
Uri treeUri = intent.getData();
612+
Uri docUri = DocumentsContract.buildDocumentUriUsingTree(treeUri,
613+
DocumentsContract.getTreeDocumentId(treeUri));
614+
Log.i("Logseq/FolderPicker", "Got uri " + docUri);
615+
String path = AndroidFileUtils.getPath(this, docUri);
616+
Log.i("picker", "Convert to path " + AndroidFileUtils.getPath(this, docUri));
617+
if (path == null || path.isEmpty())
618+
Toast.makeText(this, "Error with selected directory",
619+
Toast.LENGTH_LONG).show();
620+
else
621+
saveLocalSyncPath(path);
622+
}
623+
}
624+
576625
if (null == uploadMessage) {
577-
super.onActivityResult(requestCode, resultCode, intent);
578626
return;
579627
}
580628

0 commit comments

Comments
 (0)