33import android .app .Activity ;
44import android .content .Intent ;
55import android .net .Uri ;
6- import android .os .AsyncTask ;
6+ import android .os .Handler ;
7+ import android .os .Looper ;
78import androidx .core .content .FileProvider ;
89import org .appcelerator .kroll .KrollDict ;
910import org .appcelerator .kroll .KrollFunction ;
2122import java .net .HttpURLConnection ;
2223import java .net .URL ;
2324import java .util .HashMap ;
25+ import java .util .concurrent .ExecutorService ;
26+ import java .util .concurrent .Executors ;
2427
2528public class ShareProxy implements TiActivityResultHandler {
2629
@@ -29,14 +32,16 @@ public class ShareProxy implements TiActivityResultHandler {
2932
3033 private KrollFunction callback ;
3134 private KrollModule module ;
35+ private static final ExecutorService executorService = Executors .newSingleThreadExecutor ();
36+ private static final Handler mainHandler = new Handler (Looper .getMainLooper ());
3237
33- public static void share (HashMap params , KrollModule module ) {
38+ public static void share (HashMap < String , Object > params , KrollModule module ) {
3439 ShareProxy proxy = new ShareProxy ();
3540 proxy .module = module ;
3641 proxy .executeShare (params );
3742 }
3843
39- private void executeShare (HashMap params ) {
44+ private void executeShare (HashMap < String , Object > params ) {
4045 try {
4146 String message = TiConvert .toString (params .get ("message" ), "" );
4247 String subject = TiConvert .toString (params .get ("subject" ), "Share" );
@@ -58,8 +63,8 @@ private void executeShare(HashMap params) {
5863 String imageUrl = (String ) imageObj ;
5964 Log .d (TAG , "Detected URL image: " + imageUrl );
6065
61- // Download image asynchronously
62- new ImageDownloadTask ( message , subject ). execute ( imageUrl );
66+ // Download image asynchronously using ExecutorService
67+ downloadImageAsync ( imageUrl , message , subject );
6368
6469 } else {
6570 // Process normally (local file or blob)
@@ -80,6 +85,95 @@ private boolean isUrl(String str) {
8085 return str != null && (str .startsWith ("http://" ) || str .startsWith ("https://" ));
8186 }
8287
88+ private void downloadImageAsync (final String imageUrl , final String message , final String subject ) {
89+ executorService .execute (new Runnable () {
90+ @ Override
91+ public void run () {
92+ final File imageFile = downloadImage (imageUrl );
93+
94+ // Return to main thread
95+ mainHandler .post (new Runnable () {
96+ @ Override
97+ public void run () {
98+ if (imageFile != null && imageFile .exists ()) {
99+ Log .d (TAG , "Download completed, proceeding with share" );
100+ processShare (message , subject , imageFile );
101+ } else {
102+ Log .e (TAG , "Download failed, sharing text only" );
103+
104+ // If callback exists, notify about download failure
105+ if (callback != null ) {
106+ fireCallback (false , "Failed to download image" );
107+ } else {
108+ // Share text only if no callback
109+ processShare (message , subject , null );
110+ }
111+ }
112+ }
113+ });
114+ }
115+ });
116+ }
117+
118+ private File downloadImage (String imageUrl ) {
119+ HttpURLConnection connection = null ;
120+
121+ try {
122+ Log .d (TAG , "Starting image download from: " + imageUrl );
123+
124+ URL url = new URL (imageUrl );
125+ connection = (HttpURLConnection ) url .openConnection ();
126+ connection .setConnectTimeout (15000 );
127+ connection .setReadTimeout (15000 );
128+ connection .setRequestMethod ("GET" );
129+ connection .setDoInput (true );
130+ connection .connect ();
131+
132+ int responseCode = connection .getResponseCode ();
133+ Log .d (TAG , "Response code: " + responseCode );
134+
135+ if (responseCode == HttpURLConnection .HTTP_OK ) {
136+ InputStream input = connection .getInputStream ();
137+
138+ // Create temporary file
139+ File cacheDir = TiApplication .getInstance ().getCacheDir ();
140+ File imageFile = new File (cacheDir , "share_url_" + System .currentTimeMillis () + ".jpg" );
141+
142+ FileOutputStream output = new FileOutputStream (imageFile );
143+
144+ byte [] buffer = new byte [4096 ];
145+ int bytesRead ;
146+ long totalBytes = 0 ;
147+
148+ while ((bytesRead = input .read (buffer )) != -1 ) {
149+ output .write (buffer , 0 , bytesRead );
150+ totalBytes += bytesRead ;
151+ }
152+
153+ output .close ();
154+ input .close ();
155+
156+ Log .d (TAG , "✓ Image downloaded successfully. Size: " + totalBytes + " bytes" );
157+ Log .d (TAG , "Saved to: " + imageFile .getAbsolutePath ());
158+
159+ return imageFile ;
160+
161+ } else {
162+ Log .e (TAG , "HTTP error code: " + responseCode );
163+ return null ;
164+ }
165+
166+ } catch (Exception e ) {
167+ Log .e (TAG , "Download failed: " + e .getMessage (), e );
168+ return null ;
169+
170+ } finally {
171+ if (connection != null ) {
172+ connection .disconnect ();
173+ }
174+ }
175+ }
176+
83177 private void processShare (String message , String subject , Object imageObj ) {
84178 try {
85179 Intent shareIntent = new Intent (Intent .ACTION_SEND );
@@ -319,100 +413,4 @@ else if (imageObj instanceof String) {
319413
320414 return null ;
321415 }
322-
323- /**
324- * AsyncTask to download image from URL in background
325- */
326- private class ImageDownloadTask extends AsyncTask <String , Void , File > {
327-
328- private String message ;
329- private String subject ;
330- private String errorMessage ;
331-
332- public ImageDownloadTask (String message , String subject ) {
333- this .message = message ;
334- this .subject = subject ;
335- }
336-
337- @ Override
338- protected File doInBackground (String ... urls ) {
339- String imageUrl = urls [0 ];
340- HttpURLConnection connection = null ;
341-
342- try {
343- Log .d (TAG , "Starting image download from: " + imageUrl );
344-
345- URL url = new URL (imageUrl );
346- connection = (HttpURLConnection ) url .openConnection ();
347- connection .setConnectTimeout (15000 );
348- connection .setReadTimeout (15000 );
349- connection .setRequestMethod ("GET" );
350- connection .setDoInput (true );
351- connection .connect ();
352-
353- int responseCode = connection .getResponseCode ();
354- Log .d (TAG , "Response code: " + responseCode );
355-
356- if (responseCode == HttpURLConnection .HTTP_OK ) {
357- InputStream input = connection .getInputStream ();
358-
359- // Create temporary file
360- File cacheDir = TiApplication .getInstance ().getCacheDir ();
361- File imageFile = new File (cacheDir , "share_url_" + System .currentTimeMillis () + ".jpg" );
362-
363- FileOutputStream output = new FileOutputStream (imageFile );
364-
365- byte [] buffer = new byte [4096 ];
366- int bytesRead ;
367- long totalBytes = 0 ;
368-
369- while ((bytesRead = input .read (buffer )) != -1 ) {
370- output .write (buffer , 0 , bytesRead );
371- totalBytes += bytesRead ;
372- }
373-
374- output .close ();
375- input .close ();
376-
377- Log .d (TAG , "✓ Image downloaded successfully. Size: " + totalBytes + " bytes" );
378- Log .d (TAG , "Saved to: " + imageFile .getAbsolutePath ());
379-
380- return imageFile ;
381-
382- } else {
383- errorMessage = "HTTP error code: " + responseCode ;
384- Log .e (TAG , errorMessage );
385- return null ;
386- }
387-
388- } catch (Exception e ) {
389- errorMessage = "Download failed: " + e .getMessage ();
390- Log .e (TAG , errorMessage , e );
391- return null ;
392-
393- } finally {
394- if (connection != null ) {
395- connection .disconnect ();
396- }
397- }
398- }
399-
400- @ Override
401- protected void onPostExecute (File imageFile ) {
402- if (imageFile != null && imageFile .exists ()) {
403- Log .d (TAG , "Download completed, proceeding with share" );
404- processShare (message , subject , imageFile );
405- } else {
406- Log .e (TAG , "Download failed, sharing text only" );
407-
408- // If callback exists, notify about download failure
409- if (callback != null ) {
410- fireCallback (false , errorMessage != null ? errorMessage : "Failed to download image" );
411- } else {
412- // Share text only if no callback
413- processShare (message , subject , null );
414- }
415- }
416- }
417- }
418416}
0 commit comments