📱 Sketchware Video Player App - Mobile Ke Sare Videos Show Karne Wala Professional Video Gallery App (XML & Java Only)


📱 Sketchware Video Player App - Mobile Ke Sare Videos Show Karne Wala Professional Video Gallery App (XML & Java Only)

Agar aap Sketchware ka use karke ek professional Android Video Gallery App banana chahte ho, jisme mobile ke andar maujood saare videos automatically show ho, to ye tutorial aapke liye perfect hai. Ye guide specially un users ke liye hai jo Sketchware video player app ya Sketchware video gallery app banaana chahte hain, lekin blocks ka use kiye bina.

Is complete guide me hum step-by-step dekhenge ki kaise:

  • Mobile ke internal storage se saare videos fetch kare
  • Unhe Grid format me gallery jaisa show kare
  • Custom Video Player banaye (Play, Pause, Fullscreen)
  • Android 13+ permissions properly handle kare

Sabse khaas baat: Is project me Sketchware ke ek bhi block ka use nahi hua hai. Puri app XML + Java Code se banayi gayi hai. Ye ek perfect example hai Sketchware app without blocks banane ka.


📱 Video Gallery App Features

  • Automatically mobile ke sare videos load hote hain
  • RecyclerView + GridLayoutManager based gallery
  • Fast video thumbnail loading (ThumbnailUtils)
  • Custom Video Player with SeekBar
  • Fullscreen & Landscape support
  • Android 13+ READ_MEDIA_VIDEO support
  • No third-party library required
  • 100% Java & XML (No Blocks)

📂 Project Structure (Professional Android Style)

MainActivity.java        → Permission & video list
PermissionHelper.java   → Storage permission handling
VideoFetcher.java       → MediaStore se videos fetch
VideoModel.java         → Video data model
VideoAdapter.java       → RecyclerView adapter
PlayerActivity.java     → Custom video player

main.xml                → Gallery UI
item_video.xml          → Single video item layout
player.xml              → Video player UI

Ye structure perfect hai ek complete Android video player source code ke liye, jise aap Sketchware me easily implement kar sakte hain.


🔐 Step 1: New Project Create Karna (Sketchware)

Sabse pehle Sketchware open kare aur:

  • App Name: Video Player
  • Package Name: com.video.paly
  • Create par click kare

Project create hone ke baad:

  • Direct XML Editor open kare
  • main.xml file me niche diya gaya code paste kare
  • File save kare

📌 main.xml Code - Video Gallery Layout

<LinearLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	xmlns:app="http://schemas.android.com/apk/res-auto"
	xmlns:tools="http://schemas.android.com/tools"
	android:layout_width="match_parent"
	android:layout_height="match_parent"
	android:orientation="vertical"
	android:background="@color/light_gray">
	<com.google.android.material.appbar.MaterialToolbar
		android:id="@+id/toolbar"
		android:layout_width="match_parent"
		android:background="@color/purple_500"
		android:layout_height="?attr/actionBarSize"
		android:elevation="4dp"
		app:title="VideoGallery"
		app:titleTextColor="@color/white" />
	<ProgressBar
		android:id="@+id/progressBar"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:layout_marginTop="20dp"
		android:indeterminate="false"
		style="?android:progressBarStyle"
		android:layout_gravity="center_horizontal|center_vertical"
		android:visibility="gone" />
	<TextView
		android:id="@+id/tvEmpty"
		android:layout_width="match_parent"
		android:layout_height="match_parent"
		android:gravity="center_horizontal|center_vertical"
		android:text="No videos found"
		android:textSize="18sp"
		android:visibility="gone" />
	<androidx.recyclerview.widget.RecyclerView
		android:id="@+id/recyclerView"
		android:layout_width="match_parent"
		android:layout_height="match_parent"
		android:padding="8dp"
		android:clipToPadding="false"
		android:visibility="visible" />
</LinearLayout>

▶ Step 2: Video Player Screen (player.xml)

Ab Create New View par click karke ek nayi screen banaye:

  • View Name: player.xml
  • Toolbar: OFF

Save karne ke baad Direct XML Editor open kare aur niche diya gaya code paste kare. Ye layout Sketchware custom video player ke liye perfect hai.

📌 player.xml Code - Custom Video Player UI

<RelativeLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	xmlns:app="http://schemas.android.com/apk/res-auto"
	xmlns:tools="http://schemas.android.com/tools"
	android:layout_width="match_parent"
	android:layout_height="match_parent"
	android:background="@color/black">
	<VideoView
		android:id="@+id/videoView"
		android:layout_width="match_parent"
		android:layout_height="match_parent"
		android:layout_centerInParent="true" />
	<RelativeLayout
		android:id="@+id/controlsLayout"
		android:layout_width="match_parent"
		android:layout_height="wrap_content"
		android:padding="16dp"
		android:background="@color/transparent_black"
		android:visibility="visible"
		android:layout_alignParentBottom="true">
		<ImageButton
			android:id="@+id/btnPlayPause"
			android:layout_width="48dp"
			android:layout_height="48dp"
			android:background="@android:color/transparent"
			android:src="@drawable/ic_pause"
			android:scaleType="center"
			android:layout_centerVertical="true" />
		<TextView
			android:id="@+id/tvCurrentTime"
			android:layout_width="wrap_content"
			android:layout_height="wrap_content"
			android:text="00:00"
			android:textSize="14sp"
			android:layout_marginStart="16dp"
			android:layout_toRightOf="@id/btnPlayPause"
			android:layout_centerVertical="true" />
		<SeekBar
			android:id="@+id/seekBar"
			android:layout_width="0dp"
			android:layout_height="wrap_content"
			android:layout_marginStart="16dp"
			android:layout_marginEnd="16dp"
			android:layout_toRightOf="@id/tvCurrentTime"
			android:layout_toLeftOf="@id/tvDuration"
			android:layout_centerVertical="true" />
		<TextView
			android:id="@+id/tvDuration"
			android:layout_width="wrap_content"
			android:layout_height="wrap_content"
			android:text="00:00"
			android:textSize="14sp"
			android:layout_alignParentRight="true"
			android:layout_centerVertical="true" />
		<ImageButton
			android:id="@+id/btnFullscreen"
			android:layout_width="48dp"
			android:layout_height="48dp"
			android:background="@android:color/transparent"
			android:src="@drawable/ic_fullscreen"
			android:scaleType="center"
			android:layout_alignParentRight="true"
			android:layout_centerVertical="true" />
	</RelativeLayout>
	<RelativeLayout
		android:id="@+id/topBar"
		android:layout_width="match_parent"
		android:background="@color/transparent_black"
		android:layout_height="?attr/actionBarSize"
		android:visibility="visible">
		<ImageButton
			android:id="@+id/btnBack"
			android:layout_width="48dp"
			android:layout_height="48dp"
			android:background="@android:color/transparent"
			android:scaleType="center"
			android:src="@android:drawable/ic_menu_close_clear_cancel"
			android:tint="@color/white"
			android:layout_centerVertical="true" />
		<TextView
			android:id="@+id/tvTitle"
			android:layout_width="wrap_content"
			android:layout_height="wrap_content"
			android:textSize="18sp"
			android:textStyle="bold"
			android:ellipsize="end"
			android:maxLines="1"
			android:layout_centerInParent="true" />
	</RelativeLayout>
</RelativeLayout>


🧱 Step 3: Video Item Layout (item_video.xml)

Ab Custom View create kare:

  • View Name: item_video.xml

Direct XML Editor open kare aur niche diya gaya code paste kare. Ye layout video gallery app android java me RecyclerView ke items ke liye use hoga.

📌 item_video.xml Code

<androidx.cardview.widget.CardView
	xmlns:android="http://schemas.android.com/apk/res/android"
	xmlns:app="http://schemas.android.com/apk/res-auto"
	xmlns:tools="http://schemas.android.com/tools"
	android:layout_width="match_parent"
	android:layout_height="wrap_content"
	android:layout_margin="4dp"
	app:cardCornerRadius="8dp"
	app:cardElevation="4dp"
	app:cardUseCompatPadding="true">
	<RelativeLayout
		android:id="@+id/relativelayout2"
		android:layout_width="match_parent"
		android:layout_height="wrap_content"
		android:padding="8dp">
		<ImageView
			android:id="@+id/ivThumbnail"
			android:focusable="false"
			android:layout_width="match_parent"
			android:layout_height="180dp"
			android:background="@color/black"
			android:src="@drawable/default_image"
			android:scaleType="centerCrop"
			android:contentDescription="Videothumbnail" />
		<TextView
			android:id="@+id/tvDuration"
			android:focusable="false"
			android:layout_width="wrap_content"
			android:layout_height="wrap_content"
			android:layout_margin="8dp"
			android:background="@color/transparent_black"
			android:textSize="12sp"
			android:paddingHorizontal="6dp"
			android:paddingVertical="2dp"
			android:layout_alignParentRight="true"
			android:layout_alignParentBottom="true" />
		<ImageView
			android:id="@+id/imageview2"
			android:focusable="false"
			android:layout_width="48dp"
			android:layout_height="48dp"
			android:src="@drawable/ic_play"
			android:scaleType="center"
			android:contentDescription="Play"
			android:layout_centerInParent="true" />
		<TextView
			android:id="@+id/tvVideoName"
			android:focusable="false"
			android:layout_width="match_parent"
			android:layout_height="wrap_content"
			android:layout_marginTop="8dp"
			android:textSize="16sp"
			android:textStyle="bold"
			android:ellipsize="end"
			android:maxLines="1"
			android:layout_below="@id/ivThumbnail" />
		<TextView
			android:id="@+id/tvVideoInfo"
			android:focusable="false"
			android:layout_width="match_parent"
			android:layout_height="wrap_content"
			android:layout_marginTop="4dp"
			android:textSize="12sp"
			android:layout_below="@id/tvVideoName" />
	</RelativeLayout>
