从0到1学android:多媒体技术

点击上方“罗晓胜”,马上关注,您的支持对我帮助很大

上期文章

 

 

 

/   前言   /

 

    多媒体技术,官方定义是:多媒体是多种媒体的bai综合,一般包括du文本,声音和图像等多种zhi媒体形式。

    手机上有很多丰富的多媒体技术,常见的如:相机、相册、音视频播放器,另外还有通知,NFC等,在手机功能日益强大的今天,发一段视频肯定要比语音传递的信息更加丰富,而语音传递的信息又要比文字丰富。

 

/   正文   /

 

多媒体技术

使用通知Notification

通知(Notification)是Android 系统中比较有特色的一个功能,当某个应用程序希望向用户发出一些提示信息,而该应用程序又不在前台运行时,就可以借助通知来实现。发出一条通知后,手机最上方的状态栏中会显示一个通知的图标,下拉状态栏后可以看到通知的详细内容。

通知的用法

首先需要一个NotificationManager 来对通知进行管理,可以调用Context 的getSystemService()方法获取到。getSystemService()方法接收一个字符串参数用于确定获取系统的哪个服务, 这里我们传入Context.NOTIFICATION_SERVICE 即可。因此, 获取NotificationManager 的实例就可以写成:

NotificationManager manager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);

接下来需要创建一个Notification 对象,这个对象用于存储通知所需的各种信息,我们可以使用它的有参构造函数来进行创建。第一个参数用于指定通知的图标,比如项目的res/drawable 目录下有一张icon.png 图片,那么这里就可以传入R.drawable.icon。第二个参数用于指定通知的ticker 内容,当通知刚被创建的时候,它会在系统的状态栏一闪而过,属于一种瞬时的提示信息。第三个参数用于指定通知被创建的时间,以毫秒为单位,当下拉系统状态栏时,这里指定的时间会显示在相应的通知上。因此,创建一个Notification 对象就可以写成:

Notification notification = new Notification(R.drawable.icon, "This is ticker text",
System.currentTimeMillis());

创建好了Notification 对象后,我们还需要对通知的布局进行设定,这里只需要调用 Notification 的setLatestEventInfo()方法就可以给通知设置一个标准的布局。第一个参数是Context,这个没什么好解释的。第二个参数用于指定通知的标题内容,下拉系统状态栏就可以看到这部分内容。第三个参数用于指定通知的正文内容,同样下拉系统状态栏就可以看到这部分内容。第四个参数用于指定通知的点击效果,即PendingIntent,可以先传入null,。

notification.setLatestEventInfo(context, "This is content title", "This is content text", null);

以上工作都完成之后,只需要调用NotificationManager 的notify()方法就可以让通知显示出来了。notify()方法接收两个参数, 第一个参数是id,要保证为每个通知所指定的id 都是不同的。第二个参数则是Notification 对象,这里直接将我们刚刚创建好的Notification 对象传入即可。因此,显示一个通知就可以写成:

manager.notify(1, notification);

通知的点击效果PendingIntent

PendingIntent 从名字上看起来就和Intent 有些类似,它们之间也确实存在着不少共同点。比如它们都可以去指明某一个“意图”,都可以用于启动活动、启动服务以及发送广播等。不同的是,Intent 更加倾向于去立即执行某个动作,而PendingIntent 更加倾向于在某个合适的时机去执行某个动作。所以,也可以把PendingIntent 简单地理解为延迟执行的Intent。PendingIntent 的用法同样很简单,它主要提供了几个静态方法用于获取PendingIntent 的实例, getActivity()方法:启动一个活动 getBroadcast()方法:发送广播 还是getService()方法:启动服务

这几个方法所接收的参数都是相同的, 第一个参数依旧是Context,不用多做解释。第二个参数一般用不到,通常都是传入0 即可。第三个参数是一个Intent 对象,我们可以通过这个对象构建出PendingIntent 的“意图”。第四个参数用于确定PendingIntent 的行为,有FLAG_ONE_SHOT、FLAG_NO_CREATE、FLAG_CANCEL_CURRENT 和FLAG_UPDATE_CURRENT 这四种值可选,

因此,Notification 的setLatestEventInfo()方法的第四个参数传入PendingIntent 构建出一个延迟执行的“意图”,当用户点击这条通知时就会执行相应的逻辑。

代码如下:

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);

通知取消 调用NotificationManager 的cancel()方法就可以取消通知了。当时我们给这条通知设置的id 就是1。因此,如果你想要取消哪一条通知,就在cancel()方法中传入该通知的id 就行了。

NotificationManager manager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
manager.cancel(1);

通知的高级技巧

  1. 播放音频

