📱 Capacitor MediaStore Plugin

Simple and powerful media access for your Android apps

GitHub 📦 npm
Get Started Now →

Device Support & Platform Compatibility

📱 Supported Devices

🤖

Android Devices

Full Support

  • Android 6.0+ (API 23+)
  • All phone manufacturers
  • Tablets and foldables
  • Internal & SD card storage
  • All media types supported
🍎

iOS Devices

Coming Soon

  • iPhone iOS 12+
  • iPad iPadOS 13+
  • Photos & Videos access
  • Music library integration
  • Expected Q2 2025
🌐

Web Platform

Development Only

  • Chrome, Firefox, Safari
  • Mock data for testing
  • No real file access
  • Development fallback
  • Not for production
📱 iOS Support Coming Soon! We're actively working on iOS support with full Photos framework integration.

🏆 Android Version Compatibility

Android Version API Level Support Level Features
Android 14+ API 34+ ✅ Full All features, visual media permissions
Android 13 API 33 ✅ Full Granular media permissions
Android 10-12 API 29-32 ✅ Full Scoped storage, external volumes
Android 6-9 API 23-28 ✅ Full Runtime permissions, SD card access
Android 5 API 21-22 ⚠️ Basic Limited external storage access

💝 Support This Project

Help me improve this plugin and build better tools for the community!

🤝

GitHub Sponsors

Support through GitHub's official sponsorship program:

💡 Recommended: GitHub Sponsors offers the most transparent and developer-friendly way to support open source projects.

Cryptocurrency Support

Support via crypto donations across multiple networks:

  • Bitcoin (BTC):
    bc1q2k0ftm2fgst22kzj683e8gpau3spfa23ttkg26
  • USDT (Ethereum):
    0xd6f4d8733c8C23e7bEC8Aeba37F4b3D2e93172d1
  • USDT (BNB Chain):
    0xd6f4d8733c8C23e7bEC8Aeba37F4b3D2e93172d1
  • USDT (TRON/TRC20):
    TXVy781mQ2tCuQ1BrattXWueUHp1wB5fwt
  • USDT (Solana):
    GZ8jmSUUzc4dQF7Cthj2atomvpBZWqccR81N9DL4o1Be
  • USDT (TON):
    UQAthXSNIlauj3SrzpDAU4VYxgEVV3niOSmeTPCtMBKGfEAE
💻 Why Support? Your contributions help me:
  • Upgrade to better development hardware
  • Improve my workspace and productivity
  • Dedicate more time to open source projects
  • Add iOS support and new features faster
  • Provide better documentation and examples

🤝 Other Ways to Help

⭐ Star the Project

Give us a star on GitHub to show your support!

🐛 Report Issues

Help improve the plugin by reporting bugs and suggesting features.

📖 Improve Docs

Contribute to documentation, examples, and tutorials.

💬 Spread the Word

Share the plugin with other developers who might find it useful.

What This Plugin Does

Get access to all media files on Android devices - including music, photos, videos, and files stored on SD cards. Perfect for building music players, photo galleries, and file managers.

📚 Quick Links:
⭐ View on GitHub 📦 npm Package npm install @odion-cloud/capacitor-mediastore
🎵

Music & Audio Files

Access all music files with rich metadata like artist, album, duration, and album art.

📸

Photos & Videos

Browse device photos and videos with dimensions, file sizes, and creation dates.

💾

SD Card Support

Access files stored on external SD cards and removable storage devices.

Fast & Reliable

Uses Android's native MediaStore API for fast, indexed access to media files.

Works with all Android versions! From Android 6.0 to the latest versions, with automatic permission handling.
📱 iOS Support Coming Soon! We're actively working on iOS support with full Photos framework integration.

Quick Example

// Get all music files from device (including SD card)
const music = await CapacitorMediaStore.getMediasByType({
  mediaType: 'audio',
  includeExternal: true
});

console.log(`Found ${music.totalCount} songs!`);
music.media.forEach(song => {
  console.log(`${song.title} by ${song.artist}`);
});

Getting Started

1Install the Plugin

npm install @odion-cloud/capacitor-mediastore
npx cap sync

2Add Android Permissions

Add these permissions to android/app/src/main/AndroidManifest.xml:

<!-- For Android 6-12 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" 
                 android:maxSdkVersion="32" />

<!-- For Android 13+ -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />

3iOS Setup (Optional)

