首先service的啟動方式有兩種,Context.startService()方式啟動和Context.bindService()方式啟動.前者如果你的程序退出時不停止Service,它會在后臺一直運行.后者是跟你的程序綁定了,你的程序退出時Service也停止了.詳細(xì)的你去查一下.用Service的好處就是當(dāng)你的程序進(jìn)入后臺時,不影響音樂的播放.如果沒有把播放音樂寫在Service中當(dāng)你的播放器進(jìn)入后臺或者退出時音樂就停止了.
在長寧等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計 網(wǎng)站設(shè)計制作按需求定制制作,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),成都品牌網(wǎng)站建設(shè),全網(wǎng)整合營銷推廣,外貿(mào)網(wǎng)站建設(shè),長寧網(wǎng)站建設(shè)費用合理。
下面把具體編譯步驟描述如下,假定NDK安裝在~/android-ndk-r7:
1. 首先從FFmpeg官網(wǎng)下載最新的release版本源碼ffmpeg-0.11.tar.gz解壓縮到Android源碼樹的ffmpeg/下。
2 準(zhǔn)備一個編譯腳本build_android.sh并放在ffmpeg/下面,這個腳本也是Rockplayer提供的,需做一些修改,其內(nèi)容附在后面。我目前用的也會附在后面。
3 在ffmpeg目錄下運行./build_android.sh開始編譯FFmpeg,編譯好的libffmpeg.so會放在文件夾android里面,一共有3個版本分別對應(yīng)3種ARM體系結(jié)構(gòu),包括armv7-a、armv7-a-vfp、armv6_vfp,根據(jù)所運行的硬件平臺選取其中一個版本。為了編譯使用FFmpeg的程序時可以方便地找到libffmpeg.so,可將它復(fù)制到$OUT/system/lib/和$OUT/obj/lib/,當(dāng)然這一步也可以加在build_android.sh中做。
4. 接下來就是編譯可執(zhí)行文件ffmpeg了,這個工具可以在命令行下完成FFmpeg提供的幾乎所有功能包括編碼、解碼、轉(zhuǎn)碼等,也是用來調(diào)試和驗證很有用的工具。其實上述編譯完后在$ANDROID_BUILD_TOP/external/ffmpeg/下也會生成ffmpeg,但是在設(shè)備上無法運行。為了編出能在設(shè)備上運行的ffmpeg,可以寫一個簡單的Android.mk,
package my.android.players;
import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.TextView;
public class mainActivity extends Activity {
private ListString myMusicList=new ArrayListString();
//當(dāng)前播放歌曲的索引
private int currentListItem=0;
//音樂的路徑
private static final String MUSIC_PATH="/sdcard/mp3";
//播放對象
private MediaPlayer myMediaPlayer;
private TextView m_TextView;
//播放按鈕
private ImageButton m_start;
private ImageButton m_stop;
private ImageButton m_next;
private ImageButton m_last;
/*設(shè)定bIsPaused一開始為false */
private boolean bIsRun = false;
private boolean isplay;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main2);
myMediaPlayer=new MediaPlayer();
musicList();
m_TextView=(TextView)findViewById(R.id.mtextview);
m_start=(ImageButton)findViewById(R.id.imgbtn_start);
m_stop=(ImageButton)findViewById(R.id.imgbtn_stop);
m_next=(ImageButton)findViewById(R.id.imgbtn_next);
m_last=(ImageButton)findViewById(R.id.imgbtn_last);
listener();
Intent intent = this.getIntent();
Bundle bundle = intent.getExtras();
currentListItem = bundle.getInt("currentListItem");
isplay=bundle.getBoolean("isplay");
if(isplay==true)
{
bIsRun=false;
playMusic(MUSIC_PATH+"/"+myMusicList.get(currentListItem));
}
}
//監(jiān)聽事件
void listener(){
//開始
m_start.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
try
{
if(myMediaPlayer.isPlaying()==true)
{
myMediaPlayer.pause();
m_start.setImageResource(R.drawable.pause);
}
else
{
playMusic(MUSIC_PATH+"/"+myMusicList.get(currentListItem));
}
}
catch (IllegalStateException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
//下一首
m_next.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
nextMusic();
}
});
//上一首
m_last.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
lastMusic();
}
});
//停止
m_stop.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
stopMusic();
}
});
myMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
nextMusic();
}
});
}
//播放音樂
void playMusic(String path){
try {
if(bIsRun==false)
{
myMediaPlayer.reset();
myMediaPlayer.setDataSource(path);
myMediaPlayer.prepare();
myMediaPlayer.start();
/*
* 取出歌曲名的.mp3后綴
* */
String str=(myMusicList.get(currentListItem)).toString();
System.out.println(str);
String str1[]=str.split("\\.");
System.out.println(str1[0]);
m_TextView.setText(str1[0]);
}
else
{
myMediaPlayer.start();
}
m_start.setImageResource(R.drawable.start);
bIsRun=true;
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
//下一首
void nextMusic(){
if(++currentListItem=myMusicList.size()){
currentListItem=0;
}
bIsRun=false;
playMusic(MUSIC_PATH+"/"+myMusicList.get(currentListItem));
}
//上一首
void lastMusic(){
if(--currentListItem0)
currentListItem=myMusicList.size()-1;
bIsRun=false;
playMusic(MUSIC_PATH+"/"+myMusicList.get(currentListItem));
}
//停止
void stopMusic() {
if (myMediaPlayer.isPlaying()) {
m_start.setImageResource(R.drawable.pause);
myMediaPlayer.stop();// 停止
bIsRun=false;
}
else
playMusic(MUSIC_PATH+"/"+myMusicList.get(currentListItem));
}
//當(dāng)用戶返回時結(jié)束音樂并釋放音樂對象
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if(keyCode==KeyEvent.KEYCODE_BACK){
new AlertDialog.Builder(mainActivity.this).setTitle("message")
.setIcon(android.R.drawable.dialog_frame)
.setMessage("你確定要離開嗎?")
.setPositiveButton("確定",new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
myMediaPlayer.stop();
myMediaPlayer.release();
finish();
}
}).setNegativeButton("取消",new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
}).show();
}
return super.onKeyDown(keyCode, event);
}
/**
* 文件過濾器
*
* @author
*
*/
class MusicFilter implements FilenameFilter {
@Override
public boolean accept(File dir, String filename) {
return (filename.endsWith(".mp3"));
}
}
//綁定音樂
void musicList(){
try{
File home=new File(MUSIC_PATH);
if(!home.exists())
home.mkdirs();
if(home.listFiles(new MusicFilter()).length=0){
for(File file:home.listFiles(new MusicFilter())){
myMusicList.add(file.getName().toString());
}
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}
package my.android.players;
import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class Activity01 extends Activity {
//播放列表
private ListString myMusicList=new ArrayListString();
//當(dāng)前播放歌曲的索引
private int currentListItem;
//音樂的路徑
private static final String MUSIC_PATH="/sdcard/mp3";
//播放列表
private ListView m_ListView;
private boolean isplay=true;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
m_ListView=(ListView)findViewById(R.id.lv_music);
musicList();
//當(dāng)選擇列表項時播放音樂
m_ListView.setOnItemClickListener(new ListView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView? arg0, View arg1, int arg2,
long arg3) {
currentListItem = arg2;
Intent intent = new Intent();
Bundle mBundle=new Bundle();
mBundle.putInt("currentListItem", currentListItem);
mBundle.putBoolean("isplay", isplay);
intent.putExtras(mBundle);
intent.setClass(Activity01.this,mainActivity.class);
startActivity(intent);
finish();
}
});
}
/**
* 文件過濾器
*
* @author
*
*/
class MusicFilter implements FilenameFilter {
@Override
public boolean accept(File dir, String filename) {
return (filename.endsWith(".mp3"));
}
}
//綁定音樂
void musicList(){
try{
File home=new File(MUSIC_PATH);
if(!home.exists())
home.mkdirs();
if(home.listFiles(new MusicFilter()).length=0){
for(File file:home.listFiles(new MusicFilter())){
myMusicList.add(file.getName().toString());
}
ArrayAdapterString musicList=new ArrayAdapterString
(Activity01.this,android.R.layout.simple_list_item_1, myMusicList);
m_ListView.setAdapter(musicList);
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}
我的答案絕對OK,1. 設(shè)置-》應(yīng)用程序-》管理應(yīng)用程序-》所有應(yīng)用程序-》搜索到“媒體存儲”-》執(zhí)行“清除數(shù)據(jù)”
2. 重啟系統(tǒng),打開音樂播放器,等待媒體存儲數(shù)據(jù)庫重新加載
嚴(yán)格來說,線程是共享資源的,所以線程之間是不存在通信的,Android里面的Handle是用來解決異步調(diào)用的,這個觀念很重要,想明白了,代碼也就寫的更合理了。
進(jìn)程之間內(nèi)存等資源是隔離的,而AIDL,是Android提供的跨進(jìn)程通信IPC工具Binder的具體使用方法,跟其他Linux跨進(jìn)程通信(socket,管道,能存共享等)在概念上沒啥差。所以要實現(xiàn)跨進(jìn)程的內(nèi)存訪問(比如數(shù)據(jù)傳輸,函數(shù)跨進(jìn)程同步調(diào)用等)就需要了AIDL了,當(dāng)然了AIDL并不是Android中跨進(jìn)程通信的唯一選擇,socket(systemServer進(jìn)程與zygote進(jìn)程,pkms調(diào)用install進(jìn)程,MountService與vold進(jìn)程通信都是通過socket),共享內(nèi)存(sqlite3查詢就用了)等都可以用的,但是沒有Binder通過AIDL好用罷了。
下面這個例子是使用service和broadcastReceiver實現(xiàn)的簡單音樂播放器,麻雀雖小,五臟俱全,百度搜索安卓無憂,點擊源碼看源碼,你看演示:
MusiceService代碼
package?mm.shandong.com.testsimplemedia.service;??
import?android.app.Service;??
import?android.content.BroadcastReceiver;??
import?android.content.Context;??
import?android.content.Intent;??
import?android.content.IntentFilter;??
import?android.content.res.AssetFileDescriptor;??
import?android.content.res.AssetManager;??
import?android.media.MediaPlayer;??
import?android.os.IBinder;??
public?class?MusicService?extends?Service?{??
int?currentMusic?=?0;//0表示沒有音樂播放,1表示暫停,2表示正在播放,??
int?status;??
MediaPlayer?mp;??
String[]?musics?=?new?String[]{"first.mp3",?"second.mp3",?"third.mp3"};??
AssetManager?am;??
public?MusicService()?{??
}??
@Override??
public?void?onCreate()?{??
am?=?getAssets();??
mp?=?new?MediaPlayer();??
mp.setOnCompletionListener(new?MediaPlayer.OnCompletionListener()?{??
@Override??
public?void?onCompletion(MediaPlayer?mediaPlayer)?{??
currentMusic++;??
currentMusic?=?currentMusic?%?musics.length;??
playMusic();??
status?=?2;??
Intent?intentTemp?=?new?Intent("Update_Music_State");??
intentTemp.putExtra("status",?status);??
intentTemp.putExtra("currentMusic",?currentMusic);??
sendBroadcast(intentTemp);??
}??
});??
IntentFilter?intentFilter?=?new?IntentFilter();??
intentFilter.addAction("Get_Music_Control");??
///動態(tài)注冊播放器變化的廣播接收者??
MusicServiceReceiver?musicServiceReceiver?=?new?MusicServiceReceiver();??
registerReceiver(musicServiceReceiver,?intentFilter);??
super.onCreate();??
}??
public?class?MusicServiceReceiver?extends?BroadcastReceiver?{??
@Override??
public?void?onReceive(Context?context,?Intent?intent)?{??
int?control?=?intent.getIntExtra("control",?0);??
switch?(control)?{??
case?0:??
//暫停??
if?(status?==?2)?{??
mp.pause();??
status?=?1;??
}??
break;??
case?1:??
///播放??
if?(status?==?0)?{??
playMusic();??
status?=?2;??
}?else?if?(status?==?1)?{??
mp.start();??
status?=?2;??
}??
break;??
case?3:??
break;??
case?4:??
//上一首??
if?(status?==?0)?{??
if?(currentMusic?==?0)?{??
currentMusic?=?2;??
}?else?{??
currentMusic--;??
}??
}?else?if?(status?==?1)?{??
if?(currentMusic?==?0)?{??
currentMusic?=?2;??
}?else?{??
currentMusic--;??
}??
status?=?0;??
}?else?if?(status?==?2)?{??
if?(currentMusic?==?0)?{??
currentMusic?=?2;??
}?else?{??
currentMusic--;??
}??
playMusic();??
}??
break;??
case?5:??
//下一首??
if?(status?==?0)?{??
if?(currentMusic?==?2)?{??
currentMusic?=?0;??
}?else?{??
currentMusic++;??
}??
}?else?if?(status?==?1)?{??
if?(currentMusic?==?2)?{??
currentMusic?=?0;??
}?else?{??
currentMusic++;??
}??
status?=?0;??
}?else?if?(status?==?2)?{??
if?(currentMusic?==?2)?{??
currentMusic?=?0;??
}?else?{??
currentMusic++;??
}??
playMusic();??
}??
break;??
}??
Intent?intentTemp?=?new?Intent("Update_Music_State");??
intentTemp.putExtra("status",?status);??
intentTemp.putExtra("currentMusic",?currentMusic);??
sendBroadcast(intentTemp);??
}??
}??
@Override??
public?IBinder?onBind(Intent?intent)?{??
//?TODO:?Return?the?communication?channel?to?the?service.??
throw?new?UnsupportedOperationException("Not?yet?implemented");??
}??
public?void?playMusic()?{??
try?{??
AssetFileDescriptor?ad?=?am.openFd(musics[currentMusic]);??
mp.reset();??
mp.setDataSource(ad.getFileDescriptor(),?ad.getStartOffset(),?ad.getLength());??
//??mp.create(this,musics[currentMusic]);??
mp.prepare();??
mp.start();??
}?catch?(Exception?e)?{??
e.printStackTrace();??
}??
}??
}
activity代碼:
package?mm.shandong.com.testsimplemedia;??
import?android.content.BroadcastReceiver;??
import?android.content.Context;??
import?android.content.Intent;??
import?android.content.IntentFilter;??
import?android.support.v7.app.AppCompatActivity;??
import?android.os.Bundle;??
import?android.view.View;??
import?android.widget.ImageButton;??
import?android.widget.TextView;??
import?mm.shandong.com.testsimplemedia.service.MusicService;??
public?class?TestSimpleMediaActivity?extends?AppCompatActivity?{??
ImageButton?imageButton;??
TextView?textViewMp3Name;??
TextView?textViewMp3Author;??
int?status?=?0;??
String[]?authors?=?new?String[]{"張三",?"李四",?"王二"};??
String[]?names?=?new?String[]{"first",?"second",?"thrid"};??
int?currentMusic?=?0;??
@Override??
protected?void?onCreate(Bundle?savedInstanceState)?{??
super.onCreate(savedInstanceState);??
setContentView(R.layout.activity_test_simple_media);??
imageButton?=?(ImageButton)?findViewById(R.id.imageButton);??
textViewMp3Name?=?(TextView)?findViewById(R.id.textViewMp3Name);??
textViewMp3Author?=?(TextView)?findViewById(R.id.textViewMp3Author);??
imageButton.setOnClickListener(new?View.OnClickListener()?{??
@Override??
public?void?onClick(View?view)?{??
Intent?intent?=?new?Intent("Get_Music_Control");??
if?(status?==?2)?{??
intent.putExtra("control",?0);??
}?else?{??
intent.putExtra("control",?1);??
}??
sendBroadcast(intent);??
}??
});??
IntentFilter?intentFilter?=?new?IntentFilter();??
intentFilter.addAction("Update_Music_State");??
MusicStatusReceiver?musicStatusReceiver?=?new?MusicStatusReceiver();??
//動態(tài)注冊activity變化的廣播接收者??
registerReceiver(musicStatusReceiver,?intentFilter);??
Intent?intent?=?new?Intent(this,?MusicService.class);??
startService(intent);??
Intent?intentMusicReceiver?=?new?Intent("Get_Music_Control");??
intentMusicReceiver.putExtra("control",?3);??
sendBroadcast(intentMusicReceiver);??
}??
///上一首??
public?void?preMusic(View?view)?{??
Intent?intentMusicReceiver?=?new?Intent("Get_Music_Control");??
intentMusicReceiver.putExtra("control",?4);??
sendBroadcast(intentMusicReceiver);??
}??
///下一首??
public?void?nextMusic(View?view)?{??
Intent?intentMusicReceiver?=?new?Intent("Get_Music_Control");??
intentMusicReceiver.putExtra("control",?5);??
sendBroadcast(intentMusicReceiver);??
}??
///定義操作音樂的廣播接收者??
public?class?MusicStatusReceiver?extends?BroadcastReceiver?{??
@Override??
public?void?onReceive(Context?context,?Intent?intent)?{??
status?=?intent.getIntExtra("status",?0);??
currentMusic?=?intent.getIntExtra("currentMusic",?0);??
switch?(status)?{??
case?0:??
textViewMp3Name.setText(names[currentMusic]);??
textViewMp3Author.setText(authors[currentMusic]);??
imageButton.setBackgroundResource(R.drawable.play32);??
break;??
case?1:??
textViewMp3Name.setText(names[currentMusic]);??
textViewMp3Author.setText(authors[currentMusic]);??
imageButton.setBackgroundResource(R.drawable.play32);??
break;??
case?2:??
imageButton.setBackgroundResource(R.drawable.pause32);??
textViewMp3Name.setText(names[currentMusic]);??
textViewMp3Author.setText(authors[currentMusic]);??
break;??
}??
}??
}??
}
最后,您覺得回答滿意的話,請關(guān)注一下我的微博,我的名字除了中文以外的。