Uri soundUri = Uri.fromFile(new File("/system/media/audio/ringtones/
Basic_tone.ogg"));
notification.sound = soundUri;
  1. 设置震动

例:所以,如果想要让手机在通知到来的时候立刻振动1 秒,然后静止1 秒,再振动1 秒,代码就可以写成:
long[] vibrates = {0, 1000, 1000, 1000};
notification.vibrate = vibrates;

不过,想要控制手机振动还需要声明权限的。因此,我们还得编辑AndroidManifest.xml
文件,加入如下声明:
<uses-permission android:name="android.permission.VIBRATE" />
……
  1. 设置前置LED灯 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;

  2. 使用通知的默认效果 当然,如果你不想进行那么多繁杂的设置,也可以直接使用通知的默认效果,它会根据 当前手机的环境来决定播放什么铃声,以及如何振动,写法如下:notification.defaults = Notification.DEFAULT_ALL; 注意,以上所涉及的这些高级技巧都要在手机上运行才能看得到效果,模拟器是无法表现出振动、以及LED 灯闪烁等功能的。

接收和发送短信

接受短信

其实接收短信主要是利用了我们在第5 章学习过的广播机制。当手机接收到一条短信的时候,系统会发出一条值为android.provider.Telephony.SMS_RECEIVED 的广播, 这条广播里携带着与短信相关的所有数据。每个应用程序都可以在广播接收器里对它进行监听,收到广播时再从中解析出短信的内容即可。

1.创建一个广播接收器来接收系统发出的短信广播
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);
}

2.MessageReceiver 进行注册才能让它接收到短信广播,代码如下所示:
public class MainActivity extends Activity {
    private TextView sender;
    private TextView content;
    private IntentFilter receiveFilter;
    private MessageReceiver messageReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        sender = (TextView) findViewById(R.id.sender);
        content = (TextView) findViewById(R.id.content);
        receiveFilter = new IntentFilter();
        receiveFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
        messageReceiver = new MessageReceiver();
        registerReceiver(messageReceiver, receiveFilter);
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(messageReceiver);
    }
……
}

拦截短信

我们就已经知道,有序广播的传递是可以截断的,而系统发出的短信广播正是一条有序广播,因此

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 = new MessageReceiver();
        registerReceiver(messageReceiver, receiveFilter);
    }
    ……
    class MessageReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            ……
            abortBroadcast();
        }
    }
}

发送短信

sendTextMessage()方法接收五个参数, 其中第一个参数用于指定接收人的手机号码, 第三个参数用于指定短信的内容, 第四个参数用于监控短信发送状态回执,例:PendingIntent pi = PendingIntent.getBroadcast(MainActivity.this, 0, sentIntent, 0); 其他的几个参数我们暂时用不到,直接传入null就可以了。

SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(to.getText().toString(), null,msgInput.getText().toString(), null, null);

权限申请:
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission. SEND_SMS" />
……

调用摄像头和相册

调用摄像头拍照

主要分为两步:1.启动相机程序 2.获取保存的图片

1.启动相机程序
private Uri imageUri;
// 创建File对象,用于存储拍照后的图片
File outputImage = new File(Environment.getExternalStorageDirectory(), "tempImage.jpg");
imageUri = Uri.fromFile(outputImage);

Intent intent = new Intent("android.media.action. IMAGE_CAPTURE");
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, TAKE_PHOTO); // 启动相机程序

2.获取保存的图片(这里使用onActivityResult实现)
@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;
    }
}

权限:<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

从相册中选择照片

// 创建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() 获取载入的音频文件的时长

1.初始化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();
    }
}
2.开始播放
mediaPlayer.start(); // 开始播放
3.暂停
mediaPlayer.pause(); // 暂停播放
4.停止播放
mediaPlayer.reset(); // 停止播放
initMediaPlayer();  //停止后如需重新播放需要重新初始化

5.释放MediaPlayer
protected void onDestroy() {
    super.onDestroy();
    if (mediaPlayer != null) {
        mediaPlayer.stop();
        mediaPlayer.release();
    }
}

播放视频

播放视频文件其实并不比播放音频文件复杂,主要是使用VideoView 类来实现的。主要有以下常用方法:

setVideoPath() 设置要播放的视频文件的位置。start() 开始或继续播放视频。pause() 暂停播放视频。resume() 将视频重头开始播放。seekTo() 从指定的位置开始播放视频。isPlaying() 判断当前是否正在播放视频。getDuration() 获取载入的视频文件的时长。

1.初始化VideoView
private void initVideoPath() {
File file = new File(Environment.getExternalStorageDirectory(),
"movie.3gp");
videoView.setVideoPath(file.getPath()); // 指定视频文件的路径
}

videoView.start(); // 开始播放
videoView.pause(); // 暂时播放
videoView.resume(); // 重新播放

2.释放VideoView
@Override
protected void onDestroy() {
super.onDestroy();
if (videoView != null) {
videoView.suspend();
}
}

 

/   总结   /

 

本文主要讲了多媒体技术的相关介绍,多媒体是手机中很重要的技术之一,学好它你能做出很多酷炫的App效果。

 

往期推荐:

如何入门做软件开发

为什么我不推荐入行程序员

做全栈开发很难吗

关注我的公众号,学习技术或投稿

长按上图,识别图中二维码即可关注

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值