Formulation of the problem:
Display a list of video previews ( mp4 format) contained in the selected folder.
Decision:
To select a folder with video files we will use Android-DirectoryChooser .
Add to build.gradle :
repositories { mavenCentral() maven { url 'http://guardian.github.com/maven/repo-releases' } } ... dependencies { ... compile ('net.rdrei.android.dirchooser:library:3.0@aar') { transitive = true; } }
In AndroidManifest.xml add the attribute to the manifest tag:
xmlns:tools="http://schemas.android.com/tools"
add to the application tag:
tools:replace="android:theme"
Also, do not forget about permisson :
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Since the purpose of this answer is not to explain the work with runtime permissions , here we use the old method, and if targetSdk >= 23 , then lower it to at least 22 .
Next, the layout of the video_preview_item.xml list video_preview_item.xml :
<?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:card_view="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="7dp" card_view:cardCornerRadius="4dp"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <ImageView android:id="@+id/video_preview_image_view" android:layout_width="120dp" android:layout_height="60dp" android:layout_margin="5dp"/> <TextView android:id="@+id/video_preview_text_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@+id/video_preview_image_view" android:layout_marginTop="5dp" android:layout_marginBottom="5dp" android:layout_marginRight="5dp"/> </RelativeLayout> </android.support.v7.widget.CardView>
layout for activity - activity_preview.xml :
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <android.support.v7.widget.RecyclerView android:id="@+id/video_preview_recycler_view" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"> </android.support.v7.widget.RecyclerView> <Button android:id="@+id/choose_dir_button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Choose dir"/> </LinearLayout>
VideoPreview data VideoPreview :
public class VideoPreview { private String mVideoName; private Bitmap mVideoBitmap; public VideoPreview(String videoName, Bitmap videoBitmap) { mVideoName = videoName; mVideoBitmap = videoBitmap; } public String getVideoName() { return mVideoName; } public Bitmap getVideoBitmap() { return mVideoBitmap; } }
Adapter for RecyclerView :
public class VideoPreviewAdapter extends RecyclerView.Adapter<VideoPreviewAdapter.VideoPreviewHolder> { private Context mContext; private ArrayList<VideoPreview> mItems; public VideoPreviewAdapter(Context context) { mContext = context; mItems = new ArrayList<>(); } public void addItems(ArrayList<VideoPreview> items) { mItems.addAll(items); notifyDataSetChanged(); } public void clearItems() { mItems.clear(); } @Override public VideoPreviewHolder onCreateViewHolder(ViewGroup parent, int viewType) { LayoutInflater layoutInflater = LayoutInflater.from(mContext); View view = layoutInflater.inflate(R.layout.video_preview_item, parent, false); return new VideoPreviewHolder(view); } @Override public void onBindViewHolder(VideoPreviewHolder holder, int position) { holder.mVideoPreviewImageView.setImageBitmap(mItems.get(position).getVideoBitmap()); holder.mVideoPreviewTextView.setText(mItems.get(position).getVideoName()); } @Override public int getItemCount() { return mItems.size(); } public class VideoPreviewHolder extends RecyclerView.ViewHolder { public ImageView mVideoPreviewImageView; public TextView mVideoPreviewTextView; public VideoPreviewHolder(View itemView) { super(itemView); mVideoPreviewImageView = (ImageView) itemView.findViewById(R.id.video_preview_image_view); mVideoPreviewTextView = (TextView) itemView.findViewById(R.id.video_preview_text_view); } } }
And finally, PreviewActivity :
public class PreviewActivity extends AppCompatActivity implements DirectoryChooserFragment.OnFragmentInteractionListener { private RecyclerView mVideoPreviewRecyclerView; private Button mChooseDirButton; private DirectoryChooserFragment mDialog; private VideoPreviewAdapter mVideoPreviewAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_preview); mVideoPreviewRecyclerView = (RecyclerView) findViewById(R.id.video_preview_recycler_view); mChooseDirButton = (Button) findViewById(R.id.choose_dir_button); mVideoPreviewRecyclerView.setLayoutManager(new LinearLayoutManager(this)); mVideoPreviewAdapter = new VideoPreviewAdapter(this); mVideoPreviewRecyclerView.setAdapter(mVideoPreviewAdapter); final DirectoryChooserConfig config = DirectoryChooserConfig.builder() .newDirectoryName("DialogSample") .build(); mDialog = DirectoryChooserFragment.newInstance(config); mChooseDirButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mDialog.show(getFragmentManager(), null); } }); } @Override public void onSelectDirectory(@NonNull String path) { ArrayList<String> videoFiles = getVideoFiles(path); if (videoFiles.isEmpty()) { Toast.makeText(getApplicationContext(), "In this directory there is no videos!", Toast.LENGTH_SHORT).show(); mDialog.dismiss(); return; } mDialog.dismiss(); ArrayList<VideoPreview> videoPreviews = new ArrayList<>(); for (String filePath : videoFiles) { Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(filePath, MediaStore.Video.Thumbnails.MINI_KIND); String videoFileName = filePath.substring(filePath.lastIndexOf("/")+1); videoPreviews.add(new VideoPreview(videoFileName, bitmap)); } mVideoPreviewAdapter.clearItems(); mVideoPreviewAdapter.addItems(videoPreviews); } @Override public void onCancelChooser() { mDialog.dismiss(); } public ArrayList<String> getVideoFiles(String directoryPath) { ArrayList<String> result = new ArrayList<>(); File directory = new File(directoryPath); File files[] = directory.listFiles(new FilenameFilter() { @Override public boolean accept(File dir, String name) { return name.endsWith(".mp4"); } }); for (File file : files) { result.add(file.getAbsoluteFile().toString()); } return result; } }
To get the preview, use the ThumbnailUtils.createVideoThumbnail(...) method included in the Android SDK (for this reason I see no reason to drag Glide ).
Please note that the ThumbnailUtils.createVideoThumbnail(...) method is quite heavy and with a large number of files it will hang the UI , so it is better to put it in a separate stream and give the adapter one preview (as they are formed). But this problem is for you.
Also note that in the adapter we store a fairly voluminous list of such , the size of which is due to the presence of a mass of Bitmap in it. Think: maybe we do not need it. But as an example of a training, here we leave everything as it is.
As a result, we obtain the following:
Dialogue for selecting a folder with video:

List with thumbnails:

filePathvariable you specify the path to a specific file, not a folder. - post_zeewGlide. - post_zeew