多媒体技术每日学习

使用通知

什么是通知,通知就是下拉手机看到的那些提示信息。

通知的简单用法
在Android 8.0(API26) 后对通知更改了一些内容,以前是通过Notification.Builder(Context context).set…来设置通知的震动、灯光、音效的设置,新内容加了NotificationChannel(通知渠道),通过NotificationChannel来进行震动、灯光、音效的设置,且通知必须添加通知渠道,同样需进行版本判断,否则通知不会被发送。
1.首先创建NotificationManager对象
2.创建NotificationChannel对象,指定id,name,importance(根据这个播放对应的效果),也可以设置相应的震动、音效、如果没设置按默认的importance,调用NotificationManager的createNotificationChannel(NotificationChannel channel)方法
3.通过NotificationCompat.Builder(Context,Notification)对象指定channel并设置通知的各项信息,调用build()方法创建Notification对象,调用NotificationManager的notify(id,Notification)方法

首先创建NotificationManager对象:

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

创建NotificationChannel对象:

String channel_id="voice_channel";
NotificationChannel channel = new NotificationChannel(channel_id,"voice",
                        NotificationManager.IMPORTANCE_HIGH);
                channel.enableVibration(true);
                channel.setVibrationPattern(new long[]{0,1000,1000,1000});
                channel.enableLights(true);
                channel.setLightColor(Color.GREEN);

第一个参数是id,第二个是name,第三个是Importance,其对应的播放效果如下,其中IMPORTANCE_HIGH会弹出横幅(像qq来消息那样)

public static final int IMPORTANCE_NONE = 0;

/**
 * Min notification importance: only shows in the shade, below the fold.  This should
 * not be used with {@link Service#startForeground(int, Notification) Service.startForeground}
 * since a foreground service is supposed to be something the user cares about so it does
 * not make semantic sense to mark its notification as minimum importance.  If you do this
 * as of Android version {@link android.os.Build.VERSION_CODES#O}, the system will show
 * a higher-priority notification about your app running in the background.
 */
public static final int IMPORTANCE_MIN = 1;

/**
 * Low notification importance: shows everywhere, but is not intrusive.
 */
public static final int IMPORTANCE_LOW = 2;

/**
 * Default notification importance: shows everywhere, makes noise, but does not visually
 * intrude.
 */
public static final int IMPORTANCE_DEFAULT = 3;

/**
 * Higher notification importance: shows everywhere, makes noise and peeks. May use full screen
 * intents.
 */
public static final int IMPORTANCE_HIGH = 4;

/**
 * Unused.
 */

调用NotificationManager的createNotificationChannel(NotificationChannel channel)方法:

manager.createNotificationChannel(channel);

通过NotificationCompat.Builder(Context,Notification)对象指定channel并设置通知的各项信息,调用build()方法创建Notification对象:

Notification notification = new NotificationCompat.Builder(MainActivity.this,channel_id)
                        .setContentTitle("First notification")
                        .setContentText("nothing aha fdasfdsafdsafdsafdsfdsfdsfdsfdsfdsfdsfds")
                        //.setStyle(new NotificationCompat.BigTextStyle().bigText("nothing aha fdasfdsafdsafdsafdsfdsfdsfdsfds fdsf fds fdsf sf sffsdsfdsfdsfds"))
                        /*.setStyle(new NotificationCompat.BigPictureStyle().bigPicture
                                (BitmapFactory.decodeResource(getResources(),R.drawable.watermelon)))*/
                        .setWhen(System.currentTimeMillis())
                        .setSmallIcon(R.mipmap.ic_launcher)
                        .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))
                        .setContentIntent(pendingIntent)
                        //.setPriority(NotificationCompat.PRIORITY_MAX)
                        //.setAutoCancel(true)
                        .build();
                        manager.notify(1,notification); //第一个是id

Builder第一个参数是Context,第二个参数是指定NotificationChannel对象设置震动、音效;
setContentTitle():设置通知栏标题
setContentText():设置通知栏文本
setWhen():指定通知被创建的时间
setSmallIcon():设置小图标
setLargeIcon():设置大图标
要实现通知点击跳转一个活动需要PendingIntent,通过Intent对象创建

 Intent intent = new Intent(MainActivity.this,TestActivity.class);
 PendingIntent pendingIntent = PendingIntent.getActivity(MainActivity.this,0,intent,0);

setContentIntent():接收PendingIntent对象执行相应逻辑
setAutoCancel():点击取消通知
也可以显示取消通知:

NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.cancel(1); //这里的id就是前面notify()中的id

setStyle():实现长文本、显示大图片

