学习笔记(十)运用通知和手机多媒体

一. 通知

当某个应用程序希望向用户发出一些提示信息,而该应用程序又不在前台运行时,就可以借助通知 Notification 来实现。

1. 创建通知

(1)创建 NotificationManager:
首先需要一个 NotificationManager 来对通知进行管理,可以调用 Context 的getSystemService()方法获取到。这个方法接收一个字符串参数用于确定获取系统的哪个服务。

NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

(2)对通知的布局进行设定:
《第一行代码》书上的setLatestEventInfo()方法只能用在 API 11 以下,所以用不了了。

参考了下:http://www.piaoyi.org/mobile-app/Android-setLatestEventInfo-Handler-SimpleDateFormat.htmlhttp://stackoverflow.com/questions/32345768/cannot-resolve-method-setlatesteventinfo
高于API Level 11,低于 API Level 16 (Android 4.1.2)版本的系统中,可使用 Notification.Builder 来构造函数。但要使用getNotification()来使 notification 实现。

Notification.Builder builder = new Notification.Builder(context);//通过builder来对通知的布局进行设定
builder.setSmallIcon(R.mipmap.ic_launcher);//设置通知的图标
builder.setWhen(System.currentTimeMillis());//设置通知出现时长
builder.setTicker("瞬时的提示信息");//设置通知的瞬时的提示信息
builder.setContentTitle("通知内容标题");//设置下拉系统状态栏的通知的内容标题
builder.setContentText("通知内容");//设置下拉系统状态栏的通知的内容

Notification notification = builder.getNotification();

  
高于API Level 16的版本,就可以用 Builder 和 build() 函数实现 notification 了。

Notification notification = new Notification.Builder(context)    
         .setAutoCancel(true)    
         .setContentTitle("title")    
         .setContentText("describe")    
         .setContentIntent(pendingIntent)    
         .setSmallIcon(R.drawable.ic_launcher)    
         .setWhen(System.currentTimeMillis())    
         .build()

(3)让通知显示出来
调用 NotificationManager 的notify()方法,接收两个参数,id(要保证每个通知所指定的 id 都是不同的)和 Notification 对象。

manager.notify(1, notification);

2. 通知的点击事件

  要想实现通知的点击效果,需要使用 PendingIntent,可以把 PendingIntent 简单地理解为延迟执行的 Intent。

PendingIntent 通过getActivity()方法获得,方法接收四个参数:Context, 0, intent, flag。第二个参数通常为 0,最后一个参数有 FLAG_ONE_SHOT、FLAG_NO_CREATE、FLAG_CANCEL_CURRENT和FLAG_UPDATE_CURRENT 四种值可选。

例子如下:

private Button sendNotice;
private Notification notification;
private NotificationManager manager;

...

/*高于API Level 11,低于API Level 16 (Android 4.1.2)版本的系统中,可使用Notification.Builder来构造函数。但要使用getNotification()来使notification实现。
 *高于API Level 16的版本,就可以用Builder和build()函数实现notification了。
 */    
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.send_notice:

                manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
                Notification.Builder builder = new Notification.Builder(MainActivity.this);
                Intent intent = new Intent(MainActivity.this, NotificationActivity.class);//用Intent表达出想要启动NotificationActivity的意图
                PendingIntent pendingIntent = PendingIntent.getActivity(MainActivity.this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);//把Intent对象传入,当点击系统栏的通知就会实现跳转了

                /*下面设定通知布局*/
                builder.setAutoCancel(true);//点击下拉系统栏的通知,通知会自动消失
                builder.setSmallIcon(R.mipmap.ic_launcher);
                builder.setWhen(System.currentTimeMillis());
                builder.setTicker("瞬时的提示信息");
                builder.setContentTitle("通知内容标题");
                builder.setContentText("通知内容");
                builder.setContentIntent(pendingIntent);//别忘了pendingIntent,实现跳转

                notification = builder.getNotification();

                notification.defaults = Notification.DEFAULT_SOUND;//使用系统默认通知声

                manager.notify(1, notification);//指定id,显示出通知

                break;
            default:
                break;
        }
    }

  
另外,需要在点击之后关闭通知的话:
(1)可以直接在 MainActivity 中设置:

builder.setAutoCancel(true);//点击下拉系统栏的通知,通知会自动消失

(2)或者在 NotificationActivity 中调用cancel()来取消通知:

NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
manager.cancel(1);//这个 1 是创建通知的时候指定的id

二. 短信

1. 发送短信

获取 SMSManager 的实例

SMSManager smsmanager = SmsManager.getDefault();

调用SmsManager.sendTextMessage()方法。

private EditText to;
private EditText msgInput;
...

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

2. 接收短信

自定义一个接受短信消息的广播接收器,在onReceive()方法中编写解析短信的逻辑代码。


三. 摄像头和相册

