当前位置:  移动开发 iis7站长之家
本页文章导读:
    ▪音乐播发之进度条 - 自定义        音乐播放之进度条 - 自定义 音乐播放之进度条   [前提] * android 自身也提供了该接口 似乎是:MediaController  但看过截图 发现极丑 所以今天就自己写了一个 现于诸位分享分享     [要求] 1. 进.........
    ▪ 除此以外一种继承 Dialog的方法以及发动线程        另外一种继承 Dialog的方法以及发动线程 public class SettingsDialog extends Dialog implements android.view.View.OnClickListener {        public SettingsDialog(XMPPClient xmppClient) {        super(xmppClient);       .........
    ▪ 如何避免PIM.Event       如何处理PIM.Event 以下代码用于实现PIM Event的增加、删除,修改,它的增加、删除功能我的P990上工作得很好,但修改功能会导致异常退出,而在k750上无论增加、修改、删除都没有效果(虽.........

[1]音乐播发之进度条 - 自定义
    来源: 互联网  发布时间: 2014-02-18
音乐播放之进度条 - 自定义

音乐播放之进度条

 

[前提]

* android 自身也提供了该接口 似乎是:MediaController  但看过截图 发现极丑 所以今天就自己写了一个 现于诸位分享分享

 

 

[要求]

1. 进度条控件打算使用系统提供的SeekBar

2. SeekBar 要支持拖拉功能 即:定点播放

3. SeekBar 要反映播放位置 即:播放到哪 SeekBar 就在哪

 

 

[原理]

1. 音乐定点播放:MediaPlayer.seekTo(int msecond) //单位:毫秒

2. 音乐文件播放时间:MediaPlayer.getDuration()

3. SeekBar 获取位置:SeekBar.getProgress()

4. SeekBar 最大值: SeekBar.getMax()

 

 

 

[代码 步骤]

1. 定义界面:main.xml

1 * Button : 播放控制 如:暂停 继续
1 * TextView : 显示播放百分比
1 * SeekBar : 进度条
1 * RadioGroup : 显示所有sdcard 音乐文件

 

<?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"
    >
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    >
<Button
 android:id="@+id/cmd"
 android:text="Loading..."
 android:layout_width="90dip"
    android:layout_height="wrap_content"
    android:singleLine="true"
/>
<TextView
 android:id="@+id/progress"
 android:text="Progress.."
 android:layout_width="50dip"
    android:layout_height="fill_parent"
    android:gravity="center"
    android:singleLine="true"
/>
</LinearLayout>
<SeekBar  
 android:id="@+id/seekb"
 android:max="100"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    />
</LinearLayout>

 

2.  View 初始化

public void initialize(){
    	
    	sBar = (SeekBar)findViewById(R.id.seekb);
    	rGroup = (RadioGroup)findViewById(R.id.radio);
    	cmdButton = (Button)findViewById(R.id.cmd);
    	
    	mPlayer = new MediaPlayer();
    }

 

3. 拖动SeekBar 且播放指定位置的音乐

sBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener(){

			@Override
			public void onProgressChanged(SeekBar seekBar, int progress,
					boolean fromUser) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onStartTrackingTouch(SeekBar seekBar) {
				// TODO Auto-generated method stub
			}

			@Override
			public void onStopTrackingTouch(SeekBar seekBar) {
				// TODO Auto-generated method stub
				int dest = seekBar.getProgress();
				
				int mMax = mPlayer.getDuration();
	    		int sMax = sBar.getMax();
	    		
	    		mPlayer.seekTo(mMax*dest/sMax);
	    		
			}
			
		});

 

4. 刷新播放位置 且使其实时变化

//因为MediaPlayer没有播放进度的回调函数 所以只能:开辟一个Thread 定时通知其刷新

public void startProgressUpdate(){
    	//开辟Thread 用于定期刷新SeekBar
    	DelayThread dThread = new DelayThread(100);
    	dThread.start();
    }

 

而该Thread 具体实现为:

private Handler mHandle = new Handler(){
    	@Override
    	public void handleMessage(Message msg){
    		int position = mPlayer.getCurrentPosition();
    		
    		int mMax = mPlayer.getDuration();
    		int sMax = sBar.getMax();
    		
    		sBar.setProgress(position*sMax/mMax);
    	}
    };

    public class DelayThread extends Thread {
    	int milliseconds;
    	
    	public DelayThread(int i){
    		milliseconds = i;
    	}
    	public void run() {
    		while(true){
    			try {
					sleep(milliseconds);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				mHandle.sendEmptyMessage(0);
    		}
    	}
    }

 

 

5. emulator 运行截图:

 

 

 

 

1 楼 ucgfan 2010-04-11  
马上添加进我之前写的player里进行尝试
但是发现拖动实现定点播放都没有问题
就是没有实时更新SEEKBAR
不知道是我添加错哪里了~
2 楼 gryphone 2010-04-12  
ucgfan 写道
马上添加进我之前写的player里进行尝试
但是发现拖动实现定点播放都没有问题
就是没有实时更新SEEKBAR
不知道是我添加错哪里了~

可能是因为你没有启动DelayThread所致吧 你在Activity::onCreate() 最后加上如下代码:
startProgressUpdate()

3 楼 ucgfan 2010-04-12  
恩,果然是没有启用的问题~
无限感谢~~自己做的player又完善了一点~~
4 楼 lee306675730 2010-04-22  
學習了,最近正剛開始學習android,
看到你們好牛。。奮鬥啊!
5 楼 zhouxiaoli521 2010-09-06  
定点播放可以用一种更简单的方式
把音乐的总时间设置成进度条的最大值
musicProgressBar.setMax(mp.getDuration());

这样你在进度条上拖动的位置直接就可以定位到毫秒了
public void onStopTrackingTouch(SeekBar seekBar) {  
  mp.seekTo(musicProgressBar.getProgress());       
}

更新进度条也一样 直接把当前播放的时间定位到进度条就可以了
musicProgressBar.setProgress(mp.getCurrentPosition());
6 楼 ableouou 2010-09-06  
建议不要用音乐的总时间,因为有些比较大会超过100000,建议用个比例来进行拖动,但这样要考虑到拖放播放的声音可能有一点回播现象

    
[2] 除此以外一种继承 Dialog的方法以及发动线程
    来源: 互联网  发布时间: 2014-02-18
另外一种继承 Dialog的方法以及发动线程

public class SettingsDialog extends Dialog implements android.view.View.OnClickListener {
   

    public SettingsDialog(XMPPClient xmppClient) {
        super(xmppClient);
           }

    protected void onStart() {
        super.onStart();
        setContentView(R.layout.settings);
        getWindow().setFlags(4, 4);
        setTitle("XMPP Settings");
        Button ok = (Button) findViewById(R.id.ok);
        ok.setOnClickListener(this);
    }

    public void onClick(View v) {
        String host = getText(R.id.host);
        String port = getText(R.id.port);
        String service = getText(R.id.service);
        String username = getText(R.id.userid);
        String password = getText(R.id.password);

                          dismiss();
    }

    private String getText(int id) {
        EditText widget = (EditText) this.findViewById(id);
        return widget.getText().toString();
    }
}

 

使用

 setup.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                mHandler.post(new Runnable() {
                    public void run() {
                        mDialog.show();
                    }
                });
            }
        });


    
[3] 如何避免PIM.Event
    来源: 互联网  发布时间: 2014-02-18
如何处理PIM.Event
以下代码用于实现PIM Event的增加、删除,修改,它的增加、删除功能我的P990上工作得很好,但修改功能会导致异常退出,而在k750上无论增加、修改、删除都没有效果(虽然也会引发安全性提问)。
这段代码我花精力最多的是重复部分,主要是没有注意它的常量与Calandar的常量表示并不相同。

至于修改的异常问题和k750上没效果,哪位仁兄可以给分析一下呢?

	// 更新事务提醒
	public boolean updatePIMEvent(){
		EventList events = null;
		try {
			Resource.appendLog("Start updatePIMEvent", Resource.MESSAGE_LOG);
			// 打开事务列表
			events = (EventList)PIM.getInstance().openPIMList(PIM.EVENT_LIST, PIM.READ_WRITE);
			
			// 根据情况进行不同处理
			if(rpUID == null){
				if(repeatID == -2){
					Resource.appendLog("pre call appendEvent", Resource.MESSAGE_LOG);
					return appendEvent(events); // 增加
				}
			}else {
				if(repeatID == -2){
					Resource.appendLog("pre call updateEvent", Resource.MESSAGE_LOG);
					return updateEvent(events); // 更新
				}else{
					Resource.appendLog("pre call removeEvent", Resource.MESSAGE_LOG);
					return removeEvent(events); // 移除
				}
			}
			Resource.appendLog("error updatePIMEvent", Resource.ERROR_LOG);
			return false;
		} catch (Exception e){
			//e.printStackTrace();
			return false;
		}finally{
			if(events != null){
				try {
					events.close();
				} catch (Exception e){
					//e.printStackTrace();
				}
			}
		}
	}
	
	// 创建事务提醒
	private boolean appendEvent(EventList events) throws PIMException {
		Event event = events.createEvent();
		// 开始日期+响铃时间
		if(events.isSupportedField(Event.START)){
			event.addDate(Event.START, PIMItem.ATTR_NONE, rpStartDate + DateUtil.rawOffset);
		}
		// 结束日期
		if(events.isSupportedField(Event.END)){
			event.addDate(Event.END, PIMItem.ATTR_NONE, rpStartDate);
		}
		// 提醒摘要
		if(events.isSupportedField(Event.SUMMARY)){
			event.addString(Event.SUMMARY, PIMItem.ATTR_NONE, rpNotes == null ? "" : rpNotes);
		}
		// 提醒备注
		if(events.isSupportedField(Event.NOTE)){
			event.addString(Event.NOTE, PIMItem.ATTR_NONE, summarize == null ? "" : summarize);
		}
		// 提前响铃时间
		if (events.isSupportedField(Event.ALARM)) {
			event.addInt(Event.ALARM, PIMItem.ATTR_NONE, 300);
		}
		
		//event.setRepeat(getRepeatRule());
		setRepeatRule(event);
		
		// 提交事务提醒
		event.commit();
		
		// 保存事务提醒ID
		rpUID = event.getString(Event.UID, 0);
		Resource.appendLog("Append ok UID: " + rpUID, Resource.MESSAGE_LOG);
		return true;
	}
	
	// 更新事务提醒
	private boolean updateEvent(EventList events) throws PIMException {
		Event event = seekEvent(events);
		if(event != null){ // 执行更新
			// 开始日期+响铃时间
			if(events.isSupportedField(Event.START)){
				event.setDate(Event.START, 0, PIMItem.ATTR_NONE, rpStartDate + DateUtil.rawOffset);
			}
			// 结束日期
			if(events.isSupportedField(Event.END)){
				event.setDate(Event.END, 0, PIMItem.ATTR_NONE, rpStartDate);
			}
			// 提醒摘要
			if(events.isSupportedField(Event.SUMMARY)){
				event.setString(Event.SUMMARY, 0, PIMItem.ATTR_NONE, rpNotes == null ? "" : rpNotes + " - old");
			}
			// 提醒备注
			if(events.isSupportedField(Event.NOTE)){
				event.setString(Event.NOTE, 0, PIMItem.ATTR_NONE, summarize == null ? "" : summarize);
			}
			// 提前响铃时间
			if (events.isSupportedField(Event.ALARM)) {
				event.setInt(Event.ALARM, 0, PIMItem.ATTR_NONE, 300);
			}
			//event.setRepeat(null);
			//event.setRepeat(getRepeatRule());
			setRepeatRule(event);
			
			// 提交事务提醒
			event.commit();
			Resource.appendLog("Update ok UID: " + rpUID, Resource.MESSAGE_LOG);
		}else{ // 找不到旧记录则增加
			return appendEvent(events);
		}
		return false;
	}
	
	// 移除事务提醒
	private boolean removeEvent(EventList events) throws PIMException {
		Event event = seekEvent(events);
		if(event != null){ // 执行删除
			event.setRepeat(null);
			event.commit();
			events.removeEvent(event);
			Resource.appendLog("Remove ok UID:" + rpUID, Resource.MESSAGE_LOG);
			rpUID = null;
			return true;
		}
		return false;
	}
	
	// 查找事务提醒
	private Event seekEvent(EventList events) throws PIMException {
		// 枚举指定开始时间的事务提醒
		//Enumeration items = events.items(EventList.STARTING, rpStartDate, 0, true);
		Resource.appendLog("start seeking items", Resource.MESSAGE_LOG);
		Enumeration items = events.items();
		if(items != null && items.hasMoreElements()){
			Resource.appendLog("items read ok", Resource.MESSAGE_LOG);
		}
		
		// 从中查找对应标识的事务提醒并返回
		Event event = null;
		while(items.hasMoreElements()){
			event = (Event)items.nextElement();
			if(rpUID.equals(event.getString(Event.UID, 0))){
				Resource.appendLog("retrieve event ok", Resource.MESSAGE_LOG);
				return event;
			}
		}
		
		Resource.appendLog("retrieve event fail", Resource.MESSAGE_LOG);
		return null;
	}
	
//	private RepeatRule getRepeatRule(){
//		// 重复规则
//		RepeatRule rpRule = new RepeatRule();
//		
//		Calendar calendar = Calendar.getInstance();
//		calendar.setTime(new Date(rpStartDate));
//		// 重复类型
//		rpRule.setInt(RepeatRule.FREQUENCY, RepeatRule.DAILY + rpType);
//		switch(rpType){
//		case 0: // 每日提醒
//			break;
//		case 1: // 每周某天提醒
//			rpRule.setInt(RepeatRule.DAY_IN_WEEK, 0x20000 >> calendar.get(Calendar.DAY_OF_WEEK));
//			break;
//		case 2: // 每月某天提醒
//			rpRule.setInt(RepeatRule.DAY_IN_MONTH, calendar.get(Calendar.DAY_OF_MONTH));
//			break;
//		case 3: // 每年某天提醒
//			rpRule.setInt(RepeatRule.MONTH_IN_YEAR, 0x10000 << calendar.get(Calendar.MONTH));
//			rpRule.setInt(RepeatRule.DAY_IN_MONTH, calendar.get(Calendar.DAY_OF_MONTH));			
//			break;
//		}
//		
//		// 重复频率
//		rpRule.setInt(RepeatRule.INTERVAL, rpInterval);
//		// 结束日期
//		rpRule.setDate(RepeatRule.END, DateUtil.dayToDate(rpEndDay).getTime());
//		
//		return rpRule;
//	}
	
	private void setRepeatRule(Event event){
		// 重复规则
		RepeatRule rpRule = event.getRepeat();
		if(rpRule == null){
			rpRule = new RepeatRule();
		}
		
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date(rpStartDate));
		// 重复类型
		rpRule.setInt(RepeatRule.FREQUENCY, RepeatRule.DAILY + rpType);
		switch(rpType){
		case 0: // 每日提醒
			break;
		case 1: // 每周某天提醒
			rpRule.setInt(RepeatRule.DAY_IN_WEEK, 0x20000 >> calendar.get(Calendar.DAY_OF_WEEK));
			break;
		case 2: // 每月某天提醒
			rpRule.setInt(RepeatRule.DAY_IN_MONTH, calendar.get(Calendar.DAY_OF_MONTH));
			break;
		case 3: // 每年某天提醒
			rpRule.setInt(RepeatRule.MONTH_IN_YEAR, 0x10000 << calendar.get(Calendar.MONTH));
			rpRule.setInt(RepeatRule.DAY_IN_MONTH, calendar.get(Calendar.DAY_OF_MONTH));			
			break;
		}
		
		// 重复频率
		rpRule.setInt(RepeatRule.INTERVAL, rpInterval);
		// 结束日期
		rpRule.setDate(RepeatRule.END, DateUtil.dayToDate(rpEndDay).getTime());
		
		event.setRepeat(rpRule);
	}

    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3