Last updated: Jun 23, 2020 13:55

Problem

When media files (such as images or music files) are transferred to a device through API calls, Android apps like Gallery and Music may not be aware of the new media and will simply ignore them. This is not a Perfecto limitation, but rather an Android Limitation of not indexing the files when they are not added through the Android UI. Using File Explorer and placing a file on the SDCard will have the same effect.

Solution

The solution is to force Android to re-scan the media files. This could be accomplished by using a third-party Media re-scan application, by unmounting and remounting the SDCard, or by adding a step to programmatically force Android to re-scan a specific file upon its transfer. The latter can be achieved by running a simple adb shell script on the Device, as described in the following procedure.

To re-scan a file by running an ADB script:

  1. Upload a file to the Repository using API.
    The UploadMedia() method of the PerfectoLabUtils can be used for this. This class is part of the template project for a number of programming languages, which comes with the IDE Plugins.
  2. Transfer the file to the device using the File Transfer widget.

    In automation testing, use the "Put File" function:


  3. To trigger the rescan, use the adb command. This can be tested using DevTunnel to execute the adb command directly.

    The adb command that can rescan a specific file (here lala2.jpg, located in the Camera folder within DCIM) is:

    adb -s 9887bc425337594641 shell am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d file:///mnt/sdcard/DCIM/Camera/lala2.jpg

    To incorporate this into your test, use a Draft Function: mobile:handset:shell

    In Java:
    params.put("command", "am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d file:///mnt/sdcard/"+deviceFilePath);
    Object result1 = driver.executeScript("mobile:handset:shell", params);
    
    

    The complete example to transfer a file to an android device to then re-scan it could look like this:

    //** Define location to place the file including filename, eg DCIM/file.jpg, or DCIM/Camera/file.jpg
    
            String deviceFilePath="DCIM/anyPic.jpg";
    
    //** Upload File from Repository Location to place directly under DCIM folder (assuming DCIM is direct child node of SDCard) 
    
            Map<String, Object> params = new HashMap<>();
    		params.put("repositoryFile", "PUBLIC:lala4.jpg");
    		params.put("handsetFile", "card:/"+deviceFilePath);
    		Object result = driver.executeScript("mobile:media:put", params);
    
    //** use adb shell command to force scan on that file- this should make it visible in Gallery
    
            params.clear();
    		params.put("command", "am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d file:///mnt/sdcard/"+deviceFilePath);
    		result = driver.executeScript("mobile:handset:shell", params);

Note: The functionality used to execute the Device shell in the above example is a Draft function, which is, essentially, a Technical Preview that is not guaranteed to work across all devices.