8181import java .nio .charset .StandardCharsets ;
8282import java .text .SimpleDateFormat ;
8383import java .util .ArrayList ;
84- import java .util .Arrays ;
8584import java .util .Collection ;
8685import java .util .Date ;
8786import java .util .List ;
@@ -263,89 +262,94 @@ public boolean canOpenFile(OCFile file) {
263262 return !launchables .isEmpty ();
264263 }
265264
265+ private void openRichDocumentFileWithoutAvailableApps (@ NonNull OCFile file ) {
266+ Account account = fileActivity .getAccount ();
267+ OCCapability capability = fileActivity .getStorageManager ().getCapability (account .name );
268+ final var richDocumentMimeTypeList = capability .getRichDocumentsMimeTypeList ();
269+
270+ if (richDocumentMimeTypeList != null &&
271+ richDocumentMimeTypeList .contains (file .getMimeType ()) &&
272+ capability .getRichDocumentsDirectEditing ().isTrue ()) {
273+ openFileAsRichDocument (file , fileActivity );
274+ } else {
275+ DisplayUtils .showSnackMessage (fileActivity , R .string .file_list_no_app_for_file_type );
276+ }
277+ }
278+
266279 public void openFile (OCFile file ) {
267- if (file != null ) {
268- final Intent openFileWithIntent = createOpenFileIntent (file );
280+ if (file == null ) {
281+ Log_OC .e (TAG , "Trying to open a NULL OCFile" );
282+ return ;
283+ }
269284
270- List <ResolveInfo > launchables = fileActivity .getPackageManager ().
271- queryIntentActivities (openFileWithIntent , PackageManager .GET_RESOLVED_FILTER );
285+ final Intent openFileWithIntent = createOpenFileIntent (file );
272286
273- if ( launchables . isEmpty ()) {
274- Optional < User > optionalUser = fileActivity . getUser ( );
287+ List < ResolveInfo > availableApps = fileActivity . getPackageManager ().
288+ queryIntentActivities ( openFileWithIntent , PackageManager . GET_RESOLVED_FILTER );
275289
276- if (optionalUser .isPresent () && editorUtils .isEditorAvailable (optionalUser .get (), file .getMimeType ())) {
277- openFileWithTextEditor (file , fileActivity );
278- } else {
279- Account account = fileActivity .getAccount ();
280- OCCapability capability = fileActivity .getStorageManager ().getCapability (account .name );
281- if (capability .getRichDocumentsMimeTypeList ().contains (file .getMimeType ()) &&
282- capability .getRichDocumentsDirectEditing ().isTrue ()) {
283- openFileAsRichDocument (file , fileActivity );
284- return ;
285- } else {
286- DisplayUtils .showSnackMessage (fileActivity , R .string .file_list_no_app_for_file_type );
287- return ;
288- }
289- }
290+ if (availableApps .isEmpty ()) {
291+ Optional <User > optionalUser = fileActivity .getUser ();
292+
293+ if (optionalUser .isPresent () && editorUtils .isEditorAvailable (optionalUser .get (), file .getMimeType ())) {
294+ openFileWithTextEditor (file , fileActivity );
295+ return ;
290296 }
291297
292- fileActivity .showLoadingDialog (fileActivity .getResources ().getString (R .string .sync_in_progress ));
293- new Thread (new Runnable () {
294- @ Override
295- public void run () {
296- User user = currentAccount .getUser ();
297- FileDataStorageManager storageManager =
298- new FileDataStorageManager (user , fileActivity .getContentResolver ());
299- // a fresh object is needed; many things could have occurred to the file
300- // since it was registered to observe again, assuming that local files
301- // are linked to a remote file AT MOST, SOMETHING TO BE DONE;
302- SynchronizeFileOperation sfo = new SynchronizeFileOperation (file ,
303- null ,
304- user ,
305- true ,
306- fileActivity ,
307- storageManager ,
308- false );
309- RemoteOperationResult result = sfo .execute (fileActivity );
310- fileActivity .dismissLoadingDialog ();
311- if (result .getCode () == RemoteOperationResult .ResultCode .SYNC_CONFLICT ) {
312- // ISSUE 5: if the user is not running the app (this is a service!),
313- // this can be very intrusive; a notification should be preferred
314- Intent intent = ConflictsResolveActivity .createIntent (file ,
315- user ,
316- -1 ,
317- Intent .FLAG_ACTIVITY_NEW_TASK ,
318- fileActivity );
319- fileActivity .startActivity (intent );
320- } else {
321- if (!launchables .isEmpty ()) {
322- try {
323- if (!result .isSuccess ()) {
324- DisplayUtils .showSnackMessage (fileActivity , R .string .file_not_synced );
325- try {
326- Thread .sleep (3000 );
327- } catch (InterruptedException e ) {
328- Log_OC .e (TAG , "Failed to sleep" );
329- }
330- }
331-
332- openFileWithIntent .setFlags (openFileWithIntent .getFlags () |
333- Intent .FLAG_ACTIVITY_NEW_TASK );
334- fileActivity .startActivity (openFileWithIntent );
335- } catch (ActivityNotFoundException exception ) {
336- DisplayUtils .showSnackMessage (fileActivity , R .string .file_list_no_app_for_file_type );
337- }
338- } else {
339- DisplayUtils .showSnackMessage (fileActivity , R .string .file_list_no_app_for_file_type );
340- }
341- }
298+ openRichDocumentFileWithoutAvailableApps (file );
342299
300+ return ;
301+ }
302+
303+ fileActivity .showLoadingDialog (fileActivity .getResources ().getString (R .string .sync_in_progress ));
304+
305+ new Thread (() -> {
306+ User user = currentAccount .getUser ();
307+ final var storageManager = new FileDataStorageManager (user , fileActivity .getContentResolver ());
308+ // a fresh object is needed; many things could have occurred to the file
309+ // since it was registered to observe again, assuming that local files
310+ // are linked to a remote file AT MOST, SOMETHING TO BE DONE;
311+ final var sfo = new SynchronizeFileOperation (file ,null , user , true , fileActivity , storageManager , false );
312+ final var result = sfo .execute (fileActivity );
313+
314+ fileActivity .dismissLoadingDialog ();
315+ if (result .getCode () == RemoteOperationResult .ResultCode .SYNC_CONFLICT ) {
316+ // ISSUE 5: if the user is not running the app (this is a service!),
317+ // this can be very intrusive; a notification should be preferred
318+ Intent intent = ConflictsResolveActivity .createIntent (file ,
319+ user ,
320+ -1 ,
321+ Intent .FLAG_ACTIVITY_NEW_TASK ,
322+ fileActivity );
323+ fileActivity .startActivity (intent );
324+ return ;
325+ }
326+
327+ if (availableApps .isEmpty ()) {
328+ fileActivity .runOnUiThread (() -> DisplayUtils .showSnackMessage (fileActivity , R .string .file_list_no_app_for_file_type ));
329+
330+ return ;
331+ }
332+
333+ if (!result .isSuccess ()) {
334+ fileActivity .runOnUiThread (() -> DisplayUtils .showSnackMessage (fileActivity , R .string .file_not_synced ));
335+
336+ // Sleep to show snackbar message
337+ try {
338+ Thread .sleep (1000 );
339+ } catch (InterruptedException e ) {
340+ Log_OC .e (TAG , "Failed to sleep" );
343341 }
344- }). start ();
342+ }
345343
346- } else {
347- Log_OC .e (TAG , "Trying to open a NULL OCFile" );
348- }
344+ fileActivity .runOnUiThread (() -> {
345+ try {
346+ openFileWithIntent .setFlags (openFileWithIntent .getFlags () | Intent .FLAG_ACTIVITY_NEW_TASK );
347+ fileActivity .startActivity (openFileWithIntent );
348+ } catch (ActivityNotFoundException exception ) {
349+ DisplayUtils .showSnackMessage (fileActivity , R .string .file_list_no_app_for_file_type );
350+ }
351+ });
352+ }).start ();
349353 }
350354
351355 public void openFileAsRichDocument (OCFile file , Context context ) {
@@ -376,19 +380,16 @@ public void openRichWorkspaceWithTextEditor(OCFile file, String url, Context con
376380 @ NonNull
377381 private Intent createOpenFileIntent (OCFile file ) {
378382 String storagePath = file .getStoragePath ();
379- Uri fileUri = getFileUri ( file , MainApp . getAppContext (). getResources (). getStringArray ( R . array
380- . ms_office_extensions ));
383+ Uri fileUri = file . getExposedFileUri ( fileActivity );
384+
381385 Intent openFileWithIntent = null ;
382386 int lastIndexOfDot = storagePath .lastIndexOf ('.' );
383387 if (lastIndexOfDot >= 0 ) {
384388 String fileExt = storagePath .substring (lastIndexOfDot + 1 );
385389 String guessedMimeType = MimeTypeMap .getSingleton ().getMimeTypeFromExtension (fileExt );
386390 if (guessedMimeType != null ) {
387391 openFileWithIntent = new Intent (Intent .ACTION_VIEW );
388- openFileWithIntent .setDataAndType (
389- fileUri ,
390- guessedMimeType
391- );
392+ openFileWithIntent .setDataAndType (fileUri , guessedMimeType );
392393 }
393394 }
394395
@@ -398,25 +399,12 @@ private Intent createOpenFileIntent(OCFile file) {
398399
399400 if (openFileWithIntent == null ) {
400401 openFileWithIntent = new Intent (Intent .ACTION_VIEW );
401- openFileWithIntent .setDataAndType (
402- fileUri ,
403- file .getMimeType ()
404- );
402+ openFileWithIntent .setDataAndType (fileUri , file .getMimeType ());
405403 }
406404
407405 openFileWithIntent .setFlags (Intent .FLAG_GRANT_READ_URI_PERMISSION | Intent .FLAG_GRANT_WRITE_URI_PERMISSION );
408- return openFileWithIntent ;
409- }
410406
411- private Uri getFileUri (OCFile file , String ... officeExtensions ) {
412- if (file .getFileName ().contains ("." ) &&
413- Arrays .asList (officeExtensions ).contains (file .getFileName ().substring (file .getFileName ().
414- lastIndexOf ("." ) + 1 )) &&
415- !file .getStoragePath ().startsWith (MainApp .getAppContext ().getFilesDir ().getAbsolutePath ())) {
416- return file .getLegacyExposedFileUri ();
417- } else {
418- return file .getExposedFileUri (fileActivity );
419- }
407+ return openFileWithIntent ;
420408 }
421409
422410 public void streamMediaFile (OCFile file ) {
@@ -1063,7 +1051,7 @@ public void uploadFromCamera(Activity activity, int requestCode, boolean isVideo
10631051 File cameraFile = createCameraFile (activity , isVideo );
10641052
10651053 Uri cameraUri = FileProvider .getUriForFile (activity .getApplicationContext (),
1066- activity .getResources ().getString (R .string .file_provider_authority ), cameraFile );
1054+ activity .getResources ().getString (R .string .file_provider_authority ), cameraFile );
10671055 intent .putExtra (MediaStore .EXTRA_OUTPUT , cameraUri );
10681056
10691057 if (intent .resolveActivity (activity .getPackageManager ()) != null ) {
0 commit comments