如果是8.0以前的版本只需要创建NotificationManager对象,震动、音效、和其他标题内容都通过NotificationCompat.Builder()的set方法实现,build()创建Notification对象,调用notify()方法。

例子:

package com.example.hankzz.notificationproject;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.support.v4.app.NotificationCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import java.io.File;

public class MainActivity extends AppCompatActivity {
private Button send_notification;
private String channel_id = "voice_channel";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    send_notification = (Button) findViewById(R.id.notification_button);
    send_notification.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(MainActivity.this,TestActivity.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(MainActivity.this,0,intent,0);
            if(Build.VERSION.SDK_INT >= 26){
                NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
                NotificationChannel channel = new NotificationChannel(channel_id,"voice",
                        NotificationManager.IMPORTANCE_HIGH);
                channel.enableVibration(true);
                channel.setVibrationPattern(new long[]{0,1000,1000,1000});
                channel.enableLights(true);
                channel.setLightColor(Color.GREEN);
                manager.createNotificationChannel(channel);
                Notification notification = new NotificationCompat.Builder(MainActivity.this,channel_id)
                        .setContentTitle("First notification")
                        .setContentText("nothing aha fdasfdsafdsafdsafdsfdsfdsfdsfdsfdsfdsfds")
                        //.setStyle(new NotificationCompat.BigTextStyle().bigText("nothing aha fdasfdsafdsafdsafdsfdsfdsfdsfds fdsf fds fdsf sf sffsdsfdsfdsfds"))
                        /*.setStyle(new NotificationCompat.BigPictureStyle().bigPicture
                                (BitmapFactory.decodeResource(getResources(),R.drawable.watermelon)))*/
                        .setWhen(System.currentTimeMillis())
                        .setSmallIcon(R.mipmap.ic_launcher)
                        .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))
                        .setContentIntent(pendingIntent)
                        //.setPriority(NotificationCompat.PRIORITY_MAX)
                        //.setAutoCancel(true)
                        .build();
                manager.notify(1,notification);
            }else{
                NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
                Notification notification = new NotificationCompat.Builder(MainActivity.this)
                        .setContentTitle("First notification")
                        .setContentText("nothing aha")
                        .setWhen(System.currentTimeMillis())
                        .setSmallIcon(R.mipmap.ic_launcher)
                        .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))
                        .setContentIntent(pendingIntent)
                        .setAutoCancel(true)
                        .build();
            }
        }
    });
}
}

调用摄像头和相册

调用摄像头拍照
1.先创建图片文件放在缓冲目录下并指定名字。
2.通过版本判断,如果版本>7.0,通过FileProvider.getUriForFile()方法将File对象转换成Uri对象;<7.0,直接Uri.fromFile()获取Uri对象。
3.创建Intent对象将action指定为android.media.action.IMAGE_CPATURE,通过putExtra()方法将图片输出到指定uri,调用startActivityForResult()方法启动活动,打开摄像机,后会返回到onActivityResult()方法中可通过requestCode来把图片显示到ImageView中。
同样在AndroidManifest.xml中注册FileProvider

<provider
        android:authorities="com.example.hankzz.camereaalbumproject.fileprovider"
        android:name="android.support.v4.content.FileProvider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths"/>
    </provider>

其他详细代码:

private Button photograph_button;
private ImageView photoimage;
private static final int TAKE_PHOTO = 1;    //requestCode,根据这个在onActivityResult()中switch case执行显示照片

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    photograph_button = (Button) findViewById(R.id.photograph_button);
    photoimage = (ImageView) findViewById(R.id.photo_image);
    photograph_button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            File outputimage = new File(getExternalCacheDir(),"output_image.jpg");
            try {
                if(outputimage.exists()){
                    outputimage.delete();
                }
                outputimage.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }       //创建图片文件
            if(Build.VERSION.SDK_INT >= 24){
                imageuri = FileProvider.getUriForFile(MainActivity.this,
                        "com.example.hankzz.camereaalbumproject.fileprovider",outputimage);
            }else {
                imageuri = Uri.fromFile(outputimage);
            }   /通过版本判断进行不同的Uri获取
            Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
            intent.putExtra(MediaStore.EXTRA_OUTPUT,imageuri);
            startActivityForResult(intent,TAKE_PHOTO);           //开启活动,打开照相机
        }
    });
}
    
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch(requestCode){
        case TAKE_PHOTO:
            try {
                Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageuri)); //获取图片
                photoimage.setImageBitmap(bitmap);    //在ImageView中显示
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            break;
        default:
            break;
    }
}