创建一个 File 对象,用于存储摄像头拍下的图片,调用getExternalStorageDirectory()方法获取手机 SD 卡的根目录,再调用 Uri 的fromFile()将 File 对象转换成 Uri 对象,接着构建出一个 Intent 对象,最后调用startActivityForResult()启动活动。

public class MainActivity extends AppCompatActivity {

    public static final int TAKE_PHOTO = 1;
    public static final int CROP_PHOTO = 2;
    //public static final int CHOOSE_PHOTO = 3;
    //private Button choose;
    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);
        //choose = (Button) findViewById(R.id.choose);

        takePhoto.setOnClickListener(new View.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);//将File对象转换成Uri对象,这个Uri对象标识着output_image.jpg这张图片的唯一地址
                Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
                intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);//指定图片的输出地址
                startActivityForResult(intent, TAKE_PHOTO);//启动相机程序
            }
        });

        //选择相册中的图片
        choose.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent("android.intent.action.GET_CONTENT");
                intent.setType("image/*");
                startActivityForResult(intent, CHOOSE_PHOTO);
            }
        });


在回调函数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));//将output_image.jpg这张照片解析成Bitmap对象
                        picture.setImageBitmap(bitmap);//将裁剪后的照片显示出来
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                }
                break;
            case CHOOSE_PHOTO:
                if (resultCode == RESULT_OK) {
                //判断手机系统版本号
                    if (Build.VERSION.SDK_INT >= 19) {
                    //4.4及以上系统使用这个方法处理图片
                        handleImageOnKitKat(data);
                    } else {
                    //4.4以下使用这个方法
                        handleImageBeforeKitKat(data);
                    }
                }
                break;
            default:
                break;
        }
    }

    @TargetApi(19)
    private void handleImageOnKitKat(Intent data) {
        String imagePath = null;
        Uri uri = data.getData();
        if (DocumentsContract.isDocumentUri(this, uri)) {
        //如果是document类型的Uri,则通过document id处理
            String docId = DocumentsContract.getDocumentId(uri);
            if ("com.android.providers.media.documents".equals(uri.getAuthority())) {
                String id = docId.split(":")[1];//解析出数字格式的id
                String selection = MediaStore.Images.Media._ID + "=" + id;
                imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection);
            } else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) {
                Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(docId));
                imagePath = getImagePath(contentUri, null);
            }
        } else if ("content".equalsIgnoreCase(uri.getScheme())) {
        //如果不document类型的Uri,则使用普通方式处理
            imagePath = getImagePath(uri, null);

        }
        displayImage(imagePath);//根据图片路径显示图片
    }

    private  void handleImageBeforeKitKat(Intent data){
        Uri uri = data.getData();
        String imagePath = getImagePath(uri,null);
        displayImage(imagePath);
    }

    private String getImagePath(Uri uri,String selection){
        String path = null;
        //通过Uri和selection来获取真实的图片路径
        Cursor cursor = getContentResolver().query(uri,null,selection,null,null);
        if(cursor != null){
            if(cursor.moveToFirst()){
                path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
            }
            cursor.close();
        }
        return path;
    }

    private void displayImage(String imagePath){
        if(imagePath != null){
            Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
            picture.setImageBitmap(bitmap);
        }else{
            Toast.makeText(this,"failed to get image",Toast.LENGTH_SHORT).show();
        }
    }
}

因为涉及到向 SD 卡写数据的操作,需要声明权限

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

四. 播放多媒体文件

1.播放音频文件

在 Android 中播放音频文件一般都是使用 MediaPlayer 类来实现。首先需要创建出一个 MediaPlayer 对象,然后调用setDataSource()方法来设置音频文件的路径,在调用prepare()方法使 MediaPlayer 进入到准备状态,接下来调用start()方法播放音频,调用pause()方法暂停播放,调用reset()方法就会停止播放。

方法名功能描述
setDataSource()设置要播放的音频文件的位置
prepare()在开始播放之前调用这个方法完成准备工作
start()开始或继续播放音频
pause()暂停播放音频
reset()将 MediaPlayer 对象重制到刚刚创建的状态
seekTo()从指定的位置开始播放音频
stop()停止播放音频。调用这个方法之后的 MediaPlayer 对象无法再播放音频
release()释放掉与 MediaPlayer 对象相关的资源
isPlaying()判断当前 MediaPlayer 是否正在播放音频
getDuration()获取载入的音频文件的时长

2. 播放视频文件

使用 VideoView 类来实现。首先实例化 VideoView 对象,调用setVideoPath()指定视频文件的路径,具体方法与 MediaPlayer 差不多。

方法名功能描述
setVideoPath()设置要播放的视频文件的位置
start()开始或继续播放视频
pause()暂停播放视频
resume()将视频从头开始播放
seekTo()从指定的位置开始播放视频
isPlaying()判断当前 MediaPlayer 是否正在播放视频
getDuration()获取载入的视频文件的时长
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值