Solution 1 :
After some experimenting it was clear that DownloadManager will not download to root of external storage or removable micro sd card.
Not even to apps private directory on micro sd card.
But to Download folder on external root or sd card root is ok.
Change
/storage/9016-4EF8/Photo Memory
To
/storage/9016-4EF8/Download/PhotoMemory
and you will have success with:
request.setDestinationUri(Uri.fromFile(file));
And… you do not have to create the directory yourself.
Hmmm.. this very much offers the same as
request.setDestinationInExternalPublicDir(choice, fileName);
So why doing it with a file uri?
Solution 2 :
I believe you are trying to access files in SD Card without URI permissions. Granting read and write permissions in runtime is not enough. Managing files in SD Card requires URI permission. SimpleStorage could help you solving the crash.
Accessing files with SimpleStorage is pretty straightforward:
DocumentFile folder = DocumentFileCompat.fromPath(context, "9016-4EF8", "Photo Memory");
if (folder != null) {
// folder exists
}
You can create directory like this:
DocumentFile folder = DocumentFileCompat.mkdirs(context, "9016-4EF8", "Photo Memory");
if (file != null) {
// folder exists or has been created previously
}
Please note that above methods wont work unless you have URI permissions. To grant it, just call SimpleStorage.requestStorageAccess()
.
Problem :
I am getting an error of No permission to write on external storage. Neither User nor android has permission to write on extenral storage. Please help. Below is my code.
package com.saidev.instagramquotes;
import android.Manifest;
import android.app.DownloadManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.VideoView;
import androidx.annotation.NonNull;
import androidx.core.content.PermissionChecker;
import androidx.recyclerview.widget.RecyclerView;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import java.io.File;
import java.util.List;
import static androidx.core.content.PermissionChecker.checkSelfPermission;
import static com.saidev.instagramquotes.MainActivity.loadingDialog;
public class VideosAdapter extends FirebaseRecyclerAdapter<VideoItem , VideosAdapter.myViewHolder> {
ImageButton download;
ImageButton share;
/**
* Initialize a {@link RecyclerView.Adapter} that listens to a Firebase query. See
* {@link FirebaseRecyclerOptions} for configuration options.
*
* @param options
*/
public VideosAdapter(@NonNull FirebaseRecyclerOptions<VideoItem> options) {
super(options);
}
@Override
protected void onBindViewHolder(@NonNull myViewHolder holder, int position, @NonNull VideoItem model) {
holder.setdata(model);
download.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
File dir = new File("/storage/9016-4EF8/Photo Memory");
if ( !(dir.exists())) if ( ! (dir.mkdirs())) {
Toast.makeText(v.getContext(), "Sorry, could not create directory:nn" + dir.getAbsolutePath(),Toast.LENGTH_SHORT).show();
return;
}
File file = new File( dir, model.videoTitle);
Toast.makeText(v.getContext(), "Downloading", Toast.LENGTH_SHORT).show();
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(model.videoUrl))
.setTitle(model.videoTitle)
.setDescription("Downloading")
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
.setDestinationUri(Uri.fromFile(file))
.setAllowedOverMetered(true)
.setAllowedOverRoaming(true);
DownloadManager downloadManager = (DownloadManager) v.getContext().getSystemService(Context.DOWNLOAD_SERVICE);
long downloadID = downloadManager.enqueue(request);
}
}
});
}
@NonNull
@Override
public myViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_container_video, parent, false);
download = view.findViewById(R.id.download);
share = view.findViewById(R.id.vidshare);
return new myViewHolder(view);
}
class myViewHolder extends RecyclerView.ViewHolder{
VideoView videoView;
TextView videoTitle;
public myViewHolder(@NonNull View itemView) {
super(itemView);
videoView = itemView.findViewById(R.id.videoview);
videoTitle = itemView.findViewById(R.id.textVideoTitle);
}
void setdata(VideoItem obj){
videoView.setVideoPath(obj.videoUrl);
videoTitle.setText(obj.videoTitle);
videoView.setOnPreparedListener(mp -> {
mp.start();
});
videoView.setOnCompletionListener(MediaPlayer::start);
}
}
}
I am trying to download video from url. And I am showing the videos through video view in recycler view.
Please help me. I have used download Manager to download the video from url. And i want to save the downloaded video in the user’s download folder
Comments
Comment posted by blackapps
You should use File.exists() on the folder where you wanna download to before you start the download. Please add that code so we can check.
Comment posted by blackapps
File dir = new File(“/storage/9016-4EF8/Photo Memory); if ( !(dir.exists()) if ( ! (dir.mkdirs()) { Toast.makeText(v.getContext(), “Sorry, could not create directory:nn” + dir.getAbsolutePath(), Toast.LENGTH_SHORT).show() return; } File file = new File( dir, model.videoTitle);
Comment posted by blackapps
Which exception told that message? Further you did not tell if the directory existed and or that it could not be created. Inform me. Your app can not write to that directory on a removable micro sd card. So how could your app? How could you?
Comment posted by Shivani Dixit
@blackapps I told you that i am getting the same problem of No permission to write to file:///storage/9016-4EF8. Directory is existing in my external storage.
Comment posted by Shivani Dixit
@blackapps can i download my video in internal storage??
Comment posted by blackapps
Please adapt your code. You can remove the code i first proposed checking if the dir exists and creating it. Use a Download folder.
Comment posted by Shivani Dixit
My error has still not resolved. I am thinking that instead of downloading videos in internal storage, can we download the video on EXTERNAL STORAGE? If Yes, then what is the procedure of doing that??
Comment posted by blackapps
All the paths i mentioned here are on external storage.On removable external storage. DownloadManager will not download to internal storage to begin with.