Cordova(Monaca)でURLから画像or動画をダウンロードしてアルバムに保存する

https://www.blog.danishi.net/2020/09/15/post-3921/
前回記事よりよい方法を見つけたので

以下のCordovaプラグインを入れます。
cordova-plugin-file
cordova-plugin-file-transfer
cordova-plugin-photo-library-wkwebview

JavaScriptの実装はこんな感じ。
var downloadAndSaveToGallery = function(media, url, name, album){
    var fileTransfer = new FileTransfer();

    if(monaca.isIOS === true){
        var storeDirectory = cordova.file.syncedDataDirectory;
    }else{
        var storeDirectory = cordova.file.externalApplicationStorageDirectory;
    }

    var onSaveSuccess = function() {
        console.log('save success');
    };

    var onSaveError = function (error) {
        console.log('save error: ' + error);
    };

    fileTransfer.download(
        url,
        storeDirectory + name,
        function(entry){
            if(media == 'image'){  // 画像保存
                cordova.plugins.photoLibrary.saveImage(entry.toURL(), album,
                    onSaveSuccess, onSaveError);
            }else{  // 動画保存
                cordova.plugins.photoLibrary.saveVideo(entry.toURL(), album,
                    onSaveSuccess, onSaveError);
            }
        },
        function(error){
            console.log( "download error source" + error.source);
            console.log( "download error target" + error.target);
            console.log("download error code" + error.code);
        },
        false,
        {
            //headers: {
            //    "Authorization": "Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA=="
            //}
        }
    );
};

document.addEventListener('deviceready', function() {
    // 保存の許可をリクエスト
    cordova.plugins.photoLibrary.requestAuthorization(
        function () {
            console.log('Album Permission granted.');
        },
        function (error) {
            console.log(error);
        },
        {
            read: true,
            write: true
        }
    );

    // 画像保存
    downloadAndSaveToGallery('image',
                             'https://cordova.apache.org/static/img/cordova_bot.png',
                             'cordova.png', 'MyApp');

    // 動画保存
    downloadAndSaveToGallery('movie',
                             'https://file-examples-com.github.io/uploads/2017/04/file_example_MP4_480_1_5MG.mp4',
                             'sample.mp4', 'MyApp');
}, false);
実行すると、iOS、Androidともにギャラリーへの保存許可のダイアログが出て、許可すると画像が保存されます。

動画も扱えるし任意のアルバムに入れれるのでこっちの方が使い勝手よいです。

また、AWS S3からダウンロードしてくるときにはCORSの設定が必要になります。

追記:XMLhttpsRequest対応

cordova-plugin-file-transferは非推奨となっており、XMLhttpsRequestに移行対応しました。

var downloadAndSaveToGallery = function(media, url, name, album){

    var onSaveSuccess = function() {
        console.log('save success');
    };

    var onSaveError = function (error) {
        console.log('save error: ' + error);
    };

    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fs) {

        console.log('file system open: ' + fs.name);

        fs.root.getFile(name, { create: true, exclusive: false }, function (fileEntry) {

            console.log('fileEntry is file? ' + fileEntry.isFile.toString());
            var oReq = new XMLhttpsRequest();
            // Make sure you add the domain name to the Content-Security-Policy <meta> element.
            oReq.open("GET", url, true);

            // Define how you want the XHR data to come back
            oReq.responseType = "blob";
            oReq.onload = function (oEvent) {
                var blob = oReq.response; // Note: not oReq.responseText
                if (blob) {
                    var fileUrl = window.URL.createObjectURL(blob);
                    if(media == 'image'){  // 画像保存
                        cordova.plugins.photoLibrary.saveImage(fileUrl, album,
                            onSaveSuccess, onSaveError);
                    }else{  // 動画保存
                        cordova.plugins.photoLibrary.saveVideo(fileUrl, album,
                            onSaveSuccess, onSaveError);
                    }
                } else console.error('we didnt get an XHR response!');
            };
            oReq.send(null);

        }, function (err) { console.error('error getting file! ' + err); });

    }, function (err) { console.error('error getting persistent fs! ' + err); });
};

document.addEventListener('deviceready', function() {
    // 保存の許可をリクエスト
    cordova.plugins.photoLibrary.requestAuthorization(
        function () {
            console.log('Album Permission granted.');
        },
        function (error) {
            console.log(error);
        },
        {
            read: true,
            write: true
        }
    );

    // 画像保存
    downloadAndSaveToGallery('image',
                             'https://cordova.apache.org/static/img/cordova_bot.png',
                             'cordova.png', 'MyApp');

    // 動画保存
    downloadAndSaveToGallery('movie',
                             'https://file-examples-com.github.io/uploads/2017/04/file_example_MP4_480_1_5MG.mp4',
                             'sample.mp4', 'MyApp');
}, false);