1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-21 09:38:01 +02:00

Android: Fix file system sync issues (#6943)

This commit is contained in:
javad mnjd 2022-10-23 16:30:27 +03:30 committed by GitHub
parent 7129c0c14e
commit 5324f39561
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 26 additions and 48 deletions

View File

@ -1017,6 +1017,9 @@ packages/app-mobile/utils/TlsUtils.js.map
packages/app-mobile/utils/checkPermissions.d.ts packages/app-mobile/utils/checkPermissions.d.ts
packages/app-mobile/utils/checkPermissions.js packages/app-mobile/utils/checkPermissions.js
packages/app-mobile/utils/checkPermissions.js.map packages/app-mobile/utils/checkPermissions.js.map
packages/app-mobile/utils/debounce.d.ts
packages/app-mobile/utils/debounce.js
packages/app-mobile/utils/debounce.js.map
packages/app-mobile/utils/fs-driver-rn.d.ts packages/app-mobile/utils/fs-driver-rn.d.ts
packages/app-mobile/utils/fs-driver-rn.js packages/app-mobile/utils/fs-driver-rn.js
packages/app-mobile/utils/fs-driver-rn.js.map packages/app-mobile/utils/fs-driver-rn.js.map

3
.gitignore vendored
View File

@ -1005,6 +1005,9 @@ packages/app-mobile/utils/TlsUtils.js.map
packages/app-mobile/utils/checkPermissions.d.ts packages/app-mobile/utils/checkPermissions.d.ts
packages/app-mobile/utils/checkPermissions.js packages/app-mobile/utils/checkPermissions.js
packages/app-mobile/utils/checkPermissions.js.map packages/app-mobile/utils/checkPermissions.js.map
packages/app-mobile/utils/debounce.d.ts
packages/app-mobile/utils/debounce.js
packages/app-mobile/utils/debounce.js.map
packages/app-mobile/utils/fs-driver-rn.d.ts packages/app-mobile/utils/fs-driver-rn.d.ts
packages/app-mobile/utils/fs-driver-rn.js packages/app-mobile/utils/fs-driver-rn.js
packages/app-mobile/utils/fs-driver-rn.js.map packages/app-mobile/utils/fs-driver-rn.js.map

View File

@ -84,6 +84,7 @@
android:configChanges="orientation" android:configChanges="orientation"
android:label="@string/app_name" android:label="@string/app_name"
android:excludeFromRecents="true" android:excludeFromRecents="true"
android:launchMode="singleTask"
android:theme="@style/AppTheme"> android:theme="@style/AppTheme">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.SEND" /> <action android:name="android.intent.action.SEND" />

View File

@ -24,9 +24,6 @@ import com.facebook.react.bridge.WritableMap;
import com.facebook.react.uimanager.ViewManager; import com.facebook.react.uimanager.ViewManager;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -46,13 +43,9 @@ public class SharePackage implements ReactPackage {
} }
public static class ShareModule extends ReactContextBaseJavaModule implements ActivityEventListener { public static class ShareModule extends ReactContextBaseJavaModule implements ActivityEventListener {
private final String cacheDir;
// when refactoring the `shareDirName` make sure to refactor the dir name in `ShareUtils.ts`
private static String shareDirName = "sharedFiles";
ShareModule(@NonNull ReactApplicationContext reactContext) { ShareModule(@NonNull ReactApplicationContext reactContext) {
super(reactContext); super(reactContext);
cacheDir = reactContext.getCacheDir().getAbsolutePath();
reactContext.addActivityEventListener(this); reactContext.addActivityEventListener(this);
} }
@ -146,39 +139,7 @@ public class SharePackage implements ReactPackage {
mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension); mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
} }
Uri copiedUri = null; imageData.putString("uri", uri.toString());
try {
String shareFolderPath = cacheDir + "/" + shareDirName;
String filepath = shareFolderPath + "/" + name;
File file = new File(filepath);
copiedUri = Uri.fromFile(file);
if (new File(shareFolderPath).mkdirs()) {
try (InputStream inStream =
contentResolver.openInputStream(uri);
OutputStream outStream =
contentResolver.openOutputStream(copiedUri, "wt");
) {
byte[] buffer = new byte[1024 * 4];
int length;
while ((length = inStream.read(buffer)) > 0) {
outStream.write(buffer, 0, length);
}
}
} else {
throw new IOException("Cannot create sharedFiles directory in cacheDir");
}
} catch (Exception e) {
e.printStackTrace();
copiedUri = null;
}
if (copiedUri != null) {
imageData.putString("uri", copiedUri.toString());
} else {
imageData.putString("uri", uri.toString());
}
imageData.putString("name", name); imageData.putString("name", name);
imageData.putString("mimeType", mimeType); imageData.putString("mimeType", mimeType);
return imageData; return imageData;

View File

@ -1,3 +1,5 @@
import debounce from './debounce';
const { NativeModules, Platform } = require('react-native'); const { NativeModules, Platform } = require('react-native');
export interface SharedData { export interface SharedData {
@ -9,7 +11,9 @@ export interface SharedData {
const ShareExtension = (NativeModules.ShareExtension) ? const ShareExtension = (NativeModules.ShareExtension) ?
{ {
data: () => NativeModules.ShareExtension.data(), data: () => NativeModules.ShareExtension.data(),
close: () => NativeModules.ShareExtension.close(), // we debounce the `close` method, to keep alive permissions of Uris received from the share activity
// this is to prevent getting permission denied error while sharing the same file to joplin multiple times in a row
close: () => debounce(() => NativeModules.ShareExtension.close(), 3 * 60 * 1000), // close it after 3 minutes
shareURL: (Platform.OS === 'ios') ? NativeModules.ShareExtension.getConstants().SHARE_EXTENSION_SHARE_URL : '', shareURL: (Platform.OS === 'ios') ? NativeModules.ShareExtension.getConstants().SHARE_EXTENSION_SHARE_URL : '',
} : } :
{ {

View File

@ -0,0 +1,12 @@
import PoorManIntervals from '@joplin/lib/PoorManIntervals';
function debounce(func: (...args: any[])=> void, timeout: number) {
let timer: number;
return (...args: any[]) => {
PoorManIntervals.clearTimeout(timer);
timer = PoorManIntervals.setTimeout(() => { func.apply(this, args); }, timeout);
};
}
export default debounce;

View File

@ -465,13 +465,7 @@ public class DocumentHelper {
// It's a document picked by user // It's a document picked by user
DocumentFile doc = DocumentFile.fromSingleUri(context, Uri.parse(unknownUriString)); DocumentFile doc = DocumentFile.fromSingleUri(context, Uri.parse(unknownUriString));
if (doc != null) { if (doc != null) {
if (!doc.canRead()) { return doc;
throw new SecurityException(
"You don't have read permission to access uri: " + unknownUriString);
}
if (doc.isFile() && doc.exists()) {
return doc;
}
} }
throw new FileNotFoundException( throw new FileNotFoundException(
"Cannot find the given document. File does not exist at '" + unknownUriString + "'"); "Cannot find the given document. File does not exist at '" + unknownUriString + "'");