Playing videos in your Android app improves user engagement and enhances the multimedia experience. This guide explains how to implement video playback using VideoView, manage permissions, display thumbnails with ImageView, and securely access files using FileProvider. We’ll also cover the proper setup of AndroidManifest permissions and file sharing between apps.
1. Add Dependencies
First, make sure your build.gradle file is set properly. No extra dependencies are needed for VideoView, but FileProvider will require file-sharing configurations.
2. AndroidManifest.xml Configuration
Add the necessary permissions and provider configuration:

<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.INTERNET" />
<application
...>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application>Create a file res/xml/file_paths.xml:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path
name="external_files"
path="." />
</paths>3. Layout File (activity_main.xml)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<VideoView
android:id="@+id/videoView"
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_alignParentTop="true" />
<ImageView
android:id="@+id/thumbnailView"
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_alignParentTop="true"
android:scaleType="centerCrop"
android:visibility="visible"
android:src="@drawable/sample_thumbnail" />
<Button
android:id="@+id/playButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Play Video"
android:layout_below="@id/videoView"
android:layout_centerHorizontal="true"
android:layout_marginTop="16dp"/>
</RelativeLayout>4. Java Code (MainActivity.java)

import android.Manifest;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.ImageView;
import android.widget.MediaController;
import android.widget.Toast;
import android.widget.Button;
import android.widget.VideoView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;
import java.io.File;
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_PERMISSION = 100;
private VideoView videoView;
private ImageView thumbnailView;
private Button playButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
videoView = findViewById(R.id.videoView);
thumbnailView = findViewById(R.id.thumbnailView);
playButton = findViewById(R.id.playButton);
if (checkPermission()) {
setupVideoPlayer();
} else {
requestPermission();
}
playButton.setOnClickListener(v -> {
thumbnailView.setVisibility(View.GONE);
videoView.start();
});
}
private void setupVideoPlayer() {
File videoFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "sample_video.mp4");
Uri videoUri = FileProvider.getUriForFile(this, getPackageName() + ".fileprovider", videoFile);
videoView.setVideoURI(videoUri);
videoView.setMediaController(new MediaController(this));
}
private boolean checkPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
return ContextCompat.checkSelfPermission(this, Manifest.permission.READ_MEDIA_VIDEO) == PackageManager.PERMISSION_GRANTED;
} else {
return ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
}
}
private void requestPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_MEDIA_VIDEO}, REQUEST_PERMISSION);
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_PERMISSION);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_PERMISSION && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
setupVideoPlayer();
} else {
Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show();
}
}
}
5. Showing Thumbnail Before Playback
Set the ImageView with a thumbnail image, either static (@drawable/sample_thumbnail) or dynamically extracted using MediaMetadataRetriever if you want a real preview.
Optional: Display the video’s thumbnail using MediaMetadataRetriever.
MediaMetadataRetriever retriever = new MediaMetadataRetriever(); retriever.setDataSource(this, videoUri); Bitmap bitmap = retriever.getFrameAtTime(1000000); // 1 second thumbnailView.setImageBitmap(bitmap); retriever.release();
6. Notes on FileProvider
FileProvideris essential for sharing private file paths asUrisecurely.- Always define file paths correctly in
res/xml/file_paths.xml. - Avoid
file://URIs; always usecontent://via FileProvider for compatibility and security.
Final Tips
- Test on real device, not emulator, especially for
READ_EXTERNAL_STORAGE. - Place video in
Downloador public folders to simplify file access. - Always handle permission denial gracefully.
- Test on real device, not emulator, especially for
Creating Video Playback in Your App from res/raw (Optional)
Place your video file (e.g., sample_video.mp4) in:
app/src/main/res/raw/sample_video.mp4
Java Code: MainActivity.java

public class MainActivity extends AppCompatActivity {
private VideoView videoView;
private ImageView thumbnailView;
private Button playButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
videoView = findViewById(R.id.videoView);
thumbnailView = findViewById(R.id.thumbnailView);
playButton = findViewById(R.id.playButton);
// Prepare VideoView with raw resource
Uri videoUri = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.sample_video);
videoView.setVideoURI(videoUri);
videoView.setMediaController(new MediaController(this));
// Play button logic
playButton.setOnClickListener(v -> {
thumbnailView.setVisibility(View.GONE);
videoView.start();
});
}
}❌ No Permissions or FileProvider Needed
You do not need any of the following:
READ_MEDIA_VIDEOorREAD_EXTERNAL_STORAGEFileProvider- Runtime permission handling
Because the video is bundled inside the app APK, Android grants automatic access.