Features of working with files in applications on different mobile platforms

    When developing a cross-platform mobile application that has file functionality in its functionality, the question arises about the organization of file work processes on each platform. We faced this issue when developing a new version of Edusty , which allows you to share files with your classmates. In this article we will tell you how to import and export files in applications running on the operating systems iOS, Android, Windows Phone.




    iOS


    In the iOS operating system, the concept of a file system is hidden for the user and interaction with files is carried out by the application itself and only with files located in the application directory. There are several ways to import a file into the application directory - using iTunes File Sharing or registering File Types for the application.

    When using iTunes File Sharing, the application will be displayed in iTunes in the "Shared Files" section, where you can add files to the application from your computer. Files added in this way fall into the / Documents directory of the application.



    The application itself must control this directory for new files. You also need to keep in mind that iTunes File Sharing actually gives the user direct access to documents, which means that files in this directory can be renamed, deleted at any time, etc.

    To use iTunes File Sharing, you must add the UIFileSharingEnabled ( Application supports iTunes file sharing) in the info.plist application file.

    UIFileSharingEnabled


    When registering File Types, the application will appear in the selection list to open the file, when you click on the standard “open with” dialog box.



    When opening a file in this way, a copy of it is placed in the / Documents / Inbox directory , and the application calls the application: openURL: sourceApplication: annotation: protocol UIApplicationDelegate method , in which the url of the file to be opened is passed.

    Files in the / Documents / Inbox directory can be read and deleted, but cannot be changed. To change the file, you need to move it to another directory, for example, to / Documents .

    To be able to import files in this way, you must add the key CFBundleDocumentTypes(Document types) in the info.plist application file. Its value is an array, each element of which is a dictionary used to describe each type of document supported by the application. A full description of the possible clues and their meanings can be found in the documentation: developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html

    We did not make restrictions on file types, but made it possible to import any files . Info.plist at the same time looks as follows:

    CFBundleDocumentTypesCFBundleTypeNameAll filesCFBundleTypeRoleViewerLSHandlerRankAlternateLSItemContentTypespublic.data


    To export files from the application, the same “open with” dialog box is used, which initializes the UIDocumentInteractionController . It is possible to immediately open the list of applications for opening a file, open the list of applications for opening a file along with standard services, such as printing a file, sending by mail, etc. as well as it is possible to open the file with the built-in previewer, from where the button for opening the file by another application is also available.



    Android


    In Android, applications can access files other than those in private application directories.
    To perform operations such as selecting a file, sending an email, or opening a link in a browser, Intents are used.
    To select a file from the file system, you must use the ACTION_GET_CONTENT action .
    Using the setType () method, you can specify which file types will be available for selection. For example, if you specify
    setType (“audio / mp3”) , then in the application for viewing files we will see only files with the extension .mp3, or specify “* / *” to display all files. Then we call the startActivityForResult () method , where we pass as a parameterIntent.сreateChooser () , which creates an application selection dialog.
    Also in the manifest file, you need to add the necessary permissions:





    After we selected the file in the file manager, we get to the onActivityResult method (int requestCode, int resultCode, Intent data) , where the data will contain the Uri of our file.

    To open files from the service, use the ACTION_VIEW action . The application for opening the file is selected using the FileOpen class (found on the expanses of StackOverFlow and slightly redone), in which we check what type of file we are trying to open, according to its potential extension.

    Fileopen.class
    public class FileOpen {
        public static void openFile(Context context, File url) throws IOException {
            File file = url;
            Uri uri = Uri.fromFile(file);
            Intent intent = new Intent(Intent.ACTION_VIEW);
            if (url.toString().contains(".doc") || url.toString().contains(".docx") || url.toString().contains(".odt")) {
                // Word document
                intent.setDataAndType(uri, "application/msword");
            } else if (url.toString().contains(".pdf")) {
                // PDF file
                intent.setDataAndType(uri, "application/pdf");
            } else if (url.toString().contains(".ppt") || url.toString().contains(".pptx")) {
                // Powerpoint file
                intent.setDataAndType(uri, "application/vnd.ms-powerpoint");
            } else if (url.toString().contains(".xls") || url.toString().contains(".xlsx")) {
                // Excel file
                intent.setDataAndType(uri, "application/vnd.ms-excel");
            } else if (url.toString().contains(".zip") || url.toString().contains(".rar")) {
                // ZIP Files
                intent.setDataAndType(uri, "application/zip");
            } else if (url.toString().contains(".rtf")) {
                // RTF file
                intent.setDataAndType(uri, "application/rtf");
            } else if (url.toString().contains(".wav") || url.toString().contains(".mp3")) {
                // WAV audio file
                intent.setDataAndType(uri, "audio/x-wav");
            } else if (url.toString().contains(".gif")) {
                // GIF file
                intent.setDataAndType(uri, "image/gif");
            } else if (url.toString().contains(".jpg") || url.toString().contains(".jpeg") || url.toString().contains(".png")) {
                // JPG file
                intent.setDataAndType(uri, "image/jpeg");
            } else if (url.toString().contains(".txt")) {
                // Text file
                intent.setDataAndType(uri, "text/plain");
            } else if (url.toString().contains(".3gp") || url.toString().contains(".mpg") || url.toString().contains(".mpeg") || url.toString().contains(".mpe") || url.toString().contains(".mp4") || url.toString().contains(".avi")) {
                // Video files
                intent.setDataAndType(uri, "video/*");
            } else {
                intent.setDataAndType(uri, "*/*");
            }
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(intent);
        }
    }
    


    When finding a match, use the setDataAndType () method to specify the Uri and MIME type for the data to be transmitted.



    If the file contains a format not considered by us, then in setDataAndType () we specify “* / *” as the type. Thus, the system will show us all the applications installed on the device so that you can choose for yourself with what to open the file.

    Windows phone


    Universal applications for the Windows Store / Windows Phone Store almost completely open the file system, at least not the system folders. The OpenFilePicker class allows you to open files on any platform from any available source: device memory, external media and devices, and clouds (if appropriate applications are installed). In this regard, there are no problems with opening files on these devices, the standard class even allows you to take a photo through the file selection menu, which is very convenient.

    In order to open files through the standard file selection dialog, you need to create an instance of the OpenFilePicker class and initialize it with several parameters:
    List .FileTypeFilter
    - A collection of allowed file extensions (to allow you to select any files, you must add the entry "*").
     PickerLocationId .SuggestedStartLocation
    - this enumerated type allows you to specify the location that opens first in the dialog (for example: PickerLocationId.ComputerFolder).
    PickerViewMode .ViewMode
    - allows you to select the type of file display (list or grid).

    The call of the file selection dialog on Windows 8.1 and Windows Phone 8.1 is different, despite the universal API (as you know, it is not 100% universal).

    For a Windows 8.1 application, you must call the .PickMultipleFilesAsync () or .PickSingleFileAsync () method, depending on whether you want to select one file or several. These methods return accordingly IReadOnlyListand StorageFile (strictly speaking, they return Task, so you need to use async / await).



    For Windows Phone 8.1, things are a little more complicated. Similar methods are called .PickMultipleFilesAndContinue () and .PickSingleFileAndContinue () . Both methods return nothing (void), however, after selecting files in the dialog, the ContinueFileOpenPicker () method is called , which is a member of the IFileOpenPickerContinuable interface . This interface is not built into the standard API, but it can be taken in the ContinuationManager class . For more information about how to continue the work after calling methods * AndContinue (), as well as download class ContinuationManager possible here. And so, after the ContnuationManager class is added to the project according to the instructions, you need to inherit the class from which the .PickMultipleFilesAsync () or .PickSingleFileAsync () method is called , inherit from the IFileOpenPickerContinuable interface . Then you need to implement the void ContinueFileOpenPicker (FileOpenPickerContinuationEventArgs args) method , where args.Files contains a collection of StorageFile objects.



    Opening files from the service is done by saving the file to disk in the internal folder of the application and then specifying it in the LaunchFileAsync () method of the Launcher class. After that, the system either opens the file with the default application for this type of file, or offers to select the application from the installed ones, or offers to find it in the store.

    Also popular now: