android本地音乐播放(二)

MainActivity 代码

package cn.tedu.music_player_2.activity;

import java.util.List;

import android.app.Activity;

import android.content.ComponentName;

import android.content.Intent;

import android.content.ServiceConnection;

import android.os.Bundle;

import android.os.IBinder;

import android.util.Log;

import android.view.View;

import android.widget.AdapterView;

import android.widget.AdapterView.OnItemClickListener;

import android.widget.SeekBar.OnSeekBarChangeListener;

import android.widget.ImageButton;

import android.widget.ListView;

import android.widget.SeekBar;

import android.widget.TextView;

import cn.tedu.music_player_2.R;

import cn.tedu.music_player_2.adapter.MusicAdapter;

import cn.tedu.music_player_2.app.MusicPlayerApplication;

import cn.tedu.music_player_2.entity.Music;

import cn.tedu.music_player_2.service.PlayMusicService;

import cn.tedu.music_player_2.util.CommonUtils;

import cn.tedu.music_player_2.util.IMusicPlayer;

/**

* MainActivity

*

* @author chengheng

* @version 2.0

*/

public class MainActivity extends Activity implements View.OnClickListener,

OnItemClickListener, OnSeekBarChangeListener {

/**

* ListView:歌曲列表

*/

private ListView lvMusics;

/**

* ImageButton:播放或暂停

*/

private ImageButton ibPlayOrPause;

/**

* ImageButton:播放上一首

*/

private ImageButton ibPrevious;

/**

* ImageButton:播放下一首

*/

private ImageButton ibNext;

/**

* TextView:显示当前播放的歌曲的名称

*/

private TextView tvMusicTitle;

/**

* SeekBar:歌曲的播放进度

*/

private SeekBar sbMusicProgress;

/**

* TextView:歌曲当前播放到的时间

*/

private TextView tvMusicCurrentPosition;

/**

* TextView:当前播放的歌曲的时长

*/

private TextView tvMusicDuration;

/**

* 歌曲数据的List集合

*/

private List musics;

/**

* 歌曲列表的Adapter

*/

private MusicAdapter musicAdapter;

/**

* Application

*/

private MusicPlayerApplication app;

/**

* ServiceConnection:Activity与Service建立的连接

*/

private InnerServiceConnection conn;

/**

* 当Activity与Service连接后,调用Service方法的工具

*/

private IMusicPlayer player;

/**

* 更新歌曲播放信息的线程

*/

private UpdateProgressThread updateProgressThread;

/**

* 播放器是否已经开始运行

*/

private boolean isPlayerWorking;

/**

* 用户是否正在拖拽进度条

*/

private boolean isUserTrackingTouch;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // 绑定Service
    Intent intent = new Intent(this, PlayMusicService.class);
    conn = new InnerServiceConnection();
    bindService(intent, conn, BIND_AUTO_CREATE);

    // 初始化控件
    lvMusics = (ListView) findViewById(R.id.lv_musics);
    ibPlayOrPause = (ImageButton) findViewById

(R.id.ib_play_or_pause);

ibPrevious = (ImageButton) findViewById(R.id.ib_previous);

ibNext = (ImageButton) findViewById(R.id.ib_next);

tvMusicTitle = (TextView) findViewById(R.id.tv_music_title);

sbMusicProgress = (SeekBar) findViewById(R.id.sb_music_progress);

tvMusicCurrentPosition = (TextView) findViewById

(R.id.tv_music_current_position);

tvMusicDuration = (TextView) findViewById

(R.id.tv_music_duration);

    // 获取歌曲列表的数据
    app = (MusicPlayerApplication) getApplication();
    musics = app.getMusics();

    // 显示歌曲列表的ListView
    musicAdapter = new MusicAdapter(this, musics);
    lvMusics.setAdapter(musicAdapter);

    // 为按钮配置监听器
    ibPlayOrPause.setOnClickListener(this);
    ibPrevious.setOnClickListener(this);
    ibNext.setOnClickListener(this);

    // 为ListView配置监听器
    lvMusics.setOnItemClickListener(this);

    // 为SeekBar配置监听器
    sbMusicProgress.setOnSeekBarChangeListener(this);
}

