1
1
package com .yasirkula .unity ;
2
2
3
- import android .annotation .TargetApi ;
4
3
import android .app .Activity ;
5
4
import android .app .Fragment ;
6
- import android .content .ContentResolver ;
5
+ import android .content .ActivityNotFoundException ;
7
6
import android .content .Intent ;
8
- import android .database .Cursor ;
9
- import android .net .Uri ;
7
+ import android .content .pm .PackageManager ;
10
8
import android .os .Build ;
11
9
import android .os .Bundle ;
12
- import android .os .Environment ;
13
10
import android .provider .MediaStore ;
14
- import android .provider .OpenableColumns ;
15
11
import android .util .Log ;
16
- import android .webkit .MimeTypeMap ;
17
-
18
- import java .io .File ;
19
- import java .io .FileInputStream ;
20
- import java .io .FileOutputStream ;
21
- import java .io .InputStream ;
22
- import java .io .OutputStream ;
23
- import java .util .ArrayList ;
12
+ import android .widget .Toast ;
24
13
25
14
/**
26
15
* Created by yasirkula on 23.02.2018.
@@ -38,13 +27,13 @@ public class NativeGalleryMediaPickerFragment extends Fragment
38
27
39
28
public static boolean preferGetContent = false ;
40
29
public static boolean tryPreserveFilenames = false ; // When enabled, app's cache will fill more quickly since most of the images will have a unique filename (less chance of overwriting old files)
30
+ public static boolean showProgressbar = true ; // When enabled, a progressbar will be displayed while selected file(s) are copied (if necessary) to the destination directory
31
+ public static boolean useDefaultGalleryApp = false ; // false: Intent.createChooser is used to pick the Gallery app
41
32
42
33
private final NativeGalleryMediaReceiver mediaReceiver ;
43
34
private boolean selectMultiple ;
44
35
private String savePathDirectory , savePathFilename ;
45
36
46
- private ArrayList <String > savedFiles ;
47
-
48
37
public NativeGalleryMediaPickerFragment ()
49
38
{
50
39
mediaReceiver = null ;
@@ -125,176 +114,20 @@ else if( mediaType == NativeGallery.MEDIA_TYPE_VIDEO )
125
114
if ( title != null && title .length () > 0 )
126
115
intent .putExtra ( Intent .EXTRA_TITLE , title );
127
116
128
- startActivityForResult ( Intent .createChooser ( intent , title ), MEDIA_REQUEST_CODE );
129
- }
130
- }
131
-
132
- // Credit: https://stackoverflow.com/a/47023265/2373034
133
- @ TargetApi ( Build .VERSION_CODES .JELLY_BEAN_MR2 )
134
- private void fetchPathsOfMultipleMedia ( ArrayList <String > result , Intent data )
135
- {
136
- if ( data .getClipData () != null )
137
- {
138
- int count = data .getClipData ().getItemCount ();
139
- for ( int i = 0 ; i < count ; i ++ )
140
- {
141
- result .add ( getPathFromURI ( data .getClipData ().getItemAt ( i ).getUri () ) );
142
- }
143
- }
144
- else if ( data .getData () != null )
145
- {
146
- result .add ( getPathFromURI ( data .getData () ) );
147
- }
148
- }
149
-
150
- private String getPathFromURI ( Uri uri )
151
- {
152
- if ( uri == null )
153
- return null ;
154
-
155
- Log .d ( "Unity" , "Selected media uri: " + uri .toString () );
156
-
157
- String path = NativeGalleryUtils .GetPathFromURI ( getActivity (), uri );
158
- if ( path != null && path .length () > 0 )
159
- {
160
- // Check if file is accessible
161
- FileInputStream inputStream = null ;
162
117
try
163
118
{
164
- inputStream = new FileInputStream ( new File ( path ) );
165
- inputStream .read ();
166
-
167
- return path ;
168
- }
169
- catch ( Exception e )
170
- {
171
- }
172
- finally
173
- {
174
- if ( inputStream != null )
175
- {
176
- try
177
- {
178
- inputStream .close ();
179
- }
180
- catch ( Exception e )
181
- {
182
- }
183
- }
184
- }
185
- }
186
-
187
- // File path couldn't be determined, copy the file to an accessible temporary location
188
- return copyToTempFile ( uri );
189
- }
190
-
191
- private String copyToTempFile ( Uri uri )
192
- {
193
- // Credit: https://developer.android.com/training/secure-file-sharing/retrieve-info.html#RetrieveFileInfo
194
- ContentResolver resolver = getActivity ().getContentResolver ();
195
- Cursor returnCursor = null ;
196
- String filename = null ;
197
-
198
- try
199
- {
200
- returnCursor = resolver .query ( uri , null , null , null , null );
201
- if ( returnCursor != null && returnCursor .moveToFirst () )
202
- filename = returnCursor .getString ( returnCursor .getColumnIndex ( OpenableColumns .DISPLAY_NAME ) );
203
- }
204
- catch ( Exception e )
205
- {
206
- Log .e ( "Unity" , "Exception:" , e );
207
- }
208
- finally
209
- {
210
- if ( returnCursor != null )
211
- returnCursor .close ();
212
- }
213
-
214
- if ( filename == null || filename .length () < 3 )
215
- filename = "temp" ;
216
-
217
- String extension = null ;
218
- String mime = resolver .getType ( uri );
219
- if ( mime != null )
220
- {
221
- String mimeExtension = MimeTypeMap .getSingleton ().getExtensionFromMimeType ( mime );
222
- if ( mimeExtension != null && mimeExtension .length () > 0 )
223
- extension = "." + mimeExtension ;
224
- }
225
-
226
- if ( extension == null )
227
- {
228
- int filenameExtensionIndex = filename .lastIndexOf ( '.' );
229
- if ( filenameExtensionIndex > 0 && filenameExtensionIndex < filename .length () - 1 )
230
- extension = filename .substring ( filenameExtensionIndex );
231
- else
232
- extension = ".tmp" ;
233
- }
234
-
235
- if ( !tryPreserveFilenames )
236
- filename = savePathFilename ;
237
- else if ( filename .endsWith ( extension ) )
238
- filename = filename .substring ( 0 , filename .length () - extension .length () );
239
-
240
- try
241
- {
242
- InputStream input = resolver .openInputStream ( uri );
243
- if ( input == null )
244
- return null ;
245
-
246
- String fullName = filename + extension ;
247
- if ( savedFiles != null )
248
- {
249
- int n = 1 ;
250
- for ( int i = 0 ; i < savedFiles .size (); i ++ )
251
- {
252
- if ( savedFiles .get ( i ).equals ( fullName ) )
253
- {
254
- n ++;
255
- fullName = filename + n + extension ;
256
- i = -1 ;
257
- }
258
- }
259
- }
260
-
261
- File tempFile = new File ( savePathDirectory , fullName );
262
- OutputStream output = null ;
263
- try
264
- {
265
- output = new FileOutputStream ( tempFile , false );
266
-
267
- byte [] buf = new byte [4096 ];
268
- int len ;
269
- while ( ( len = input .read ( buf ) ) > 0 )
270
- {
271
- output .write ( buf , 0 , len );
272
- }
273
-
274
- if ( selectMultiple )
275
- {
276
- if ( savedFiles == null )
277
- savedFiles = new ArrayList <String >();
278
-
279
- savedFiles .add ( fullName );
280
- }
281
-
282
- return tempFile .getAbsolutePath ();
119
+ // MIUI devices have issues with Intent.createChooser on at least Android 11 (https://stackoverflow.com/questions/67785661/taking-and-picking-photos-on-poco-x3-with-android-11-does-not-work)
120
+ if ( useDefaultGalleryApp || ( Build .VERSION .SDK_INT == 30 && NativeGalleryUtils .IsXiaomiOrMIUI () ) )
121
+ startActivityForResult ( intent , MEDIA_REQUEST_CODE );
122
+ else
123
+ startActivityForResult ( Intent .createChooser ( intent , title ), MEDIA_REQUEST_CODE );
283
124
}
284
- finally
125
+ catch ( ActivityNotFoundException e )
285
126
{
286
- if ( output != null )
287
- output .close ();
288
-
289
- input .close ();
127
+ Toast .makeText ( getActivity (), "No apps can perform this action." , Toast .LENGTH_LONG ).show ();
128
+ onActivityResult ( MEDIA_REQUEST_CODE , Activity .RESULT_CANCELED , null );
290
129
}
291
130
}
292
- catch ( Exception e )
293
- {
294
- Log .e ( "Unity" , "Exception:" , e );
295
- }
296
-
297
- return null ;
298
131
}
299
132
300
133
@ Override
@@ -303,49 +136,32 @@ public void onActivityResult( int requestCode, int resultCode, Intent data )
303
136
if ( requestCode != MEDIA_REQUEST_CODE )
304
137
return ;
305
138
306
- if ( !selectMultiple )
139
+ NativeGalleryMediaPickerResultFragment resultFragment = null ;
140
+
141
+ if ( mediaReceiver == null )
142
+ Log .d ( "Unity" , "NativeGalleryMediaPickerFragment.mediaReceiver became null!" );
143
+ else if ( resultCode != Activity .RESULT_OK || data == null )
307
144
{
308
- String result ;
309
- if ( resultCode != Activity .RESULT_OK || data == null )
310
- result = "" ;
145
+ if ( !selectMultiple )
146
+ mediaReceiver .OnMediaReceived ( "" );
311
147
else
312
- {
313
- result = getPathFromURI ( data .getData () );
314
- if ( result == null )
315
- result = "" ;
316
- }
317
-
318
- if ( result .length () > 0 && !( new File ( result ).exists () ) )
319
- result = "" ;
320
-
321
- if ( mediaReceiver != null )
322
- mediaReceiver .OnMediaReceived ( result );
148
+ mediaReceiver .OnMultipleMediaReceived ( "" );
323
149
}
324
150
else
325
151
{
326
- ArrayList <String > result = new ArrayList <String >();
327
- if ( resultCode == Activity .RESULT_OK && data != null )
328
- fetchPathsOfMultipleMedia ( result , data );
329
-
330
- for ( int i = result .size () - 1 ; i >= 0 ; i -- )
331
- {
332
- if ( result .get ( i ) == null || result .get ( i ).length () == 0 || !( new File ( result .get ( i ) ).exists () ) )
333
- result .remove ( i );
334
- }
335
-
336
- String resultCombined = "" ;
337
- for ( int i = 0 ; i < result .size (); i ++ )
152
+ NativeGalleryMediaPickerResultOperation resultOperation = new NativeGalleryMediaPickerResultOperation ( getActivity (), mediaReceiver , data , selectMultiple , savePathDirectory , savePathFilename );
153
+ if ( showProgressbar )
154
+ resultFragment = new NativeGalleryMediaPickerResultFragment ( resultOperation );
155
+ else
338
156
{
339
- if ( i == 0 )
340
- resultCombined += result .get ( i );
341
- else
342
- resultCombined += ">" + result .get ( i );
157
+ resultOperation .execute ();
158
+ resultOperation .sendResultToUnity ();
343
159
}
344
-
345
- if ( mediaReceiver != null )
346
- mediaReceiver .OnMultipleMediaReceived ( resultCombined );
347
160
}
348
161
349
- getFragmentManager ().beginTransaction ().remove ( this ).commit ();
162
+ if ( resultFragment == null )
163
+ getFragmentManager ().beginTransaction ().remove ( this ).commit ();
164
+ else
165
+ getFragmentManager ().beginTransaction ().remove ( this ).add ( 0 , resultFragment ).commit ();
350
166
}
351
167
}
0 commit comments