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
FileProvider
is essential for sharing private file paths asUri
securely.- 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
Download
or 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_VIDEO
orREAD_EXTERNAL_STORAGE
FileProvider
- Runtime permission handling
Because the video is bundled inside the app APK, Android grants automatic access.