</androidx.cardview.widget.CardView>

🎨 Step 4: Drawable Icons Add Karna

Resource Manager → drawable me ye files banaye:

  • ic_play.xml
  • ic_pause.xml
  • ic_fullscreen.xml
  • ic_fullscreen_exit.xml

📌 Drawable Code Examples

    ic_play.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="60dp"
    android:height="60dp"
    android:viewportWidth="24"
    android:viewportHeight="24"
    android:tint="?attr/colorControlNormal">
    <path
        android:fillColor="@android:color/white"
        android:pathData="M8,5.14v14l11,-7z"/>
</vector>

📌 Drawable Code Examples

   ic_fullscreen.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="60dp"
    android:height="60dp"
    android:viewportWidth="24"
    android:viewportHeight="24"
    android:tint="?attr/colorControlNormal">
    <path
        android:fillColor="@android:color/white"
        android:pathData="M7,14L5,14v5h5v-2L7,17v-3zM5,10h2L7,7h3L10,5L5,5v5zM17,17h-3v2h5v-5h-2v3zM14,5v2h3v3h2L19,5h-5z"/>
</vector>

📌 Drawable Code Examples

    ic_fullscreen_exit.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="60dp"
    android:height="60dp"
    android:viewportWidth="24"
    android:viewportHeight="24"
    android:tint="?attr/colorControlNormal">
    <path
        android:fillColor="@android:color/white"
        android:pathData="M5,16h3v3h2v-5L5,14v2zM19,8h-3L16,5h-2v5h5L19,8zM11,19v-2h2v3h-2zM8,8L5,8v2h5L10,5L8,5v3zM16,16h3v-2h-5v5h2v-3z"/>
</vector>

📌 Drawable Code Examples

    ic_pause.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="60dp"
    android:height="60dp"
    android:viewportWidth="24"
    android:viewportHeight="24"
    android:tint="?attr/colorControlNormal">
    <path
        android:fillColor="@android:color/white"
        android:pathData="M6,19h4L10,5L6,5v14zM14,5v14h4L18,5h-4z"/>
</vector>

🎨 Step 5: Colors & Theme Setup

Resource Manager → values me ye files banaye:

  • colors.xml
  • themes.xml

📌 values Code

  colors.xml

<resources>
    <color name="colorAccent">#6E72AD</color>
    <color name="colorPrimary">#6E72AD</color>
    <color name="colorPrimaryDark">#6E72AD</color>
    <color name="colorControlHighlight">#E0E0FF</color>
    <color name="colorControlNormal">#6E72AD</color>
    <color name="purple_200">#FFBB86FC</color>
    <color name="purple_500">#FF6200EE</color>
    <color name="purple_700">#FF3700B3</color>
    <color name="teal_200">#FF03DAC5</color>
    <color name="teal_700">#FF018786</color>
    <color name="black">#FF000000</color>
    <color name="white">#FFFFFFFF</color>
    <color name="gray">#808080</color>
    <color name="light_gray">#F5F5F5</color>
    <color name="transparent_black">#80000000</color>
    <color name="accent">#2196F3</color>
</resources>

📌 values Code

  themes.xml

<resources xmlns:tools="http://schemas.android.com/tools">
    <style name="Theme.VideoGalleryApp" parent="Theme.MaterialComponents.DayNight.NoActionBar">
        <item name="colorPrimary">@color/purple_500</item>
        <item name="colorPrimaryVariant">@color/purple_700</item>
        <item name="colorOnPrimary">@color/white</item>
        <item name="colorSecondary">@color/teal_200</item>
        <item name="colorSecondaryVariant">@color/teal_700</item>
        <item name="colorOnSecondary">@color/black</item>
        <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
    </style>
</resources>

💻 Step 6: Java Files Add Karna

Java/Kotlin Manager me ye files create kare:

  • MainActivity.java
  • PermissionHelper.java
  • PlayerActivity.java
  • VideoAdapter.java
  • VideoFetcher.java
  • VideoModel.java

