From 63bc28d38d15df88923c245fe5717cc99e8e1be2 Mon Sep 17 00:00:00 2001 From: Mansi Singh Date: Tue, 25 Nov 2025 16:45:34 +0530 Subject: [PATCH 1/3] Add support to share URI of captured screenshot - Added support to share the URI of the captured screenshot when triggering shaky. --- .../android/shaky/CollectDataTask.java | 20 +++++++------------ .../com/linkedin/android/shaky/Shaky.java | 12 +++++++++++ .../com/linkedin/android/shaky/Utils.java | 11 ++++++++++ 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/shaky/src/main/java/com/linkedin/android/shaky/CollectDataTask.java b/shaky/src/main/java/com/linkedin/android/shaky/CollectDataTask.java index 00caa76..42edab9 100644 --- a/shaky/src/main/java/com/linkedin/android/shaky/CollectDataTask.java +++ b/shaky/src/main/java/com/linkedin/android/shaky/CollectDataTask.java @@ -50,7 +50,7 @@ class CollectDataTask extends AsyncTask { @Override protected Result doInBackground(Bitmap... params) { - String screenshotDirectoryRoot = getScreenshotDirectoryRoot(activity); + String screenshotDirectoryRoot = Utils.getScreenshotDirectoryRoot(activity); if (screenshotDirectoryRoot == null) { return null; } @@ -70,8 +70,7 @@ protected Result doInBackground(Bitmap... params) { Uri screenshotUri = null; Bitmap bitmap = params != null && params.length != 0 ? params[0] : null; if (bitmap != null) { - File screenshotFile = Utils.writeBitmapToDirectory(bitmap, screenshotDirectory); - screenshotUri = Uri.fromFile(screenshotFile); + screenshotUri = getScreenshotUri(bitmap, screenshotDirectory); } Result result = new Result(); @@ -80,6 +79,11 @@ protected Result doInBackground(Bitmap... params) { return result; } + public Uri getScreenshotUri(Bitmap bitmap, File screenshotDirectory) { + File screenshotFile = Utils.writeBitmapToDirectory(bitmap, screenshotDirectory); + return Uri.fromFile(screenshotFile); + } + @Override protected void onPostExecute(Result result) { super.onPostExecute(result); @@ -87,16 +91,6 @@ protected void onPostExecute(Result result) { callback.onDataReady(result); } - @Nullable - @WorkerThread - private static String getScreenshotDirectoryRoot(@NonNull Context context) { - File filesDir = context.getFilesDir(); - if (filesDir == null) { - return null; - } - return filesDir.getAbsolutePath() + SCREENSHOT_DIRECTORY; - } - interface Callback { void onDataReady(@Nullable Result result); } diff --git a/shaky/src/main/java/com/linkedin/android/shaky/Shaky.java b/shaky/src/main/java/com/linkedin/android/shaky/Shaky.java index 33db569..0109a55 100644 --- a/shaky/src/main/java/com/linkedin/android/shaky/Shaky.java +++ b/shaky/src/main/java/com/linkedin/android/shaky/Shaky.java @@ -41,6 +41,7 @@ import com.jraska.falcon.Falcon; import com.squareup.seismic.ShakeDetector; +import java.io.File; import java.util.ArrayList; import java.util.concurrent.TimeUnit; @@ -387,6 +388,17 @@ private Bitmap getScreenshotBitmap() { } } + @Nullable + public Uri getCapturedScreenshotUri() { + if (activity != null) { + String screenshotDirectoryRoot = Utils.getScreenshotDirectoryRoot(activity); + if (screenshotDirectoryRoot != null && collectDataTask != null) { + return collectDataTask.getScreenshotUri(getScreenshotBitmap(), new File(screenshotDirectoryRoot)); + } + } + return null; + } + private void dismissCollectFeedbackDialogIfNecessary() { if (collectDataTask != null || activity == null) { return; diff --git a/shaky/src/main/java/com/linkedin/android/shaky/Utils.java b/shaky/src/main/java/com/linkedin/android/shaky/Utils.java index 1cd371b..8f51af9 100644 --- a/shaky/src/main/java/com/linkedin/android/shaky/Utils.java +++ b/shaky/src/main/java/com/linkedin/android/shaky/Utils.java @@ -49,6 +49,8 @@ final class Utils { private static final String BITMAP_PREFIX = "bitmap"; private static final String FILE_PROVIDER_SUFFIX = ".fileprovider"; + private static final String SCREENSHOT_DIRECTORY = "/screenshots"; + // prevent instantiation private Utils() {} @@ -165,4 +167,13 @@ static LayoutInflater applyThemeToInflater(@NonNull LayoutInflater inflater, @St } return inflater; } + + @Nullable + static String getScreenshotDirectoryRoot(@NonNull Context context) { + File filesDir = context.getFilesDir(); + if (filesDir == null) { + return null; + } + return filesDir.getAbsolutePath() + SCREENSHOT_DIRECTORY; + } } From 2c2d5be50e0f95a3c6e77245b21326d2c0525f22 Mon Sep 17 00:00:00 2001 From: Mansi Singh Date: Thu, 27 Nov 2025 18:01:26 +0530 Subject: [PATCH 2/3] Made changes to share screenshot URI and collect data --- .../android/shaky/CollectDataTask.java | 20 ++++++++---- .../android/shaky/DataCollectionCallback.java | 16 ++++++++++ .../com/linkedin/android/shaky/Shaky.java | 32 ++++++++++++------- .../com/linkedin/android/shaky/Utils.java | 11 ------- 4 files changed, 49 insertions(+), 30 deletions(-) create mode 100644 shaky/src/main/java/com/linkedin/android/shaky/DataCollectionCallback.java diff --git a/shaky/src/main/java/com/linkedin/android/shaky/CollectDataTask.java b/shaky/src/main/java/com/linkedin/android/shaky/CollectDataTask.java index 42edab9..00caa76 100644 --- a/shaky/src/main/java/com/linkedin/android/shaky/CollectDataTask.java +++ b/shaky/src/main/java/com/linkedin/android/shaky/CollectDataTask.java @@ -50,7 +50,7 @@ class CollectDataTask extends AsyncTask { @Override protected Result doInBackground(Bitmap... params) { - String screenshotDirectoryRoot = Utils.getScreenshotDirectoryRoot(activity); + String screenshotDirectoryRoot = getScreenshotDirectoryRoot(activity); if (screenshotDirectoryRoot == null) { return null; } @@ -70,7 +70,8 @@ protected Result doInBackground(Bitmap... params) { Uri screenshotUri = null; Bitmap bitmap = params != null && params.length != 0 ? params[0] : null; if (bitmap != null) { - screenshotUri = getScreenshotUri(bitmap, screenshotDirectory); + File screenshotFile = Utils.writeBitmapToDirectory(bitmap, screenshotDirectory); + screenshotUri = Uri.fromFile(screenshotFile); } Result result = new Result(); @@ -79,11 +80,6 @@ protected Result doInBackground(Bitmap... params) { return result; } - public Uri getScreenshotUri(Bitmap bitmap, File screenshotDirectory) { - File screenshotFile = Utils.writeBitmapToDirectory(bitmap, screenshotDirectory); - return Uri.fromFile(screenshotFile); - } - @Override protected void onPostExecute(Result result) { super.onPostExecute(result); @@ -91,6 +87,16 @@ protected void onPostExecute(Result result) { callback.onDataReady(result); } + @Nullable + @WorkerThread + private static String getScreenshotDirectoryRoot(@NonNull Context context) { + File filesDir = context.getFilesDir(); + if (filesDir == null) { + return null; + } + return filesDir.getAbsolutePath() + SCREENSHOT_DIRECTORY; + } + interface Callback { void onDataReady(@Nullable Result result); } diff --git a/shaky/src/main/java/com/linkedin/android/shaky/DataCollectionCallback.java b/shaky/src/main/java/com/linkedin/android/shaky/DataCollectionCallback.java new file mode 100644 index 0000000..28b5cad --- /dev/null +++ b/shaky/src/main/java/com/linkedin/android/shaky/DataCollectionCallback.java @@ -0,0 +1,16 @@ +package com.linkedin.android.shaky; + + +import androidx.annotation.Nullable; + +/** + * Callback interface for screenshot capture and data collection. + */ +public interface DataCollectionCallback { + /** + * Called when screenshot capture and data collection is complete. + * + * @param result the collected data and screenshot URI, or null if some failure occurred + */ + void onDataCollected(@Nullable Result result); +} diff --git a/shaky/src/main/java/com/linkedin/android/shaky/Shaky.java b/shaky/src/main/java/com/linkedin/android/shaky/Shaky.java index 0109a55..99bd769 100644 --- a/shaky/src/main/java/com/linkedin/android/shaky/Shaky.java +++ b/shaky/src/main/java/com/linkedin/android/shaky/Shaky.java @@ -41,7 +41,6 @@ import com.jraska.falcon.Falcon; import com.squareup.seismic.ShakeDetector; -import java.io.File; import java.util.ArrayList; import java.util.concurrent.TimeUnit; @@ -169,6 +168,26 @@ public void startEditScreenshotFlow(@Nullable Uri screenshotUri) { } } + /** + * Capture a screenshot and collect data without starting the feedback flow UI. + * This is for consumers to use their own custom UI with the captured data. + * + * @param callback called when the screenshot and data collection is complete + */ + public void captureScreenshotAndCollectData(@NonNull final DataCollectionCallback callback) { + if (activity == null) { + callback.onDataCollected(null); + return; + } + + Bitmap screenshotBitmap = getScreenshotBitmap(); + collectDataTask = new CollectDataTask(activity, delegate, result -> { + collectDataTask = null; + callback.onDataCollected(result); + }); + collectDataTask.execute(screenshotBitmap); + } + public void setSensitivity(@ShakeDelegate.SensitivityLevel int sensitivityLevel) { delegate.setSensitivityLevel(sensitivityLevel); shakeDetector.setSensitivity(getDetectorSensitivityLevel()); @@ -388,17 +407,6 @@ private Bitmap getScreenshotBitmap() { } } - @Nullable - public Uri getCapturedScreenshotUri() { - if (activity != null) { - String screenshotDirectoryRoot = Utils.getScreenshotDirectoryRoot(activity); - if (screenshotDirectoryRoot != null && collectDataTask != null) { - return collectDataTask.getScreenshotUri(getScreenshotBitmap(), new File(screenshotDirectoryRoot)); - } - } - return null; - } - private void dismissCollectFeedbackDialogIfNecessary() { if (collectDataTask != null || activity == null) { return; diff --git a/shaky/src/main/java/com/linkedin/android/shaky/Utils.java b/shaky/src/main/java/com/linkedin/android/shaky/Utils.java index 8f51af9..1cd371b 100644 --- a/shaky/src/main/java/com/linkedin/android/shaky/Utils.java +++ b/shaky/src/main/java/com/linkedin/android/shaky/Utils.java @@ -49,8 +49,6 @@ final class Utils { private static final String BITMAP_PREFIX = "bitmap"; private static final String FILE_PROVIDER_SUFFIX = ".fileprovider"; - private static final String SCREENSHOT_DIRECTORY = "/screenshots"; - // prevent instantiation private Utils() {} @@ -167,13 +165,4 @@ static LayoutInflater applyThemeToInflater(@NonNull LayoutInflater inflater, @St } return inflater; } - - @Nullable - static String getScreenshotDirectoryRoot(@NonNull Context context) { - File filesDir = context.getFilesDir(); - if (filesDir == null) { - return null; - } - return filesDir.getAbsolutePath() + SCREENSHOT_DIRECTORY; - } } From d4f9a1dd6ee8ea950e6321aa742ccfb5998e7642 Mon Sep 17 00:00:00 2001 From: Mansi Singh Date: Thu, 27 Nov 2025 18:21:49 +0530 Subject: [PATCH 3/3] Added testing support for the new API in the demo app --- .../com/linkedin/android/shaky/app/ShakyDemo.java | 15 +++++++++++++++ .../src/main/res/layout/activity_demo.xml | 7 +++++++ shaky-sample/src/main/res/values/strings.xml | 1 + 3 files changed, 23 insertions(+) diff --git a/shaky-sample/src/main/java/com/linkedin/android/shaky/app/ShakyDemo.java b/shaky-sample/src/main/java/com/linkedin/android/shaky/app/ShakyDemo.java index 951cfd8..f7bba5b 100644 --- a/shaky-sample/src/main/java/com/linkedin/android/shaky/app/ShakyDemo.java +++ b/shaky-sample/src/main/java/com/linkedin/android/shaky/app/ShakyDemo.java @@ -13,6 +13,7 @@ import android.graphics.Color; import android.os.Bundle; +import android.util.Log; import android.view.View; import android.widget.CheckBox; import android.widget.Toast; @@ -29,6 +30,7 @@ public class ShakyDemo extends FragmentActivity { private static final int RGB_MAX = 256; + public static final String TAG = "ShakyDemo"; @Override protected void onCreate(Bundle savedInstanceState) { @@ -101,5 +103,18 @@ public void onClick(View v) { ((ShakyApplication) getApplication()).getShaky().startEditScreenshotFlow(null); } }); + + findViewById(R.id.demo_capture_screenshot_collect_data_button).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + ((ShakyApplication) getApplication()).getShaky().captureScreenshotAndCollectData(result -> { + Toast.makeText(v.getContext(), + "Data collection complete. Check logs for complete data.", + Toast.LENGTH_LONG).show(); + Log.d(TAG, "Screenshot URI: " + (result != null ? result.getScreenshotUri() : "null")); + Log.d(TAG, "Collected data: " + (result != null ? result.getData() : "null")); + }); + } + }); } } diff --git a/shaky-sample/src/main/res/layout/activity_demo.xml b/shaky-sample/src/main/res/layout/activity_demo.xml index 8553bb3..a667498 100644 --- a/shaky-sample/src/main/res/layout/activity_demo.xml +++ b/shaky-sample/src/main/res/layout/activity_demo.xml @@ -64,4 +64,11 @@ android:layout_height="wrap_content" android:text="@string/manual_edit_screenshot"/> +