简体   繁体   中英

how to download pdf form a url, to internal storage and open it : Android studio using kotlin

class Eco9 : AppCompatActivity() {

    lateinit internal var uri: Uri

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_eco9)
        this.getActionBar();
        this.supportActionBar!!.title = "Class 9th Economics";

        fab.setOnClickListener { view ->
            Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show()
        }
        supportActionBar?.setDisplayHomeAsUpEnabled(true)

       val openActivityDownload: Button = findViewById(R.id.eco9ch1)
        openActivityDownload.setOnClickListener {
            val s = "https://drive.google.com/file/d/0B71LXrqWr0mFUTk5WnVyVEQ3MFE/export?format=pdf"
            val fname = "123.pdf"
            if (FileExists(fname)) { previewpdf(fname) }
            else { download(s)
                Toast.makeText(applicationContext, "File will download", Toast.LENGTH_LONG).show()
            }
        }

    }

    fun FileExists(name: String): Boolean {
        val file = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).path + separator + name)
        return file.exists()
    }

    private fun download(s: String) {
        val downloadManager = getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
        val uri = Uri.parse(s)
        val request = DownloadManager.Request(uri)
        val nameOfFile = URLUtil.guessFileName(uri.toString(), null, MimeTypeMap.getFileExtensionFromUrl(uri.toString()))
        val destinationInExternalPublicDir = request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS)
        request.setAllowedOverMetered(true)
        request.setAllowedOverRoaming(true)
        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE)
        request.allowScanningByMediaScanner()
        downloadManager.enqueue(request)
    }

    private fun previewpdf(name: String) {
       val file = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).path + separator + name)
       val path = fromFile(file)
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
        val intent = Intent(Intent.ACTION_VIEW, path)

        val chooser = Intent.createChooser(intent, "Open with")
        if (intent.resolveActivity(packageManager) != null)
            startActivity(chooser)
        else
            Toast.makeText(applicationContext, "No suitable application to open file", Toast.LENGTH_LONG).show()
    }
}

I want to download a pdf from given url (s), I am pressing button named "echo9ch1", and calling function download(s) if file is not present in internal public download folder and otherwise if it is present, it should open pdf, not download it again. Where am i missing ? I can open 123.pdf, which was downloaded earlier. but I deleted my pdf file and download function is not working now . Actually a small problem came, as i was playing with code in download function.Help me with download() function, and see preview() and fileExists() function also. I added permissions in manifest.xml also. And I want to download pdf without wifi also.

Manifest permissions are :

 <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

For download you have to use async task.

like in this example I am downloading mutliple file it can be PDF, Image etc

class DownloadFileAsync(paths: Array<String?>, listener: AsyncResponse?, size: Int) : AsyncTask<String, String, Array<String?>>() {
    private val listener: AsyncResponse? = listener
    var current = 0
    var paths: Array<String?>
    val downPaths = arrayOfNulls<String>(size)

    lateinit var fpath: String
    var show = false


    init {
        this.paths = paths
    }


    protected override fun onPreExecute() {
        super.onPreExecute()
    }

    protected override fun doInBackground(vararg aurl: String): Array<String?> {
        val rows = aurl.size
        while (current < rows) {
            var count: Int
            try {
                println("Current: " + current + "\t\tRows: " + rows)
                fpath = getFileName(this.paths[current]!!)
                val url = URL(this.paths[current])
                val conexion = url.openConnection()
                conexion.connect()
                val lenghtOfFile = conexion.getContentLength()
                val input = BufferedInputStream(url.openStream(), 512)
                val file = File(Environment.getExternalStorageDirectory().path.plus(File.separator).plus(fpath))
                downPaths.set(current, file.absolutePath)
                if (!file.exists()) file.createNewFile()
                val output = FileOutputStream(file)
                val data = ByteArray(512)
                var total: Long = 0
                while (true) {
                    count = input.read(data)
                    if (count == -1) break
                    total += count
                    output.write(data, 0, count)
                }


                show = true
                output.flush()
                output.close()
                input.close()
                current++
            } catch (e: Exception) {
                Log.d("Exception", "" + e)
            }
        } // while end
        onPostExecute(downPaths)
        return downPaths
    }

    override fun onProgressUpdate(progress: Array<String?>) {

    }

    override fun onPostExecute(result: Array<String?>) {
        listener?.processFinish(result)
    }

    private fun getFileName(wholePath: String): String {
        var name: String? = null
        val start: Int
        val end: Int
        start = wholePath.lastIndexOf('/')
        end = wholePath.length //lastIndexOf('.');
        name = wholePath.substring((start + 1), end)
        return name
    }
}

After that I am geting the call back of file path via interface listener?.processFinish(result)

Note: Maybe I should use comment section for this, but my reputation is still low so...

I try running your code, the only thing missing is on the download function. It should be:

 val destinationInExternalPublicDir = request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, nameOfFile)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM