欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android第一行代码-第八章运用手机多媒体

程序员文章站 2022-06-17 22:28:18
目录使用通知使用通知Notication是android系统中比较特色的一个功能,可使用通知向用户发出一些提示信息...

使用通知

通知的使用

调用摄像头

调用摄像图主要通过Intent来打开相机,并把图片保存在Uri中,然后通过回调方法拿到此图片
注:在6.0后要用到FileProvider,是一种特殊的内容提供器,提高了应用的安全性。
1.调用逻辑

//getExternalCacheDir()获取SD卡应用关联目录,
//使用这个目录读写SD卡可不用动态申请权限
 //第一步:创建文件用于保存图片
File file = new File(getExternalCacheDir(),"photo");
try {
    if(file.exists()){
         file.delete();
     }
     file.createNewFile();
	} catch (IOException e) {
    e.printStackTrace();
}
//第二步:将文件转换成Uri对象
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){     //版本大于6.0
    imageUri = FileProvider.getUriForFile(MainActivity.this,
    	"com.example.revise_8_3.fileprovider",file);
}
else
   imageUri = Uri.fromFile(file);
   //第三步:启动相机
  Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
	intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri);      //指定图片的输出地址为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 :
                if(resultCode == RESULT_OK){
                    try {
                        Bitmap bitmap  = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));
                        imageView.setImageBitmap(bitmap);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }

                }
                break;
}

2.内容提供器的注册

<provider
			//和刚才FileProvider.getUriForFile参数中的保持一致
            android:authorities="com.example.revise_8_4.fileprovider"
             //name是固定的,不能改变
            android:name="androidx.core.content.FileProvider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
            //name是固定的,不能改变
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths"/>
        </provider>

3.创建@xml/file_paths资源
右击res目录,new->Directory,创建一个xml目录,在这个目录中新建file_paths文件

<?xml version="1.0" encoding="utf-8"?>
<paths
    xmlns:android="http://schemas.android.com/apk/res/android">
<external-path		//用来指定Uri共享的
    name="m_images"		//可随意指定
    path="/"/>			//这样设置表示将整个SD卡共享
</paths>

4.权限配置

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

调用相册

调用相册也是用Intent实现,选择的照片可从回调的Intent中得到
1.打开相册逻辑

 private void openAclum() {
        Intent intent = new Intent("android.intent.action.GET_CONTENT");
        intent.setType("image/*");
        /*
        intent.setType(“image/*”);
        //intent.setType(“audio/*”); //选择音频
        //intent.setType(“video/*”); //选择视频 (mp4 3gp 是android支持的视频格式)
        //intent.setType(“video/;image/”);//同时选择视频和图片
         */
        startActivityForResult(intent,CHOOSE_PHOTO);
    }

2.动态申请权限(要从sd卡读取照片,是危险权限)

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

onRequestPermissionsResult()方法对申请结果进行处理

 public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode){
            case 1:
                if(grantResults.length > 0 && grantResults[0]== PackageManager.PERMISSION_GRANTED)
                    openAlbum();
                else
                    Toast.makeText(MainActivity.this,"没有权限",Toast.LENGTH_SHORT).show();
                break;
        }
    }

在AndroidManifest.xml中声明此权限

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

onActivityResult方法得到拿到的图片
由于对于不同类型解析方式不同,这里我直接把他们封装在一个类里

package com.example.revise_8_4;

import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;

import android.net.Uri;
import android.os.Build;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.util.Log;

import androidx.annotation.RequiresApi;

public class ImageKitKat {

    private  Context context;
    public ImageKitKat(Context context) {
        this.context = context;
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)

    public  String handleImageOnKitKat(Intent data){
        String imagePath = null;
        Uri uri = data.getData();
        if(DocumentsContract.isDocumentUri(context,uri)){
            String docId = DocumentsContract.getDocumentId(uri);
            if ("com.android.providers.media.documents".equals(uri.getAuthority())) {
                //如果uri的authority是media格式 再次解析id 将字符串分割取出后半部分才能得到真正的数字id
                String id = docId.split(":")[1];//解析出数字格式的id
                String selection = MediaStore.Images.Media._ID + "=" + id;
                imagePath = getPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection);
            }
            else if("com.android.providers.downloads.documents".equals(uri.getAuthority())){
                Log.d("MainActivity.this","2");
                Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),Long.valueOf(docId));
                imagePath = getPath(contentUri,null);
            }
        }else if("content".equalsIgnoreCase(uri.getScheme())){
            Log.d("MainActivity.this","3");
            imagePath = getPath(uri,null);
        }else if("file".equalsIgnoreCase(uri.getScheme())){
            Log.d("MainActivity.this","44");
            imagePath = uri.getPath();
        }
        return imagePath;

    }
    public  String handleImageBeforeKitKat(Intent data){
        Uri pathUri = data.getData();
        String imagePath = getPath(pathUri,null);
        return imagePath;
    }
    public  String getPath(Uri externalContentUri, String selection) {
        String path = null;

        Cursor cursor = context.getContentResolver().query(externalContentUri,null,selection,null,null);
        if(cursor!=null){
            if(cursor.moveToFirst()){
                path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
            }
        }
        cursor.close();
        return path;
    }

}

 protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode){
          
            case CHOOSE_PHOTO:
               if(resultCode==RESULT_OK){
                    ImageKitKat imageKitKat = new ImageKitKat(MainActivity.this);
                    String path;
                    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
                        //handle(data);
                        path = imageKitKat.handleImageOnKitKat(data);
                    }
                    else
                        //headbefore(data);
                    path = imageKitKat.handleImageBeforeKitKat(data);
                    Bitmap bitmap = BitmapFactory.decodeFile(path);
                    imageView.setImageBitmap(bitmap);
                }
        }
    }

播放音频

在Android中播放音频文件主要使用MediaPlayer类去实现

方法名 功能描述
void setDataSource(Context context, Uri uri) 通过给定的Uri来设置MediaPlayer的数据源,这里的Uri可以是网络路径或是一个ContentProvider的Uri。
void setDataSource(FileDescriptor fd) 通过文件描述符FileDescriptor来设置数据源
int getCurrentPosition() 获取当前播放的位置
int getAudioSessionId() 返回音频的session ID
boolean isLooping () 是否循环播放
boolean isPlaying() 是否正在播放
void prepare() 同步的方式装载流媒体文件。
void pause () 暂停
void start () 开始
void stop () 停止
void release () 回收流媒体资源。
int getDuration() 得到文件的时长

当然播放之前要动态申请permission.WRITE_EXTERNAL_STORAGE权限

  private void onplay() {

        try {
            //第一步:获取MediaPlayer对象
            MediaPlayer mediaPlayer = new MediaPlayer();
            //第二步:关联要播放的资源
            mediaPlayer.setDataSource(file.getPath());
            // 让mediaPlayer进入准备阶段
            mediaPlayer.prepare();
            //开始播放
            mediaPlayer.start();
            //停止播放
            mediaPlayer.stop();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

播放视频

播放视频文件主要是使用VideoView控件来实现的,和MediaPlyer类似

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

1 添加 videoView 控件


    <VideoView
        android:id="@+id/videoView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

2.使用逻辑

当然播放之前要动态申请permission.WRITE_EXTERNAL_STORAGE权限

 //第一步:获取videoView对象
 videoView = (VideoView)this.findViewById(R.id.videoView );
 //第二步:关联要播放的资源
  videoView.setVideoPath(file.getPath());
  //开始播放
  videoView.start();
  //暂停播放
  videoView.pause();

本文地址:https://blog.csdn.net/haazzz/article/details/108689689