获取相册中照片
1.向用户申请权限,先判断是否有权限,没有申请,在onRequestPermissionsResult()对申请结果进行执行相应事件。
2.创建Intent对象将action指定为android.intent.action.GET_CONTENT,通过putType()设置参数,调用startActivityForResult()方法启动活动,打开相册,后会返回到onActivityResult()方法中可通过requestcode来进行处理图片。
3.获取通过Intent对象的getData()方法获取Uri对象,对不同类型的Uri进行处理通过getCotentResolver().query()方法获取路径,通过路径获取图片给ImageView设置图片。
详细代码:

private Button choose_button;
private ImageView photoimage;
private static final int CHOOSE_PIC = 2;
private Uri imageuri;
protected void onCreate(Bundle savedInstanceState) {
 ....
choose_button = (Button) findViewById(R.id.choose_button);
    choose_button.setOnClickListener(new View.OnClickListener(){
        public void onClick(View v){
        //判断是否有权限
            if(ContextCompat.checkSelfPermission(MainActivity.this,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){
                ActivityCompat.requestPermissions(MainActivity.this,new
                        String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);    //申请权限
            }else{
                openAlbum();    //打开相册
            }
        }
    });
    }
    private void openAlbum(){
    Intent intent = new Intent("android.intent.action.GET_CONTENT");
    intent.setType("images/*");
    startActivityForResult(intent,CHOOSE_PIC);   //启动活动打开相册
}

private String getImagepath(Uri uri,String selection){
    String path = null;
    Cursor cursor = getContentResolver().query(uri,null,selection,null,null);  //通过内容提供器获取图片路径
    if(cursor!=null){
        while(cursor.moveToNext()){
            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);    //根据路径获取图片
        photoimage.setImageBitmap(bitmap);    //在ImageView中显示图片
    }else{
        Toast.makeText(this,"failed",Toast.LENGTH_SHORT).show();
    }
}

private void handleImageOnKitKat(Intent data){
    String imagePath = null;
    Uri uri = data.getData();  获取Uri对象
    //根据不同类型Uri获取路径
    if(DocumentsContract.isDocumentUri(this,uri)){
        String docId = DocumentsContract.getDocumentId(uri);
        if("com.android.providers.media.documents".equals(uri.getAuthority())){
            String id = docId.split(":")[1];
            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())){
        imagePath = getImagepath(uri,null);     //获取路径
    }else if("file".equalsIgnoreCase(uri.getScheme())){
        imagePath = uri.getPath();            //获取路径
    }
    displayImage(imagePath);     //在ImageView中显示图片
}
    @Override
    //根据授权结果执行相应事件
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode){
        case 1:
            if(grantResults.length>0 && grantResults[0]==PackageManager.PERMISSION_GRANTED){
                openAlbum();
            }else{
                Toast.makeText(this,"you denied the permission",Toast.LENGTH_SHORT).show();
            }
            break;
        default:
            break;
    }
}
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch(requestCode){
        case TAKE_PHOTO:
            ...
            break;
        case CHOOSE_PIC:   //如果是打开相册执行以下
            handleImageOnKitKat(data);
        default:
            break;
    }
}

播放多媒体文件

播放音频
简单的播放音频文件通过MediaPlayer类实现
1.首先创建MediaPlayer类对象
2.调用MediaPlayer.setDataSource(String path)方法指定音频文件路径,调用Prepare()方法完成准备工作
3.调用start()、pause()、reset()、seekTo()等方法实现相应功能
4.stop()、release()将相关资源释放掉
各方法作用如下:
在这里插入图片描述

例子:

