From c2ac1817c3dacb39c7c8b4ad5466182c8602f5b6 Mon Sep 17 00:00:00 2001 From: Michael Gangolf Date: Wed, 2 Oct 2024 10:14:45 +0200 Subject: [PATCH 1/9] picker test --- android/app/build.gradle | 1 + .../modules/titanium/media/MediaModule.java | 57 ++++++++++++++++++- android/templates/build/app.build.gradle | 1 + android/titanium/build.gradle | 1 + 4 files changed, 58 insertions(+), 2 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 2577c868951..ce02f53a58c 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -86,6 +86,7 @@ dependencies { // exclude group: 'com.google.android.gms' } + implementation "androidx.activity:activity:1.6.0" implementation "androidx.appcompat:appcompat:${project.ext.tiAndroidXAppCompatLibVersion}" implementation "com.google.android.material:material:${project.ext.tiMaterialLibVersion}" } diff --git a/android/modules/media/src/java/ti/modules/titanium/media/MediaModule.java b/android/modules/media/src/java/ti/modules/titanium/media/MediaModule.java index 87ec0194fcf..f3381ffa7cc 100644 --- a/android/modules/media/src/java/ti/modules/titanium/media/MediaModule.java +++ b/android/modules/media/src/java/ti/modules/titanium/media/MediaModule.java @@ -21,6 +21,7 @@ import org.appcelerator.kroll.KrollModule; import org.appcelerator.kroll.KrollObject; import org.appcelerator.kroll.KrollPromise; +import org.appcelerator.kroll.KrollProxy; import org.appcelerator.kroll.annotations.Kroll; import org.appcelerator.kroll.common.Log; import org.appcelerator.titanium.ContextSpecific; @@ -39,6 +40,8 @@ import org.appcelerator.titanium.util.TiFileHelper; import org.appcelerator.titanium.util.TiIntentWrapper; import org.appcelerator.titanium.util.TiUIHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import android.Manifest; import android.annotation.SuppressLint; @@ -67,11 +70,15 @@ import android.util.Size; import android.view.Window; +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.PickVisualMediaRequest; +import androidx.activity.result.contract.ActivityResultContracts; +import androidx.appcompat.app.AppCompatActivity; import androidx.camera.core.AspectRatio; @Kroll.module @ContextSpecific -public class MediaModule extends KrollModule implements Handler.Callback +public class MediaModule extends KrollModule implements Handler.Callback, TiActivityResultHandler { private static final String TAG = "TiMedia"; @@ -237,6 +244,7 @@ public class MediaModule extends KrollModule implements Handler.Callback public static final int VERTICAL_ALIGN_TOP = 1; @Kroll.constant public static final int VERTICAL_ALIGN_BOTTOM = 2; + private static final Logger log = LoggerFactory.getLogger(MediaModule.class); private static String mediaType = MEDIA_TYPE_PHOTO; private static ContentResolver contentResolver; @@ -965,7 +973,7 @@ public void hideCamera() } /** - * @see org.appcelerator.kroll.KrollProxy#handleMessage(android.os.Message) + * @see KrollProxy#handleMessage(Message) */ @Override public boolean handleMessage(Message message) @@ -1180,6 +1188,38 @@ public void openPhotoGallery(KrollDict options) final int code = allowMultiple ? PICK_IMAGE_MULTIPLE : PICK_IMAGE_SINGLE; + ActivityResultLauncher pickMedia; + AppCompatActivity appCompatActivity = (AppCompatActivity) TiApplication.getAppRootOrCurrentActivity(); + if (allowMultiple) { + pickMedia = appCompatActivity + .registerForActivityResult(new ActivityResultContracts.PickMultipleVisualMedia(), uri -> { + Log.i("---", "Res"); + if (uri != null) { + // done + } else { + // error + } + }); + } else { + pickMedia = appCompatActivity + .registerForActivityResult(new ActivityResultContracts.PickVisualMedia(), uri -> { + Log.i("---", "Res"); + if (uri != null) { + // done + String path = uri.toString(); + Log.i("---", "URI: " + path); + if (fSuccessCallback != null) { + fSuccessCallback.callAsync(getKrollObject(), createDictForImage(path)); + } + } else { + // error + } + }); + } + pickMedia.launch(new PickVisualMediaRequest.Builder() + .setMediaType(ActivityResultContracts.PickVisualMedia.ImageOnly.INSTANCE) + .build()); + /* activitySupport.launchActivityForResult(galleryIntent.getIntent(), code, new TiActivityResultHandler() { @Override public void onResult(Activity activity, int requestCode, int resultCode, Intent data) @@ -1311,6 +1351,7 @@ public void onError(Activity activity, int requestCode, Exception e) } } }); + */ } protected static KrollDict createDictForImage(String path) @@ -1768,4 +1809,16 @@ public String getApiName() { return "Ti.Media"; } + + @Override + public void onResult(Activity activity, int requestCode, int resultCode, Intent data) + { + Log.i("----", "TEST"); + } + + @Override + public void onError(Activity activity, int requestCode, Exception e) + { + + } } diff --git a/android/templates/build/app.build.gradle b/android/templates/build/app.build.gradle index dcb91f38827..1df2eb902aa 100644 --- a/android/templates/build/app.build.gradle +++ b/android/templates/build/app.build.gradle @@ -98,6 +98,7 @@ android { tasks.lint.enabled = false dependencies { + implementation "androidx.activity:activity:1.6.0" implementation "androidx.appcompat:appcompat:${project.ext.tiAndroidXAppCompatLibVersion}" implementation fileTree(dir: "${rootDir}/libs", include: ['*.aar', '*.jar']) implementation fileTree(dir: "${projectDir}/src/main", include: ['*.aar', '*.jar']) diff --git a/android/titanium/build.gradle b/android/titanium/build.gradle index c3078c48701..0a0794afbc8 100644 --- a/android/titanium/build.gradle +++ b/android/titanium/build.gradle @@ -278,6 +278,7 @@ dependencies { compileOnly project(':kroll-apt') // AndroidX Library dependencies. + implementation "androidx.activity:activity:1.6.0" implementation "androidx.appcompat:appcompat:${project.ext.tiAndroidXAppCompatLibVersion}" implementation 'androidx.cardview:cardview:1.0.0' implementation "androidx.core:core:${project.ext.tiAndroidXCoreLibVersion}" From 03a7a12ce601329f50dea3cc4b71a16865dcef5b Mon Sep 17 00:00:00 2001 From: Michael Gangolf Date: Thu, 3 Oct 2024 16:01:31 +0200 Subject: [PATCH 2/9] picker --- .../modules/titanium/media/MediaModule.java | 138 ++++++++++++------ .../appcelerator/titanium/TiBaseActivity.java | 21 +++ 2 files changed, 118 insertions(+), 41 deletions(-) diff --git a/android/modules/media/src/java/ti/modules/titanium/media/MediaModule.java b/android/modules/media/src/java/ti/modules/titanium/media/MediaModule.java index f3381ffa7cc..198098b1024 100644 --- a/android/modules/media/src/java/ti/modules/titanium/media/MediaModule.java +++ b/android/modules/media/src/java/ti/modules/titanium/media/MediaModule.java @@ -15,6 +15,7 @@ import java.util.Arrays; import java.util.Date; import java.util.HashMap; +import java.util.List; import org.appcelerator.kroll.KrollDict; import org.appcelerator.kroll.KrollFunction; @@ -46,11 +47,13 @@ import android.Manifest; import android.annotation.SuppressLint; import android.app.Activity; +import android.content.BroadcastReceiver; import android.content.ClipData; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.content.pm.PackageManager; import android.graphics.BitmapFactory; import android.graphics.ImageFormat; @@ -62,6 +65,7 @@ import android.media.MediaMetadataRetriever; import android.net.Uri; import android.os.Build; +import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Message; @@ -73,12 +77,12 @@ import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.PickVisualMediaRequest; import androidx.activity.result.contract.ActivityResultContracts; -import androidx.appcompat.app.AppCompatActivity; import androidx.camera.core.AspectRatio; +import androidx.localbroadcastmanager.content.LocalBroadcastManager; @Kroll.module @ContextSpecific -public class MediaModule extends KrollModule implements Handler.Callback, TiActivityResultHandler +public class MediaModule extends KrollModule implements Handler.Callback { private static final String TAG = "TiMedia"; @@ -250,11 +254,18 @@ public class MediaModule extends KrollModule implements Handler.Callback, TiActi private static ContentResolver contentResolver; private boolean useCameraX = false; private static boolean pathOnly = false; + ActivityResultLauncher pickMedia; + private final IntentFilter mIntentFilter; + + KrollFunction fSuccessCallback; + KrollFunction fCancelCallback; + KrollFunction fErrorCallback; public MediaModule() { super(); - + mIntentFilter = new IntentFilter(); + mIntentFilter.addAction("image"); if (contentResolver == null) { contentResolver = TiApplication.getInstance().getContentResolver(); } @@ -1113,9 +1124,9 @@ public void openPhotoGallery(KrollDict options) errorCallback = (KrollFunction) options.get(TiC.EVENT_ERROR); } - final KrollFunction fSuccessCallback = successCallback; - final KrollFunction fCancelCallback = cancelCallback; - final KrollFunction fErrorCallback = errorCallback; + fSuccessCallback = successCallback; + fCancelCallback = cancelCallback; + fErrorCallback = errorCallback; Log.d(TAG, "openPhotoGallery called", Log.DEBUG_MODE); @@ -1188,37 +1199,19 @@ public void openPhotoGallery(KrollDict options) final int code = allowMultiple ? PICK_IMAGE_MULTIPLE : PICK_IMAGE_SINGLE; - ActivityResultLauncher pickMedia; - AppCompatActivity appCompatActivity = (AppCompatActivity) TiApplication.getAppRootOrCurrentActivity(); + LocalBroadcastManager.getInstance(TiApplication.getAppRootOrCurrentActivity()) + .registerReceiver(new LocalBroadcastReceiver(), mIntentFilter); + if (allowMultiple) { - pickMedia = appCompatActivity - .registerForActivityResult(new ActivityResultContracts.PickMultipleVisualMedia(), uri -> { - Log.i("---", "Res"); - if (uri != null) { - // done - } else { - // error - } - }); + ((TiBaseActivity) activity).pickMultipleMediaResult.launch(new PickVisualMediaRequest.Builder() + .setMediaType(ActivityResultContracts.PickVisualMedia.ImageOnly.INSTANCE) + .build()); } else { - pickMedia = appCompatActivity - .registerForActivityResult(new ActivityResultContracts.PickVisualMedia(), uri -> { - Log.i("---", "Res"); - if (uri != null) { - // done - String path = uri.toString(); - Log.i("---", "URI: " + path); - if (fSuccessCallback != null) { - fSuccessCallback.callAsync(getKrollObject(), createDictForImage(path)); - } - } else { - // error - } - }); + ((TiBaseActivity) activity).pickMediaResult.launch(new PickVisualMediaRequest.Builder() + .setMediaType(ActivityResultContracts.PickVisualMedia.ImageOnly.INSTANCE) + .build()); } - pickMedia.launch(new PickVisualMediaRequest.Builder() - .setMediaType(ActivityResultContracts.PickVisualMedia.ImageOnly.INSTANCE) - .build()); + /* activitySupport.launchActivityForResult(galleryIntent.getIntent(), code, new TiActivityResultHandler() { @Override @@ -1810,15 +1803,78 @@ public String getApiName() return "Ti.Media"; } - @Override - public void onResult(Activity activity, int requestCode, int resultCode, Intent data) + public class LocalBroadcastReceiver extends BroadcastReceiver { - Log.i("----", "TEST"); - } + @Override + public void onReceive(Context context, Intent intent) + { + KrollDict kd = new KrollDict(); + String action = intent.getAction(); + if (action.equals("image")) { + Bundle extras = intent.getExtras(); + if (extras.get("uri") != null) { + // single image + Uri uri = (Uri) extras.get("uri"); + String path = (uri != null) ? uri.toString() : null; + + if (fSuccessCallback != null && path != null) { + fSuccessCallback.callAsync(getKrollObject(), createDictForImage(path)); + } + } else if (extras.get("uris") != null) { + // multiple images + List uri = (List) extras.get("uris"); - @Override - public void onError(Activity activity, int requestCode, Exception e) - { + ArrayList selectedFiles = new ArrayList<>(); + // Fetch file(s) from clip data. + int count = uri.size(); + for (int index = 0; index < count; index++) { + KrollDict dictionary = createDictForImage(uri.get(index).toString()); + if (dictionary == null) { + continue; + } + selectedFiles.add(dictionary); + } + + ArrayList selectedImages = new ArrayList<>(); + for (KrollDict dictionary : selectedFiles) { + String mediaType = dictionary.getString("mediaType"); + if (mediaType != null) { + if (mediaType.equals(MEDIA_TYPE_PHOTO)) { + selectedImages.add(dictionary); + } + } + } + + // Invoke a callback with the selection result. + if (selectedImages.isEmpty()) { + if (selectedFiles.isEmpty()) { + // Invoke the "cancel" callback if no files were selected. + if (fCancelCallback != null) { + KrollDict response = new KrollDict(); + response.putCodeAndMessage(NO_ERROR, null); + fCancelCallback.callAsync(getKrollObject(), response); + } + } else { + // Invoke the "error" callback if non-image/video files were selected. + String message = "Invalid file types were selected"; + Log.e(TAG, message); + if (fErrorCallback != null) { + fErrorCallback.callAsync(getKrollObject(), + createErrorResponse(UNKNOWN_ERROR, message)); + } + } + } else { + // Invoke the "success" callback with the selected file(s). + if (fSuccessCallback != null) { + KrollDict d = new KrollDict(); + d.putCodeAndMessage(NO_ERROR, null); + d.put("images", selectedImages.toArray(new KrollDict[0])); + fSuccessCallback.callAsync(getKrollObject(), d); + } + } + } + } + } } } diff --git a/android/titanium/src/java/org/appcelerator/titanium/TiBaseActivity.java b/android/titanium/src/java/org/appcelerator/titanium/TiBaseActivity.java index 8421b066570..42f4ebd93e9 100644 --- a/android/titanium/src/java/org/appcelerator/titanium/TiBaseActivity.java +++ b/android/titanium/src/java/org/appcelerator/titanium/TiBaseActivity.java @@ -6,6 +6,7 @@ */ package org.appcelerator.titanium; +import java.io.Serializable; import java.lang.ref.WeakReference; import java.util.HashMap; import java.util.Iterator; @@ -48,6 +49,9 @@ import android.app.Activity; +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.PickVisualMediaRequest; +import androidx.activity.result.contract.ActivityResultContracts; import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AppCompatActivity; import android.app.Dialog; @@ -69,6 +73,7 @@ import androidx.appcompat.app.AppCompatDelegate; import androidx.appcompat.widget.Toolbar; import androidx.core.app.ActivityCompat; +import androidx.localbroadcastmanager.content.LocalBroadcastManager; import android.text.Spannable; import android.text.SpannableStringBuilder; @@ -141,6 +146,22 @@ void onRequestPermissionsResult( private boolean overridenLayout; + public ActivityResultLauncher pickMediaResult + = registerForActivityResult(new ActivityResultContracts.PickVisualMedia(), uri -> { + Intent broadcastIntent = new Intent(); + broadcastIntent.setAction("image"); + broadcastIntent.putExtra("uri", uri); + LocalBroadcastManager.getInstance(TiApplication.getAppCurrentActivity()).sendBroadcast(broadcastIntent); + }); + + public ActivityResultLauncher pickMultipleMediaResult + = registerForActivityResult(new ActivityResultContracts.PickMultipleVisualMedia(), uris -> { + Intent broadcastIntent = new Intent(); + broadcastIntent.setAction("image"); + broadcastIntent.putExtra("uris", (Serializable) uris); + LocalBroadcastManager.getInstance(TiApplication.getAppCurrentActivity()).sendBroadcast(broadcastIntent); + }); + public static class DialogWrapper { boolean isPersistent; From 839138381a2c7137e66bbf9fe445fdd8bd9f3e42 Mon Sep 17 00:00:00 2001 From: Michael Gangolf Date: Thu, 3 Oct 2024 16:10:05 +0200 Subject: [PATCH 3/9] clean up --- .../modules/titanium/media/MediaModule.java | 137 ------------------ 1 file changed, 137 deletions(-) diff --git a/android/modules/media/src/java/ti/modules/titanium/media/MediaModule.java b/android/modules/media/src/java/ti/modules/titanium/media/MediaModule.java index 198098b1024..4203cd16bca 100644 --- a/android/modules/media/src/java/ti/modules/titanium/media/MediaModule.java +++ b/android/modules/media/src/java/ti/modules/titanium/media/MediaModule.java @@ -41,8 +41,6 @@ import org.appcelerator.titanium.util.TiFileHelper; import org.appcelerator.titanium.util.TiIntentWrapper; import org.appcelerator.titanium.util.TiUIHelper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import android.Manifest; import android.annotation.SuppressLint; @@ -248,7 +246,6 @@ public class MediaModule extends KrollModule implements Handler.Callback public static final int VERTICAL_ALIGN_TOP = 1; @Kroll.constant public static final int VERTICAL_ALIGN_BOTTOM = 2; - private static final Logger log = LoggerFactory.getLogger(MediaModule.class); private static String mediaType = MEDIA_TYPE_PHOTO; private static ContentResolver contentResolver; @@ -1211,140 +1208,6 @@ public void openPhotoGallery(KrollDict options) .setMediaType(ActivityResultContracts.PickVisualMedia.ImageOnly.INSTANCE) .build()); } - - /* - activitySupport.launchActivityForResult(galleryIntent.getIntent(), code, new TiActivityResultHandler() { - @Override - public void onResult(Activity activity, int requestCode, int resultCode, Intent data) - { - if (requestCode != code) { - return; - } - - // Do not continue if no selection was made. - Log.d(TAG, "OnResult called: " + resultCode, Log.DEBUG_MODE); - if ((resultCode == Activity.RESULT_CANCELED) || (data == null)) { - if (fCancelCallback != null) { - KrollDict response = new KrollDict(); - response.putCodeAndMessage(NO_ERROR, null); - fCancelCallback.callAsync(getKrollObject(), response); - } - return; - } - - // Fetch a URI to file selected. (Only applicable to single file selection.) - Uri uri = data.getData(); - String path = (uri != null) ? uri.toString() : null; - - // Handle multiple file selection, if enabled. - if (requestCode == PICK_IMAGE_MULTIPLE) { - // Wrap all selected file(s) in Titanium "CameraMediaItemType" dictionaries. - ArrayList selectedFiles = new ArrayList<>(); - ClipData clipData = data.getClipData(); - if (clipData != null) { - // Fetch file(s) from clip data. - int count = clipData.getItemCount(); - for (int index = 0; index < count; index++) { - ClipData.Item item = clipData.getItemAt(index); - if ((item == null) || (item.getUri() == null)) { - continue; - } - KrollDict dictionary = createDictForImage(item.getUri().toString()); - if (dictionary == null) { - continue; - } - selectedFiles.add(dictionary); - } - } else if (path != null) { - // Only a single file was found. - KrollDict dictionary = createDictForImage(path); - if (dictionary != null) { - selectedFiles.add(dictionary); - } - } - - // Copy each selected file to either an "images" or "videos" collection. - ArrayList selectedImages = new ArrayList<>(); - ArrayList selectedVideos = new ArrayList<>(); - for (KrollDict dictionary : selectedFiles) { - String mediaType = dictionary.getString("mediaType"); - if (mediaType != null) { - if (mediaType.equals(MEDIA_TYPE_PHOTO)) { - selectedImages.add(dictionary); - } else if (mediaType.equals(MEDIA_TYPE_VIDEO)) { - selectedVideos.add(dictionary); - } - } - } - - // Invoke a callback with the selection result. - if (selectedImages.isEmpty() && selectedVideos.isEmpty()) { - if (selectedFiles.isEmpty()) { - // Invoke the "cancel" callback if no files were selected. - if (fCancelCallback != null) { - KrollDict response = new KrollDict(); - response.putCodeAndMessage(NO_ERROR, null); - fCancelCallback.callAsync(getKrollObject(), response); - } - } else { - // Invoke the "error" callback if non-image/video files were selected. - String message = "Invalid file types were selected"; - Log.e(TAG, message); - if (fErrorCallback != null) { - fErrorCallback.callAsync(getKrollObject(), - createErrorResponse(UNKNOWN_ERROR, message)); - } - } - } else { - // Invoke the "success" callback with the selected file(s). - if (fSuccessCallback != null) { - KrollDict d = new KrollDict(); - d.putCodeAndMessage(NO_ERROR, null); - d.put("images", selectedImages.toArray(new KrollDict[0])); - d.put("videos", selectedVideos.toArray(new KrollDict[0])); - fSuccessCallback.callAsync(getKrollObject(), d); - } - } - return; - } - - // Handle single file selection. - try { - //Check for invalid path - if (path == null) { - String msg = "File path is invalid"; - Log.e(TAG, msg); - if (fErrorCallback != null) { - fErrorCallback.callAsync(getKrollObject(), createErrorResponse(UNKNOWN_ERROR, msg)); - } - return; - } - if (fSuccessCallback != null) { - fSuccessCallback.callAsync(getKrollObject(), createDictForImage(path)); - } - } catch (OutOfMemoryError e) { - String msg = "Not enough memory to get image: " + e.getMessage(); - Log.e(TAG, msg); - if (fErrorCallback != null) { - fErrorCallback.callAsync(getKrollObject(), createErrorResponse(UNKNOWN_ERROR, msg)); - } - } - } - - @Override - public void onError(Activity activity, int requestCode, Exception e) - { - if (requestCode != code) { - return; - } - String msg = "Gallery problem: " + e.getMessage(); - Log.e(TAG, msg, e); - if (fErrorCallback != null) { - fErrorCallback.callAsync(getKrollObject(), createErrorResponse(UNKNOWN_ERROR, msg)); - } - } - }); - */ } protected static KrollDict createDictForImage(String path) From f003341d7b5c9d50c97a2a47c5c54c04f36ff192 Mon Sep 17 00:00:00 2001 From: Michael Gangolf Date: Thu, 24 Oct 2024 19:33:21 +0200 Subject: [PATCH 4/9] video picker --- .../modules/titanium/media/MediaModule.java | 39 +++++++++++++++---- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/android/modules/media/src/java/ti/modules/titanium/media/MediaModule.java b/android/modules/media/src/java/ti/modules/titanium/media/MediaModule.java index 4203cd16bca..f63e13e7207 100644 --- a/android/modules/media/src/java/ti/modules/titanium/media/MediaModule.java +++ b/android/modules/media/src/java/ti/modules/titanium/media/MediaModule.java @@ -1199,14 +1199,39 @@ public void openPhotoGallery(KrollDict options) LocalBroadcastManager.getInstance(TiApplication.getAppRootOrCurrentActivity()) .registerReceiver(new LocalBroadcastReceiver(), mIntentFilter); - if (allowMultiple) { - ((TiBaseActivity) activity).pickMultipleMediaResult.launch(new PickVisualMediaRequest.Builder() - .setMediaType(ActivityResultContracts.PickVisualMedia.ImageOnly.INSTANCE) - .build()); + if (isSelectingPhoto && isSelectingVideo) { + // photo and video + if (allowMultiple) { + ((TiBaseActivity) activity).pickMultipleMediaResult.launch(new PickVisualMediaRequest.Builder() + .setMediaType(ActivityResultContracts.PickVisualMedia.ImageAndVideo.INSTANCE) + .build()); + } else { + ((TiBaseActivity) activity).pickMediaResult.launch(new PickVisualMediaRequest.Builder() + .setMediaType(ActivityResultContracts.PickVisualMedia.ImageAndVideo.INSTANCE) + .build()); + } + } else if (isSelectingPhoto) { + // photo + if (allowMultiple) { + ((TiBaseActivity) activity).pickMultipleMediaResult.launch(new PickVisualMediaRequest.Builder() + .setMediaType(ActivityResultContracts.PickVisualMedia.ImageOnly.INSTANCE) + .build()); + } else { + ((TiBaseActivity) activity).pickMediaResult.launch(new PickVisualMediaRequest.Builder() + .setMediaType(ActivityResultContracts.PickVisualMedia.ImageOnly.INSTANCE) + .build()); + } } else { - ((TiBaseActivity) activity).pickMediaResult.launch(new PickVisualMediaRequest.Builder() - .setMediaType(ActivityResultContracts.PickVisualMedia.ImageOnly.INSTANCE) - .build()); + // video + if (allowMultiple) { + ((TiBaseActivity) activity).pickMultipleMediaResult.launch(new PickVisualMediaRequest.Builder() + .setMediaType(ActivityResultContracts.PickVisualMedia.VideoOnly.INSTANCE) + .build()); + } else { + ((TiBaseActivity) activity).pickMediaResult.launch(new PickVisualMediaRequest.Builder() + .setMediaType(ActivityResultContracts.PickVisualMedia.VideoOnly.INSTANCE) + .build()); + } } } From a8e8db2c272e60cdb83cefd16a09d2e2124bb6a6 Mon Sep 17 00:00:00 2001 From: Michael Gangolf Date: Sat, 14 Dec 2024 16:56:30 +0100 Subject: [PATCH 5/9] fix import --- .../src/java/org/appcelerator/titanium/TiBaseActivity.java | 1 - 1 file changed, 1 deletion(-) diff --git a/android/titanium/src/java/org/appcelerator/titanium/TiBaseActivity.java b/android/titanium/src/java/org/appcelerator/titanium/TiBaseActivity.java index 11ff974d08e..8345c60d170 100644 --- a/android/titanium/src/java/org/appcelerator/titanium/TiBaseActivity.java +++ b/android/titanium/src/java/org/appcelerator/titanium/TiBaseActivity.java @@ -72,7 +72,6 @@ import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatDelegate; import androidx.appcompat.widget.Toolbar; -import androidx.core.app.ActivityCompat; import androidx.localbroadcastmanager.content.LocalBroadcastManager; import android.text.Spannable; From ce75de7ac8c0737b798d2488a10c03164f6539b1 Mon Sep 17 00:00:00 2001 From: Michael Gangolf Date: Sat, 14 Dec 2024 17:35:56 +0100 Subject: [PATCH 6/9] unregister listener again --- .../ti/modules/titanium/media/MediaModule.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/android/modules/media/src/java/ti/modules/titanium/media/MediaModule.java b/android/modules/media/src/java/ti/modules/titanium/media/MediaModule.java index f63e13e7207..f4157d5dd62 100644 --- a/android/modules/media/src/java/ti/modules/titanium/media/MediaModule.java +++ b/android/modules/media/src/java/ti/modules/titanium/media/MediaModule.java @@ -253,6 +253,7 @@ public class MediaModule extends KrollModule implements Handler.Callback private static boolean pathOnly = false; ActivityResultLauncher pickMedia; private final IntentFilter mIntentFilter; + LocalBroadcastReceiver localReceiver; KrollFunction fSuccessCallback; KrollFunction fCancelCallback; @@ -1196,8 +1197,9 @@ public void openPhotoGallery(KrollDict options) final int code = allowMultiple ? PICK_IMAGE_MULTIPLE : PICK_IMAGE_SINGLE; + localReceiver = new LocalBroadcastReceiver(); LocalBroadcastManager.getInstance(TiApplication.getAppRootOrCurrentActivity()) - .registerReceiver(new LocalBroadcastReceiver(), mIntentFilter); + .registerReceiver(localReceiver, mIntentFilter); if (isSelectingPhoto && isSelectingVideo) { // photo and video @@ -1723,18 +1725,22 @@ public void onReceive(Context context, Intent intent) selectedFiles.add(dictionary); } + // Copy each selected file to either an "images" or "videos" collection. ArrayList selectedImages = new ArrayList<>(); + ArrayList selectedVideos = new ArrayList<>(); for (KrollDict dictionary : selectedFiles) { String mediaType = dictionary.getString("mediaType"); if (mediaType != null) { if (mediaType.equals(MEDIA_TYPE_PHOTO)) { selectedImages.add(dictionary); + } else if (mediaType.equals(MEDIA_TYPE_VIDEO)) { + selectedVideos.add(dictionary); } } } // Invoke a callback with the selection result. - if (selectedImages.isEmpty()) { + if (selectedImages.isEmpty() && selectedVideos.isEmpty()) { if (selectedFiles.isEmpty()) { // Invoke the "cancel" callback if no files were selected. if (fCancelCallback != null) { @@ -1757,10 +1763,14 @@ public void onReceive(Context context, Intent intent) KrollDict d = new KrollDict(); d.putCodeAndMessage(NO_ERROR, null); d.put("images", selectedImages.toArray(new KrollDict[0])); + d.put("videos", selectedVideos.toArray(new KrollDict[0])); fSuccessCallback.callAsync(getKrollObject(), d); } } } + + LocalBroadcastManager.getInstance(TiApplication.getAppRootOrCurrentActivity()) + .unregisterReceiver(localReceiver); } } From 6652558754fb797959d89bc24bcca7f3c4469053 Mon Sep 17 00:00:00 2001 From: Michael Gangolf Date: Sat, 14 Dec 2024 19:03:57 +0100 Subject: [PATCH 7/9] optimize code, remove old intent --- .../modules/titanium/media/MediaModule.java | 35 ++++----------- .../appcelerator/titanium/TiBaseActivity.java | 43 +++++++++++++------ 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/android/modules/media/src/java/ti/modules/titanium/media/MediaModule.java b/android/modules/media/src/java/ti/modules/titanium/media/MediaModule.java index f4157d5dd62..1904ad17bfa 100644 --- a/android/modules/media/src/java/ti/modules/titanium/media/MediaModule.java +++ b/android/modules/media/src/java/ti/modules/titanium/media/MediaModule.java @@ -1131,18 +1131,6 @@ public void openPhotoGallery(KrollDict options) Activity activity = TiApplication.getInstance().getCurrentActivity(); TiActivitySupport activitySupport = (TiActivitySupport) activity; - TiIntentWrapper galleryIntent = new TiIntentWrapper(new Intent()); - galleryIntent.getIntent().setAction(Intent.ACTION_GET_CONTENT); - - if (options.containsKeyAndNotNull(TiC.PROPERTY_MAX_IMAGES) - && options.containsKey(TiC.PROPERTY_ALLOW_MULTIPLE) - && Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - // set max image count - galleryIntent = new TiIntentWrapper(new Intent(MediaStore.ACTION_PICK_IMAGES)); - galleryIntent.getIntent() - .putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, options.getInt(TiC.PROPERTY_MAX_IMAGES)); - } - boolean isSelectingPhoto = false; boolean isSelectingVideo = false; if (options.containsKey(TiC.PROPERTY_MEDIA_TYPES)) { @@ -1167,27 +1155,19 @@ public void openPhotoGallery(KrollDict options) isSelectingPhoto = true; } if (isSelectingPhoto && isSelectingVideo) { - galleryIntent.getIntent().setType("*/*"); - galleryIntent.getIntent().putExtra(Intent.EXTRA_MIME_TYPES, new String[] { "image/*", "video/*" }); MediaModule.mediaType = MEDIA_TYPE_PHOTO; } else if (isSelectingVideo) { - galleryIntent.getIntent().setType("video/*"); MediaModule.mediaType = MEDIA_TYPE_VIDEO; } else { - galleryIntent.getIntent().setType("image/*"); MediaModule.mediaType = MEDIA_TYPE_PHOTO; } - galleryIntent.getIntent().addCategory(Intent.CATEGORY_DEFAULT); - galleryIntent.setWindowId(TiIntentWrapper.createActivityName("GALLERY")); - final int PICK_IMAGE_SINGLE = activitySupport.getUniqueResultCode(); final int PICK_IMAGE_MULTIPLE = activitySupport.getUniqueResultCode(); boolean allowMultiple = false; if (options.containsKey(TiC.PROPERTY_ALLOW_MULTIPLE)) { allowMultiple = TiConvert.toBoolean(options.get(TiC.PROPERTY_ALLOW_MULTIPLE)); - galleryIntent.getIntent().putExtra(Intent.EXTRA_ALLOW_MULTIPLE, allowMultiple); } pathOnly = false; @@ -1204,33 +1184,36 @@ public void openPhotoGallery(KrollDict options) if (isSelectingPhoto && isSelectingVideo) { // photo and video if (allowMultiple) { - ((TiBaseActivity) activity).pickMultipleMediaResult.launch(new PickVisualMediaRequest.Builder() + ((TiBaseActivity) activity).registerMultipleMediaPicker(options.getInt(TiC.PROPERTY_MAX_IMAGES)) + .launch(new PickVisualMediaRequest.Builder() .setMediaType(ActivityResultContracts.PickVisualMedia.ImageAndVideo.INSTANCE) .build()); } else { - ((TiBaseActivity) activity).pickMediaResult.launch(new PickVisualMediaRequest.Builder() + ((TiBaseActivity) activity).registerMediaPicker().launch(new PickVisualMediaRequest.Builder() .setMediaType(ActivityResultContracts.PickVisualMedia.ImageAndVideo.INSTANCE) .build()); } } else if (isSelectingPhoto) { // photo if (allowMultiple) { - ((TiBaseActivity) activity).pickMultipleMediaResult.launch(new PickVisualMediaRequest.Builder() + ((TiBaseActivity) activity).registerMultipleMediaPicker(options.getInt(TiC.PROPERTY_MAX_IMAGES)) + .launch(new PickVisualMediaRequest.Builder() .setMediaType(ActivityResultContracts.PickVisualMedia.ImageOnly.INSTANCE) .build()); } else { - ((TiBaseActivity) activity).pickMediaResult.launch(new PickVisualMediaRequest.Builder() + ((TiBaseActivity) activity).registerMediaPicker().launch(new PickVisualMediaRequest.Builder() .setMediaType(ActivityResultContracts.PickVisualMedia.ImageOnly.INSTANCE) .build()); } } else { // video if (allowMultiple) { - ((TiBaseActivity) activity).pickMultipleMediaResult.launch(new PickVisualMediaRequest.Builder() + ((TiBaseActivity) activity).registerMultipleMediaPicker(options.getInt(TiC.PROPERTY_MAX_IMAGES)) + .launch(new PickVisualMediaRequest.Builder() .setMediaType(ActivityResultContracts.PickVisualMedia.VideoOnly.INSTANCE) .build()); } else { - ((TiBaseActivity) activity).pickMediaResult.launch(new PickVisualMediaRequest.Builder() + ((TiBaseActivity) activity).registerMediaPicker().launch(new PickVisualMediaRequest.Builder() .setMediaType(ActivityResultContracts.PickVisualMedia.VideoOnly.INSTANCE) .build()); } diff --git a/android/titanium/src/java/org/appcelerator/titanium/TiBaseActivity.java b/android/titanium/src/java/org/appcelerator/titanium/TiBaseActivity.java index 8345c60d170..87f4c6b6775 100644 --- a/android/titanium/src/java/org/appcelerator/titanium/TiBaseActivity.java +++ b/android/titanium/src/java/org/appcelerator/titanium/TiBaseActivity.java @@ -144,21 +144,38 @@ void onRequestPermissionsResult( private boolean overridenLayout; - public ActivityResultLauncher pickMediaResult - = registerForActivityResult(new ActivityResultContracts.PickVisualMedia(), uri -> { - Intent broadcastIntent = new Intent(); - broadcastIntent.setAction("image"); - broadcastIntent.putExtra("uri", uri); - LocalBroadcastManager.getInstance(TiApplication.getAppCurrentActivity()).sendBroadcast(broadcastIntent); + public ActivityResultLauncher registerMediaPicker() + { + return registerForActivityResult(new ActivityResultContracts.PickVisualMedia(), uri -> { + Intent intent = new Intent(); + intent.setAction("image"); + intent.putExtra("uri", uri); + LocalBroadcastManager.getInstance(TiApplication.getAppCurrentActivity()).sendBroadcast(intent); }); + } - public ActivityResultLauncher pickMultipleMediaResult - = registerForActivityResult(new ActivityResultContracts.PickMultipleVisualMedia(), uris -> { - Intent broadcastIntent = new Intent(); - broadcastIntent.setAction("image"); - broadcastIntent.putExtra("uris", (Serializable) uris); - LocalBroadcastManager.getInstance(TiApplication.getAppCurrentActivity()).sendBroadcast(broadcastIntent); - }); + public ActivityResultLauncher registerMultipleMediaPicker(int count) + { + ActivityResultLauncher pickMultipleMediaResult; + if (count > 0) { + pickMultipleMediaResult + = registerForActivityResult(new ActivityResultContracts.PickMultipleVisualMedia(count), uris -> { + Intent intent = new Intent(); + intent.setAction("image"); + intent.putExtra("uris", (Serializable) uris); + LocalBroadcastManager.getInstance(TiApplication.getAppCurrentActivity()).sendBroadcast(intent); + }); + } else { + pickMultipleMediaResult + = registerForActivityResult(new ActivityResultContracts.PickMultipleVisualMedia(), uris -> { + Intent intent = new Intent(); + intent.setAction("image"); + intent.putExtra("uris", (Serializable) uris); + LocalBroadcastManager.getInstance(TiApplication.getAppCurrentActivity()).sendBroadcast(intent); + }); + } + return pickMultipleMediaResult; + } public static class DialogWrapper { From 9b06b80a186afc2c369835b8c98d1838b379f3d9 Mon Sep 17 00:00:00 2001 From: Michael Gangolf Date: Fri, 3 Jan 2025 14:44:36 +0100 Subject: [PATCH 8/9] refactor --- .../modules/titanium/media/MediaModule.java | 49 ++++++------- .../appcelerator/titanium/TiBaseActivity.java | 68 ++++++++++++------- .../util/TiPickMultipleVisualMedia.java | 45 ++++++++++++ 3 files changed, 107 insertions(+), 55 deletions(-) create mode 100644 android/titanium/src/java/org/appcelerator/titanium/util/TiPickMultipleVisualMedia.java diff --git a/android/modules/media/src/java/ti/modules/titanium/media/MediaModule.java b/android/modules/media/src/java/ti/modules/titanium/media/MediaModule.java index 1904ad17bfa..0a65dc0bb8d 100644 --- a/android/modules/media/src/java/ti/modules/titanium/media/MediaModule.java +++ b/android/modules/media/src/java/ti/modules/titanium/media/MediaModule.java @@ -1176,47 +1176,38 @@ public void openPhotoGallery(KrollDict options) } final int code = allowMultiple ? PICK_IMAGE_MULTIPLE : PICK_IMAGE_SINGLE; - + int maxCount = 0; + if (options.containsKeyAndNotNull(TiC.PROPERTY_MAX_IMAGES)) { + maxCount = options.getInt(TiC.PROPERTY_MAX_IMAGES); + } localReceiver = new LocalBroadcastReceiver(); LocalBroadcastManager.getInstance(TiApplication.getAppRootOrCurrentActivity()) .registerReceiver(localReceiver, mIntentFilter); + PickVisualMediaRequest.Builder pickerBuilder = new PickVisualMediaRequest.Builder(); if (isSelectingPhoto && isSelectingVideo) { // photo and video - if (allowMultiple) { - ((TiBaseActivity) activity).registerMultipleMediaPicker(options.getInt(TiC.PROPERTY_MAX_IMAGES)) - .launch(new PickVisualMediaRequest.Builder() - .setMediaType(ActivityResultContracts.PickVisualMedia.ImageAndVideo.INSTANCE) - .build()); - } else { - ((TiBaseActivity) activity).registerMediaPicker().launch(new PickVisualMediaRequest.Builder() - .setMediaType(ActivityResultContracts.PickVisualMedia.ImageAndVideo.INSTANCE) - .build()); - } + pickerBuilder.setMediaType(ActivityResultContracts.PickVisualMedia.ImageAndVideo.INSTANCE); } else if (isSelectingPhoto) { // photo - if (allowMultiple) { - ((TiBaseActivity) activity).registerMultipleMediaPicker(options.getInt(TiC.PROPERTY_MAX_IMAGES)) - .launch(new PickVisualMediaRequest.Builder() - .setMediaType(ActivityResultContracts.PickVisualMedia.ImageOnly.INSTANCE) - .build()); - } else { - ((TiBaseActivity) activity).registerMediaPicker().launch(new PickVisualMediaRequest.Builder() - .setMediaType(ActivityResultContracts.PickVisualMedia.ImageOnly.INSTANCE) - .build()); - } + pickerBuilder.setMediaType(ActivityResultContracts.PickVisualMedia.ImageOnly.INSTANCE); } else { // video - if (allowMultiple) { - ((TiBaseActivity) activity).registerMultipleMediaPicker(options.getInt(TiC.PROPERTY_MAX_IMAGES)) - .launch(new PickVisualMediaRequest.Builder() - .setMediaType(ActivityResultContracts.PickVisualMedia.VideoOnly.INSTANCE) - .build()); + pickerBuilder.setMediaType(ActivityResultContracts.PickVisualMedia.VideoOnly.INSTANCE); + } + + TiBaseActivity baseActivity = ((TiBaseActivity) activity); + if (allowMultiple) { + if (maxCount > 1) { + // use max item count + baseActivity.customPicker.updateMaxItems(maxCount); + baseActivity.pickMultipleMediaResultMax.launch(pickerBuilder.build()); } else { - ((TiBaseActivity) activity).registerMediaPicker().launch(new PickVisualMediaRequest.Builder() - .setMediaType(ActivityResultContracts.PickVisualMedia.VideoOnly.INSTANCE) - .build()); + // single item picker + baseActivity.pickMultipleMediaResult.launch(pickerBuilder.build()); } + } else { + baseActivity.pickMediaResult.launch(pickerBuilder.build()); } } diff --git a/android/titanium/src/java/org/appcelerator/titanium/TiBaseActivity.java b/android/titanium/src/java/org/appcelerator/titanium/TiBaseActivity.java index 87f4c6b6775..d2be62d60a8 100644 --- a/android/titanium/src/java/org/appcelerator/titanium/TiBaseActivity.java +++ b/android/titanium/src/java/org/appcelerator/titanium/TiBaseActivity.java @@ -39,6 +39,7 @@ import org.appcelerator.titanium.util.TiConvert; import org.appcelerator.titanium.util.TiLocaleManager; import org.appcelerator.titanium.util.TiMenuSupport; +import org.appcelerator.titanium.util.TiPickMultipleVisualMedia; import org.appcelerator.titanium.util.TiUIHelper; import org.appcelerator.titanium.util.TiWeakList; import org.appcelerator.titanium.view.TiActionBarStyleHandler; @@ -143,39 +144,54 @@ void onRequestPermissionsResult( public static boolean canFinishRoot = true; private boolean overridenLayout; + public TiPickMultipleVisualMedia customPicker = new TiPickMultipleVisualMedia(10); - public ActivityResultLauncher registerMediaPicker() - { - return registerForActivityResult(new ActivityResultContracts.PickVisualMedia(), uri -> { + public ActivityResultLauncher pickMediaResult + = registerForActivityResult(new ActivityResultContracts.PickVisualMedia(), uri -> { Intent intent = new Intent(); intent.setAction("image"); intent.putExtra("uri", uri); LocalBroadcastManager.getInstance(TiApplication.getAppCurrentActivity()).sendBroadcast(intent); }); - } - public ActivityResultLauncher registerMultipleMediaPicker(int count) - { - ActivityResultLauncher pickMultipleMediaResult; - if (count > 0) { - pickMultipleMediaResult - = registerForActivityResult(new ActivityResultContracts.PickMultipleVisualMedia(count), uris -> { - Intent intent = new Intent(); - intent.setAction("image"); - intent.putExtra("uris", (Serializable) uris); - LocalBroadcastManager.getInstance(TiApplication.getAppCurrentActivity()).sendBroadcast(intent); - }); - } else { - pickMultipleMediaResult - = registerForActivityResult(new ActivityResultContracts.PickMultipleVisualMedia(), uris -> { - Intent intent = new Intent(); - intent.setAction("image"); - intent.putExtra("uris", (Serializable) uris); - LocalBroadcastManager.getInstance(TiApplication.getAppCurrentActivity()).sendBroadcast(intent); - }); - } - return pickMultipleMediaResult; - } + public ActivityResultLauncher pickMultipleMediaResultMax + = registerForActivityResult(customPicker, uris -> { + Intent intent = new Intent(); + intent.setAction("image"); + intent.putExtra("uris", (Serializable) uris); + LocalBroadcastManager.getInstance(TiApplication.getAppCurrentActivity()).sendBroadcast(intent); + }); + + public ActivityResultLauncher pickMultipleMediaResult + = registerForActivityResult(new ActivityResultContracts.PickMultipleVisualMedia(), uris -> { + Intent intent = new Intent(); + intent.setAction("image"); + intent.putExtra("uris", (Serializable) uris); + LocalBroadcastManager.getInstance(TiApplication.getAppCurrentActivity()).sendBroadcast(intent); + }); + +// public ActivityResultLauncher registerMultipleMediaPicker(int count) +// { +// ActivityResultLauncher pickMultipleMediaResult; +// if (count > 0) { +// pickMultipleMediaResult +// = registerForActivityResult(new ActivityResultContracts.PickMultipleVisualMedia(count), uris -> { +// Intent intent = new Intent(); +// intent.setAction("image"); +// intent.putExtra("uris", (Serializable) uris); +// LocalBroadcastManager.getInstance(TiApplication.getAppCurrentActivity()).sendBroadcast(intent); +// }); +// } else { +// pickMultipleMediaResult +// = registerForActivityResult(new ActivityResultContracts.PickMultipleVisualMedia(), uris -> { +// Intent intent = new Intent(); +// intent.setAction("image"); +// intent.putExtra("uris", (Serializable) uris); +// LocalBroadcastManager.getInstance(TiApplication.getAppCurrentActivity()).sendBroadcast(intent); +// }); +// } +// return pickMultipleMediaResult; +// } public static class DialogWrapper { diff --git a/android/titanium/src/java/org/appcelerator/titanium/util/TiPickMultipleVisualMedia.java b/android/titanium/src/java/org/appcelerator/titanium/util/TiPickMultipleVisualMedia.java new file mode 100644 index 00000000000..bb2efad3704 --- /dev/null +++ b/android/titanium/src/java/org/appcelerator/titanium/util/TiPickMultipleVisualMedia.java @@ -0,0 +1,45 @@ +/** + * Titanium SDK + * Copyright TiDev, Inc. 04/07/2022-Present + * Licensed under the terms of the Apache Public License + * Please see the LICENSE included with this distribution for details. + */ +package org.appcelerator.titanium.util; + +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import android.os.ext.SdkExtensions; +import android.provider.MediaStore; + +import androidx.activity.result.PickVisualMediaRequest; +import androidx.activity.result.contract.ActivityResultContracts; + +public class TiPickMultipleVisualMedia extends ActivityResultContracts.PickMultipleVisualMedia +{ + private int maxItems; + + public TiPickMultipleVisualMedia(int maxItems) + { + super(maxItems); + this.maxItems = maxItems; + } + + public void updateMaxItems(int newMaxItems) + { + if (maxItems > 1) { + this.maxItems = newMaxItems; + } + } + + @Override + public Intent createIntent(Context context, PickVisualMediaRequest input) + { + Intent intent = super.createIntent(context, input); + if (maxItems > 1 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R + && SdkExtensions.getExtensionVersion(Build.VERSION_CODES.R) >= 2) { + intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, maxItems); + } + return intent; + } +} From 1dd2adf5e47a5694439eb3a230cb0c30311cb0ff Mon Sep 17 00:00:00 2001 From: Michael Gangolf Date: Fri, 3 Jan 2025 14:46:32 +0100 Subject: [PATCH 9/9] remove comment --- .../appcelerator/titanium/TiBaseActivity.java | 23 ------------------- 1 file changed, 23 deletions(-) diff --git a/android/titanium/src/java/org/appcelerator/titanium/TiBaseActivity.java b/android/titanium/src/java/org/appcelerator/titanium/TiBaseActivity.java index d2be62d60a8..7f073040433 100644 --- a/android/titanium/src/java/org/appcelerator/titanium/TiBaseActivity.java +++ b/android/titanium/src/java/org/appcelerator/titanium/TiBaseActivity.java @@ -170,29 +170,6 @@ void onRequestPermissionsResult( LocalBroadcastManager.getInstance(TiApplication.getAppCurrentActivity()).sendBroadcast(intent); }); -// public ActivityResultLauncher registerMultipleMediaPicker(int count) -// { -// ActivityResultLauncher pickMultipleMediaResult; -// if (count > 0) { -// pickMultipleMediaResult -// = registerForActivityResult(new ActivityResultContracts.PickMultipleVisualMedia(count), uris -> { -// Intent intent = new Intent(); -// intent.setAction("image"); -// intent.putExtra("uris", (Serializable) uris); -// LocalBroadcastManager.getInstance(TiApplication.getAppCurrentActivity()).sendBroadcast(intent); -// }); -// } else { -// pickMultipleMediaResult -// = registerForActivityResult(new ActivityResultContracts.PickMultipleVisualMedia(), uris -> { -// Intent intent = new Intent(); -// intent.setAction("image"); -// intent.putExtra("uris", (Serializable) uris); -// LocalBroadcastManager.getInstance(TiApplication.getAppCurrentActivity()).sendBroadcast(intent); -// }); -// } -// return pickMultipleMediaResult; -// } - public static class DialogWrapper { boolean isPersistent;