@Override
protected void onRestart() {
    // 判断是否正在播放
    if(player.callIsPlaying()) {
        // 开启线程更新播放信息
        startUpdateProgressThread();
    }

    super.onRestart();
}

@Override
protected void onStop() {
    // 停止更新播放信息
    stopUpdateProgressThread();

    super.onStop();
}

@Override
protected void onDestroy() {
    // 解除与Service的绑定
    if (conn != null) {
        unbindService(conn);
    }

    super.onDestroy();
}

@Override
public void onClick(View v) {
    switch (v.getId()) {
    case R.id.ib_play_or_pause:
        // 判断当前的状态
        if (player.callIsPlaying()) {
            // 正在播放,则暂停
            player.callPause();
            // 更换按钮图片:换为“播放”
            ibPlayOrPause.setImageResource

(android.R.drawable.ic_media_play);

// 停止更新歌曲播放信息

stopUpdateProgressThread();

} else {

// 没有播放,则播放

player.callPlay();

// 更换按钮图片:换为“暂停”

ibPlayOrPause.setImageResource

(android.R.drawable.ic_media_pause);

// 开启线程,更新播放信息

startUpdateProgressThread();

// 更新标识:播放器开始工作

isPlayerWorking = true;

}

break;

    case R.id.ib_previous:
        // 播放上一首
        player.callPrevious();
        // 更换按钮图片:换为“暂停”
        ibPlayOrPause.setImageResource

(android.R.drawable.ic_media_pause);

// 开启线程,更新播放信息

startUpdateProgressThread();

// 更新标识:播放器开始工作

isPlayerWorking = true;

break;

    case R.id.ib_next:
        // 播放下一首
        player.callNext();
        // 更换按钮图片:换为“暂停”
        ibPlayOrPause.setImageResource

(android.R.drawable.ic_media_pause);

// 开启线程,更新播放信息

startUpdateProgressThread();

// 更新标识:播放器开始工作

isPlayerWorking = true;

break;

}

}

@Override
public void onItemClick(AdapterView<?> parent, View view, int position,

long id) {

// 播放指定的歌曲

player.callPlay(position);

// 更换按钮图片:换为“暂停”

ibPlayOrPause.setImageResource

(android.R.drawable.ic_media_pause);

// 开启线程,更新播放信息

startUpdateProgressThread();

// 更新标识:播放器开始工作

isPlayerWorking = true;

}

@Override
public void onStartTrackingTouch(SeekBar seekBar) {
    // 标志用户正在拖拽进度条
    isUserTrackingTouch = true;
}

@Override
public void onStopTrackingTouch(SeekBar seekBar) {
    // 标志用户已经停止拖拽进度条
    isUserTrackingTouch = false;
    // 判断播放器是否已开始工作
    if(isPlayerWorking) {
        // 获取拖拽后的进度
        int progress = sbMusicProgress.getProgress();
        // 调用Service中对应的方法
        player.callSeekTo(progress);
        // 开启线程,更新播放进度
        startUpdateProgressThread();
        // 设置播放按钮显示的图片为“暂停”
        ibPlayOrPause.setImageResource

(android.R.drawable.ic_media_pause);

}

}

/**
 * 开启线程,更新播放信息
 */
private void startUpdateProgressThread() {
    if(updateProgressThread == null) {
        updateProgressThread = new UpdateProgressThread();
        updateProgressThread.setRunning(true);
        updateProgressThread.start();
    }
}

/**
 * 停止更新播放信息的线程
 */
private void stopUpdateProgressThread() {
    if(updateProgressThread != null) {
        updateProgressThread.setRunning(false);
        updateProgressThread = null;
    }
}

/**
 * 更新播放信息的线程
 */
private class UpdateProgressThread extends Thread {
    private boolean isRunning;
    private String musicName;
    private int progress;
    private String currentPositionString;
    private String durationString;

