How to update MediaStore on Android?

It started as a general user question on Android forums. However, it became, of necessity, a programming issue. Here is my problem.

Android has a service - MediaScanner - that runs in the background at any time (I think), the SD card is not mounted and is installed again. This service collects data about all the media files on the map and provides SQLite DB that can be requested by music applications. Most music apps use this service because it saves battery power associated with scanning an SD card.

Since I started using android, I constantly had a problem where M3U playlists synchronized with the device remain in this SQLite DB even after deleting from the SD card. This went so far that I now have a collection of approximately 40 playlists that appear in any music application that I use, despite the fact that there are only about 10 m3u files on the map. The rest of the playlists do not play, and they are empty. I can delete them manually by deleting them from the music application, but I'm tired of it. There must be a better way to remove these ghost playlists.

There are two applications on the Android Market - SDRescan and Music Scanner, which supposedly do just that, but none of them work.

I started writing my own application to update or delete the MediaStore database and start from scratch, but I'm not very far away. I have an Android app that runs the following code:

sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory()))); 

I found some examples of this code online as a way to scan an SD card, but I had no luck with that. Any tips?

FULL CODE:

 package com.roryok.MediaRescan; import android.app.Activity; import android.content.Intent; import android.content.IntentFilter; import android.net.Uri; import android.os.Bundle; import android.os.Environment; public class MediaRescan extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory()))); setContentView(R.layout.main); } //Rescan the sdcard after copy the file private void rescanSdcard() throws Exception{ Intent scanIntent = new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())); IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_SCANNER_STARTED); intentFilter.addDataScheme("file"); sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory()))); } } 
+50
android mediastore
Jul 21 '10 at 14:11
source share
3 answers

Ok, I did it.

Instead of checking the map again, the application iterates through all the playlists in the media star and checks the length of the _data field. I found that for all lists without an associated M3U file, this field was always empty. Then it was just a case of searching for the source code for the original Android Android application, searching for the deletion method and using it to delete any playlists with a length of 0. I renamed the PlaylistPurge application (since it does not โ€œre-scanโ€) and I send the code below.

I will probably also post this somewhere in the market or on my own website, http://roryok.com

 package com.roryok.PlaylistPurge; import java.util.ArrayList; import java.util.List; import android.app.ListActivity; import android.content.ContentUris; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.provider.MediaStore; import android.widget.ArrayAdapter; import android.widget.ListAdapter; public class PlaylistPurge extends ListActivity { private List<String> list = new ArrayList<String>(); private final String [] STAR= {"*"}; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ListAdapter adapter = createAdapter(); setListAdapter(adapter); } /** * Creates and returns a list adapter for the current list activity * @return */ protected ListAdapter createAdapter() { // return play-lists Uri playlist_uri= MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI; Cursor cursor= managedQuery(playlist_uri, STAR, null,null,null); cursor.moveToFirst(); for(int r= 0; r<cursor.getCount(); r++, cursor.moveToNext()){ int i = cursor.getInt(0); int l = cursor.getString(1).length(); if(l>0){ // keep any playlists with a valid data field, and let me know list.add("Keeping : " + cursor.getString(2) + " : id(" + i + ")"); }else{ // delete any play-lists with a data length of '0' Uri uri = ContentUris.withAppendedId(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI, i); getContentResolver().delete(uri, null, null); list.add("Deleted : " + cursor.getString(2) + " : id(" + i + ")"); } } cursor.close(); // publish list of retained / deleted playlists ListAdapter adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, list); return adapter; } } 

UPDATE:

Here is a link to a post on my blog about the application http://roryok.com/blog/index.php/2010/07/23/clearing-out-deleted-playlists-in-android/

UPDATE 2: Tuesday April 9, 2013

I got a lot of traffic on my blog from this post and a lot of letters from people who thanked me for this. Glad it helped! Any potential users should know that my crappy app is crashing as soon as you launch it, but actually doing what it should do! I was always going to come back and correct this destructive behavior and put it on the market, I hope 2013 will be the year I do it.

+17
Jul 22 2018-10-22T00:
source share

Here is a simple single file solution:

Whenever you add a file, let the MediaStore Content Provider know about it using

 sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(imageAdded))); 

To remove : just use getContentResolver (). delete (uri, null, null) (credit is sent by DDSports )

+48
Feb 13 '13 at 8:52
source share

You can request rescan of certain files with the following code.

NOTE. The transmitted MIME TYPE is important. I noticed that changes made to MP3 ID3 tags did not update properly in SQLite if I used "* / *", however using "audio / mp3" worked

 MediaScannerConnection.scanFile( context, new String[]{ pathToFile1, pathToFile2 }, new String[]{ "audio/mp3", "*/*" }, new MediaScannerConnectionClient() { public void onMediaScannerConnected() { } public void onScanCompleted(String path, Uri uri) { } }); 
+12
Dec 19 '12 at 22:57
source share



All Articles