Compare commits

..

10 Commits

Author SHA1 Message Date
copilot-swe-agent[bot] e68bb791f7 Add fallback to synchronous fetch when onCreate() fails
Co-authored-by: adbenitez <24558636+adbenitez@users.noreply.github.com>
2026-01-07 15:58:54 +00:00
copilot-swe-agent[bot] 2297a72e29 Clear service variable when onCreate() fails to start foreground service
Co-authored-by: adbenitez <24558636+adbenitez@users.noreply.github.com>
2026-01-07 15:53:23 +00:00
copilot-swe-agent[bot] 5aabb40c48 Improve logging for foreground service exception
Co-authored-by: adbenitez <24558636+adbenitez@users.noreply.github.com>
2026-01-07 14:50:08 +00:00
copilot-swe-agent[bot] 53aa3c3ccb Fix ForegroundServiceStartNotAllowedException in FetchForegroundService.onCreate
Co-authored-by: adbenitez <24558636+adbenitez@users.noreply.github.com>
2026-01-07 14:48:30 +00:00
copilot-swe-agent[bot] 47cbdc6a44 Initial plan 2026-01-07 14:44:26 +00:00
adbenitez 8d6147761b add comment 2025-12-23 20:11:03 +01:00
adbenitez 9d6abfd979 avoid wrongly showing emoji icon while recording audio and event arrives 2025-12-23 20:08:57 +01:00
adbenitez 46f4324478 upload mappings to release 2025-12-22 20:03:44 +01:00
adbenitez bfeab57744 update screenshots 2025-12-22 19:36:26 +01:00
adbenitez 2e99926e82 Fix file_provider_paths.xml to support SD card 2025-12-22 19:21:22 +01:00
9 changed files with 34 additions and 25 deletions
+5 -1
View File
@@ -59,6 +59,8 @@ jobs:
rm build/outputs/apk/foss/release/*universal*
./gradlew assembleGplayRelease
mv build/outputs/apk/gplay/release/*universal* build/outputs/apk/foss/release/ArcaneChat-gplay.apk
mv build/outputs/mapping/fossRelease/mapping.txt build/outputs/mapping/fossRelease/mapping-foss.txt
mv build/outputs/mapping/gplayRelease/mapping.txt build/outputs/mapping/fossRelease/mapping-gplay.txt
- name: Release on GitHub
uses: softprops/action-gh-release@v1
@@ -67,7 +69,9 @@ jobs:
body: '[<img src="store/get-it-on-gplay.png" alt="Get it on Google Play" height="48">](https://play.google.com/store/apps/details?id=com.github.arcanechat) [<img src="store/get-it-on-fdroid.png" alt="Get it on F-Droid" height="48">](https://f-droid.org/packages/chat.delta.lite) [<img src="store/get-it-on-github.png" alt="Get it on GitHub" height="48">](https://github.com/ArcaneChat/android/releases/latest/download/ArcaneChat-gplay.apk)'
prerelease: ${{ contains(github.event.ref, '-beta') }}
fail_on_unmatched_files: true
files: build/outputs/apk/foss/release/*.apk
files: |
build/outputs/apk/foss/release/*.apk
build/outputs/mapping/fossRelease/mapping-*.txt
- name: Release on ZapStore
run: |
Binary file not shown.

Before

Width:  |  Height:  |  Size: 137 KiB

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 287 KiB

After

Width:  |  Height:  |  Size: 283 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 256 KiB

After

Width:  |  Height:  |  Size: 250 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 447 KiB

After

Width:  |  Height:  |  Size: 446 KiB

@@ -202,7 +202,8 @@ public class InputPanel extends ConstraintLayout
public void setSubjectVisible(boolean visible) {
subjectText.setVisibility(visible ? View.VISIBLE : View.GONE);
emojiToggle.setVisibility(!visible ? View.VISIBLE : View.GONE);
// don't make it visible if visible is false to avoid showing it while recording audio and an event triggers setSubjectVisible(false)
if (visible) emojiToggle.setVisibility(View.GONE);
}
public String getSubject() {
@@ -122,26 +122,8 @@ public class PersistentBlobProvider {
}
public Uri createForExternal(@NonNull Context context, @NonNull String mimeType) throws IOException, IllegalStateException, NullPointerException {
String filename = System.currentTimeMillis() + "." + getExtensionFromMimeType(mimeType);
// Try external cache first
try {
File externalDir = getExternalDir(context);
File target = new File(externalDir, filename);
return FileProviderUtil.getUriFor(context, target);
} catch (IllegalArgumentException e) {
// FileProvider doesn't support the external cache path (e.g., on removable SD card).
// Note: getExternalDir() already falls back to internal cache when external cache is null,
// but when external cache exists on a removable SD card, FileProvider may reject it.
// In that case, we explicitly use internal cache which FileProvider always supports.
Log.w(TAG, "FileProvider doesn't support external cache path, falling back to internal cache", e);
File internalDir = context.getCacheDir();
if (internalDir == null) {
throw new IOException("no cache directory available");
}
File target = new File(internalDir, filename);
return FileProviderUtil.getUriFor(context, target);
}
File target = new File(getExternalDir(context), System.currentTimeMillis() + "." + getExtensionFromMimeType(mimeType));
return FileProviderUtil.getUriFor(context, target);
}
public boolean delete(@NonNull Context context, @NonNull Uri uri) {
@@ -88,7 +88,27 @@ public final class FetchForegroundService extends Service {
.setSmallIcon(R.drawable.notification_permanent)
.build();
startForeground(NotificationCenter.ID_FETCH, notification);
try {
startForeground(NotificationCenter.ID_FETCH, notification);
} catch (Exception e) {
Log.w(TAG, "Failed to start foreground service, falling back to synchronous fetch", e);
synchronized (SERVICE_LOCK) {
service = null;
}
stopSelf();
// Fallback to synchronous fetching when foreground service fails
fetchingSynchronously = true;
if (ApplicationContext.getDcAccounts().backgroundFetch(10)) {
synchronized (STOP_NOTIFIER) {
while (fetchingSynchronously) {
try {
STOP_NOTIFIER.wait();
} catch (InterruptedException ex) {}
}
}
}
return;
}
Util.runOnAnyBackgroundThread(() -> {
Log.i(TAG, "Starting fetch");
+4 -2
View File
@@ -1,11 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<paths>
<cache-path name="cache" path="." />
<external-cache-path name="external_cache" path="." />
<external-files-path name="external_files" path="." />
<!-- this is needed for access to the cache dir in SD card -->
<root-path name="external_root" path="/storage/" />
<external-path name="external_pictures" path="Pictures"/>
<external-path name="external_video" path="Movies"/>
<external-path name="external_audio" path="Music"/>
<external-path name="external_download" path="Download"/>
</paths>
</paths>