    public void setRunning(boolean isRunning) {
        this.isRunning = isRunning;
    }

    private Runnable runner = new Runnable() {
        @Override
        public void run() {
            // 更新控件:歌曲标题
            tvMusicTitle.setText(musicName);
            // 更新控件:当前歌曲时长
            tvMusicDuration.setText(durationString);
            // 更新控件:当前播放时间
            tvMusicCurrentPosition.setText

(currentPositionString);

            // 判断用户是否正在拖拽进度条
            if(!isUserTrackingTouch) {
                // 更新控件:进度条
                sbMusicProgress.setProgress(progress);
            }
        }
    };

    @Override
    public void run() {
        // 循环
        while(isRunning) {
            // 日志
            Log.d("tedu", "UpdateProgressThread.run()");
            // 判断是否正在播放
            if(player.callIsPlaying()) {
                // 获取所需的数据
                int currentMusicIndex =

player.callGetCurrentMusicIndex();

int currentPosition =

player.callGetCurrentPosition();

int duration = player.callGetDuration();

                // 计算需要被显示的数据
                musicName = "正在播放:" + musics.get

(currentMusicIndex).getName();

progress = currentPosition * 100 /

duration;

currentPositionString =

CommonUtils.getFormattedTime(currentPosition);

durationString =

CommonUtils.getFormattedTime(duration);

                // 更新显示
                runOnUiThread(runner);
            }

            // 休眠
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

/**
 * ServiceConnection
 */
private class InnerServiceConnection implements ServiceConnection {

    @Override
    public void onServiceConnected(ComponentName name, IBinder

service) {

player = (IMusicPlayer) service;

}

    @Override
    public void onServiceDisconnected(ComponentName name) {
        // (无视)
    }

}

@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean

fromUser) {

// (无视)

}

}

MusicAdapter 代码

package cn.tedu.music_player_2.adapter;

import java.util.List;

import android.content.Context;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.BaseAdapter;

import android.widget.TextView;

import cn.tedu.music_player_2.R;

import cn.tedu.music_player_2.R.id;

import cn.tedu.music_player_2.R.layout;

import cn.tedu.music_player_2.entity.Music;

/**

* 显示歌曲列表ListView的Adapter

* @author chengheng

* @version 2.0

*/

public class MusicAdapter extends BaseAdapter {

/**

* Context

*/

private Context context;

/**

* 歌曲列表的数据

*/

private List musics;

/**
 * 构造方法
 * @param context 上下文对象
 * @param musics 歌曲的数据的List集合
 */
public MusicAdapter(Context context, List<Music> musics) {
    super();
    this.context = context;
    this.musics = musics;
}

@Override
public int getCount() {
    return musics.size();
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    Music music = musics.get(position);

    if (convertView == null) {
        LayoutInflater inflater = LayoutInflater.from(context);
        convertView = inflater.inflate(R.layout.music_item, null);
    }

    TextView tvName = (TextView) convertView.findViewById(R.id.tv_music_item_name);
    TextView tvPath = (TextView) convertView.findViewById(R.id.tv_music_item_path);

    tvName.setText(music.getName());
    tvPath.setText(music.getPath());

    return convertView;
}

@Override
public Object getItem(int position) {
    return null;
}

@Override
public long getItemId(int position) {
    return 0;
}

}

自定义的application代码

package cn.tedu.music_player_2.app;

import java.util.List;

import android.app.Application;

import android.util.Log;

import cn.tedu.music_player_2.dal.IDao;

import cn.tedu.music_player_2.dal.MusicDaoFactory;

import cn.tedu.music_player_2.entity.Music;

public class MusicPlayerApplication extends Application {

private List musics = null;

@Override
public void onCreate() {
    // 日志
    Log.e("tedu", "MusicPlayerApplication.onCreate()");

    // 获取数据
    Log.e("tedu", "MusicPlayerApplication. 准备获取歌曲列表!");
    // MusicDao dao = new MusicDao();
    IDao dao = MusicDaoFactory.newInstance();
    musics = dao.getData();
    Log.e("tedu", "MusicPlayerApplication. 获取歌曲列表完成!");
}

/**
 * 获取歌曲数据的List集合
 * @return 歌曲数据的List集合,该返回值永不为null
 */
public List<Music> getMusics() {
    return musics;
}

}

工具类IDao代码:

package cn.tedu.music_player_2.dal;

import java.util.List;

import cn.tedu.music_player_2.entity.Music;

public interface IDao {

List<Music> getData();

}

工具类InternetMusicDao 代码:

package cn.tedu.music_player_2.dal;

import java.util.ArrayList;

import java.util.List;

import cn.tedu.music_player_2.entity.Music;

public class InternetMusicDao implements IDao {

@Override
public List<Music> getData() {
    List<Music> musics = new ArrayList<Music>();

    Music m1 = new Music();
    m1.setName("长城");
    m1.setPath("http://mp3.baidu.com/changcheng.mp3");
    musics.add(m1);

    Music m2 = new Music();
    m2.setName("大地");
    m2.setPath("http://mp3.baidu.com/dadi.mp3");
    musics.add(m2);

    Music m3 = new Music();
    m3.setName("光辉岁月");
    m3.setPath("http://mp3.baidu.com/guanghuisuiyue.mp3");
    musics.add(m3);

    return musics;
}

}

LoadMusicDao 代码;

package cn.tedu.music_player_2.dal;

import java.io.File;

import java.util.ArrayList;

import java.util.List;

import java.util.Locale;

import android.os.Environment;

import android.util.Log;

import cn.tedu.music_player_2.entity.Music;

/**

* 歌曲数据的访问类

* @author chengheng

* @version 2.0

*/

public class LocalMusicDao implements IDao {

/**

* 扫描sdcard中Music下所有.mp3文件

* @return 扫描到的Music对象的List集合,该返回值永不为null

*/

@Override

public List getData() {

// 准备返回值

List musics = new ArrayList();

    // 扫描sdcard中Music下所有.mp3文件
    if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
        File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);
        if (dir.exists()) {
            File[] files = dir.listFiles();
            if (files != null && files.length > 0) {
                for (int i = 0; i < files.length; i++) {
                    if (files[i].isFile()) {
                        if (files[i].getName().toLowerCase(Locale.CHINA).endsWith(".mp3")) {
                            Music music = new Music();
                            music.setPath(files[i].getAbsolutePath());
                            music.setName(files[i].getName().substring(0, files[i].getName().length() - 4));
                            Log.v("tedu", "" + music);
                            musics.add(music);
                        }
                    }
                }
            } else {
                Log.w("tedu", "Music文件夹下没有有效的文件!");
            }
        } else {
            Log.w("tedu", "sdcard下Music文件夹不存在!无法扫描到歌曲!");
        }
    } else {
        Log.w("tedu", "sdcard没有正确挂载!无法访问!");
    }