📌 Java Code - Core Files

MainActivity


package com.video.paly;

import android.os.Bundle;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private RecyclerView recyclerView;
    private ProgressBar progressBar;
    private TextView tvEmpty;
    private VideoAdapter videoAdapter;
    private List<VideoModel> videoList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        initializeViews();
        setupRecyclerView();
        
        // Check and request permissions
        if (PermissionHelper.checkPermissions(this)) {
            loadVideos();
        } else {
            PermissionHelper.requestPermissions(this);
        }
    }
    
    private void initializeViews() {
        recyclerView = findViewById(R.id.recyclerView);
        progressBar = findViewById(R.id.progressBar);
        tvEmpty = findViewById(R.id.tvEmpty);
        
        // Set up toolbar
        androidx.appcompat.widget.Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        if (getSupportActionBar() != null) {
            getSupportActionBar().setTitle("Video Gallery");
        }
    }
    
    private void setupRecyclerView() {
        // Use GridLayoutManager for better appearance
        GridLayoutManager layoutManager = new GridLayoutManager(this, 2);
        recyclerView.setLayoutManager(layoutManager);
        
        videoAdapter = new VideoAdapter(this, videoList);
        recyclerView.setAdapter(videoAdapter);
    }
    
    private void loadVideos() {
        showLoading(true);
        
        // Run video fetching in background thread (No lambda)
        new Thread(new Runnable() {
            @Override
            public void run() {
                final List<VideoModel> fetchedVideos = VideoFetcher.getAllVideos(MainActivity.this);
                
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        videoList.clear();
                        videoList.addAll(fetchedVideos);
                        videoAdapter.notifyDataSetChanged();
                        
                        showLoading(false);
                        
                        // Show empty state if no videos found
                        if (videoList.isEmpty()) {
                            tvEmpty.setVisibility(View.VISIBLE);
                            recyclerView.setVisibility(View.GONE);
                        } else {
                            tvEmpty.setVisibility(View.GONE);
                            recyclerView.setVisibility(View.VISIBLE);
                        }
                    }
                });
            }
        }).start();
    }
    
    private void showLoading(boolean isLoading) {
        progressBar.setVisibility(isLoading ? View.VISIBLE : View.GONE);
        recyclerView.setVisibility(isLoading ? View.GONE : View.VISIBLE);
    }
    
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions,
                                          int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        
        if (PermissionHelper.handlePermissionResult(requestCode, permissions, grantResults)) {
            // Permission granted, load videos
            loadVideos();
        } else {
            // Permission denied
            tvEmpty.setText("Permission denied. Please grant storage permission.");
            tvEmpty.setVisibility(View.VISIBLE);
            showLoading(false);
        }
    }
    
    @Override
    protected void onResume() {
        super.onResume();
        // Reload videos if permission is granted
        if (PermissionHelper.checkPermissions(this)) {
            loadVideos();
        }
    }
}


PermissionHelper.java



package com.video.paly;


import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Build;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

public class PermissionHelper {

    public static final int PERMISSION_REQUEST_CODE = 1001;
    
    public static boolean checkPermissions(Activity activity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            // Android 13+ needs READ_MEDIA_VIDEO permission
            return ContextCompat.checkSelfPermission(activity,
                    Manifest.permission.READ_MEDIA_VIDEO) == PackageManager.PERMISSION_GRANTED;
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            // Android 11-12 needs READ_EXTERNAL_STORAGE for legacy
            return ContextCompat.checkSelfPermission(activity,
                    Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
        } else {
            // Android 10 and below
            return ContextCompat.checkSelfPermission(activity,
                    Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
        }
    }
    
    public static void requestPermissions(Activity activity) {
        String[] permissions;
        
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            // Android 13+
            permissions = new String[]{
                    Manifest.permission.READ_MEDIA_VIDEO
            };
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            // Android 11-12
            permissions = new String[]{
                    Manifest.permission.READ_EXTERNAL_STORAGE
            };
        } else {
            // Android 10 and below
            permissions = new String[]{
                    Manifest.permission.READ_EXTERNAL_STORAGE
            };
        }
        
        ActivityCompat.requestPermissions(activity, permissions, PERMISSION_REQUEST_CODE);
    }
    
    public static boolean handlePermissionResult(int requestCode, String[] permissions,
                                                int[] grantResults) {
        if (requestCode == PERMISSION_REQUEST_CODE) {
            return grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED;
        }
        return false;
    }
}

PlayerActivity.java



package com.video.paly;

