Search code examples
androidkotlinandroid-recyclerviewandroid-download-manager

How to download a file when a button inside a RecyclerView is pressed?


I'm creating an app where there's a button that when pressed, it will start a download of a file. The button is on a RecyclerView and I'm using the stock Android Download Manager.

I tried to do a setOnClickListener on that button inside the onBindViewHolder on my Recycler View adaptor and include the contents of the function inside it:

holder.button.setOnClickListener {
    val request = DownloadManager.Request(Uri.parse(downloadurl))
    request.setTitle("$downloadname.apk")
    request.setDescription("Download")
    request.setVisibleInDownloadsUi(true)
    request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS)
    request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
    val manager = getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
    manager.enqueue(request)
}

but in the getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager says me that I need a Context and not a String.

Then I tried to create an object that has a download function but it gives me the same error as the function.

How can I make that work in the object or the setOnClickListener?


Solution

  • that error message is caused by not passing the expected destination file-name:

    request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename);
    

    and you need to obtain a handle to the Context as method getSystemService() demands:

    @Override
    public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder viewHolder, int position) {
    
        final SomeClass item = getItem(position);
    
        ((ViewHolder) viewHolder).getDataBinding().buttonDownload.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
    
                Context context = ((ViewHolder) viewHolder).mRecyclerView.getContext();
                DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
    
                DownloadManager.Request request = new DownloadManager.Request(Uri.parse(item.getDownloadUrl()));
                request.setTitle(item.getTitle());
                request.setDescription(item.getDescription());
                request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, item.getFileName());
                request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
                request.setVisibleInDownloadsUi(true);
                manager.enqueue(request);
            }
        });
    }
    

    fell free to convert this yourself from Java to Kotlin (it will ask when pasting the code into .kt).