If you plan to support iOS, add to ios/App/App/Info.plist:

<key>NSPhotoLibraryUsageDescription</key>
<string>This app needs access to your photos and media</string>
That's it! The plugin will automatically handle permission requests when you use it. No additional setup needed.

How to Use

1. Import the Plugin

import { CapacitorMediaStore } from '@odion-cloud/capacitor-mediastore';

2. Request Permissions

// Request all permissions
const permissions = await CapacitorMediaStore.requestPermissions();

// Or request specific types only
const audioPermission = await CapacitorMediaStore.requestPermissions({
  types: ['audio']  // Only ask for music access
});

3. Get Media Files

Get All Media

const allMedia = await CapacitorMediaStore.getMedias({
  limit: 100,              // Get first 100 files
  includeExternal: true    // Include SD card files
});

console.log(`Total files: ${allMedia.totalCount}`);

Get Specific Types

// Get all music files
const music = await CapacitorMediaStore.getMediasByType({
  mediaType: 'audio',
  sortBy: 'TITLE',
  sortOrder: 'ASC'
});

// Get all photos  
const photos = await CapacitorMediaStore.getMediasByType({
  mediaType: 'image',
  limit: 50
});

// Get all videos
const videos = await CapacitorMediaStore.getMediasByType({
  mediaType: 'video'
});

// Get documents (PDF, DOC, TXT, etc.)
const documents = await CapacitorMediaStore.getMediasByType({
  mediaType: 'document'
});

4. Access File Information

// Each file includes detailed information
music.media.forEach(song => {
  console.log('Title:', song.title);
  console.log('Artist:', song.artist);
  console.log('Album:', song.album);
  console.log('Duration:', song.duration + 'ms');
  console.log('File size:', song.size + ' bytes');
  console.log('SD Card?:', song.isExternal);
});
Remember: Always check permissions before accessing media files. The plugin will show permission dialogs automatically when needed.

Real-World Examples

🎵 Music Player App

async function createMusicLibrary() {
  // Ask for music access
  await CapacitorMediaStore.requestPermissions({ types: ['audio'] });
  
  // Get all songs (including from SD card)
  const result = await CapacitorMediaStore.getMediasByType({
    mediaType: 'audio',
    sortBy: 'TITLE',
    includeExternal: true
  });
  
  // Create playlist
  const playlist = result.media.map(song => ({
    id: song.id,
    title: song.title || 'Unknown Song',
    artist: song.artist || 'Unknown Artist',
    album: song.album || 'Unknown Album',
    duration: song.duration || 0,
    filePath: song.uri,
    isOnSDCard: song.isExternal
  }));
  
  console.log(`Created playlist with ${playlist.length} songs`);
  return playlist;
}
Output:
Created playlist with 847 songs
Song: "Bohemian Rhapsody" by Queen (SD Card: true)
Song: "Hotel California" by Eagles (SD Card: false)

📸 Photo Gallery App

async function createPhotoGallery() {
  // Ask for photo access
  await CapacitorMediaStore.requestPermissions({ types: ['images'] });
  
  // Get recent photos
  const photos = await CapacitorMediaStore.getMediasByType({
    mediaType: 'image',
    sortBy: 'DATE_ADDED',
    sortOrder: 'DESC',
    limit: 100
  });
  
  // Create gallery
  const gallery = photos.media.map(photo => ({
    id: photo.id,
    name: photo.displayName,
    size: `${photo.width}×${photo.height}`,
    fileSize: Math.round(photo.size / 1024) + ' KB',
    dateTaken: new Date(photo.dateAdded),
    thumbnailPath: photo.uri
  }));
  
  return gallery;
}

🔍 Search Music by Artist

async function findSongsByArtist(artistName) {
  const songs = await CapacitorMediaStore.getMediasByType({
    mediaType: 'audio',
    artistName: artistName,  // Filter by specific artist
    sortBy: 'TITLE'
  });
  
  console.log(`Found ${songs.totalCount} songs by ${artistName}`);
  return songs.media;
}

// Usage
const beatlesSongs = await findSongsByArtist('The Beatles');
const taylorSwiftSongs = await findSongsByArtist('Taylor Swift');

💿 Get Music Albums

async function getMusicAlbums() {
   await CapacitorMediaStore.requestPermissions({ types: ['audio'] });
   
   const albums = await CapacitorMediaStore.getAlbums();
   
   albums.albums.forEach(album => {
     console.log(`${album.name} by ${album.artist}`);
     console.log(`${album.trackCount} tracks`);
   });
   
   return albums.albums;
 }