import android.annotation.SuppressLint;
import android.content.pm.ActivityInfo;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageButton;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.VideoView;
import androidx.appcompat.app.AppCompatActivity;
import java.util.Locale;
import java.util.concurrent.TimeUnit;

public class PlayerActivity extends AppCompatActivity {

    private VideoView videoView;
    private ImageButton btnPlayPause, btnFullscreen, btnBack;
    private SeekBar seekBar;
    private TextView tvCurrentTime, tvDuration, tvTitle;
    private RelativeLayout controlsLayout, topBar;
    
    private Handler handler = new Handler();
    private Runnable updateSeekBar;
    private Runnable hideControlsRunnable;
    private boolean isPlaying = true;
    private boolean isFullscreen = false;
    private boolean isControlsVisible = true;
    private int originalOrientation;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.player);
        
        // Get video URI and title from intent
        String videoUriString = getIntent().getStringExtra("videoUri");
        String videoTitle = getIntent().getStringExtra("videoTitle");
        
        initializeViews();
        setupVideoPlayer(videoUriString, videoTitle);
        setupListeners();
        setupAutoHideControls();
        
        // Save original orientation
        originalOrientation = getRequestedOrientation();
    }
    
    private void initializeViews() {
        videoView = findViewById(R.id.videoView);
        btnPlayPause = findViewById(R.id.btnPlayPause);
        btnFullscreen = findViewById(R.id.btnFullscreen);
        btnBack = findViewById(R.id.btnBack);
        seekBar = findViewById(R.id.seekBar);
        tvCurrentTime = findViewById(R.id.tvCurrentTime);
        tvDuration = findViewById(R.id.tvDuration);
        tvTitle = findViewById(R.id.tvTitle);
        controlsLayout = findViewById(R.id.controlsLayout);
        topBar = findViewById(R.id.topBar);
    }
    
    private void setupVideoPlayer(String videoUriString, String videoTitle) {
        if (videoUriString == null || videoUriString.isEmpty()) {
            finish();
            return;
        }
        
        // Set video title
        if (videoTitle != null) {
            tvTitle.setText(videoTitle);
        }
        
        // Setup VideoView
        Uri videoUri = Uri.parse(videoUriString);
        videoView.setVideoURI(videoUri);
        
        videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp) {
                // Get video duration
                int duration = mp.getDuration();
                tvDuration.setText(formatDuration(duration));
                seekBar.setMax(duration);
                
                // Start playback
                videoView.start();
                isPlaying = true;
                btnPlayPause.setImageResource(R.drawable.ic_pause);
                
                // Start updating seekbar
                startSeekBarUpdate();
            }
        });
        
        videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                // Video completed
                isPlaying = false;
                btnPlayPause.setImageResource(R.drawable.ic_play);
                seekBar.setProgress(seekBar.getMax());
            }
        });
        
        videoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
            @Override
            public boolean onError(MediaPlayer mp, int what, int extra) {
                // Handle playback error
                finish();
                return true;
            }
        });
    }
    
    private void setupListeners() {
        // Play/Pause button
        btnPlayPause.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                togglePlayPause();
            }
        });
        
        // Fullscreen button
        btnFullscreen.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                toggleFullscreen();
            }
        });
        
        // Back button
        btnBack.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onBackPressed();
            }
        });
        
        // SeekBar listener
        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                if (fromUser) {
                    videoView.seekTo(progress);
                    tvCurrentTime.setText(formatDuration(progress));
                }
            }
            
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                handler.removeCallbacks(updateSeekBar);
                showControls();
            }
            
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                startSeekBarUpdate();
                PlayerActivity.this.startAutoHideControls();
            }
        });
        
        // VideoView click to toggle controls
        videoView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                toggleControlsVisibility();
            }
        });
    }
    
    private void togglePlayPause() {
        if (isPlaying) {
            videoView.pause();
            btnPlayPause.setImageResource(R.drawable.ic_play);
        } else {
            videoView.start();
            btnPlayPause.setImageResource(R.drawable.ic_pause);
        }
        isPlaying = !isPlaying;
        showControls();
        startAutoHideControls();
    }
    
    private void toggleFullscreen() {
        if (isFullscreen) {
            exitFullscreen();
        } else {
            enterFullscreen();
        }
        isFullscreen = !isFullscreen;
        btnFullscreen.setImageResource(isFullscreen ? 
            R.drawable.ic_fullscreen_exit : R.drawable.ic_fullscreen);
    }
    
    private void enterFullscreen() {
        // Hide status bar
        getWindow().setFlags(
            WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN
        );
        
        // Hide action bar
        if (getSupportActionBar() != null) {
            getSupportActionBar().hide();
        }
        
        // Set landscape orientation
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        
        // Adjust layout for fullscreen
        RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) videoView.getLayoutParams();
        params.width = RelativeLayout.LayoutParams.MATCH_PARENT;
        params.height = RelativeLayout.LayoutParams.MATCH_PARENT;
        videoView.setLayoutParams(params);
    }
    
    private void exitFullscreen() {
        // Show status bar
        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        
        // Show action bar
        if (getSupportActionBar() != null) {
            getSupportActionBar().show();
        }
        
        // Restore original orientation
        setRequestedOrientation(originalOrientation);
        
        // Restore video view layout
        RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) videoView.getLayoutParams();
        params.width = RelativeLayout.LayoutParams.MATCH_PARENT;
        params.height = RelativeLayout.LayoutParams.MATCH_PARENT;
        videoView.setLayoutParams(params);
    }
    
    private void toggleControlsVisibility() {
        if (isControlsVisible) {
            hideControls();
        } else {
            showControls();
        }
        isControlsVisible = !isControlsVisible;
    }
    
    private void showControls() {
        controlsLayout.setVisibility(View.VISIBLE);
        topBar.setVisibility(View.VISIBLE);
    }
    
    private void hideControls() {
        controlsLayout.setVisibility(View.GONE);
        topBar.setVisibility(View.GONE);
    }
    
    private void setupAutoHideControls() {
        hideControlsRunnable = new Runnable() {
            @Override
            public void run() {
                if (isPlaying && isFullscreen) {
                    hideControls();
                    isControlsVisible = false;
                }
            }
        };
        startAutoHideControls();
    }
    
    private void startAutoHideControls() {
        handler.removeCallbacks(hideControlsRunnable);
        handler.postDelayed(hideControlsRunnable, 3000); // Hide after 3 seconds
    }
    
    private void startSeekBarUpdate() {
        updateSeekBar = new Runnable() {
            @Override
            public void run() {
                if (videoView.isPlaying()) {
                    int currentPosition = videoView.getCurrentPosition();
                    seekBar.setProgress(currentPosition);
                    tvCurrentTime.setText(formatDuration(currentPosition));
                }
                handler.postDelayed(this, 1000); // Update every second
            }
        };
        handler.postDelayed(updateSeekBar, 1000);
    }
    
    private String formatDuration(int milliseconds) {
        long minutes = TimeUnit.MILLISECONDS.toMinutes(milliseconds);
        long seconds = TimeUnit.MILLISECONDS.toSeconds(milliseconds) - 
                      TimeUnit.MINUTES.toSeconds(minutes);
        return String.format(Locale.getDefault(), "%02d:%02d", minutes, seconds);
    }
    
    @Override
    protected void onPause() {
        super.onPause();
        handler.removeCallbacks(updateSeekBar);
        if (videoView.isPlaying()) {
            videoView.pause();
            isPlaying = false;
            btnPlayPause.setImageResource(R.drawable.ic_play);
        }
    }
    
    @Override
    protected void onResume() {
        super.onResume();
        if (!isPlaying && videoView.getDuration() > 0) {
            startSeekBarUpdate();
        }
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        handler.removeCallbacks(updateSeekBar);
        if (hideControlsRunnable != null) {
            handler.removeCallbacks(hideControlsRunnable);
        }
        videoView.stopPlayback();
    }
    
    @Override
    public void onBackPressed() {
        if (isFullscreen) {
            exitFullscreen();
            isFullscreen = false;
        } else {
            super.onBackPressed();
        }
    }
}

