PolCPP / nativescript-downloadmanager

A small library to download files with android DownloadManager from nativescript
9 stars 10 forks source link

Open downloaded file #5

Open davorpeic opened 6 years ago

davorpeic commented 6 years ago

Hi,

do you know how I could open downloaded file on android, I successfully download new apk version of the app and I would like to open it once its done, I tried doing custom intents, but I couldn't get it working.

thanks

davorpeic commented 6 years ago

Ok, we added feature to open downloaded file once it is downloaded in Android, are you interested in PR?

PolCPP commented 6 years ago

Sorry for missing the previous comment. Actually yes. It works on android 7+? I know they pretty much broke creating intents from a file.

davorpeic commented 6 years ago

Good question, we have tried it only on android 5 & 6, will try and let you know.

PolCPP commented 6 years ago

Probably it wont work if you haven't adjusted it for N+ and theres almost no docs about it. Just managed to do it (opening an apk to install), i'll release it on an app i want to update and make open source before xmas. But if you can manage with ugly/hacky vanilla js here's a "preview".

Not sure how to integrate this easily inside this package tbh. Switched to react native so i haven't touched ns nor ts for a while.

                var loader = new LoadingIndicator();        
                loader.show();                      
                this.ndm.downloadFile(url, {}, ((res, path) => {
                    loader.hide();                
                    if (res) {
                        console.log(path);
                        var myuri = undefined;                                       
                        if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.M){
                            var o = new java.io.File(path.replace("file://",""));
                            o.setReadable(true, false);
                            var con = Application.android.foregroundActivity;                    
                            myuri =  android.support.v4.content.FileProvider.getUriForFile
                                (con, "com.tns.NativeScriptApplication.fileprovider", o);
                        } else {
                            myuri = android.net.Uri.parse(path);
                        }

                        var promptInstall = new android.content.Intent(android.content.Intent.ACTION_VIEW).setDataAndType(myuri,"application/vnd.android.package-archive");
                        if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.M){
                            var resolvedIntentActivities = Application.android.foregroundActivity.getPackageManager().queryIntentActivities(promptInstall, android.content.pm.PackageManager.MATCH_ALL);
                            var size = resolvedIntentActivities.size()
                            for (var i = 0; i < size; i++) {
                                var resolvedIntentInfo = resolvedIntentActivities.get(i);
                                var packageName = resolvedIntentInfo.activityInfo.packageName;
                                Application.android.foregroundActivity.grantUriPermission(packageName, myuri, android.content.Intent.FLAG_GRANT_WRITE_URI_PERMISSION | android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION);
                            }
                        }                        
                        Application.android.foregroundActivity.startActivity(promptInstall);
                    } else {
                        this.showError("Download has failed, please ensure you have internet access");
                    }

                }).bind(this)); 

You will also need to create a fileprovider on the manifest.xml file.

        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.tns.NativeScriptApplication.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/filepaths" />
        </provider>

and create another xml file with the filepaths.

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-files-path name="files" path="files/"/>
    <external-files-path name="downloads" path="downloads/"/>
</paths>

Also in Oreo it will fail silently unless you add this permission.

    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>