23 广播服务结合音乐Demo5
MainActivity.java
package com.dmy.demo5;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
public class MainActivity extends Activity {
private TextView time;
private SeekBar seekBar;
private Button play;
private Button stop;
private BroadcastReceiver receiver;
boolean onTouch =false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化控件
init();
}
private void init() {
time = (TextView) findViewById(R.id.time);
seekBar = (SeekBar) findViewById(R.id.seek_bar);
play = (Button) findViewById(R.id.play);
stop = (Button) findViewById(R.id.stop);
//为进度条设置监听
seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
//用户停止进度条操作
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
Intent intent = new Intent();
intent.setAction(com.dmy.demo5.Menu.SERVER_INTENT);
//flase意义表示播放音乐 true为暂停
intent.putExtra(com.dmy.demo5.Menu.IS_PAUSE, false);
intent.putExtra(Menu.POS, seekBar.getProgress());
sendBroadcast(intent);
onTouch=false;
}
//用户手指点击点击
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
//给服务发送一个暂停状态过去
Intent intent = new Intent();
intent.setAction(com.dmy.demo5.Menu.SERVER_INTENT);
intent.putExtra(com.dmy.demo5.Menu.IS_PAUSE, true);
//-1表示不改变当前进度
intent.putExtra(com.dmy.demo5.Menu.POS, -1);
onTouch = true;
sendBroadcast(intent);
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
}
});
receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// 音乐的总长度
int total = intent.getIntExtra(com.dmy.demo5.Menu.TOTAL, 0);
// 音乐当前位置
int pos = intent.getIntExtra(com.dmy.demo5.Menu.POS, 0);
// 音乐总分钟
int totalM = total / 1000 / 60;
// 音乐总分钟剩余秒
int totalS = total / 1000 % 60;
// 音乐当前分钟
int posM = pos / 1000 / 60;
// 音乐总分钟剩余秒
int posS = pos / 1000 % 60;
StringBuilder sb = new StringBuilder();
sb.append(posM / 10)
.append(posM % 10)
.append(":")
.append(posS / 10)
.append(posS % 10)
.append("/")
.append(totalM / 10).append(totalM % 10).append(":").append(totalS / 10).append(totalS % 10);
time.setText(sb);
seekBar.setMax(total);
if (!onTouch) {
seekBar.setProgress(pos);
}
}
};
Intent intent = new Intent("com.dmy.demo5.MyServer");
// 6.0需要写上包
intent.setPackage(getPackageName());
// 开启服务
startService(intent);
//注册广播
IntentFilter filter = new IntentFilter();
filter.addAction(com.dmy.demo5.Menu.UI_INTENT);
registerReceiver(receiver, filter);
}
public void play(View v) {
boolean flag = false;
// 如果当前按钮的内容是暂停则返回true
flag = "暂停".equals(play.getText());
// 给按钮设置新的文字
String newFlag = flag ? "播放" : "暂停";
play.setText(newFlag);
Intent intent = new Intent();
intent.setAction(com.dmy.demo5.Menu.SERVER_INTENT);
intent.putExtra(com.dmy.demo5.Menu.IS_PAUSE, flag);
//-1表示不改变当前进度
intent.putExtra(com.dmy.demo5.Menu.POS, -1);
sendBroadcast(intent);
}
public void stop(View v) {
}
}
Menu.java
package com.dmy.demo5;
public class Menu {
// 在itent中传入值 boolean如果为true是暂停状态的按钮
public static final String IS_PAUSE = "isPause";
// 判断是否按下停止状态
public static final String IS_STOP = "is_stop";
// 音乐当前位置
public static final String POS = "pos";
// 发送服务广播的意图
public static final String SERVER_INTENT = "updata.music.server";
// 发送UI界面广播的意图
public static final String UI_INTENT = "updata.music.ui";
// 音乐总时长
public static final String TOTAL = "total";
}
MyServer.java
package com.dmy.demo5;
import java.io.IOException;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.MediaPlayer;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
public class MyServer extends Service {
private MediaPlayer mp;
int pos = 0;
// 用于接收音乐播放时用户点击按钮和拉动滚动条
private BroadcastReceiver stateReceiver;
boolean flagStop = false;
@Override
public void onCreate() {
super.onCreate();
mp = MediaPlayer.create(getApplicationContext(), R.raw.wlxq);
// 初始化广播接受者
initBroadCast();
// 初始化线程不断发送消息 改变UI
initThread();
}
// 初始化线程不断发送消息 改变UI
public void initThread() {
new Thread() {
public void run() {
while (true) {
Intent intent = new Intent(Menu.UI_INTENT);
if (mp != null) {
intent.putExtra(Menu.TOTAL, mp.getDuration());
intent.putExtra(Menu.POS, mp.getCurrentPosition());
}
if (!flagStop) {
sendBroadcast(intent);
}
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
}.start();
}
private void initBroadCast() {
stateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// 如果为true 现在的状态是用户点击了了暂停按钮
Boolean is_pause = intent.getBooleanExtra(Menu.IS_PAUSE, false);
if (is_pause && mp != null) {
mp.pause();
} else if (mp != null) {
pos = intent.getIntExtra(Menu.POS, -1);
mp.seekTo(pos);
// 否则用户点了播放按钮
mp.start();
}
}
};
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// 注册广播接受者
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("updata.music.server");
registerReceiver(stateReceiver, intentFilter);
Log.e("fmy", "onStartCommand");
return START_NOT_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return new MyBinder();
}
class MyBinder extends Binder {
public MyServer getServer() {
return MyServer.this;
}
}
}
清单文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.dmy.demo5"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="21" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".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>
<service android:name="com.dmy.demo5.MyServer">
<intent-filter>
<action android:name="com.dmy.demo5.MyServer"></action>
</intent-filter>
</service>
</application>
</manifest>
23 广播服务结合音乐Demo5的更多相关文章
- Openfire开发广播服务接口,支持离线广播消息
Openfire开发广播服务接口,支持离线广播消息 概要 最近公司要求做一个web端向所有移动端发送公告,所以考虑到即时性就用openfire做服务.不过为了减轻web端的工作量,我们开发一个简单的插 ...
- CentOS 7下MySQL5.7.23的服务配置参数测试
CentOS 7默认安装MySQL5.7.23,服务管理发生了变化,从sysvinit(service mysql start)变化为systemd(systemctl start mysqld.se ...
- 2-3 sshd服务---暴力破解应对策略
sshd服务暴力破解步骤 sshd暴力破解方法 防止暴力破解调优 1. 变更默认端口 2. 变更root用户 3. 日志监控-->防止暴力破解(fail2ban应用) fail2ban详解 ...
- vlc 播放器的点播和广播服务
vlc 是一个开源的,同时跨平台的播放器.在研究 rtsp 协议时发现,它同时还是一个强大的流媒体服务器 VLM VLM(VideoLAN Manager) 在 vlc 中是一个小型的媒体管理器,它能 ...
- Android应用开发基础之八:广播与服务(二)
服务两种启动方式 startService:服务被启动之后,跟启动它的组件没有一毛钱关系 bindService:跟启动它的组件同生共死 绑定服务和解绑服务的生命周期方法:onCreate->o ...
- Android开发学习—— Service 服务
Service运行于后台的一个组件,用来运行适合运行在后台的代码,服务是没有前台界面,可以视为没有界面的activity. 服务可以被手动关闭,不会重启,但是如果被自动关闭,内存充足就会重启. sta ...
- iOS开发——高级技术&蓝牙服务
蓝牙服务 蓝牙 随着蓝牙低功耗技术BLE(Bluetooth Low Energy)的发展,蓝牙技术正在一步步成熟,如今的大部分移动设备都配备有蓝牙4.0,相比之前的蓝牙技术耗电量大大降低.从iOS的 ...
- Linux多线程服务端编程:使用muduo C++网络库
内容推荐本 书主要讲述采用现代C++在x86-64 Linux上编写多线程TCP网络服务程序的主流常规技术,重点讲解一种适应性较强的多线程服务器的编程模型,即one loop per thread.这 ...
- Android服务——Service
服务 Service 是一个可以在后台执行长时间运行操作而不使用用户界面的应用组件.服务可由其他应用组件启动,而且即使用户切换到其他应用,服务仍将在后台继续运行. 此外,组件可以绑定到服务,以与之进行 ...
随机推荐
- MySQL 并行复制从库发生自动重启分析
并行复制从库发生自动重启分析 背景 半同步复制从库在晚上凌晨2点半发生自动重启,另一个异步复制从库在第二天凌晨3点也发生了自动重启. 分析 版本mysql 5.7.16 mysql> show ...
- TCP三次握手详解及释放连接过程
TCP在传输之前会进行三次沟通,一般称为"三次握手",传完数据断开的时候要进行四次沟通,一般称为"四次挥手". 两个序号和三个标志位: (1)序号:seq序号, ...
- [HNOI 2002]营业额统计
Description 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司成立以来每 ...
- [Codeforces 863D]Yet Another Array Queries Problem
Description You are given an array a of size n, and q queries to it. There are queries of two types: ...
- TopCoder SRM 558 Div 1 - Problem 1000 SurroundingGame
传送门:https://284914869.github.io/AEoj/558.html 题目简述 一个人在一个n * m棋盘上玩游戏,想要占领一个格子有两个方法: 在这个格子放一个棋子. 这个 ...
- 【USACO】干草金字塔
题目描述 贝西要用干草包堆出一座金字塔.干草包会从传送带上陆续运来,依次出现 N 包,每包干草可 以看做是一个二维平面上的一个长方形,第 i 包干草的宽度是 W i ,长度统一为 1. 金字塔的修建有 ...
- bzoj 2783: [JLOI2012]树
Description 在这个问题中,给定一个值S和一棵树.在树的每个节点有一个正整数,问有多少条路径的节点总和达到S.路径中节点的深度必须是升序的.假设节点1是根节点,根的深度是0,它的儿子节点的深 ...
- Python之作业购物车
作业之购物车优化 购物车优化要求如下: 用户入口: 启动程序后,输入用户名密码后,如果是第一次登录,让用户输入工资,然后打印商品列表 允许用户根据商品编号购买商品 用户选择商品后,检测余额是否够,够就 ...
- SQl语句中使用占位符的优点
1.增加SQL代码可读性2.占位符可以预先编译,提高执行效率3.防止SQL注入4用占位符的目的是绑定变量,这样可以减少数据SQL的硬解析,所以执行效率会提高不少 绑定变量是Oracle解决硬解析的首要 ...
- selenium登录163邮箱
环境:windows8 python2.7+selenium+chrome 直接上脚本: # coding=utf-8from selenium import webdriverimport tim ...