本节内容:使用通知(基本用法/点击效果/取消通知/高级技巧)、接收和发送短信(接收短信/拦截短信/发送短信)、调用摄像头和相册、播放多媒体文件
使用通知------------------------------------------
基本用法:可以在活动(少)里创建,也可以在广播接收器里创建,服务里创建。
1、首先需要一个NotificationManager 来对通知进行管理,可以调用Context 的getSystemService()方法获取到并传入Context.NOTIFICATION_SERVICE 。
2、创建一个Notification 对象,有参构造函数接收三个参数,第一个参数用于指定通知的图标,第二个参数用于指定通知的ticker 内容,当通知刚被创建的时候,它会在系统的状态栏一闪而过,属于一种瞬时的提示信息。第三个参数用于指定通知被创建的时间,以毫秒为单位,当下拉系统状态栏时,这里指定的时间会显示在相应的通知上。
3、我们还需要对通知的布局进行设定,这里只需要调用Notification 的setLatestEventInfo()方法就可以给通知设置一个标准的布局。这个方法接收四个参数,第一个参数是Context。第二个参数用于指定通知的标题内容。第三个参数用于指定通知的正文内容。第四个参数我们暂时还用不到,可以先传入null。
4、最后需要调用NotificationManager 的notify()方法就可以让通知显示出来了。notify()方法接收两个参数,第一个参数是id,要保证为每个通知所指定的id 都是不同的。第二个参数则是Notification 对象。
栗子:在主活动里添加一个发送通知的按钮,并为其添加监听事件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
public
class
MainActivity
extends
Activity
implements
OnClickListener {
private
Button sendNotice;
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sendNotice = (Button) findViewById(R.id.send_notice);
sendNotice.setOnClickListener(
this
);
}
@Override
public
void
onClick(View v) {
switch
(v.getId()) {
case
R.id.send_notice:
NotificationManager manager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
Notification notification =
new
Notification(R.drawable.ic_launcher,
"This is ticker text"
, System.currentTimeMillis());
notification.setLatestEventInfo(
this
,
"This is content title"
,
"This is content text"
,
null
);
manager.notify(
1
, notification);
break
;
default
:
break
;
}
}
}
|
给通知添加点击效果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public
class
MainActivity
extends
Activity
implements
OnClickListener {
……
@Override
public
void
onClick(View v) {
switch
(v.getId()) {
case
R.id.send_notice:
NotificationManager manager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
Notification notification =
new
Notification(R.drawable.ic_launcher,
"This is ticker text"
, System.currentTimeMillis());
Intent intent =
new
Intent(
this
, NotificationActivity.
class
);
PendingIntent pi = PendingIntent.getActivity(
this
,
0
, intent,PendingIntent.FLAG_CANCEL_CURRENT);
notification.setLatestEventInfo(
this
,
"This is content title"
,
"This is content text"
, pi);
manager.notify(
1
, notification);
break
;
default
:
break
;
}
}
}
|
PendingIntent 的用法同样很简单,它主要提供了几个静态方法用于获取PendingIntent 的实例,可以根据需求来选择是使用getActivity()方法、getBroadcast()方法、还是getService()方法。这几个方法所接收的参数都是相同的,第一个参数依旧是Context,不用多做解释。第二个参数一般用不到,通常都是传入0 即可。第三个参数是一个Intent 对象,我们可以通过这个对象构建出PendingIntent 的“意图”。第四个参数用于确定PendingIntent 的行为,有FLAG_ONE_SHOT、FLAG_NO_CREATE、FLAG_CANCEL_CURRENT 和FLAG_UPDATE_CURRENT 这四种值可选。
取消通知:
1
2
3
4
5
6
7
8
9
10
|
public
class
NotificationActivity
extends
Activity {
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.notification_layout);
NotificationManager manager = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
manager.cancel(
1
);
}
}
|
通知的高级技巧:
sound属性:在通知发出的时候播放一段音频。sound 这个属性是一个Uri 对象,所以在指定音频文件的时候还需要先获取到音频文件对应的URI。比如说,我们手机的/system/media/audio/ringtones 目录下有一个Basic_tone.ogg音频文件,那么在代码中这样就可以这样指定:
Uri soundUri = Uri.fromFile(new File("/system/media/audio/ringtones/Basic_tone.ogg"));
notification.sound = soundUri;
vibrate属性:它是一个长整型的数组,用于设置手机静止和振动的时长,以毫秒为单位。下标为0 的值表示手机静止的时长,下标为1 的值表示手机振动的时长,下标为2 的值又表示手机静止的时长,以此类推。所以,如果想要让手机在通知到来的时候立刻振动1 秒,然后静止1 秒,再振动1 秒,代码就可以写成:
long[] vibrates = {0, 1000, 1000, 1000};
notification.vibrate = vibrates;
不过,想要控制手机振动还需要声明权限的。因此,我们还得编辑AndroidManifest.xml文件,加入如下声明:
<uses-permission android:name="android.permission.VIBRATE" />
控制手机LED 灯的显示:我们可以使用ledARGB、ledOnMS、ledOffMS 以及flags 这几个属性来实现这种效果。ledARGB 用于控制LED 灯的颜色,一般有红绿蓝三种颜色可选。ledOnMS 用于指定LED 灯亮起的时长,以毫秒为单位。ledOffMS用于指定LED 灯暗去的时长,也是以毫秒为单位。flags 可用于指定通知的一些行为,其中就包括显示LED 灯这一选项。
所以,当通知到来时,如果想要实现LED 灯以绿色的灯光一闪一闪的效果,就可以写成:
notification.ledARGB = Color.GREEN;
notification.ledOnMS = 1000;
notification.ledOffMS = 1000;
notification.flags = Notification.FLAG_SHOW_LIGHTS;
使用通知的默认效果,它会根据当前手机的环境来决定播放什么铃声,以及如何振动,写法如下:
notification.defaults = Notification.DEFAULT_ALL;
注意,以上所涉及的这些高级技巧都要在手机上运行才能看得到效果,模拟器是无法表现出振动、以及LED 灯闪烁等功能的。
接收和发送短信---------------------------------------
接收短信主要是利用了广播机制。当手机接收到一条短信的时候,系统会发出一条值为android.provider.Telephony.SMS_RECEIVED 的广播,这条广播里携带着与短信相关的所有数据。每个应用程序都可以在广播接收器里对它进行监听,收到广播时再从中解析出短信的内容即可。
新建一个SMSTest 项目,首先修改activity_main.xml 中的代码,如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
<
LinearLayout
xmlns:android
=
"http://schemas.android.com/apk/res/android"
android:layout_width
=
"match_parent"
android:layout_height
=
"match_parent"
android:orientation
=
"vertical"
>
<
LinearLayout
android:layout_width
=
"match_parent"
android:layout_height
=
"50dp"
>
<
TextView
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:layout_gravity
=
"center_vertical"
android:padding
=
"10dp"
android:text
=
"From:"
/>
<
TextView
android:id
=
"@+id/sender"
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:layout_gravity
=
"center_vertical"
/>
</
LinearLayout
>
<
LinearLayout
android:layout_width
=
"match_parent"
android:layout_height
=
"50dp"
>
<
TextView
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:layout_gravity
=
"center_vertical"
android:padding
=
"10dp"
android:text
=
"Content:"
/>
<
TextView
android:id
=
"@+id/content"
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:layout_gravity
=
"center_vertical"
/>
</
LinearLayout
>
</
LinearLayout
>
|
接着修改MainActivity 中的代码,在onCreate()方法中获取到两个TextView 的实例;
然后我们需要创建一个广播接收器来接收系统发出的短信广播。并在onReceive()方法中编写获取短信数据的逻辑,代码如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
public
class
MainActivity
extends
Activity {
……
class
MessageReceiver
extends
BroadcastReceiver {
@Override
public
void
onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
Object[] pdus = (Object[]) bundle.get(
"pdus"
);
// 提取短信消息
SmsMessage[] messages =
new
SmsMessage[pdus.length];
for
(
int
i =
0
; i < messages.length; i++) {
messages[i] = SmsMessage.createFromPdu((
byte
[]) pdus[i]);
}
String address = messages[
0
].getOriginatingAddress();
// 获取发送方号码
String fullMessage =
""
;
for
(SmsMessage message : messages) {
fullMessage += message.getMessageBody();
// 获取短信内容
}
sender.setText(address);
content.setText(fullMessage);
}
}
}
|
可以看到,首先我们从Intent 参数中取出了一个Bundle 对象,然后使用pdu 密钥来提取一个SMS pdus 数组,其中每一个pdu 都表示一条短信消息。接着使用SmsMessage 的()方法将每一个pdu 字节数组转换为SmsMessage 对象,调用这个对象的getOriginatingAddress()方法就可以获取到短信的发送方号码,调用getMessageBody()方法就获取到短信的内容,然后将每一个SmsMessage 对象中的短信内容拼接起来,就组成了完整的短信。最后将获取到的发送方号码和短信内容显示在TextView 上。
完成了MessageReceiver 之后,我们还需要对它进行注册(动态)以及取消。
代码到这里就已经完成得差不多了,不过最后我们还需要给程序声明一个接收短信的权限才行,修改AndroidManifest.xml 中的代码,如下所示:
<uses-permission android:name="android.permission.RECEIVE_SMS" />
拦截短信:系统发出的短信广播正是一条有序广播;
修改MainActivity中的代码,如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
public
class
MainActivity
extends
Activity {
……
@Override
protected
void
onCreate(Bundle savedInstanceState) {
……
receiveFilter =
new
IntentFilter();
receiveFilter.addAction(
"android.provider.Telephony.SMS_RECEIVED"
);
receiveFilter.setPriority(
100
);
//一是提高MessageReceiver 的优先级
messageReceiver =
new
MessageReceiver();
registerReceiver(messageReceiver, receiveFilter);
}
……
class
MessageReceiver
extends
BroadcastReceiver {
@Override
public
void
onReceive(Context context, Intent intent) {
……
abortBroadcast();
//二是在onReceive()方法中调用abortBroadcast()方法
}
}
}
|
注意:随意拦截短信有可能会造成重要数据的丢失,所以你在拦截之前一定要先想清楚这种功能是不是你想要的。
发送短信:下面我们继续对SMSTest 项目进行扩展,给它加上发送短信的功能。
修改activity_main.xml 中的代码,如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
<
LinearLayout
xmlns:android
=
"http://schemas.android.com/apk/res/android"
android:layout_width
=
"match_parent"
android:layout_height
=
"match_parent"
android:orientation
=
"vertical"
>
……
<
LinearLayout
android:layout_width
=
"match_parent"
android:layout_height
=
"50dp"
>
<
TextView
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:layout_gravity
=
"center_vertical"
android:padding
=
"10dp"
android:text
=
"To:"
/>
<
EditText
android:id
=
"@+id/to"
android:layout_width
=
"0dp"
android:layout_height
=
"wrap_content"
android:layout_gravity
=
"center_vertical"
android:layout_weight
=
"1"
/>
</
LinearLayout
>
<
LinearLayout
android:layout_width
=
"match_parent"
android:layout_height
=
"50dp"
>
<
EditText
android:id
=
"@+id/msg_input"
android:layout_width
=
"0dp"
android:layout_height
=
"wrap_content"
android:layout_gravity
=
"center_vertical"
android:layout_weight
=
"1"
/>
<
Button
android:id
=
"@+id/send"
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:layout_gravity
=
"center_vertical"
android:text
=
"Send"
/>
</
LinearLayout
>
</
LinearLayout
>
|
然后修改MainActivity 中的代码,在里面加入发送短信的处理逻辑,代码如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
public
class
MainActivity
extends
Activity {
……
private
EditText to;
private
EditText msgInput;
private
Button send;
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
……
to = (EditText) findViewById(R.id.to);
msgInput = (EditText) findViewById(R.id.msg_input);
send = (Button) findViewById(R.id.send);
send.setOnClickListener(
new
OnClickListener() {
@Override
public
void
onClick(View v) {
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(to.getText().toString(),
null
,
msgInput.getText().toString(),
null
,
null
);
}
});
}
……
}
|
可以看到,首先我们获取到了布局文件中新增控件的实例,然后在Send 按钮的点击事件里面处理了发送短信的具体逻辑。当Send 按钮被点击时,会先调用SmsManager 的getDefault()方法获取到SmsManager 的实例,然后再调用它的sendTextMessage()方法就可以去发送短信了。sendTextMessage()方法接收五个参数,其中第一个参数用于指定接收人的手机号码,第三个参数用于指定短信的内容,其他的几个参数我们暂时用不到,直接传入null就可以了。
接下来也许你已经猜到了,发送短信也是需要声明权限的,因此修改AndroidManifest.xml中的代码,如下所示:
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission. SEND_SMS" />
利用sendTextMessage()方法的第四个参数来对短信的发送状态进行监控。修改MainActivity 中的代码,如下所示:
public class MainActivity extends Activity {
……
private IntentFilter sendFilter;
private SendStatusReceiver sendStatusReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
……
sendFilter = new IntentFilter();
sendFilter.addAction("SENT_SMS_ACTION");
sendStatusReceiver = new SendStatusReceiver();
registerReceiver(sendStatusReceiver, sendFilter);
send.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
SmsManager smsManager = SmsManager.getDefault();
Intent sentIntent = new Intent("SENT_SMS_ACTION");
PendingIntent pi = PendingIntent.getBroadcast(MainActivity.this, 0, sentIntent, 0);
smsManager.sendTextMessage(to.getText().toString(), null,msgInput.getText().toString(), pi, null);
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(messageReceiver);
unregisterReceiver(sendStatusReceiver);
}
……
class SendStatusReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (getResultCode() == RESULT_OK) {
// 短信发送成功
Toast.makeText(context, "Send succeeded",Toast.LENGTH_LONG).show();
} else {
// 短信发送失败
Toast.makeText(context, "Send failed",Toast.LENGTH_LONG).show();
}
}
}
}
另外,根据国际标准,每条短信的长度不得超过160 个字符,如果想要发送超出这个长度的短信,则需要将这条短信分割成多条短信来发送,使用SmsManager 的sendMultipart-TextMessage()方法就可以实现上述功能。它的用法和sendTextMessage()方法也基本类似
调用摄像头和相册---------------------------------------------
将程序运行到手机上(使用真机模拟)先通过数据线把手机连接到电脑上。然后进入到设置→开发者选项界面,并在这个界面中勾选中USB 调试选项,如图8.9 所示。注意从Android4.2 版本开始,系统默认是把开发者选项隐藏掉的,你需要先进入到关于手机界面,然后对着最下面的版本号那一栏连击四次,就会让开发者选项显示出来。
然后如果你使用的是Windows 操作系统,还需要在电脑上安装手机的驱动。一般借助91 手机助手或豌豆荚等工具都可以快速地进行安装,安装完成后就可以看到手机已经连接到电脑上了
现在进入到Eclipse 的DDMS 视图,你会发现当前是有两个设备在线的,一个是我们一直使用的模拟器,另外一个则是刚刚连接上的手机了
然后,对着Eclipse 中的任何一个项目右击→Run As→Android Application,这时不会直接将程序运行到模拟器或者手机上,而是会弹出一个对话框让你进行选择
选择第一行的那个设备后点击OK,就会将程序运行到手机上了。
调用摄像头拍照
public class MainActivity extends Activity {
public static final int TAKE_PHOTO = 1;
public static final int CROP_PHOTO = 2;
private Button takePhoto;
private ImageView picture;
private Uri imageUri;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
takePhoto = (Button) findViewById(R.id.take_photo);
picture = (ImageView) findViewById(R.id.picture);
takePhoto.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 创建File对象,用于存储拍照后的图片
File outputImage = new File(Environment.
getExternalStorageDirectory(), "tempImage.jpg");
try {
if (outputImage.exists()) {
outputImage.delete();
}
outputImage.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
imageUri = Uri.fromFile(outputImage);
Intent intent = new Intent("android.media.action. IMAGE_CAPTURE");
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, TAKE_PHOTO); // 启动相机程序
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case TAKE_PHOTO:
if (resultCode == RESULT_OK) {
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(imageUri, "image/*");
intent.putExtra("scale", true);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, CROP_PHOTO); // 启动裁剪程序
}
break;
case CROP_PHOTO:
if (resultCode == RESULT_OK) {
try {
Bitmap bitmap = BitmapFactory.decodeStream
(getContentResolver()
.openInputStream(imageUri));
picture.setImageBitmap(bitmap); // 将裁剪后的照片显示出来
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
break;
default:
break;
}
}
}
首先这里创建了一个File 对象,用于存储摄像头拍下的图片,这里我们把图片命名为
output_image.jpg , 并将它存放在手机SD 卡的根目录下, 调用Environment 的
getExternalStorageDirectory()方法获取到的就是手机SD 卡的根目录。然后再调用Uri 的
fromFile()方法将File 对象转换成Uri 对象,这个Uri 对象标识着output_image.jpg 这张图片
的唯一地址。接着构建出一个Intent对象,并将这个Intent的action指定为android.media.action.
IMAGE_CAPTURE,再调用Intent 的putExtra()方法指定图片的输出地址,这里填入刚刚得
到的Uri 对象,最后调用startActivityForResult()来启动活动。由于我们使用的是一个隐式
Intent,系统会找出能够响应这个Intent 的活动去启动,这样照相机程序就会被打开,拍下的
照片将会输出到output_image.jpg 中。
注意刚才我们是使用startActivityForResult()来启动活动的,因此拍完照后会有结果返回
到onActivityResult()方法中。如果发现拍照成功,则会再次构建出一个Intent 对象,并把它
的action 指定为com.android.camera.action.CROP。这个Intent 是用于对拍出的照片进行裁剪
326
第2 章先从看得到的入手,探究活动
的,因为摄像头拍出的照片都比较大,而我们可能只希望截取其中的一小部分。然后给这个
Intent 设置上一些必要的属性,并再次调用startActivityForResult()来启动裁剪程序。裁剪后
的照片同样会输出到output_image.jpg 中。
裁剪操作完成之后,程序又会回调到onActivityResult()方法中,这个时候我们就可以调
用BitmapFactory 的decodeStream()方法将output_image.jpg 这张照片解析成Bitmap 对象,然
后把它设置到ImageView 中显示出来。
由于这个项目涉及到了向SD 卡中写数据的操作,因此我们还需要在AndroidManifest.xml
中声明权限:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.choosepictest"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
……
</manifest>
从相册中选择照片
修改MainActivity 中的代码,加入从相册选择照片的逻辑,代码如下所示:
public class MainActivity extends Activity {
……
private Button chooseFromAlbum;
329
第一行代码——Android
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
……
chooseFromAlbum = (Button) findViewById(R.id.choose_from_album);
chooseFromAlbum.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 创建File对象,用于存储选择的照片
File outputImage = new File(Environment.
getExternalStorageDirectory(), "output_image.jpg");
try {
if (outputImage.exists()) {
outputImage.delete();
}
outputImage.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
imageUri = Uri.fromFile(outputImage);
Intent intent = new Intent("android.intent.action.
GET_CONTENT");
intent.setType("image/*");
intent.putExtra("crop", true);
intent.putExtra("scale", true);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, CROP_PHOTO);
}
});
}
……
}
某些照片即使经过裁剪后体积仍然很大,直接加
载到内存中有可能会导致程序崩溃。更好的做法是根据项目的需求先对照片进行适当的压
缩,然后再加载到内存中。
播放多媒体文件------------------------------------------------
在Android 中播放音频文件一般都是使用MediaPlayer 类来实现的,它对多种格式的音
频文件提供了非常全面的控制方法,从而使得播放音乐的工作变得十分简单。下表列出了
MediaPlayer 类中一些较为常用的控制方法。
方法名功能描述
setDataSource() 设置要播放的音频文件的位置。
prepare() 在开始播放之前调用这个方法完成准备工作。
start() 开始或继续播放音频。
pause() 暂停播放音频。
reset() 将MediaPlayer 对象重置到刚刚创建的状态。
seekTo() 从指定的位置开始播放音频。
stop() 停止播放音频。调用这个方法后的MediaPlayer 对象无法再播放音频。
release() 释放掉与MediaPlayer 对象相关的资源。
isPlaying() 判断当前MediaPlayer 是否正在播放音频。
getDuration() 获取载入的音频文件的时长。
简单了解了上述方法后,我们再来梳理一下MediaPlayer 的工作流程。首先需要创建出
一个MediaPlayer 对象,然后调用setDataSource()方法来设置音频文件的路径,再调用prepare()
333
第一行代码——Android
方法使MediaPlayer 进入到准备状态,接下来调用start()方法就可以开始播放音频,调用pause()
方法就会暂停播放,调用reset()方法就会停止播放。
public class MainActivity extends Activity implements OnClickListener {
private Button play;
private Button pause;
334
第2 章先从看得到的入手,探究活动
private Button stop;
private MediaPlayer mediaPlayer = new MediaPlayer();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
play = (Button) findViewById(R.id.play);
pause = (Button) findViewById(R.id.pause);
stop = (Button) findViewById(R.id.stop);
play.setOnClickListener(this);
pause.setOnClickListener(this);
stop.setOnClickListener(this);
initMediaPlayer(); // 初始化MediaPlayer
}
private void initMediaPlayer() {
try {
File file = new File(Environment.getExternalStorageDirectory(),
"music.mp3");
mediaPlayer.setDataSource(file.getPath()); // 指定音频文件的路径
mediaPlayer.prepare(); // 让MediaPlayer进入到准备状态
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.play:
if (!mediaPlayer.isPlaying()) {
mediaPlayer.start(); // 开始播放
}
break;
case R.id.pause:
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause(); // 暂停播放
}
335
第一行代码——Android
break;
case R.id.stop:
if (mediaPlayer.isPlaying()) {
mediaPlayer.reset(); // 停止播放
initMediaPlayer();
}
break;
default:
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
}
}
}
播放视频
主要是使用VideoView 类来实现的。这个
类将视频的显示和控制集于一身,使得我们仅仅借助它就可以完成一个简易的视频播放器。
VideoView 的用法和MediaPlayer 也比较类似,主要有以下常用方法:
方法名功能描述
setVideoPath() 设置要播放的视频文件的位置。
start() 开始或继续播放视频。
pause() 暂停播放视频。
resume() 将视频重头开始播放。
seekTo() 从指定的位置开始播放视频。
isPlaying() 判断当前是否正在播放视频。
getDuration() 获取载入的视频文件的时长。
337
public class MainActivity extends Activity implements OnClickListener {
private VideoView videoView;
private Button play;
private Button pause;
private Button replay;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
play = (Button) findViewById(R.id.play);
pause = (Button) findViewById(R.id.pause);
replay = (Button) findViewById(R.id.replay);
videoView = (VideoView) findViewById(R.id.video_view);
play.setOnClickListener(this);
pause.setOnClickListener(this);
replay.setOnClickListener(this);
initVideoPath();
}
private void initVideoPath() {
File file = new File(Environment.getExternalStorageDirectory(),
"movie.3gp");
videoView.setVideoPath(file.getPath()); // 指定视频文件的路径
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.play:
if (!videoView.isPlaying()) {
videoView.start(); // 开始播放
339
第一行代码——Android
}
break;
case R.id.pause:
if (videoView.isPlaying()) {
videoView.pause(); // 暂时播放
}
break;
case R.id.replay:
if (videoView.isPlaying()) {
videoView.resume(); // 重新播放
}
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (videoView != null) {
videoView.suspend();
}
}
}