By calling Android MediaPlayer can directly complete the MP3 and other mainstream audio playback, while using contentresolver and cursor can directly read the information of the Android intrinsic database, directly get the current SDcard all the audio list, do not need to like "" Android "Memory card picture reader, library app" (Click to open the link) like using the original Java code to traverse the entire SDcard card, directly invoke the native Android class is both convenient and fast. Finally, the read-out MP3 can be loaded directly into the ListView list via the adapter, making the memory card shown below MP3 the Player app effect. This app is actually tested on your real 16G memory card.
First of all, assume that the memory card has the following 5 MP3 files, here Incidentally, the use of DDMS copy files to the memory card when note, the pro-Test found that unable to send a Chinese named file on the PC to the Android virtual machine AVD, can only send English files. Not too troublesome, you can rename the transfer, to the Android virtual machine AVD renamed again. Or use English songs directly. DDMS can be used to refer to "Android" to copy the external files on the AVD Android emulator on the SDcard, and in the AVD browse sdcard files "(Click to open the link).
After that, as shown, implement an approximate function of a MP3 player, you can adjust the volume, previous, Next, play, and so on, in the absence of selected music these buttons are disabled.
The production process is as follows:
1, first set the individual buttons and the menu font in Res\values\strings.xml as follows:
<? xml version = "1.0" encoding = "utf-8"?>
<resources>
<string name = "app_name"> Memory card mp3 player </ string>
<string name = "action_settings"> Settings </ string>
<string name = "button1"> Previous song </ string>
<string name = "button2"> Pause </ string>
<string name = "button3"> Stop </ string>
<string name = "button4"> Next song </ string>
<string name = "menu_author"> yongh701 </ string>
<string name = "menu_exit"> Exit </ string>
</ resources>
2, second, such as "Android" date picker, Time Picker and menu (click to open the link), modify the Res\menu\main.xml, set a very simple menu:
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/menu_exit"
android:title="@string/menu_exit"/>
<item android:title="@string/menu_author"/>
</menu>
3, then, due to set sdcard operation and change the system's media volume, need to Androidmanifest.xml request permission, this file modified as follows:
<? xml version = "1.0" encoding = "utf-8"?>
<manifest xmlns: android = "http://schemas.android.com/apk/res/android"
package = "com.mp3player"
android: versionCode = "1"
android: versionName = "1.0">
<uses-sdk
android: minSdkVersion = "8"
android: targetSdkVersion = "18" />
<uses-permission android: name = "android.permission.READ_EXTERNAL_STORAGE" /> <!-requires permission to read data from SDCard->
<uses-permission android: name = "android.permission.WRITE_EXTERNAL_STORAGE" /> <!-requires permission to write data to SDCard->
<uses-permission android: name = "android.permission.MODIFY_AUDIO_SETTINGS" /> <!-permission to change volume->
<application
android: allowBackup = "true"
android: icon = "@ drawable / ic_launcher"
android: label = "@ string / app_name"
android: theme = "@ style / AppTheme">
<activity
android: name = "com.mp3player.MainActivity"
android: label = "@ string / app_name">
<intent-filter>
<action android: name = "android.intent.action.MAIN" />
<category android: name = "android.intent.category.LAUNCHER" />
</ intent-filter>
</ activity>
</ application>
</ manifest>
4, after, modify the Res\layout\activity_main.xml to Mainactivity.java layout.
Thoughts such as:
Under a linear layout with a top-down vertical, two horizontal horizontal lines are laid out with a list view ListView, with widths matching the parent layout. Among them, the first horizontal horizontal line layout through the "Android" using the relative layout of the update software style as a theme dialog activity, using the Layout_weight property of the table layout of the row division (click Open link) mentioned in the way, Divide four buttons, second, in the second horizontal horizontal line layout, place a package content only, for the text to display the volume of the TextView with a progress bar seekbar. The height of these two horizontal horizontal line layouts is only the content of the parcel. The height of the last ListView directly matches the parent layout. Therefore, the code is as follows:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="@+id/button1"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="@string/button1" />
<Button
android:id="@+id/button2"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="@string/button2" />
<Button
android:id="@+id/button3"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="@string/button3" />
<Button
android:id="@+id/button4"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="@string/button4" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<SeekBar
android:id="@+id/seekBar1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
</LinearLayout>
5, finally, is the core of this app implementation, the Mainactivity.java is written, broadly divided into three parts: the code implementation of the various components, the implementation of the menu and the monitoring of the return button. The reason to listen to the return physical button is to require that the user press the back physical button to exit the program completely. When you exit the program, you also release the MediaPlayer that the app consumes, so also rewrite the Ondestory method to free up resources. Otherwise, the music played will still "very talented" after the program exits.
In the part of component code implementation, there are the following subdivision, after registering each component, you can directly utilize contentresolver Contentresolver = Getcontentresolver (); Get the data interface of the Android system, This data interface is the internal Android database, which contains a few records of the current system all media, like pictures, music, video and other information of the table, through the cursor of this database iterator, or cursor, anyway is iterator to the table to traverse, you can directly take out the media information, Take the most critical information here, without using the Java original traversal method "Java" read all the folders and files under the path "(Click Open link), iterate to find the path of each music media, resulting in a huge time complexity.
package com.mp3player;
import java.util.ArrayList;
import java.util.Collections;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.provider.MediaStore;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private MediaPlayer mediaPlayer = new MediaPlayer ();
private ListView listView1;
private ArrayList <String> audioList; // A dynamic array that stores the music path
private int currentAudioId;
private Button button1;
private Button button2;
private Button button3;
private Button button4;
private TextView textView1;
private SeekBar seekBar1;
@Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate (savedInstanceState);
setContentView (R.layout.activity_main);
// Register each component
listView1 = (ListView) findViewById (R.id.listView1);
button1 = (Button) findViewById (R.id.button1);
button2 = (Button) findViewById (R.id.button2);
button3 = (Button) findViewById (R.id.button3);
button4 = (Button) findViewById (R.id.button4);
textView1 = (TextView) findViewById (R.id.textView1);
seekBar1 = (SeekBar) findViewById (R.id.seekBar1);
// "Pause / Play" button is not available in the initial state because no music is selected
button1.setEnabled (false);
button2.setEnabled (false);
button3.setEnabled (false);
button4.setEnabled (false);
// load music resources
ContentResolver contentResolver = getContentResolver ();
Cursor cursor = contentResolver.query (
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null,
MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
audioList = new ArrayList <String> ();
for (cursor.moveToFirst ();! (cursor.isAfterLast ()); cursor.moveToNext ()) {
String path = cursor.getString (cursor
.getColumnIndexOrThrow (MediaStore.Video.Media.DATA));
audioList.add (path);
}
Collections.sort (audioList);
ArrayAdapter <String> arrayAdapter = new ArrayAdapter <String> (this,
android.R.layout.simple_list_item_1, audioList);
listView1.setAdapter (arrayAdapter);
listView1.setOnItemClickListener (new OnItemClickListener () {
@Override
public void onItemClick (AdapterView <?> arg0, View arg1,
int position, long arg3) {
currentAudioId = position;
String path = audioList.get (currentAudioId);
playMusic (path);
button1.setEnabled (true);
button3.setEnabled (true);
button4.setEnabled (true);
}
});
Toast.makeText (MainActivity.this,
"Music Loading Completed" + audioList.size () + "First Music", Toast.LENGTH_SHORT)
.show ();
// Function of adjusting the volume
final AudioManager audioManager = (AudioManager) MainActivity.this
.getSystemService (Context.AUDIO_SERVICE); // The music manager must be defined in OnCreate using the final class
MainActivity.this.setVolumeControlStream (AudioManager.STREAM_MUSIC); // Adjusts the media volume
seekBar1.setMax (audioManager
.getStreamMaxVolume (AudioManager.STREAM_MUSIC)); // Set the maximum value of the volume bar to the maximum value of the system media volume
int volume = audioManager.getStreamVolume (AudioManager.STREAM_MUSIC); // current media volume
seekBar1.setProgress (volume);
textView1.setText ("Volume:" + volume);
seekBar1.setOnSeekBarChangeListener (new OnSeekBarChangeListener () {
@Override
public void onStopTrackingTouch (SeekBar arg0) {
}
@Override
public void onStartTrackingTouch (SeekBar arg0) {
}
@Override
public void onProgressChanged (SeekBar arg0, int progress,
boolean arg2) {
textView1.setText ("Volume:" + progress);
audioManager.setStreamVolume (AudioManager.STREAM_MUSIC,
progress, AudioManager.FLAG_PLAY_SOUND); // set the volume after the change
}
});
// Click monitoring for each button
// previous song
button1.setOnClickListener (new OnClickListener () {
@Override
public void onClick (View arg0) {
currentAudioId--;
if (currentAudioId <0) {
currentAudioId = 0;
}
String path = audioList.get (currentAudioId);
playMusic (path);
}
});
// Pause / play button
button2.setOnClickListener (new OnClickListener () {
@Override
public void onClick (View arg0) {
if (mediaPlayer.isPlaying ()) {
mediaPlayer.pause ();
button2.setText ("Continue");
} else {
mediaPlayer.start ();
button2.setText ("pause");
}
}
}); // stop button
button3.setOnClickListener (new OnClickListener () {
@Override
public void onClick (View arg0) {
// TODO Auto-generated method stub
if (mediaPlayer.isPlaying ()) {
mediaPlayer.stop ();
}
button2.setEnabled (false);
button3.setEnabled (false);
}
});
// next button
button4.setOnClickListener (new OnClickListener () {
@Override
public void onClick (View arg0) {
// TODO Auto-generated method stub
currentAudioId ++;
if (currentAudioId> audioList.size ()-1) {
currentAudioId = audioList.size ()-1;
}
String path = audioList.get (currentAudioId);
playMusic (path);
}
});
} // play music
public void playMusic (String path) {
try {
if (mediaPlayer.isPlaying ()) {
mediaPlayer.stop ();
}
mediaPlayer.reset ();
mediaPlayer.setDataSource (path);
mediaPlayer.prepare ();
mediaPlayer.start ();
} catch (Exception e) {
e.printStackTrace ();
}
button2.setEnabled (true);
button2.setText ("pause");
button3.setEnabled (true);
Toast.makeText (MainActivity.this, "Play:" + path + "", Toast.LENGTH_SHORT)
.show ();
}
// When exiting the program, release the current music resources
protected void onDestroy () {
super.onDestroy ();
if (mediaPlayer.isPlaying ()) {
mediaPlayer.stop ();
}
mediaPlayer.release ();
}
// Method for creating menu. Without this method, the menu will not be set in the upper right corner.
@Override
public boolean onCreateOptionsMenu (Menu menu) {
// Set the menu interface to res \ menu \ menu.xml
getMenuInflater (). inflate (R.menu.main, menu);
return true;
}
// handle menu events
public boolean onOptionsItemSelected (MenuItem item) {
// Get the ID of the currently selected MenuItem,
int item_id = item.getItemId ();
switch (item_id) {
// Set the method to be executed for the menu child with id menu_exit.
case R.id.menu_exit:
System.exit (0); // End the program
break;
}
return true;
}
// Listen for physical buttons
@Override
public boolean onKeyDown (int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
System.exit (0);
break;
}
return super.onKeyDown (keyCode, event);
}
}
After that, for the read-out file information, the adapter is loaded directly into the ListView list. Then the monitoring of the individual buttons there is nothing to say, remember to play the music to release the music is currently playing before the new song, Android system will not cover the playback itself. There is also a need to handle an exception that fails to load music.
In the Volume Processing section, you need to create your own music manager Audiomanager, which must be defined as final in the OnCreate method, or the error will appear:
Through the music manager can get and change the current system's media volume, you can load this volume value into the progress bar, the use of the progress bar in the "Android" progress bar and the message processing between threads (click on the link) has been said, here no longer repeat.
I also got a copy of the source code to everyone: http://download.csdn.net/detail/yongh701/8932343, Welcome to exchange, last thank you to remind users of the Android system inside the database to get SDcard card media information, I'm Shengwu don't need to iterate so hard.
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
"Android" uses Android Data interface, multimedia processing to write memory card MP3 player app