import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ProgressBar; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import com.example.movieflix.R; import com.example.movieflix.ui.adapters.DownloadAdapter; import com.example.movieflix.ui.adapters.FileUtils; import java.io.File; import java.util.ArrayList; import java.util.List; public class DownloadFragment extends Fragment implements FileUtils.DownloadCallback { private RecyclerView recyclerView; private DownloadAdapter adapter; private List<String> downloadedVideos; private SwipeRefreshLayout swipeRefreshLayout; @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_download, container, false); recyclerView = view.findViewById(R.id.recyclerView_download); recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); swipeRefreshLayout = view.findViewById(R.id.swipeRefresh_download); // Initialize the list of downloaded videos downloadedVideos = new ArrayList<>(); // Initialize and set the adapter to the RecyclerView adapter = new DownloadAdapter(downloadedVideos); recyclerView.setAdapter(adapter); swipeRefreshLayout.setOnRefreshListener(this::refreshData); return view; } // Method to handle swipe-to-refresh action private void refreshData() { // Clear the existing list of downloaded videos downloadedVideos.clear(); // Populate downloaded videos list again populateDownloadedVideos(); // Notify the adapter of data change adapter.notifyDataSetChanged(); // Stop the swipe-to-refresh animation swipeRefreshLayout.setRefreshing(false); } // Method to download a video using FileUtils and save it to internal storage private void downloadVideo(String videoUrl, String name) { FileUtils.saveVideoToInternalStorage(requireContext(), videoUrl, name, success -> { if (success) { // If download is successful, add the video path to downloadedVideos list String filePath = requireContext().getFilesDir() + File.separator + name; downloadedVideos.add(filePath); Log.d("DownloadFragment", "File path added: " + filePath); // Notify the adapter of the data change adapter.notifyItemInserted(downloadedVideos.size() - 1); } else { // Handle download failure Log.e("DownloadFragment", "Download failed for: " + name); } }); } @Override public void onDownloadComplete(boolean success) { if (success) { // Refresh the list of downloaded videos populateDownloadedVideos(); // Notify the adapter of data change adapter.notifyDataSetChanged(); } else { // Handle download failure Log.e("DownloadFragment", "Download failed"); } } // Method to populate the list of downloaded videos private void populateDownloadedVideos() { try { // Clear the existing list of downloaded videos downloadedVideos.clear(); // Get the directory for downloaded videos File directory = requireContext().getFilesDir(); if (directory != null && directory.isDirectory()) { // List all files in the directory File[] files = directory.listFiles(); if (files != null) { for (File file : files) { // Add absolute path of each file to the downloadedVideos list if (file.isFile()) { downloadedVideos.add(file.getAbsolutePath()); } } } } } catch (Exception e) { e.printStackTrace(); Log.e("DownloadFragment", "Error populating downloaded videos: " + e.getMessage()); } } }
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.movieflix.R;
import java.io.File;
import java.util.List;
public class DownloadAdapter extends RecyclerView.Adapter<DownloadAdapter.ViewHolder> {
private final List<String> downloadedVideos;
public DownloadAdapter(List<String> downloadedVideos) {
this.downloadedVideos = downloadedVideos;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_download, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
String videoPath = downloadedVideos.get(position);
holder.bind(videoPath);
}
@Override
public int getItemCount() {
return downloadedVideos.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
private final TextView textViewTitle;
public ViewHolder(@NonNull View itemView) {
super(itemView);
textViewTitle = itemView.findViewById(R.id.textViewTitle);
}
public void bind(String videoPath) {
// Display video title or metadata in the item view
textViewTitle.setText(getVideoTitleFromPath(videoPath));
}
private String getVideoTitleFromPath(String videoPath) {
if (videoPath == null || videoPath.isEmpty()) {
return "Unknown Title";
}
File file = new File(videoPath);
return file.getName();
}
}
}
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class FileUtils {
public interface DownloadCallback {
void onDownloadComplete(boolean success);
}
public static void saveVideoToInternalStorage(Context context, String videoUrl, String name, DownloadCallback callback) {
new DownloadTask(context, videoUrl, name, callback).execute();
}
private static class DownloadTask extends AsyncTask<Void, Void, Boolean> {
private final Context context;
private final String videoUrl;
private final String name;
private final DownloadCallback callback;
DownloadTask(Context context, String videoUrl, String name, DownloadCallback callback) {
this.context = context;
this.videoUrl = videoUrl;
this.name = name;
this.callback = callback;
}
@Override
protected Boolean doInBackground(Void... voids) {
try {
URL url = new URL(videoUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.connect();
// Create a new File object for saving the video in internal storage
File directory = context.getFilesDir(); // Use internal storage directory
File file = new File(directory, name);
// Create buffered streams
InputStream inputStream = new BufferedInputStream(connection.getInputStream());
FileOutputStream outputStream = new FileOutputStream(file);
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
// Close streams
outputStream.close();
inputStream.close();
return true; // Video saved successfully
} catch (IOException e) {
e.printStackTrace();
return false; // Error occurred while saving video
}
}
@Override
protected void onPostExecute(Boolean success) {
super.onPostExecute(success);
callback.onDownloadComplete(success);
}
}
}
Hi, I am trying to download a video from url and save it in the internal app storage which can be viewed in the Downloaded Fragment. The problem is that when i click the download button video starts downloading and in notification bar downloading status also shows. But after download complete video is not appearing in the Downloaded Fragment. When i open the Downloaded Fragment there is a file name profileinstalled. this file remains there either i download or not. please help me with that