    // 返回
    return musics;
}

}

工具类MusicDaoFactory 代码;

package cn.tedu.music_player_2.dal;

public class MusicDaoFactory {

private MusicDaoFactory() {

}

public static IDao newInstance() {
    return new LocalMusicDao();
}

}

实体类 Music 代码

package cn.tedu.music_player_2.entity;

/**

* 歌曲信息的实体类

* @author chengheng

* @version 2.0

*/

public class Music {

/**

* 歌曲名称,用于显示

*/

private String name;

/**

* 歌曲路径

*/

private String path;

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getPath() {
    return path;
}

public void setPath(String path) {
    this.path = path;
}

@Override
public String toString() {
    return "Music [name=" + name + ", path=" + path + "]";
}

}

service服务PlayMusicSevice

package cn.tedu.music_player_2.service;

import java.io.IOException;

import java.util.List;

import android.app.Service;

import android.content.Intent;

import android.media.MediaPlayer;

import android.os.Binder;

import android.os.IBinder;

import cn.tedu.music_player_2.app.MusicPlayerApplication;

import cn.tedu.music_player_2.entity.Music;

import cn.tedu.music_player_2.util.IMusicPlayer;

public class PlayMusicService extends Service {

/**

* 播放工具

*/

private MediaPlayer player;

/**

* 歌曲数据的List集合

*/

private List musics;

/**

* Application

*/

private MusicPlayerApplication app;

/**

* 当前播放的歌曲的索引

*/

private int currentMusicIndex;

/**

* 暂停位置

*/

private int pausePosition;

@Override
public void onCreate() {
    // 创建MediaPlayer
    player = new MediaPlayer();

    // 获取歌曲列表的数据
    app = (MusicPlayerApplication) getApplication();
    musics = app.getMusics();

    // 为MediaPlayer对象配置监听器
    player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mp) {
            // 播放下一首
            next();
        }
    });
    player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
        @Override
        public void onPrepared(MediaPlayer mp) {
            // 快进到之前暂停的位置
            player.seekTo(pausePosition);
            // 播放
            player.start();
        }
    });
}