VideoAdapter.java



package com.video.paly;


import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.media.ThumbnailUtils;
import android.provider.MediaStore;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;

public class VideoAdapter extends RecyclerView.Adapter<VideoAdapter.ViewHolder> {

    private final Context context;
    private final List<VideoModel> videoList;

    public VideoAdapter(Context context, List<VideoModel> videoList) {
        this.context = context;
        this.videoList = videoList;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item_video, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull final ViewHolder holder, final int position) {
        final VideoModel video = videoList.get(position);
        
        // Set video name
        holder.tvVideoName.setText(video.getTitle());
        
        // Set duration
        holder.tvDuration.setText(video.getDuration());
        
        // Set video info
        String info = video.getSize() + " • " + video.getResolution();
        holder.tvVideoInfo.setText(info);
        
        // Set placeholder initially
        holder.ivThumbnail.setImageResource(android.R.color.darker_gray);
        
        // Load thumbnail using ThumbnailUtils (No Glide needed)
        new Thread(new Runnable() {
            @Override
            public void run() {
                final Bitmap thumbnail = ThumbnailUtils.createVideoThumbnail(
                        video.getPath(),
                        MediaStore.Video.Thumbnails.MINI_KIND
                );
                
                ((android.app.Activity) context).runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if (thumbnail != null) {
                            holder.ivThumbnail.setImageBitmap(thumbnail);
                        }
                    }
                });
            }
        }).start();
        
        // Set click listener (No lambda)
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(context, PlayerActivity.class);
                intent.putExtra("videoUri", video.getUri().toString());
                intent.putExtra("videoTitle", video.getTitle());
                context.startActivity(intent);
            }
        });
    }

    @Override
    public int getItemCount() {
        return videoList.size();
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        ImageView ivThumbnail;
        TextView tvVideoName, tvDuration, tvVideoInfo;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            ivThumbnail = itemView.findViewById(R.id.ivThumbnail);
            tvVideoName = itemView.findViewById(R.id.tvVideoName);
            tvDuration = itemView.findViewById(R.id.tvDuration);
            tvVideoInfo = itemView.findViewById(R.id.tvVideoInfo);
        }
    }
}

