Reprint Please specify source: http://blog.csdn.net/zhaokaiqiang1992
Today, an open blog, found a friend sent me a private message, ask the following questions, so close this article, for its doubts.
From this friend's question, we need to understand the following questions, in order to give him a good answer:
(1) How can I get information about all the songs in my phone?
(2) When the song file changes, such as adding and deleting operations, how to update the Media Library in a timely manner to obtain the latest song information?
(3) After the 4.4 version, scan the SD card, update the Media Library operation has changed?
Below, I will answer the above three questions.
(1) How can I get information about all the songs in my phone?
If we want to solve this problem, we must first know how to manage the song information in the Android system.
In Android, the system establishes a database (SQLite database) for multimedia types of files (compared to slices, audio, video, etc.), thus completing the maintenance of multimedia data. Of course we can not use the database of these systems, for example, if we want to get all the songs, we can scan all the files on the SD folder, and then according to the file suffix, we can take the MP3, WMA files and so on. However, this kind of operation is very inefficient, so it is not feasible.
Android system for us to build a multimedia database, then the multimedia commonly used information, such as song name, file size, play length, album, singer and other commonly used information stored in the database, we can directly use the data in the multimedia library to complete this demand. Although we need to use the multimedia library, but we can not directly operate. Android has created ContentProvider for these commonly used data that needs to be shared (multimedia and contacts, etc.), so if we want to get this information, we need to use ContentProvider.
Before you begin, give the entity class of the song you need to use first
/*** * @ClassName: Com.example.mediastore.Song * @Description: Song entity class *@authorZhaokaiqiang * @date 2014-12-4 a.m. 11:49:59 **/ Public classSong {PrivateString FileName; PrivateString title; Private intduration; PrivateString singer; PrivateString album; PrivateString Year; PrivateString type; PrivateString size; PrivateString FileUrl; PublicString GetFileName () {returnFileName; } Public voidsetfilename (String fileName) { This. FileName =FileName; } PublicString GetTitle () {returntitle; } Public voidSettitle (String title) { This. title =title; } Public intgetduration () {returnduration; } Public voidSetduration (intduration) { This. Duration =duration; } PublicString Getsinger () {returnsinger; } Public voidSetsinger (String singer) { This. Singer =singer; } PublicString getalbum () {returnalbum; } Public voidSetalbum (String album) { This. album =album; } PublicString getYear () {returnYear ; } Public voidSetyear (String year) { This. Year =Year ; } PublicString GetType () {returntype; } Public voidsetType (String type) { This. Type =type; } PublicString GetSize () {returnsize; } Public voidsetSize (String size) { This. Size =size; } PublicString Getfileurl () {returnFileUrl; } Public voidSetfileurl (String fileUrl) { This. FILEURL =FileUrl; } PublicSong () {Super(); } PublicSong (String fileName, string title,intDuration, string singer, string album, string year, String type, string size, string fileUrl) { Super(); This. FileName =FileName; This. title =title; This. Duration =duration; This. Singer =singer; This. album =album; This. Year =Year ; This. Type =type; This. Size =size; This. FILEURL =FileUrl; } @Override PublicString toString () {return"Song [filename=" + FileName + ", title=" +title+ ", duration=" + Duration + ", singer=" + singer + ", album=" + album + ", year=" + year + ", type=" + Type + ", s Ize= "+ size +", fileurl= "+ FileUrl +"] "; }}
With this information above, we can make a player completely!
With the entity class, I encapsulated a class that was specifically used to get the song information, and here's the implementation code
/*** * @ClassName: Com.example.mediastore.AudioUtils * @Description: Audio file Help class *@authorZhaokaiqiang * @date 2014-12-4 a.m. 11:39:45 **/ Public classAudioutils {/*** Get all the music files of SD card * *@return * @throwsException*/ Public StaticArraylist<song>getallsongs (Context context) {ArrayList<Song> songs =NULL; Cursor Cursor=context.getcontentresolver (). Query (MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,Newstring[] {mediastore.audio.media._id, MediaStore.Audio.Media.DISPLAY_NAME, MediaStore.Audio.Me Dia. TITLE, MediaStore.Audio.Media.DURATION, MediaStore.Audio.Media.ARTIST, MEDIASTORE.AUDIO.M Edia. ALBUM, MediaStore.Audio.Media.YEAR, MediaStore.Audio.Media.MIME_TYPE, MediaStore.Audio.Me Dia. SIZE, MediaStore.Audio.Media.DATA}, MediaStore.Audio.Media.MIME_TYPE+ "=? or "+ MediaStore.Audio.Media.MIME_TYPE +" =? ", NewString[] {"Audio/mpeg", "audio/x-ms-wma"},NULL); Songs=NewArraylist<song>(); if(Cursor.movetofirst ()) {Song Song=NULL; Do{Song=NewSong (); //file nameSong.setfilename (cursor.getstring (1)); //Song nameSong.settitle (Cursor.getstring (2)); //Length of TimeSong.setduration (Cursor.getint (3)); //Name of singerSong.setsinger (Cursor.getstring (4)); //Album nameSong.setalbum (Cursor.getstring (5)); //years if(Cursor.getstring (6)! =NULL) {song.setyear (cursor.getstring (6)); } Else{song.setyear (Unknown); } //Song Format if("Audio/mpeg". Equals (Cursor.getstring (7). (Trim ())) {Song.settype ("MP3"); } Else if("Audio/x-ms-wma". Equals (Cursor.getstring (7). (Trim ())) {Song.settype ("WMA"); } //File Size if(Cursor.getstring (8)! =NULL) { floatSize = Cursor.getint (8)/1024f/1024f; Song.setsize ((Size+ ""). Substring (0, 4) + "M"); } Else{song.setsize (Unknown); } //file path if(Cursor.getstring (9)! =NULL) {Song.setfileurl (cursor.getstring (9)); } songs.add (song); } while(Cursor.movetonext ()); Cursor.close (); } returnsongs; }}
The idea of the code is simple, we need to get a cursor based on contentresover, and then iterate through all of the song's information based on this cursor. In the above code, we have found a total of 10 data including song name, path, file size, etc., which is sufficient for the general application. After querying, we convert the information into entity classes, which makes it easier to operate.
If you want to use this tool class, remember to add permissions <uses-permission android:name= "Android.permission.READ_EXTERNAL_STORAGE"/>
(2) How to update the Media Library in time
When the Android system refreshes the data of the Media Library, it is at the time of boot, that is, when the phone is switched on, the system will rescan the SD card and update the multimedia database. If a user deletes an audio file and does not reboot, the data in the database is not updated. So, if we want users to open the software, forcing the update of the multimedia database, what should be done?
Before the 4.4 release, we can force the Media Library to be refreshed by sending a broadcast
New Intentfilter ( intent.action_media_scanner_started); Intentfilter.addaction (intent.action_media_scanner_finished); Intentfilter.adddatascheme ("file"); Sendbroadcast (new Intent (intent.action_media_mounted, uri.parse ("file://" + environment.getexternalstoragedirectory () . GetAbsolutePath ( )));
After you send a broadcast, you also need to register a broadcast recipient to accept and process the scan start and end events
private class scanreceiver extends Broadcastreceiver { public void OnReceive (context context, Intent Intent) {String action = Intent.getaction (); // When the system starts scanning the SD card, you can add a wait box for the user experience if (Intent.action_media_scanner_ Started.equals (action) {} // When the system scan is complete , stop displaying the wait box and requery contentprovider if ( Intent.ACTION_MEDIA_SCANNER_FINISHED.equals (ACTION)) {}}}
In this way, we can force the Media Library to be updated.
However, after 4.4, Android has increased permissions on some operations, and if you use this method on a 4.4 system, the following error will occur
caused By:java.lang.SecurityException:Permission Denial:not allowed to send broadcast android.intent.action.MEDIA_ Mounted from pid=22360, uid=10163
This is because after 4.4, this broadcast can only be issued by the system application, so we can't use this method, we could use the following code to achieve the same function:
Mediascannerconnection.scanfile (Thisnew string[] {environment null Null);
Using Mediascannerconnection's Scanfile method, we can force scan the file path we need to update, and then the media database will be updated synchronously, so that there will be no file deletion, in the Media Library can search for the situation, can also solve the new song that the friend raised the information acquisition problem.
"Android Development experience" How to get all the audio file information in the library, and update the Media Library (go) after adding and deleting files