Repository: cgeo/cgeo
Pull request #16983: #16882: Add snackbar for log visit with share option
Author: login: kennygchen
Labels: name: ok-to-test
description: Allow running GitHub Workflows
Created: 2025-05-26T07:57:35Z | Merged: 2025-05-28T20:39:38Z

## Description
- Add share intent in `LogCacheActivity`.
- Add `startForCreateForResult()` in `LogCacheActivity` to support request code.
- The share text prefix changes based on the log type (e.g., `FOUND_IT`, `DIDNT_FIND_IT`, `NOTE`, `NEEDS_MAINTENANCE`, and `NEEDS_ARCHIVE`) to provide more meaningful context for social media sharing.
- Add snackbar confirmation in `CacheDetailActivity`, `CacheListActivity`, `CompassActivity`, and `UnifiedMapActivity` after the user posts a log.
- Add `logVisitForResult()` in `Geocache` to launch the log activity with a result callback.
- Update `LoggingUI` to use `logVisitForResult()`.

From `CacheListActivity`:
![Screenshot_20250526_003455_cgeo](https://github.com/user-attachments/assets/e78ac14e-f43a-4364-9132-78df6ba169e7)

From `CacheDetailActivity`:
![Screenshot_20250526_002031_cgeo](https://github.com/user-attachments/assets/3b37ec83-56bf-4f5c-a673-86517d3148de)

From `CompassActivity`:
![Screenshot_20250526_003336_cgeo](https://github.com/user-attachments/assets/4f13eea6-3d57-4aa0-b053-c3b568aa0077)

From `UnifiedMapActivity`:
![Screenshot_20250526_003111_cgeo (1)](https://github.com/user-attachments/assets/58a64aaa-6445-4558-8a25-bc8366e5a955)

Sharesheet:
![Screenshot_20250526_002706_IntentResolver (4)](https://github.com/user-attachments/assets/25095467-44ec-4726-9b19-53e90cd4facf)

## Related issues
#16882 


Diff:
diff --git a/main/src/main/java/cgeo/geocaching/CacheDetailActivity.java b/main/src/main/java/cgeo/geocaching/CacheDetailActivity.java
index 5ea047c6a25..496685addea 100644
--- a/main/src/main/java/cgeo/geocaching/CacheDetailActivity.java
+++ b/main/src/main/java/cgeo/geocaching/CacheDetailActivity.java
@@ -199,6 +199,7 @@ public class CacheDetailActivity extends TabbedViewPagerActivity
 
     private static final int MESSAGE_FAILED = -1;
     private static final int MESSAGE_SUCCEEDED = 1;
+    private static final int REQUEST_CODE_LOG = 1001;
 
     private static final String EXTRA_FORCE_WAYPOINTSPAGE = "cgeo.geocaching.extra.cachedetail.forceWaypointsPage";
     private static final String EXTRA_EDIT_PERSONALNOTE = "cgeo.geocaching.extra.cachedetail.editPersonalNote";
@@ -2486,6 +2487,9 @@ protected void onActivityResult(final int requestCode, final int resultCode, @Nu
             imageGalleryResultResultCode = resultCode;
             imageGalleryData = data;
         }
+        if (requestCode == REQUEST_CODE_LOG && resultCode == Activity.RESULT_OK && data != null) {
+            ShareUtils.showLogPostedSnackbar(this, data, findViewById(R.id.tab_layout));
+        }
     }
 
     @Override
diff --git a/main/src/main/java/cgeo/geocaching/CacheListActivity.java b/main/src/main/java/cgeo/geocaching/CacheListActivity.java
index 974cf927565..db698108d0e 100644
--- a/main/src/main/java/cgeo/geocaching/CacheListActivity.java
+++ b/main/src/main/java/cgeo/geocaching/CacheListActivity.java
@@ -89,6 +89,7 @@
 import cgeo.geocaching.utils.Log;
 import cgeo.geocaching.utils.MapMarkerUtils;
 import cgeo.geocaching.utils.MenuUtils;
+import cgeo.geocaching.utils.ShareUtils;
 import cgeo.geocaching.utils.functions.Action1;
 
 import android.annotation.SuppressLint;
@@ -144,6 +145,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
 
     private static final int REFRESH_WARNING_THRESHOLD = 100;
 
+    private static final int REQUEST_CODE_LOG = 1001;
     private static final int REQUEST_CODE_IMPORT_PQ = 10003;
     private static final int REQUEST_CODE_IMPORT_BOOKMARK = 10004;
 
@@ -1241,6 +1243,11 @@ protected void onActivityResult(final int requestCode, final int resultCode, fin
             }
         } else if (requestCode == GeocacheFilterActivity.REQUEST_SELECT_FILTER && resultCode == Activity.RESULT_OK) {
             setAndRefreshFilterForOnlineSearch(data.getParcelableExtra(GeocacheFilterActivity.EXTRA_FILTER_CONTEXT));
+        } else if (requestCode == REQUEST_CODE_LOG && resultCode == Activity.RESULT_OK && data != null) {
+            final View navBar = findViewById(R.id.activity_navigationBar);
+            final boolean isNavBarVisible = navBar != null && navBar.getVisibility() == View.VISIBLE && navBar.getHeight() > 0;
+
+            ShareUtils.showLogPostedSnackbar(this, data, isNavBarVisible ? navBar : null);
         }
     }
 
diff --git a/main/src/main/java/cgeo/geocaching/CompassActivity.java b/main/src/main/java/cgeo/geocaching/CompassActivity.java
index 7711c9024ff..451c5d9a325 100644
--- a/main/src/main/java/cgeo/geocaching/CompassActivity.java
+++ b/main/src/main/java/cgeo/geocaching/CompassActivity.java
@@ -26,8 +26,10 @@
 import cgeo.geocaching.utils.AngleUtils;
 import cgeo.geocaching.utils.Formatter;
 import cgeo.geocaching.utils.Log;
+import cgeo.geocaching.utils.ShareUtils;
 
 import android.annotation.SuppressLint;
+import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Configuration;
@@ -44,6 +46,7 @@
 import java.util.Arrays;
 import java.util.Locale;
 
+
 import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
 import io.reactivex.rxjava3.functions.Consumer;
 import org.apache.commons.lang3.StringUtils;
@@ -67,6 +70,8 @@ public class CompassActivity extends AbstractActionBarActivity {
 
     private final PermissionAction<Void> askLocationPermissionAction = PermissionAction.register(this, PermissionContext.LOCATION, b -> binding.hint.locationStatus.updatePermissions());
 
+    private static final int REQUEST_CODE_LOG = 1001;
+
     @Override
     public void onCreate(final Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -255,6 +260,17 @@ public boolean onOptionsItemSelected(final MenuItem item) {
         return true;
     }
 
+    @Override
+    protected void onActivityResult(final int requestCode, final int resultCode, @Nullable final Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+
+        if (requestCode == REQUEST_CODE_LOG && resultCode == Activity.RESULT_OK && data != null) {
+            ShareUtils.showLogPostedSnackbar(this, data, findViewById(R.id.location_status));
+        }
+    }
+
+
+
     private void setTarget(@NonNull final Geopoint coords, final String newDescription) {
         setDestCoords(coords);
         setTargetDescription(newDescription);
diff --git a/main/src/main/java/cgeo/geocaching/log/LogCacheActivity.java b/main/src/main/java/cgeo/geocaching/log/LogCacheActivity.java
index ea76d106b96..a16c4db9841 100644
--- a/main/src/main/java/cgeo/geocaching/log/LogCacheActivity.java
+++ b/main/src/main/java/cgeo/geocaching/log/LogCacheActivity.java
@@ -138,6 +138,12 @@ public static void startForCreate(@NonNull final Context fromActivity, final Str
         startActivityInternal(fromActivity, geocode, null);
     }
 
+    public static void startForCreateForResult(@NonNull final Activity fromActivity, final String geocode, final int requestCode) {
+        final Intent intent = new Intent(fromActivity, LogCacheActivity.class);
+        intent.putExtra(Intents.EXTRA_GEOCODE, geocode);
+        fromActivity.startActivityForResult(intent, requestCode);
+    }
+
     public static void startForEdit(@NonNull final Context fromActivity, final String geocode, final LogEntry logEntry) {
         startActivityInternal(fromActivity, geocode, logEntry);
     }
@@ -561,6 +567,32 @@ private void onPostExecuteInternal(final StatusResult statusResult) {
                 Settings.setLastCacheLog(currentLogText);
             }
 
+            final LogContext logContext = getLogContext();
+            final LogType logType = logContext.getLogEntry().logType;
+            final String cacheName = logContext.getCache().getName();
+            final String cacheUrl = logContext.getCache().getUrl();
+            final String prefix;
+            switch (logType) {
+                case FOUND_IT:
+                    prefix = LocalizationUtils.getString(R.string.log_share_prefix_found, cacheName, cacheUrl);
+                    break;
+                case DIDNT_FIND_IT:
+                    prefix = LocalizationUtils.getString(R.string.log_share_prefix_dnf, cacheName, cacheUrl);
+                    break;
+                case NOTE:
+                    prefix = LocalizationUtils.getString(R.string.log_share_prefix_note, cacheName, cacheUrl);
+                    break;
+                case NEEDS_MAINTENANCE:
+                    prefix = LocalizationUtils.getString(R.string.log_share_prefix_maintenance, cacheName, cacheUrl);
+                    break;
+                case NEEDS_ARCHIVE:
+                    prefix = LocalizationUtils.getString(R.string.log_share_prefix_archive, cacheName, cacheUrl);
+                    break;
+                default:
+                    prefix = LocalizationUtils.getString(R.string.log_share_prefix_default, cacheName, cacheUrl);
+                    break;
+            }
+
             //reset Gui and all values
             resetValues();
             refreshGui();
@@ -569,7 +601,10 @@ private void onPostExecuteInternal(final StatusResult statusResult) {
             imageListFragment.clearImages();
             imageListFragment.adjustImagePersistentState();
 
-            showToast(res.getString(R.string.info_log_posted));
+            final Intent shareIntent = new Intent();
+            shareIntent.putExtra("EXTRA_SHARE_TEXT", prefix + currentLogText);
+            setResult(Activity.RESULT_OK, shareIntent);
+
             // Prevent from saving log after it was sent successfully.
             finish(LogCacheActivity.SaveMode.SKIP);
         } else if (!LogCacheActivity.this.isFinishing()) {
diff --git a/main/src/main/java/cgeo/geocaching/log/LoggingUI.java b/main/src/main/java/cgeo/geocaching/log/LoggingUI.java
index c4dc21627c2..e574c2caf5c 100644
--- a/main/src/main/java/cgeo/geocaching/log/LoggingUI.java
+++ b/main/src/main/java/cgeo/geocaching/log/LoggingUI.java
@@ -22,6 +22,7 @@
 import java.util.List;
 
 public final class LoggingUI extends AbstractUIFactory {
+    public static final int REQUEST_CODE_LOG = 1001;
 
     private LoggingUI() {
         // utility class
@@ -74,7 +75,7 @@ public String getL10n() {
     public static boolean onMenuItemSelected(final MenuItem item, final Activity activity, final Geocache cache, final DialogInterface.OnDismissListener listener) {
         final int itemId = item.getItemId();
         if (itemId == R.id.menu_log_visit) {
-            cache.logVisit(activity);
+            cache.logVisitForResult(activity, REQUEST_CODE_LOG);
         } else if (itemId == R.id.menu_log_visit_offline) {
             showOfflineMenu(cache, activity, listener);
         } else {
diff --git a/main/src/main/java/cgeo/geocaching/models/Geocache.java b/main/src/main/java/cgeo/geocaching/models/Geocache.java
index b205f090431..5d1ca0d47c3 100644
--- a/main/src/main/java/cgeo/geocaching/models/Geocache.java
+++ b/main/src/main/java/cgeo/geocaching/models/Geocache.java
@@ -563,6 +563,19 @@ public void logVisit(@NonNull final Activity fromActivity) {
         LogCacheActivity.startForCreate(fromActivity, geocode);
     }
 
+    public void logVisitForResult(@NonNull final Activity fromActivity, final int requestCode) {
+        if (!getConnector().canLog(this)) {
+            ActivityMixin.showToast(fromActivity, fromActivity.getString(R.string.err_cannot_log_visit));
+            return;
+        }
+        String geocode = this.geocode;
+        if (StringUtils.isBlank(geocode)) {
+            geocode = DataStore.getGeocodeForGuid(this.cacheId);
+        }
+        LogCacheActivity.startForCreateForResult(fromActivity, geocode, requestCode);
+    }
+
+
     public boolean hasLogOffline() {
         return BooleanUtils.isTrue(hasLogOffline);
     }
diff --git a/main/src/main/java/cgeo/geocaching/unifiedmap/UnifiedMapActivity.java b/main/src/main/java/cgeo/geocaching/unifiedmap/UnifiedMapActivity.java
index a4b292586c3..2e4e28390bc 100644
--- a/main/src/main/java/cgeo/geocaching/unifiedmap/UnifiedMapActivity.java
+++ b/main/src/main/java/cgeo/geocaching/unifiedmap/UnifiedMapActivity.java
@@ -74,6 +74,7 @@
 import cgeo.geocaching.utils.Log;
 import cgeo.geocaching.utils.MapMarkerUtils;
 import cgeo.geocaching.utils.MenuUtils;
+import cgeo.geocaching.utils.ShareUtils;
 import cgeo.geocaching.utils.TextUtils;
 import cgeo.geocaching.utils.functions.Func1;
 import cgeo.geocaching.wherigo.WherigoGame;
@@ -141,6 +142,7 @@ public class UnifiedMapActivity extends AbstractNavigationBarMapActivity impleme
 
     private static final String STATE_ROUTETRACKUTILS = "routetrackutils";
     private static final String ROUTING_SERVICE_KEY = "UnifiedMap";
+    private static final int REQUEST_CODE_LOG = 1001;
 
     private UnifiedMapViewModel viewModel = null;
     private AbstractTileProvider tileProvider = null;
@@ -1056,6 +1058,8 @@ protected void onActivityResult(final int requestCode, final int resultCode, fin
         if (requestCode == GeocacheFilterActivity.REQUEST_SELECT_FILTER && resultCode == Activity.RESULT_OK) {
             viewModel.mapType.filterContext = data.getParcelableExtra(EXTRA_FILTER_CONTEXT);
             refreshMapData(true);
+        } else if (requestCode == REQUEST_CODE_LOG && resultCode == Activity.RESULT_OK && data != null) {
+            ShareUtils.showLogPostedSnackbar(this, data, findViewById(R.id.activity_navigationBar));
         }
     }
 
diff --git a/main/src/main/java/cgeo/geocaching/utils/ShareUtils.java b/main/src/main/java/cgeo/geocaching/utils/ShareUtils.java
index 60f6c8fd1b9..1addcbe86b7 100644
--- a/main/src/main/java/cgeo/geocaching/utils/ShareUtils.java
+++ b/main/src/main/java/cgeo/geocaching/utils/ShareUtils.java
@@ -22,6 +22,7 @@
 import android.net.Uri;
 import android.os.Build;
 import android.os.Parcelable;
+import android.view.View;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -33,6 +34,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import com.google.android.material.snackbar.Snackbar;
 import org.apache.commons.collections4.IterableUtils;
 import org.apache.commons.lang3.StringUtils;
 
@@ -264,4 +266,22 @@ public static void openCustomTab(final Context context, final String url) {
         customTabsIntent.intent.setPackage(CHROME_PACKAGE_NAME);
         customTabsIntent.launchUrl(context, Uri.parse(url));
     }
+
+    public static void showLogPostedSnackbar(@NonNull final Activity activity, @Nullable final Intent data, final View anchor) {
+        if (data == null) {
+            return;
+        }
+        final String shareText = data.getStringExtra("EXTRA_SHARE_TEXT");
+        if (!StringUtils.isBlank(shareText)) {
+            Snackbar.make(activity.findViewById(android.R.id.content), activity.getString(R.string.info_log_posted), Snackbar.LENGTH_LONG)
+                    .setAnchorView(anchor)
+                    .setAction(R.string.snackbar_action_share, v -> {
+                        final Intent shareIntent = new Intent(Intent.ACTION_SEND);
+                        shareIntent.setType("text/plain");
+                        shareIntent.putExtra(Intent.EXTRA_TEXT, shareText);
+                        activity.startActivity(Intent.createChooser(shareIntent, null));
+                    })
+                    .show();
+        }
+    }
 }
diff --git a/main/src/main/res/values/strings.xml b/main/src/main/res/values/strings.xml
index 0654b49886b..e1fed791b64 100644
--- a/main/src/main/res/values/strings.xml
+++ b/main/src/main/res/values/strings.xml
@@ -232,6 +232,13 @@
     <string name="log_delete_confirm">Do you really want to delete log of type \'%1$s\' by author \'%2$s\' with log date \'%3$s\'?</string>
     <string name="log_offline_delete_confirm">Do you really want to delete your stored offline log of type \'%1$s\' with log date \'%2$s\'?</string>
 
+    <string name="log_share_prefix_found">I found %1$s (%2$s):\n\n</string>
+    <string name="log_share_prefix_dnf">I couldn\'t find %1$s (%2$s):\n\n</string>
+    <string name="log_share_prefix_note">I left a note on %1$s (%2$s):\n\n</string>
+    <string name="log_share_prefix_maintenance">I reported maintenance needed for %1$s (%2$s):\n\n</string>
+    <string name="log_share_prefix_archive">I think %1$s (%2$s) should be archived:\n\n</string>
+    <string name="log_share_prefix_default">My log for %1$s (%2$s):\n\n</string>
+
     <string name="datetime_nodateset_display">No date set</string>
 
     <!-- Contacts -->
@@ -355,6 +362,7 @@
     <string name="dont_show_again">Don\'t show again</string>
     <string name="tap_icon_more_info">Tap on icon for more info</string>
     <string name="use_slider_adjust_value">Use slider to adjust value</string>
+    <string name="snackbar_action_share">Share</string>
 
     <string name="warn_gm_not_available">Google Maps not available.</string>
     <string name="switch_to_mf">Your Google Play Service is outdated. Do you want to switch to Mapsforge map provider instead?</string>


Reviews:
user: login: SammysHP
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-26T18:47:14Z
user: login: SammysHP
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-26T18:48:09Z
user: login: kennygchen
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-27T00:07:38Z

Review comments:
diff_hunk: @@ -255,6 +259,28 @@ public boolean onOptionsItemSelected(final MenuItem item) {
         return true;
     }
 
+    @Override
+    protected void onActivityResult(final int requestCode, final int resultCode, @Nullable final Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+
+        if (requestCode == REQUEST_CODE_LOG && resultCode == Activity.RESULT_OK && data != null) {
path: main/src/main/java/cgeo/geocaching/CompassActivity.java
user: login: SammysHP
body: This part of the code can be found at ~~three~~ four places, would be good to move at to a single location and reuse it.
created_at: 2025-05-26T18:47:14Z
author_association: MEMBER
diff_hunk: @@ -561,6 +567,32 @@ private void onPostExecuteInternal(final StatusResult statusResult) {
                 Settings.setLastCacheLog(currentLogText);
             }
 
+            final LogContext logContext = getLogContext();
+            final LogType logType = logContext.getLogEntry().logType;
+            final String cacheName = logContext.getCache().getName();
+            final String cacheUrl = logContext.getCache().getUrl();
+            final String prefix;
+            switch (logType) {
+                case FOUND_IT:
+                    prefix = "I found " + cacheName + " (" + cacheUrl + "):\n\n";
path: main/src/main/java/cgeo/geocaching/log/LogCacheActivity.java
user: login: SammysHP
body: Strings should be translatable.
created_at: 2025-05-26T18:48:09Z
author_association: MEMBER
diff_hunk: @@ -255,6 +259,28 @@ public boolean onOptionsItemSelected(final MenuItem item) {
         return true;
     }
 
+    @Override
+    protected void onActivityResult(final int requestCode, final int resultCode, @Nullable final Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+
+        if (requestCode == REQUEST_CODE_LOG && resultCode == Activity.RESULT_OK && data != null) {
path: main/src/main/java/cgeo/geocaching/CompassActivity.java
user: login: kennygchen
body: Thanks! I’ve moved the shared code to `ShareUtils` and pushed the changes.
created_at: 2025-05-27T00:07:38Z
author_association: CONTRIBUTOR

PR comments:
user: login: bekuno
created_at: 2025-05-26T08:25:04Z
body: ok to test
author_association: MEMBER
user: login: cgeo-ci-bot
created_at: 2025-05-26T08:25:09Z
body: Can one of the core team members give me the the permission to test this?
author_association: COLLABORATOR
user: login: github-actions[bot]
created_at: 2025-05-26T18:16:09Z
body: <h3>Job Summary for Gradle</h3>
<a href="https://github.com/cgeo/cgeo/actions/runs/15249213337" target="_blank">
<h5>Unit tests :: <em>integration-tests</em></h5>
</a>



<table>
    <tr>
        <th>Gradle Root Project</th>
        <th>Requested Tasks</th>
        <th>Gradle Version</th>
        <th>Build Outcome</th>
        <th>Build&nbsp;Scan®</th>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>testDebug</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:x:</td>
        <td><a href="https://gradle.com/s/fyuv2ymkju2dq" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>packageBasicDebug</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:white_check_mark:</td>
        <td><a href="https://gradle.com/s/b7oh2opfczr6s" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>packageBasicDebugAndroidTest</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:white_check_mark:</td>
        <td><a href="https://gradle.com/s/dr3gxlyhz7vrw" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
</table>
    
author_association: NONE
user: login: github-actions[bot]
created_at: 2025-05-26T18:26:12Z
body: <h3>Job Summary for Gradle</h3>
<a href="https://github.com/cgeo/cgeo/actions/runs/15249213337" target="_blank">
<h5>Unit tests :: <em>integration-tests</em></h5>
</a>



<table>
    <tr>
        <th>Gradle Root Project</th>
        <th>Requested Tasks</th>
        <th>Gradle Version</th>
        <th>Build Outcome</th>
        <th>Build&nbsp;Scan®</th>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>testDebug</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:x:</td>
        <td><a href="https://gradle.com/s/ionbpwenaodvg" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>packageBasicDebug</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:white_check_mark:</td>
        <td><a href="https://gradle.com/s/nhh5rwiyc54qu" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>packageBasicDebugAndroidTest</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:white_check_mark:</td>
        <td><a href="https://gradle.com/s/5amf3dw3cf636" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
</table>
    
author_association: NONE
user: login: github-actions[bot]
created_at: 2025-05-26T18:49:53Z
body: <h3>Job Summary for Gradle</h3>
<a href="https://github.com/cgeo/cgeo/actions/runs/15249213337" target="_blank">
<h5>Unit tests :: <em>integration-tests</em></h5>
</a>



<table>
    <tr>
        <th>Gradle Root Project</th>
        <th>Requested Tasks</th>
        <th>Gradle Version</th>
        <th>Build Outcome</th>
        <th>Build&nbsp;Scan®</th>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>testDebug</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:x:</td>
        <td><a href="https://gradle.com/s/uep6h74ee3adi" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>packageBasicDebug</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:white_check_mark:</td>
        <td><a href="https://gradle.com/s/aahm2csnp4fpu" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>packageBasicDebugAndroidTest</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:white_check_mark:</td>
        <td><a href="https://gradle.com/s/g7mxjkdq3d66a" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
</table>
    
author_association: NONE
user: login: github-actions[bot]
created_at: 2025-05-26T19:53:10Z
body: <h3>Job Summary for Gradle</h3>
<a href="https://github.com/cgeo/cgeo/actions/runs/15249213337" target="_blank">
<h5>Unit tests :: <em>integration-tests</em></h5>
</a>



<table>
    <tr>
        <th>Gradle Root Project</th>
        <th>Requested Tasks</th>
        <th>Gradle Version</th>
        <th>Build Outcome</th>
        <th>Build&nbsp;Scan®</th>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>testDebug</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:x:</td>
        <td><a href="https://gradle.com/s/3q2trd4uqueje" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>packageBasicDebug</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:white_check_mark:</td>
        <td><a href="https://gradle.com/s/xlxstdl25x4ew" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>packageBasicDebugAndroidTest</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:white_check_mark:</td>
        <td><a href="https://gradle.com/s/k2oxcxptmt5js" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
</table>
    
author_association: NONE
user: login: github-actions[bot]
created_at: 2025-05-27T00:15:38Z
body: <h3>Job Summary for Gradle</h3>
<a href="https://github.com/cgeo/cgeo/actions/runs/15263752401" target="_blank">
<h5>Unit tests :: <em>integration-tests</em></h5>
</a>



<table>
    <tr>
        <th>Gradle Root Project</th>
        <th>Requested Tasks</th>
        <th>Gradle Version</th>
        <th>Build Outcome</th>
        <th>Build&nbsp;Scan®</th>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>testDebug</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:x:</td>
        <td><a href="https://gradle.com/s/tem5aei5u46mo" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>packageBasicDebug</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:white_check_mark:</td>
        <td><a href="https://gradle.com/s/6o7om7wxhfct4" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>packageBasicDebugAndroidTest</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:white_check_mark:</td>
        <td><a href="https://gradle.com/s/j3dxgums3xn7g" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
</table>
    
author_association: NONE
user: login: github-actions[bot]
created_at: 2025-05-27T00:29:53Z
body: <h3>Job Summary for Gradle</h3>
<a href="https://github.com/cgeo/cgeo/actions/runs/15263911861" target="_blank">
<h5>Unit tests :: <em>integration-tests</em></h5>
</a>



<table>
    <tr>
        <th>Gradle Root Project</th>
        <th>Requested Tasks</th>
        <th>Gradle Version</th>
        <th>Build Outcome</th>
        <th>Build&nbsp;Scan®</th>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>testDebug</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:x:</td>
        <td><a href="https://gradle.com/s/ysy4rjuq2rkwo" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>packageBasicDebug</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:white_check_mark:</td>
        <td><a href="https://gradle.com/s/t427lx7nhgrhu" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>packageBasicDebugAndroidTest</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:white_check_mark:</td>
        <td><a href="https://gradle.com/s/x7ezdo24jei24" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
</table>
    
author_association: NONE
user: login: kennygchen
created_at: 2025-05-27T00:40:22Z
body: Rebased and squashed the commits into one. Sorry for the extra CI runs during the force pushes.
It should be all set now.
author_association: CONTRIBUTOR
user: login: github-actions[bot]
created_at: 2025-05-27T00:46:29Z
body: <h3>Job Summary for Gradle</h3>
<a href="https://github.com/cgeo/cgeo/actions/runs/15264096182" target="_blank">
<h5>Unit tests :: <em>integration-tests</em></h5>
</a>



<table>
    <tr>
        <th>Gradle Root Project</th>
        <th>Requested Tasks</th>
        <th>Gradle Version</th>
        <th>Build Outcome</th>
        <th>Build&nbsp;Scan®</th>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>testDebug</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:x:</td>
        <td><a href="https://gradle.com/s/yywerdmw7kgws" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>packageBasicDebug</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:white_check_mark:</td>
        <td><a href="https://gradle.com/s/7m3xb2e3uldjy" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>packageBasicDebugAndroidTest</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:white_check_mark:</td>
        <td><a href="https://gradle.com/s/ow4n7rslx56xa" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
</table>
    
author_association: NONE
user: login: github-actions[bot]
created_at: 2025-05-27T00:55:17Z
body: <h3>Job Summary for Gradle</h3>
<a href="https://github.com/cgeo/cgeo/actions/runs/15264096182" target="_blank">
<h5>Unit tests :: <em>integration-tests</em></h5>
</a>



<table>
    <tr>
        <th>Gradle Root Project</th>
        <th>Requested Tasks</th>
        <th>Gradle Version</th>
        <th>Build Outcome</th>
        <th>Build&nbsp;Scan®</th>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>testDebug</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:x:</td>
        <td><a href="https://gradle.com/s/e3scx7slucnmm" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>packageBasicDebug</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:white_check_mark:</td>
        <td><a href="https://gradle.com/s/t5e47dgu3ktzu" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>packageBasicDebugAndroidTest</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:white_check_mark:</td>
        <td><a href="https://gradle.com/s/o2gy7nkc7mfga" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
</table>
    
author_association: NONE
user: login: github-actions[bot]
created_at: 2025-05-27T01:03:44Z
body: <h3>Job Summary for Gradle</h3>
<a href="https://github.com/cgeo/cgeo/actions/runs/15264096182" target="_blank">
<h5>Unit tests :: <em>integration-tests</em></h5>
</a>



<table>
    <tr>
        <th>Gradle Root Project</th>
        <th>Requested Tasks</th>
        <th>Gradle Version</th>
        <th>Build Outcome</th>
        <th>Build&nbsp;Scan®</th>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>testDebug</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:x:</td>
        <td><a href="https://gradle.com/s/fspercfe2sbxs" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>packageBasicDebug</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:white_check_mark:</td>
        <td><a href="https://gradle.com/s/4hc77fstx4ung" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>packageBasicDebugAndroidTest</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:white_check_mark:</td>
        <td><a href="https://gradle.com/s/xeeijvubuyxuy" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
</table>
    
author_association: NONE
user: login: github-actions[bot]
created_at: 2025-05-27T01:20:58Z
body: <h3>Job Summary for Gradle</h3>
<a href="https://github.com/cgeo/cgeo/actions/runs/15264096182" target="_blank">
<h5>Unit tests :: <em>integration-tests</em></h5>
</a>



<table>
    <tr>
        <th>Gradle Root Project</th>
        <th>Requested Tasks</th>
        <th>Gradle Version</th>
        <th>Build Outcome</th>
        <th>Build&nbsp;Scan®</th>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>testDebug</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:x:</td>
        <td><a href="https://gradle.com/s/346odf5fga6ue" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>packageBasicDebug</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:white_check_mark:</td>
        <td><a href="https://gradle.com/s/uyeoqqp5ugnpo" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>packageBasicDebugAndroidTest</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:white_check_mark:</td>
        <td><a href="https://gradle.com/s/fmgxcafepy7bg" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
</table>
    
author_association: NONE
user: login: github-actions[bot]
created_at: 2025-05-27T01:30:28Z
body: <h3>Job Summary for Gradle</h3>
<a href="https://github.com/cgeo/cgeo/actions/runs/15264096182" target="_blank">
<h5>Unit tests :: <em>integration-tests</em></h5>
</a>



<table>
    <tr>
        <th>Gradle Root Project</th>
        <th>Requested Tasks</th>
        <th>Gradle Version</th>
        <th>Build Outcome</th>
        <th>Build&nbsp;Scan®</th>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>testDebug</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:x:</td>
        <td><a href="https://gradle.com/s/sla2fvhnrgyvc" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>packageBasicDebug</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:white_check_mark:</td>
        <td><a href="https://gradle.com/s/llbqpp3oso73s" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>packageBasicDebugAndroidTest</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:white_check_mark:</td>
        <td><a href="https://gradle.com/s/qecfssi7y3iai" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
</table>
    
author_association: NONE
user: login: github-actions[bot]
created_at: 2025-05-27T01:47:41Z
body: <h3>Job Summary for Gradle</h3>
<a href="https://github.com/cgeo/cgeo/actions/runs/15264096182" target="_blank">
<h5>Unit tests :: <em>integration-tests</em></h5>
</a>



<table>
    <tr>
        <th>Gradle Root Project</th>
        <th>Requested Tasks</th>
        <th>Gradle Version</th>
        <th>Build Outcome</th>
        <th>Build&nbsp;Scan®</th>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>testDebug</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:x:</td>
        <td><a href="https://gradle.com/s/lvhxok7gp6wvi" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>packageBasicDebug</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:white_check_mark:</td>
        <td><a href="https://gradle.com/s/hiryr4y7luoy2" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
    <tr>
        <td>cgeo</td>
        <td>packageBasicDebugAndroidTest</td>
        <td align='center'>8.11.1</td>
        <td align='center'>:white_check_mark:</td>
        <td><a href="https://gradle.com/s/j7vxmqi3z7gcm" rel="nofollow" target="_blank"><img src="https://img.shields.io/badge/Build%20Scan%C2%AE-06A0CE?logo=Gradle" alt="Build Scan published" /></a></td>
    </tr>
</table>
    
author_association: NONE
user: login: moving-bits
created_at: 2025-05-28T20:39:55Z
body: Thanks for your contribution, @kennygchen!
author_association: MEMBER
user: login: kennygchen
created_at: 2025-05-28T20:50:59Z
body: You're welcome, happy to contribute 😁
author_association: CONTRIBUTOR