VideoFetcher.java



package com.video.paly;


import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
import java.util.ArrayList;
import java.util.List;

public class VideoFetcher {

    public static List<VideoModel> getAllVideos(Context context) {
        List<VideoModel> videoList = new ArrayList<>();
        ContentResolver contentResolver = context.getContentResolver();
        
        // Define the columns we want to retrieve
        String[] projection = {
                MediaStore.Video.Media._ID,
                MediaStore.Video.Media.TITLE,
                MediaStore.Video.Media.DURATION,
                MediaStore.Video.Media.SIZE,
                MediaStore.Video.Media.DATA,
                MediaStore.Video.Media.DATE_ADDED
        };
        
        // Sort by date added (newest first)
        String sortOrder = MediaStore.Video.Media.DATE_ADDED + " DESC";
        
        // Query the media store
        Cursor cursor = contentResolver.query(
                MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
                projection,
                null,
                null,
                sortOrder
        );
        
        if (cursor != null) {
            int idColumn = cursor.getColumnIndex(MediaStore.Video.Media._ID);
            int titleColumn = cursor.getColumnIndex(MediaStore.Video.Media.TITLE);
            int durationColumn = cursor.getColumnIndex(MediaStore.Video.Media.DURATION);
            int sizeColumn = cursor.getColumnIndex(MediaStore.Video.Media.SIZE);
            int dataColumn = cursor.getColumnIndex(MediaStore.Video.Media.DATA);
            
            if (cursor.moveToFirst()) {
                do {
                    // Get values from cursor
                    String id = cursor.getString(idColumn);
                    String title = cursor.getString(titleColumn);
                    long duration = cursor.getLong(durationColumn);
                    long size = cursor.getLong(sizeColumn);
                    String path = cursor.getString(dataColumn);
                    
                    // Create URI for the video
                    Uri videoUri = Uri.withAppendedPath(
                            MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
                            id
                    );
                    
                    // Format duration (ms to MM:SS)
                    String formattedDuration = formatDuration(duration);
                    
                    // Format size (bytes to MB)
                    String formattedSize = formatSize(size);
                    
                    // Create video model
                    VideoModel video = new VideoModel();
                    video.setId(id);
                    video.setTitle(title != null ? title : "Unknown");
                    video.setDuration(formattedDuration);
                    video.setSize(formattedSize);
                    video.setResolution("HD"); // Default resolution
                    video.setUri(videoUri);
                    video.setPath(path);
                    
                    videoList.add(video);
                    
                } while (cursor.moveToNext());
            }
            
            cursor.close();
        }
        
        return videoList;
    }
    
    private static String formatDuration(long duration) {
        if (duration <= 0) return "00:00";
        
        long seconds = duration / 1000;
        long minutes = seconds / 60;
        long hours = minutes / 60;
        
        seconds = seconds % 60;
        minutes = minutes % 60;
        
        if (hours > 0) {
            return String.format("%02d:%02d:%02d", hours, minutes, seconds);
        } else {
            return String.format("%02d:%02d", minutes, seconds);
        }
    }
    
    private static String formatSize(long size) {
        if (size <= 0) return "0 MB";
        
        float sizeInMB = size / (1024f * 1024f);
        return String.format("%.2f MB", sizeInMB);
    }
}

VideoModel.java



package com.video.paly;


import android.net.Uri;

public class VideoModel {
    private String id;
    private String title;
    private String duration;
    private String size;
    private String resolution;
    private Uri uri;
    private String path;
    private String thumbnail;

    public VideoModel() {
    }