💾 Save Media File

async function saveAudioFile(audioData, fileName) {
   await CapacitorMediaStore.requestPermissions({ types: ['audio'] });
   
   const result = await CapacitorMediaStore.saveMedia({
     data: audioData,           // Base64 encoded audio data
     fileName: fileName,        // e.g., 'my-song.mp3'
     mediaType: 'audio',
     albumName: 'My Custom Album',
     relativePath: 'MyApp/Audio'  // Optional custom folder
   });
   
   if (result.success) {
     console.log('File saved successfully at:', result.uri);
     return result.uri;
   } else {
     console.error('Save failed:', result.error);
   }
 }

🔍 Get Detailed Metadata

async function getDetailedSongInfo(fileUri) {
   const metadata = await CapacitorMediaStore.getMediaMetadata({
     filePath: fileUri
   });
   
   const song = metadata.media;
   
   console.log('🎵 Song Details:');
   console.log(`Title: ${song.title}`);
   console.log(`Artist: ${song.artist}`);
   console.log(`Album: ${song.album}`);
   console.log(`Duration: ${song.duration}ms`);
   console.log(`Bitrate: ${song.bitrate} kbps`);
   console.log(`Sample Rate: ${song.sampleRate} Hz`);
   console.log(`Channels: ${song.channels === 1 ? 'Mono' : 'Stereo'}`);
   console.log(`Genre: ${song.genre}`);
   console.log(`Year: ${song.year}`);
   
   return song;
 }

Complete API Reference

getMedias(options?)

Get all media files from the device (photos, music, videos).

getMedias({
  limit?: number;           // How many files to return
  offset?: number;          // Skip first N files (for pagination)
  sortBy?: string;          // 'DATE_ADDED', 'TITLE', 'SIZE'
  sortOrder?: 'ASC' | 'DESC'; // Sort direction
  includeExternal?: boolean;  // Include SD card files (default: true)
})
getMediasByType(options)

Get specific types of media files with filtering options.

getMediasByType({
  mediaType: 'audio' | 'image' | 'video' | 'document';
  limit?: number;
  offset?: number;
  sortBy?: string;
  sortOrder?: 'ASC' | 'DESC';
  includeExternal?: boolean;
  albumName?: string;       // Filter by album (music only)
  artistName?: string;      // Filter by artist (music only)
})
getAlbums()

Get all music albums from the device.

getAlbums(): Promise<{
  albums: {
    id: string;
    name: string;
    artist: string;
    trackCount: number;
    albumArtUri?: string;
  }[];
  totalCount: number;
}>
requestPermissions(options?)

Request permissions to access media files.

requestPermissions({
  types?: ('audio' | 'images' | 'video')[];  // Specific permission types
})
saveMedia(options)

Save a media file to device storage with proper metadata.

saveMedia({
   data: string;             // Base64 data or file URI
   fileName: string;         // Name for the file
   mediaType: 'audio' | 'image' | 'video';
   albumName?: string;       // Album to save in (optional)
   relativePath?: string;    // Custom folder path (optional)
 })
getMediaMetadata(options)

Get detailed metadata for a specific media file including audio tags.

getMediaMetadata({
   filePath: string;         // URI of the media file
 }): Promise<{
   media: MediaFile;         // File with complete metadata
 }>
checkPermissions()

Check current permission status without requesting.

checkPermissions(): Promise<PermissionStatus>

Media File Properties

Every media file returned includes these properties:

Property Type Description
id string Unique file identifier
uri string File path/URI
displayName string File name
size number File size in bytes
mimeType string File type (e.g., 'audio/mp3')
dateAdded number When file was added (timestamp)
mediaType string 'audio', 'image', 'video', etc.
isExternal boolean true if file is on SD card

Music Files Also Include:

Basic Info

  • title - Song title
  • artist - Artist name
  • album - Album name
  • duration - Length in milliseconds
  • albumArtist - Album artist
  • composer - Song composer

Extended Info

  • genre - Music genre
  • year - Release year
  • track - Track number
  • albumArtUri - Album cover image
  • bitrate - Audio bitrate
  • sampleRate - Sample rate
  • channels - Audio channels (mono/stereo)

Images & Videos Also Include:

Tip: Use includeExternal: true to access files stored on SD cards and external storage devices.