@Override
public IBinder onBind(Intent intent) {
    InnerBinder binder = new InnerBinder();
    return binder;
}

@Override
public void onDestroy() {
    // 释放播放器相关资源
    player.release();
    player = null;
}

/**
 * Binder
 */
private class InnerBinder extends Binder implements IMusicPlayer {

    @Override
    public void callPlay() {
        PlayMusicService.this.play();
    }

    @Override
    public void callPause() {
        PlayMusicService.this.pause();
    }

    @Override
    public void callPrevious() {
        PlayMusicService.this.previous();
    }

    @Override
    public void callNext() {
        PlayMusicService.this.next();
    }

    @Override
    public boolean callIsPlaying() {
        return player.isPlaying();
    }

    @Override
    public void callPlay(int position) {
        PlayMusicService.this.play(position);
    }

    @Override
    public int callGetCurrentMusicIndex() {
        return currentMusicIndex;
    }

    @Override
    public int callGetCurrentPosition() {
        return player.getCurrentPosition();
    }

    @Override
    public int callGetDuration() {
        return player.getDuration();
    }

    @Override
    public void callSeekTo(int progress) {
        PlayMusicService.this.seekTo(progress);
    }

}

/**
 * 播放
 */
private void play() {
    try {
        // 1. 重置
        player.reset();
        // 2. 设置歌曲的路径
        player.setDataSource(musics.get(currentMusicIndex).getPath());
        // 3. 异步加载歌曲数据,必须匹配OnPreparedListener
        player.prepareAsync();

// // 3. 加载歌曲数据

// player.prepare();

// // 4. 快进到暂停位置

// player.seekTo(pausePosition);

// // 5. 播放

// player.start();

} catch (IllegalArgumentException e) {

e.printStackTrace();

} catch (SecurityException e) {

e.printStackTrace();

} catch (IllegalStateException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

/**
 * 播放指定的歌曲
 *
 * @param position
 *            歌曲的索引
 */
private void play(int position) {
    // 确定需要播放的歌曲的索引
    currentMusicIndex = position;
    // 清除暂停位置
    pausePosition = 0;
    // 播放
    play();
}

/**
 * 暂停
 */
private void pause() {
    // 暂停播放
    player.pause();
    // 记录当前播放到的位置
    pausePosition = player.getCurrentPosition();
}

/**
 * 播放上一首
 */
private void previous() {
    // 计算上一首歌曲的索引值
    currentMusicIndex--;
    if (currentMusicIndex < 0) {
        currentMusicIndex = musics.size() - 1;
    }
    // 清除暂停位置
    pausePosition = 0;
    // 播放
    play();
}

/**
 * 播放下一首
 */
private void next() {
    // 计算上一首歌曲的索引值
    currentMusicIndex++;
    if (currentMusicIndex >= musics.size()) {
        currentMusicIndex = 0;
    }
    // 清除暂停位置
    pausePosition = 0;
    // 播放
    play();
}

/**
 * 快进到指定的进度位置开始播放
 *
 * @param progress
 *            进度值,假设从60%位置开始播放,则参数值为60
 */
private void seekTo(int progress) {
    // 根据进度计算出需要从??毫秒开始播放,并将值赋给pausePosition
    pausePosition = player.getDuration() * progress / 100;
    // 播放
    play();
}

}

commonutils 类代码:

package cn.tedu.music_player_2.util;

import java.util.Date;

import java.text.SimpleDateFormat;

import java.util.Locale;

/**

* 通用工具类

*/

public class CommonUtils {

/**

* 格式化时间的工具

*/

private static SimpleDateFormat sdf = new SimpleDateFormat(“mm:ss”, Locale.CHINA);

/**

* 被格式化的时间对象

*/

private static Date date = new Date();

/**
 * 获取格式化后的时间
 *
 * @param timeMillis
 *            时间值,取值为从1970-1-1 0:00:00至今的毫秒数
 * @return 格式化为mm:ss格式的字符串
 */
public static String getFormattedTime(long timeMillis) {
    // 设置时间
    date.setTime(timeMillis);
    // 返回格式化后的结果
    return sdf.format(date);
}

}

consts工具类

package cn.tedu.music_player_2.util;

/**

* 保存常量

* @author chengheng

* @version 2.0

*/

public interface Consts {

/**

* 指令:播放或暂停

*/

int COMMAND_PLAY_OR_PAUSE = 0;

/**

* 指令:播放上一首

*/

int COMMAND_PREVIOUS = 1;

/**

* 指令:播放下一首

*/

int COMMAND_NEXT = 2;

/**

* 指令:播放指定的歌曲

*/

int COMMAND_PLAY_POSITION = 3;

/**
 * Intent中封装的数据的key:指令
 */
String EXTRA_COMMAND = "command";
/**
* Intent中封装的数据的key:需要播放的歌曲的索引
*/
String EXTRA_POSITION = "position";

}

IMusicPlayer类代码:

package cn.tedu.music_player_2.util;

public interface IMusicPlayer {

/**

* 播放歌曲

*/

void callPlay();

/**
 * 暂停播放
 */
void callPause();

/**
 * 播放上一首
 */
void callPrevious();

/**
 * 播放下一首
 */
void callNext();

/**
 * 获取播放状态,即判断是否正在播放
 *
 * @return 返回true则表示正在播放,返回false则表示没有播放
 */
boolean callIsPlaying();

/**
 * 播放指定的歌曲
 *
 * @param position
 *            歌曲的索引
 */
void callPlay(int position);

/**
 * 获取当前播放的歌曲的索引
 *
 * @return 当前播放的歌曲的索引
 */
int callGetCurrentMusicIndex();

/**
 * 获取当前播放到的位置
 *
 * @return 当前播放到的位置
 */
int callGetCurrentPosition();

/**
 * 获取当前播放的歌曲的时长
 *
 * @return 当前播放的歌曲的时长
 */
int callGetDuration();

/**
 * 快进到指定的进度位置开始播放
 *
 * @param progress
 *            进度值,假设从60%位置开始播放,则参数值为60
 */
void callSeekTo(int progress);

}

时间: 2024-10-15 03:39:21

android本地音乐播放(二)的相关文章

Android Mediaplayer本地音乐播放器(绑定服务)

本文章介绍MediaPlayer本地音乐播放器,而当应用程序不再位于前台且没有正在使用它的活动时,为了确保音频继续播放,我们需要建立一个服务Service. Activity与绑定服务Service之间的交互是本文章的重点(这里需要说明一点的是,Activity不能直接访问服务对象中的方法,所以才有了我们一下的介绍,这也是为服务的安全等方面的考虑). 直接上代码: 布局文件:activity_main: <LinearLayout xmlns:android="http://schemas

Android实现音乐播放器(一)

Graphical User Interface 本篇文章记录了我实现Android简单音乐播放器的过程,(一)中介绍了怎么构建音乐播放器的前端页面.首先大家看一下,界面最后是这样的(界面有点粗陋) 音乐文件列表是从SD卡中读取出来的. 首先我们先在Layout里面创建Music Player的GUI,diagram如下图所示: 根据diagram我们在activity_main.xml写出如下代码: <LinearLayout xmlns:android="http://schemas.

[Android应用]音乐播放器

Service是一个不可见的进程在后台执行. Android中的服务,它与Activity不同,它是不能与用户交互的,不能自己启动的,运行在后台的程序,如果我们退出应用时,Service进程并没有结束,它仍然在后台运行,例如我们打开一个音乐播放器来听音乐,在听音乐的同时也想做下其它的事情,比如上网聊Q.或者上网浏览新闻之类的事情.这样的话,我们就需要用到Service服务了.下面我们以一个简单的音乐播放器的实例来说明下Service的生命周期和Service的使用. 下面是音乐播放器Demo的程

本地音乐播放、在线音乐播放与视频播放

1.本地音乐播放 1.导入库:AVFoundation.framework 2.添加头文件:#import <AVFoundation/AVFoundation.h> 代码如下: #import "ConfigViewController.h" #import "UIView+DLQuickView.h" #import <AVFoundation/AVFoundation.h> @interface ConfigViewController

android调用音乐播放器,三种方

小弟想请问一下,如何在自己写的程序中调用系统的音乐播放器呢. 我在google上搜索了,主要是有两种方法,但是都不是我想要的. 第一种是,使用mp3音乐文件的uri,和intent,进行调用,但是这种是针对某一首歌曲的播放使用的. /** * 播放指定名称的歌曲 * @param audioPath 指定默认播放的音乐 */ public static void playAudio(String audioPath){ Intent mIntent = new Intent(); mIntent

简单本地音乐播放器

// //  ViewController.m //  AudioPlayer // //  Created by apple on 14-7-18. //  Copyright (c) 2014年 苹果IOS软件开发者. All rights reserved. // #import "ViewController.h" #import <AVFoundation/AVFoundation.h> @interface ViewController ()<AVAudi

android版音乐播放器----卡拉OK歌词实现(二)

相信大家都看过酷狗的音乐播放器,特别是酷狗的滚动歌词实现起来,效果特别好.我自己也尝试看了一下酷狗的歌词文件,发现是加密的,根本就看不了,所以只能是从目前开源的歌词文件出发了.我自己选择的是ksc歌词文件. 要实现歌词的功能,那首先就是要先认识一下ksc歌词的文件与普通的lrc歌词有那方面的区别? 当然,这里我从网上找了一个文档,看了文档里面的介绍,大家大概就会明白两都的区别. http://wenku.baidu.com/link?url=Ga4ESBrytlx3qUoxX5ApHbFIZro

Xamarin.Android开发音乐播放器

最近.Net开源着实让C#火了一把,好久就听说Mono for Android一直没静下心来看,上周末找来看看,确实不错,前台界面axml编写跟Java安卓开发毫无区别,后台用C#其实很多windows下的方法都可以用,做一个安卓音乐播放器,主要实现音乐播放,上一曲下一曲,音乐播放列表,随机播放,扫描SD卡内所有音乐. 先show一组界面啊,话说有图有真相啊: 项目结构如图: Lrc是歌词处理方法 MusicService是安卓服务播放音乐,服务Broadcast,以及界面接收Receiver

本地音乐播放

iOS开发拓展篇—音乐的播放 一.简单说明 音乐播放用到一个叫做AVAudioPlayer的类,这个类可以用于播放手机本地的音乐文件. 注意: (1)该类(AVAudioPlayer)只能用于播放本地音频. (2)时间比较短的(称之为音效)使用AudioServicesCreateSystemSoundID来创建,而本地时间较长(称之为音乐)使用AVAudioPlayer类. 二.代码示例 AVAudioPlayer类依赖于AVFoundation框架,因此使用该类必须先导入AVFoundati