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