- 浏览: 14982 次
- 性别:
最新评论
-
JuliaAilse:
深表同感啊!就觉得,自己理解的那点东西,写又不好写,写了还自己 ...
夜行者——技术之外的一点东西 -
JuliaAilse:
厉害啊!2楼正解啊,最好是用自己的照片当专辑封面,假装下是“ ...
Android手机音乐播放器的初步实现 -
云初静:
我也想写个播放器了,哈哈。用自己写的播放器听歌,多爽呀,嘿嘿! ...
Android手机音乐播放器的初步实现 -
yangzhizhen:
牛。。。。。
Android手机音乐播放器的初步实现 -
luozhong915127:
有点嫉妒
初涉黑白棋之简单双人对战
习惯于在做事情的时候听一些熟悉的歌,你也许会说,这是一心二用,但有的时候却反而更能让人投入自己的工作中。至少对于我来说是这样,当然他人也许无法理解。或许是为了给自己找个正当的理由听音乐,所以做了这个安卓手机的播放器。在此之前由于搭档有意向的是另一个方面,于是在商量之后,我们决定将二者联合起来。当然,这里写的也许不算严格意义上的通信项目,播放器只是项目的一部分而已。下面是播放器的实现过程。
这里利用Android jdk中的MediaPlayer这个类来实现。
先看布局文件:
在这边简单介绍一下。界面没有什么特别的,正是最为normal的一个播放器界面。上左是一个图片框,右面三个按钮。下方三排TextView用于显示歌曲信息,再下面是控制播放的按钮和进度条。 (这里说明一下,图片暂用白色背景代替,音乐播放总时间未获得到是由于本人系统重装,模拟器里的sd卡中无内容导致,与下面的方法无关。) 下面是主界面的activity: 这上面只是一部分。在这里要说的是,用 MediaPlayer.setDataSource(url)的方法来创建播放歌曲时,需执行MediaPlayer.prepare()方法,才能使MediaPlayer.getDuration()方法得到正确的音乐播放时间(未prepare时,该方法也能得到一个long型的整数,但是相对来说很大,这里不是很清楚得到的是什么值);而通过MediaPlayer.create()方法创建则不需要。 播放过程中需要另一个线程来同步控制进度条的移动,这里用安卓特有的Handler来控制。 此外,当玩家拖动进度条时,相应的歌曲进度也将随之匹配变化。 最后,是一个刷新主线程UI的Handler。Android与普通java工程不同之处的在于,对于一个activity,它自带一个管理主界面的runnable,因此不允许其他的子线程随意刷新主界面。如果你尝试在自定义的线程中刷新界面,则系统会给你报出CalledFromWrongThreadException:Only the original thread that created a view hierarchy can touch its views这个错误。于是我们重新写了handleMessage的方法。 这里还有一个无关紧要的方法,也就是把时间的毫秒形式转换成我们习惯的格式。 到了这里,一个简单的播放器就完成了。这里仅仅是整个项目的一部分,此外还有播放列表和歌曲的选择以及与电脑通信中歌曲的下载等等,这里暂时不写了。<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/title"
/>
<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<ImageView
android:layout_x="7dip"
android:layout_y="17dip"
android:layout_width="198dip"
android:layout_height="198dip"
android:background="#ffffff"
/>
<Button
android:layout_x="230dip"
android:layout_y="125dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="playlist"
android:id="@+id/playlist"
/>
<Button
android:layout_x="230dip"
android:layout_y="70dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="choose"
android:id="@+id/choose"
/>
<LinearLayout
android:layout_x="3dip"
android:layout_y="230dip"
android:layout_width="fill_parent"
android:layout_height="65dip"
android:orientation="vertical">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/songname"
android:id="@+id/songname"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/record"
android:id="@+id/record"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/artist"
android:id="@+id/artist"
/>
</LinearLayout>
</AbsoluteLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:gravity="center_horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="start"
android:id="@+id/start_pause"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="stop"
android:id="@+id/stop"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="next"
android:id="@+id/next"
/>
</LinearLayout>
<SeekBar android:id="@+id/seekbar"
android:layout_width="300dip"
android:layout_height="20px"
android:layout_gravity="center"
/>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:gravity="clip_horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:id="@+id/goTime"
android:text="@string/original_time"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="244dip"
android:id="@+id/totalTime"
android:text="@string/original_time"
/>
</LinearLayout>
</LinearLayout>
package lsy.mp20120211;
import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;
public class MainPanel extends Activity implements Runnable {
private MediaPlayer mp1 = new MediaPlayer();// 新建的一個播放器對象
private Button start_pause, stop, next;
private TextView goTime, totalTime, song, album, artist;
private SeekBar seek;// 進度條
private String[] total_tim = new String[2];// 這兩項和時間顯示有關
private String[] current_tim = new String[2];
private int t, i = 0;
private android.os.Handler handler = new android.os.Handler();// 控制線程的Handler
private boolean userChangeSeek;
private boolean isStop = true;
private mainhandler mhandler = new mainhandler();
private final int CHANGE_SONG = 1;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
/** 得到各組件 */
seek = (SeekBar) this.findViewById(R.id.seekbar);
goTime = (TextView) this.findViewById(R.id.goTime);
totalTime = (TextView) this.findViewById(R.id.totalTime);
song = (TextView) this.findViewById(R.id.songname);
album = (TextView) this.findViewById(R.id.record);
artist = (TextView) this.findViewById(R.id.artist);
start_pause = (Button) this.findViewById(R.id.start_pause);
stop = (Button) this.findViewById(R.id.stop);
next = (Button) this.findViewById(R.id.next);
// 加载音乐队列
Tools.addSongs();
System.out.println("队列里的音乐个数为:" + Tools.songlist.size());
// 啟動新建音樂的線程
Thread tt = new Thread(this);
tt.start();
// 給按鈕添加監聽器
start_pause.setOnClickListener(oc1);
stop.setOnClickListener(oc2);
next.setOnClickListener(oc3);
// 進度條拖動的監聽器
seek.setOnSeekBarChangeListener(osl);
}
/** 程序運行的run方法 */
public void run() {
while (i < Tools.songlist.size()) {
if (isStop) {
System.out.println("停止播放" + isStop);
mhandler.sendEmptyMessage(CHANGE_SONG);
newPlayer(Tools.songlist.get(i).getUrl());
System.out.println("完成一遍" + i);
}
}
}
/**
* 新建一個播放器的操作
*/
public void newPlayer(String url) {
// 新建一個播放器
isStop = false;
try {
//mp1.reset();
mp1.setDataSource(url);
mp1.prepare();
// 得到播放總时间(单位:毫秒)
t = mp1.getDuration();
System.out.println("t=" + t);
// 轉成時間格式
total_tim = changeInt2Time(t);
// 顯示總時間
String total_time = total_tim[0] + ":" +total_tim[1];
totalTime.setText(total_time);
// 如果直接下一首则不用点击直接播放
if (start_pause.getText().equals("pause")) {
// mp1.prepare();
mp1.start();
System.out.println("音乐播放中..." + mp1.isPlaying());
}
mp1.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer arg0) {
seek.setProgress(0);
if (Tools.songlist.size() == 0) {
Toast.makeText(MainPanel.this, "结束", 1000).show();
mp1.release();
} else {
isStop = true;
}
}
});
} catch (Exception e) {
System.out.println("找不到文件!!!");
e.printStackTrace();
}
}
下面要说的是控制播放按钮的监听器:/** 開始和暫停的监听 */
OnClickListener oc1 = new OnClickListener() {
public void onClick(View v) {
try {
if (start_pause.getText().equals("start")) {
if (mp1 != null) {
mp1.stop();
}
// 計時
seek.setMax(t);
handler.post(time_thread);
// 播放
mp1.prepare();
mp1.start();
start_pause.setText("pause");
System.out.println("音乐播放中..." + mp1.isPlaying());
} else if (start_pause.getText().equals("pause")) {
// 暫停
mp1.stop();
start_pause.setText("start");
handler.removeCallbacks(time_thread);
System.out.println("暂停" + mp1.isLooping());
}
} catch (Exception e) {
System.out.println("播放发生异常...");
e.printStackTrace();
}
}
};
/** 停止按鈕的監聽 */
OnClickListener oc2 = new OnClickListener() {
public void onClick(View v) {
mp1.stop();
handler.removeCallbacks(time_thread);
seek.setProgress(0);
isStop = true;
goTime.setText("00:00");
start_pause.setText("start");
}
};
/** 下一首按鈕的監聽 */
OnClickListener oc3 = new OnClickListener() {
public void onClick(View v) {
mp1.stop();
seek.setProgress(0);
goTime.setText("00:00");
i = 1;
isStop = true;
}
};
/** 時間進度條的線程 */
private Runnable time_thread = new Runnable() {
public void run() {
// 設置進度
int current = seek.getProgress() + 1000;
seek.setProgress(current);
// 設置目前播放時間
int cur_time = mp1.getCurrentPosition();
// 轉換格式使之顯示在介面上
current_tim = changeInt2Time(cur_time);
goTime.setText(current_tim[0] + ":" + current_tim[1]);
// 控制線程
handler.postDelayed(time_thread, 1000);
}
};
/** 拖動進度條時對進度條的監聽 */
OnSeekBarChangeListener osl = new OnSeekBarChangeListener() {
// 進度改變時的動作
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
fromUser = userChangeSeek;
// 設置音樂播放與進度匹配
mp1.seekTo(progress);
current_tim = changeInt2Time(progress);
goTime.setText(current_tim[0] + ":" + current_tim[1]);
}
// 觸摸進度條時的監聽
public void onStartTrackingTouch(SeekBar seekBar) {
}
// 停止觸摸時的監聽
public void onStopTrackingTouch(SeekBar seekBar) {
userChangeSeek = true;
}
};
/** 新建一个主线程中的handler */
private class mainhandler extends android.os.Handler {
public void handleMessage(Message msg) {
super.handleMessage(msg);
int what = msg.what;
switch (what) {
case CHANGE_SONG: {
// 切換下一首歌曲時,用來刷新主界面UI
song.setText(" 歌曲: " + Tools.songlist.get(i).getName());
album.setText(" 专辑: " + Tools.songlist.get(i).getAlbum());
artist.setText("艺术家: " + Tools.songlist.get(i).getArtist());
}
}
}
}
/**
* 把時間的毫秒形式改成xx:xx
*
* @param t
*/
public String[] changeInt2Time(int t) {
int s, min = 0;
String[] time = new String[2];
String minutes, seconds;
s = t / 1000;
if (s >= 60) {
min = s / 60;
s = s % 60;
}
// 將分秒轉為字符串
if (s < 10) {
seconds = "0" + s;
} else {
seconds = s + "";
}
if (min < 10) {
minutes = "0" + min;
} else {
minutes = min + "";
}
time[0] = minutes;
time[1] = seconds;
return time;
}
评论
发表评论
-
夜行者——技术之外的一点东西
2012-03-11 09:42 919人是夜行性动物,如果他们有一双像猫科动物一样能够夜视的 ... -
关于hash的一点理解
2012-03-11 09:26 832一直以来对哈 ... -
关于Android与pc通信时中文乱码的分析和解决
2012-02-11 14:54 5515初步实现了Andro ... -
初涉黑白棋之简单双人对战
2011-11-07 22:51 3860黑白棋 ... -
再言画板的总结
2011-10-21 23:27 1041依旧是画板,已经写到第七个版本了,与上篇所说的 ... -
浅谈初级画板开发
2011-10-02 20:15 855学习JAVA也有几个 ...
相关推荐
还有简单的密码验证 开发软件:Android StudioAndroid 开源在线音乐播放器Android 开源在线音乐播放器Android 开源在线音乐播放器Android 开源在线音乐播放器Android 开源在线音乐播放器Android 开源在线音乐播放器...
android简单音乐播放器的播放,暂停,前一首,后一首的控制。简单音乐播放器的播放,暂停,前一首,后一首的控制。简单音乐播放器的播放,暂停,前一首,后一首的控制。简单音乐播放器的播放,暂停,前一首,后一首...
android 简易音乐播放器的实现 附说明和全部代码
基于Android手机平台的音乐播放器设计与实现.doc 基于Android手机平台的音乐播放器设计与实现.doc 基于Android手机平台的音乐播放器设计与实现.doc 基于Android手机平台的音乐播放器设计与实现.doc 基于Android手机...
手机音乐播放器
Android音乐播放器实战,实现本地歌曲播放控制,可后台播放,拔出耳机暂停,来电暂停,电话挂断继续播放。这个项目很好的结合了Android的四大组件知识。其中音乐来源于手机本地,使用了Content Provider获取,播放...
android studio 音乐播放器.zipandroid studio 音乐播放器.zipandroid studio 音乐播放器.zipandroid studio 音乐播放器.zipandroid studio 音乐播放器.zipandroid studio 音乐播放器.zipandroid studio 音乐播放器....
android studio手机MP3音乐播放器
Android实现简单音乐播放器(MediaPlayer),供大家参考,具体内容如下 开发工具:Andorid Studio 1.3 运行环境:Android 4.4 KitKat 工程内容 实现一个简单的音乐播放器,要求功能有: 播放、暂停功能; 进度条显示...
Android实例源码-音乐播放器类安卓源代码(9例) ...简单音乐播放器,实现了播放器基本功能,使用service后台播放音乐,并使用异步线程加载音乐图片 边下载边播music 音乐播放器 音乐播放器 音乐播放器源码
个性化Android手机音乐播放器的实现.pdf
基于Android的音乐播放器的设计与实现20150417 需求报告 演示视频.zip,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习。
(论文)基于android的音乐播放器下载与歌词显示为核心的设计与实现
这是我的优秀课程设计,移动应用开发课期末的课程报告,包含实验目的、实验内容、程序设计和说明...每部分都写的很详细,具体的源码在我的博客《Android Studio实现音乐播放器》里面,这份课程设计报告和它是配套的。
Android简易本地音乐播放器源码,基于Android的简易本地音乐播放器源码
Android本地音乐播放器的设计与实现.pdf
本文实例为大家分享了android实现音乐播放器进度条效果的具体代码,供大家参考,具体内容如下 效果图 依赖3个对象 MediaPlayer:实现音乐播放,暂停,缓冲。 SeekBar:滑动的进度条。 java.util.Timer:定时器,时时...
一个用Android实现的支持登录注册的简单音乐播放器
第一版的《Android Studio如何实现音乐播放器(简单易上手)》博客链接:https://blog.csdn.net/qq_42257666/article/details/105555550。 本项目就是对最初版本的一个完善,即2.0版本,主要进行了如下三点优化升级...
Android中简单音乐播放器的实现 陆续上传音乐播放器的实现视频及文档说明 请关注