package com.example.hankzz.playaudioproject;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.media.MediaPlayer;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import java.io.File;
import java.io.IOException;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private Button play_button;
private Button pause_button;
private Button reset_button;
private MediaPlayer player = new MediaPlayer();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    play_button = (Button) findViewById(R.id.play_button);
    pause_button = (Button) findViewById(R.id.pause_button);
    reset_button = (Button) findViewById(R.id.reset_button);
    //判断是否向用户申请权限
    if(ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)!=
            PackageManager.PERMISSION_GRANTED){
        ActivityCompat.requestPermissions(this,new String[]
                {Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
    }else{
        initPlayer();  //初始化player,就是设置音频路径调用prepare()方法
    }
    //各个按钮事件
    play_button.setOnClickListener(this);
    pause_button.setOnClickListener(this);
    reset_button.setOnClickListener(this);
}

private void initPlayer(){
    /*File file  = new File(Environment.getExternalStorageDirectory()+"/netease/cloudmusic/Music",
            "dadandme.mp3");*/   //通过路径获取音频文件,Environment.getExternalStorageDirectory()为sd卡根目录
    File file = new File("/storage/emulated/0/netease/cloudmusic/Music","dadandme.mp3");
    try {
        //player.setDataSource(file.getPath());  //通过文件的getPath()方法获取路径,设置路径
        player.setDataSource("/storage/emulated/0/netease/cloudmusic/Music/Ghoat.mp3");  //可以直接设置音频路径
        player.prepare();   //准备工作
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public void onClick(View v){
    switch(v.getId()){
        case R.id.play_button:   //播放点击事件
            if(!player.isPlaying()){
                player.start();   //播放音频
            }
            break;
        case R.id.pause_button:   //暂停点击事件
            if(player.isPlaying()){
                player.pause();   //暂停
            }
            break;
        case R.id.reset_button:    //重置点击事件
            if(player.isPlaying()){
                player.reset();     //将player对象重置
            }
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode){
        case 1:
            if(grantResults.length>0 && grantResults[0]==PackageManager.PERMISSION_GRANTED){
                initPlayer();
            }else{
                Toast.makeText(this,"you denied the permission",Toast.LENGTH_SHORT).show();
            }
            break;
        default:
            break;
    }
}

@Override
protected void onDestroy() {
    super.onDestroy();
    if(player!=null){
        player.stop();
        player.release();
    }
}
}

1.要访问手机sd卡中数据需要先向用户申明权限,并做权限处理,别忘了在在AndroidManifest.xml声明权限
2.给MediaPlayer对象player设置音频路径,准备
3.通过按钮点击事件执行播放、暂停、重播的功能
4.销毁player对象

播放视频
只能是简单播放视频,对视频格式和播放效率方面存在较大不足,通过VideoView类实现,VideoView也是一个控件,用于播放视频,因为背后仍然是MediaPlayer对视频文件进行控制,所以各方法类似播放音频。
1.首先创建VideoView类对象,获取布局中的VideoView控件
2.调用VideoView.setVideoPaht(String path)方法指定视频文件路径
3.调用start()、pause()、resume()、seekTo()等方法实现相应功能
4.suspend()将相关资源释放掉
各方法作用如下:
在这里插入图片描述
例子:

package com.example.hankzz.playvideoproject;

import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import android.widget.VideoView;

import java.io.File;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button play_button;
private Button pause_button;
private Button replay_button;
private VideoView myvideoview;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    play_button = (Button) findViewById(R.id.play_button);
    pause_button = (Button) findViewById(R.id.pause_button);
    replay_button = (Button) findViewById(R.id.replay_button);
    myvideoview = (VideoView) findViewById(R.id.myvideoview);
    //判断是否有权限
    if(ContextCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE)!=
            PackageManager.PERMISSION_GRANTED){
        ActivityCompat.requestPermissions(this,new String[]
                {Manifest.permission.WRITE_EXTERNAL_STORAGE},1);   //向用户申请权限
    }else{
        initMyvideoview();    //初始化,设置视频路径
    }
    //设置按钮事件
    play_button.setOnClickListener(this);
    pause_button.setOnClickListener(this);
    replay_button.setOnClickListener(this);
}

//初始化ViewVideo对象,设置路径
private void initMyvideoview(){
    File file = new File(Environment.getExternalStorageDirectory(),"Test.mp4");   //获取文件
    myvideoview.setVideoPath(file.getPath());     //通过文件获取路径,设置视频路径
}

public void onClick(View v){
    switch(v.getId()){
        case R.id.play_button:    //播放事件
            if(!myvideoview.isPlaying()){
                myvideoview.start();   //播放
            }
            break;
        case R.id.pause_button:  //暂停事件
            if(myvideoview.isPlaying()){
                myvideoview.pause();   //暂停
            }
            break;
        case R.id.replay_button:   //重新播放
            if(myvideoview.isPlaying()){
                myvideoview.resume();  //重播
            }
            break;
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch(requestCode){
        case 1:
            if(grantResults.length>0 && grantResults[0]==PackageManager.PERMISSION_GRANTED){
                initMyvideoview();
            }else{
                Toast.makeText(this,"you denied the permission",Toast.LENGTH_SHORT).show();
            }
            break;
        default:
            break;
    }
}

@Override
protected void onDestroy() {
    super.onDestroy();
    if (myvideoview != null) {
        myvideoview.suspend();   //销毁ViewVideo对象
    }
}

在AndroidManifest.xml声明权限

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

1.要访问手机sd卡中数据需要先向用户申明权限,并做权限处理,别忘了在在AndroidManifest.xml声明权限
2.给VideoView对象myvideoview设置音频路径
3.通过按钮点击事件执行播放、暂停、重播的功能
4.销毁myvideoview对象

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值