    public VideoModel(String id, String title, String duration, String size, 
                     String resolution, Uri uri, String path, String thumbnail) {
        this.id = id;
        this.title = title;
        this.duration = duration;
        this.size = size;
        this.resolution = resolution;
        this.uri = uri;
        this.path = path;
        this.thumbnail = thumbnail;
    }

    // Getters and Setters
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDuration() {
        return duration;
    }

    public void setDuration(String duration) {
        this.duration = duration;
    }

    public String getSize() {
        return size;
    }

    public void setSize(String size) {
        this.size = size;
    }

    public String getResolution() {
        return resolution;
    }

    public void setResolution(String resolution) {
        this.resolution = resolution;
    }

    public Uri getUri() {
        return uri;
    }

    public void setUri(Uri uri) {
        this.uri = uri;
    }

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    public String getThumbnail() {
        return thumbnail;
    }

    public void setThumbnail(String thumbnail) {
        this.thumbnail = thumbnail;
    }
}

🔐 Step 7: Permissions & Libraries

Permission Manager me ye permissions add kare:

  • android.permission.READ_EXTERNAL_STORAGE (Android 12 tak)
  • android.permission.READ_MEDIA_VIDEO (Android 13+ ke liye)

Important: Ye app READ_MEDIA_VIDEO permission ka proper use karti hai jo Android 13+ me required hai. Isse aapka app modern devices par perfectly work karega.

Library Manager me:

  • AppCompat → ON
  • Design → ON

📌 Keywords Optimized Content

🏆 Featured Keywords:

Sketchware video player app banane ka ye complete tutorial hai jo Android video player source code provide karta hai. Ye project specifically design kiya gaya hai Sketchware custom video player ke liye, jisme Sketchware app without blocks ka concept use kiya gaya hai.

Video gallery app android java me mobile storage video fetch android technique ka use karke, hum MediaStore se videos fetch karte hain. Is tutorial me Sketchware media store example bhi diya gaya hai jo aapko batata hai ki kaise Android video player xml java combination se professional app banayein.

Modern Android development ke liye READ_MEDIA_VIDEO permission ka proper handling ye app sikhati hai. Agar aap Sketchware professional app banana chahte hain, to ye tutorial aapke liye perfect hai.


❓ Frequently Asked Questions (FAQ)

Q1: Kya ye app Sketchware me 100% work karegi?

Answer: Ha, bilkul! Ye pure code me hai - XML aur Java. Sketchware ke blocks ka ek bhi use nahi hai.

Q2: Android 13 par permission issue to nahi hoga?

Answer: Nahin, is app me proper READ_MEDIA_VIDEO permission handling hai jo Android 13+ ke liye designed hai.

Q3: Kya ye app large videos handle kar sakti hai?

Answer: Ha, MediaStore ki madad se sabhi size ke videos fetch ho jate hain. Player bhi large videos handle kar leta hai.

Q4: Thumbnail generation fast hai ya slow?

Answer: Fast hai! Hum ThumbnailUtils use karte hain jo Android ka built-in optimized method hai.

Q5: Kya is app ko Play Store par upload kar sakte hain?

Answer: Ha, bilkul! Ye app Play Store policies ka follow karti hai. Bas package name change karna hoga.

Q6: Video player me seek bar kaise kaam karta hai?

Answer: Seek bar video ke duration ke hisaab se update hota hai aur user ko video ke kisi bhi part me jump karne deta hai.

Q7: Kya is app me fullscreen mode hai?

Answer: Ha, fullscreen button par click karte hi video fullscreen mode me chala jata hai.

Q8: Agar Sketchware me error aaye to kya karein?

Answer: Sabse pehle check karein ki sabhi permissions add ki hain, libraries enabled hain, aur sabhi files properly create ki hain.


🚀 App Run Kare

Ab project run kare, app install kare aur permission allow karte hi aapko mobile ke sare videos gallery format me dikhne lagenge. Ye ek complete Sketchware video gallery app hai jo professionally work karti hai.


📌 Conclusion

Sketchware sirf beginners ke liye nahi hai. Agar aap XML aur Java jaante ho, to aap Sketchware me bhi professional level Android apps bana sakte ho.

Is concept se aap bana sakte ho:

  • Video Player App
  • Status Saver App
  • Private Video Locker
  • File Manager App
  • Music Player App
  • Photo Gallery App

Happy Coding 🚀

Keywords Summary: Sketchware video player app, Sketchware video gallery app, Video player app using sketchware, Sketchware app without blocks, Android video player source code, Video gallery app android java, Sketchware media store example, READ_MEDIA_VIDEO permission, Sketchware custom video player, Android video player xml java, Mobile storage video fetch android, Sketchware professional app

Post a Comment

0 Comments