Android运用手机多媒体

Android运用手机多媒体,第1张

Android运用手机多媒体

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录
  • 使用通知
    • 通知的基本用法
    • 通知的点击----PendingIntent
    • 通知的高级功能
  • 调用摄像头和相册
    • 调用摄像头拍照
    • 从相册中选择照片
  • 播放多媒体文件
    • 播放音频
    • 播放视频


使用通知

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

通知的基本用法

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

NotificationManager manager= (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

接下来需要NotificationChannel。构造方法需要三个参数,ChannelId是自定义的字符串;第二个参数是频道的名称;第三个是优先级。创建完NotificationChannel之后,还需要使用createNotificationChannels方法注册到系统中

NotificationChannel mchannel=new NotificationChannel("channelid1","test",NotificationManager.importANCE_HIGH);
manager.createNotificationChannel(mchannel);

接下来,setContentTitle()方法用于指定通知的标题内容,下拉系统状态栏就可以看到这部分内容。setContentText()方法用于指定通知的正文内容,同样下拉系统状态栏就可以看到这部分内容。setWhen()方法用于指定通知被创建的时间,以毫秒为单位,当下拉系统状态栏时,这里指定的时间会显示在相应的通知上。setSmallIcon()方法用于设置通知的小图标,注意只能使用纯alpha图层的图片进行设置,小图标会显示在系统状态栏上。setLargeIcon()方法用于设置通知的大图标,当下拉系统状态栏时,就可以看到设置的大图标了。

NotificationCompat.Builder builder=new NotificationCompat.Builder(MainActivity.this,"channelid1");
builder.setContentTitle("this is content title");
builder.setContentText("this is content text");
builder.setWhen(System.currentTimeMillis());
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher));

以上工作都完成之后,只需要调用NotificationManager的notify()方法就可以让通知显示出来了

manager.notify(1,builder.build());

通知的点击----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这4种值可选,每种值的具体含义你可以查看文档,通常情况下这个参数传入0就可以了。

Intent intent=new Intent(this,NotificationActivity.class);
PendingIntent pi=PendingIntent.getActivity(this,0,intent,0);
...
builder.setContentIntent(pi);

点击就会跳转到新的Activity
但是通知图标还没有消失,该如何解决?

第一种 在builder后连缀一个setAutoCancel()方法

builder.setAutoCancel(true);

第二种显示的调用NotificationManager对象的cancel()方法

NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
manager.cancel(1);
通知的高级功能

setStyle()这个方法允许我们构建出富文本的通知内容

通知内容文字过长的效果

builder.setStyle(new NotificationCompat.BigTextStyle().bigText("Learn how to build notifications, send and sync data, and use voice actions. Get the official Android IDE and developer tools to build apps for Android."));

setPriority()可以用于设置通知的重要程度

一共有5个常量值可选:
PRIORITY_DEFAULT表示默认的重要程度,和不设置效果是一样的;
PRIORITY_MIN表示最低的重要程度,系统可能只会在特定的场景才显示这条通知,比如用户下拉状态栏的时候;
PRIORITY_LOW表示较低的重要程度,系统可能会将这类通知缩小,或改变其显示的顺序,将其排在更重要的通知之后;PRIORITY_HIGH表示较高的重要程度,系统可能会将这类通知放大,或改变其显示的顺序,将其排在比较靠前的位置;PRIORITY_MAX表示最高的重要程度,这类通知消息必须要让用户立刻看到,甚至需要用户做出响应 *** 作

调用摄像头和相册 调用摄像头拍照

新建一个CameraAlbumTest项目,然后修改activity_main.xml中的代码,如下所示:
只有两个控件,一个Button和一个ImageView。Button是用于打开摄像头进行拍照的,而ImageView则是用于将拍到的图片显示出来。



    

开始编写调用摄像头的具体逻辑,修改MainActivity中的代码

package com.example.cameraalbumtest;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.FileProvider;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

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

public class MainActivity extends AppCompatActivity {
    public static final int TAKE_PHOTO = 1;

    private ImageView picture;

    private Uri imageUri;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //获取到Button和ImageView的实例,并给Button注册上点击事件
        Button takePhoto=findViewById(R.id.take_photo);
        picture=findViewById(R.id.picture);
        takePhoto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //创建File对象,用于存储拍照后的图片
                //图片命名为output_image.jpg
                //将它存放在手机SD卡的应用关联缓存目录,调用getExternalCacheDir()方法可以得到这个目录
                File outputImage=new File(getExternalCacheDir(),"output_image.jdp");
                try{
                    if(outputImage.exists()){
                        outputImage.delete();
                    }
                    outputImage.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }

                //判断设备的系统版本是否高于Android7.0
                if(Build.VERSION.SDK_INT>24){
                    //调用FileProvider的getUriForFile()方法将File对象转换成一个封装过的Uri对象
                    //因为从Android 7.0系统开始,直接使用本地真实路径的Uri被认为是不安全的,
                    // 会抛出一个FileUriExposedException异常。
                    // 而FileProvider则是一种特殊的内容提供器,
                    // 它使用了和内容提供器类似的机制来对数据进行保护,
                    // 可以选择性地将封装过的Uri共享给外部,从而提高了应用的安全性。
                    imageUri= FileProvider.getUriForFile(MainActivity.this,"com.example.android.choosepicdemo.fileprovider",outputImage);
                }else{
                    //低于7.0版本调用Uri的fromFile()方法将File对象转换成Uri对象
                    //这个Uri对象标识着output_image.jpg这张图片的本地真实路径
                    imageUri=Uri.fromFile(outputImage);
                }

                //启动相机程序
                Intent intent=new Intent("android.media.action.IMAGE_CAPTURE");
                //Intent的putExtra()方法指定图片的输出地址
                intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri);
                startActivityForResult(intent,TAKE_PHOTO);
            }
        });
    }
    @Override
    protected void onActivityResult(int requestCode,int resultCode,Intent data) {

        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode){
            case TAKE_PHOTO:
                if(resultCode==RESULT_OK){
                    try{
                        //调用BitmapFactory的decodeStream()方法将output_image.jpg这张照片解析成Bitmap对象,
                        // 然后把它设置到ImageView中显示出来。
                        Bitmap bitmap= BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));
                        picture.setImageBitmap(bitmap);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                }
                break;
            default:
                break;
        }
    }
}

刚才提到了内容提供器,那么我们自然要在AndroidManifest.xml中对内容提供器进行注册了,如下所示:



    
        
            
                

                
            
        

        
            
        
    


另外,这里还在标签的内部使用来指定Uri的共享路径,并引用了一个@xml/file_paths资源
右击res目录→New→Directory,创建一个xml目录,接着右击xml目录→New→File,创建一个file_paths.xml文件。然后修改file_paths.xml文件中的内容,如下所示:



    

从相册中选择照片
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;

import android.Manifest;
import android.app.Activity;
import android.content.ContentUris;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Path;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.documentsContract;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

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

public class MainActivity extends AppCompatActivity {
    //通过调用摄像头
    public static final int TAKE_PHOTO = 1;

    private ImageView picture;

    private Uri imageUri;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //获取到Button和ImageView的实例,并给Button注册上点击事件
        Button takePhoto=findViewById(R.id.take_photo);
        picture=findViewById(R.id.picture);
        takePhoto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //创建File对象,用于存储拍照后的图片
                //图片命名为output_image.jpg
                //将它存放在手机SD卡的应用关联缓存目录,调用getExternalCacheDir()方法可以得到这个目录
                File outputImage=new File(getExternalCacheDir(),"output_image.jdp");
                try{
                    if(outputImage.exists()){
                        outputImage.delete();
                    }
                    outputImage.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }

                //判断设备的系统版本是否高于Android7.0
                if(Build.VERSION.SDK_INT>24){
                    //调用FileProvider的getUriForFile()方法将File对象转换成一个封装过的Uri对象
                    //因为从Android 7.0系统开始,直接使用本地真实路径的Uri被认为是不安全的,
                    // 会抛出一个FileUriExposedException异常。
                    // 而FileProvider则是一种特殊的内容提供器,
                    // 它使用了和内容提供器类似的机制来对数据进行保护,
                    // 可以选择性地将封装过的Uri共享给外部,从而提高了应用的安全性。
                    imageUri= FileProvider.getUriForFile(MainActivity.this,"com.example.android.choosepicdemo.fileprovider",outputImage);
                }else{
                    //低于7.0版本调用Uri的fromFile()方法将File对象转换成Uri对象
                    //这个Uri对象标识着output_image.jpg这张图片的本地真实路径
                    imageUri=Uri.fromFile(outputImage);
                }

                //启动相机程序
                Intent intent=new Intent("android.media.action.IMAGE_CAPTURE");
                //Intent的putExtra()方法指定图片的输出地址
                intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri);
                startActivityForResult(intent,TAKE_PHOTO);
            }
        });

        Button chooseFromAlbum=findViewById(R.id.choose_from_album);
        chooseFromAlbum.setOnClickListener(new View.OnClickListener() {
            @Override
            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{
                    Log.d("tag","edg");
                    openAlbum();
                }

            }
        });
    }
    @Override
    protected void onActivityResult(int requestCode,int resultCode,Intent data) {

       // super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode){
            case TAKE_PHOTO:
                if(resultCode==RESULT_OK){
                    try{
                        //调用BitmapFactory的decodeStream()方法将output_image.jpg这张照片解析成Bitmap对象,
                        // 然后把它设置到ImageView中显示出来。
                        Bitmap bitmap= BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));
                        picture.setImageBitmap(bitmap);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                }
                break;

            case CHOOSE_PHOTO:
                if(resultCode==RESULT_OK){
                    //判断手机系统版本号
                    if(Build.VERSION.SDK_INT>=19){
                        Log.d("tag","666");
                        handleImageOnkitkat(data);
                    }else{
                        handleImageBeforeKitKat(data);
                    }
                }

            default:
                break;
        }
    }

    //通过访问图库
    public static final int CHOOSE_PHOTO = 2;

    private void openAlbum(){
        Intent intent=new Intent("android.intent.action.GET_CONTENT");
        intent.setType("image/*");
        startActivityForResult(intent,CHOOSE_PHOTO);
    }

    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] 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;
        }
    }
    private void handleImageOnkitkat(Intent data){
        String imagePath=null;
        Uri uri=data.getData();
        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())) {
                // 如果是content类型的Uri,则使用普通方式处理
                imagePath = getImagePath(uri, null);
            } else if ("file".equalsIgnoreCase(uri.getScheme())) {
                // 如果是file类型的Uri,直接获取图片路径即可
                imagePath = uri.getPath();
            }
            displayImage(imagePath);
        }
    }
    private void handleImageBeforeKitKat(Intent data) {
        Uri uri = data.getData();
        String imagePath = getImagePath(uri, null);
        displayImage(imagePath);
    }

    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();
        }
    }
//
    private String getImagePath(Uri uri, String selection) {
        String path=null;
        Cursor cursor=getContentResolver().query(uri,null,selection,null,null);
        if(cursor!=null){
            if(cursor.moveToFirst()){
                path=cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA));
            }
            cursor.close();
        }
        return path;
    }
}

如果出现权限不允许的情况下,需要在AndroidManifest.xml文件上添加


选择照片后无法显示出来,还有如何解决super.onActivityResult()的办法
我们需要去build.gradle修改下面内容,降低版本即可使用OnActivityResult的第二种方法(不调用super)

播放多媒体文件 播放音频

在Android中播放音频文件一般都是使用MediaPlayer类来实现的,它对多种格式的音频文件提供了非常全面的控制方法,从而使得播放音乐的工作变得十分简单。下表列出了MediaPlayer类中一些较为常用的控制方法。

新建一个PlayAudioTest项目,然后修改activity_main.xml中的代码,如下所示:



    

在app/src/main->new->Directory 创建“assets” ,添加音频MP3进去, 修改MainActivity中的代码,如下所示:

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private MediaPlayer mediaPlayer = new MediaPlayer();

    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button play = (Button) findViewById(R.id.play);
        Button pause = (Button) findViewById(R.id.pause);
        Button stop = (Button) findViewById(R.id.stop);
        play.setOnClickListener(this);
        pause.setOnClickListener(this);
        stop.setOnClickListener(this);
        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 {
            initMediaPlayer(); // 初始化MediaPlayer
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    private void initMediaPlayer() {
        try {
            //File file = new File(Environment.getExternalStorageDirectory(), "music.mp3");
            AssetManager assetManager=getAssets();
            AssetFileDescriptor path=assetManager.openFd("music.mp3");
            mediaPlayer.setDataSource(path); // 指定音频文件的路径
            mediaPlayer.prepare(); // 让MediaPlayer进入到准备状态
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case 1:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    initMediaPlayer();
                } else {
                    Toast.makeText(this, "拒绝权限将无法使用程序", Toast.LENGTH_SHORT).show();
                    finish();
                }
                break;
            default:
        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.play:
                if (!mediaPlayer.isPlaying()) {
                    mediaPlayer.start(); // 开始播放
                }
                break;
            case R.id.pause:
                if (mediaPlayer.isPlaying()) {
                    mediaPlayer.pause(); // 暂停播放
                }
                break;
            case R.id.stop:
                if (mediaPlayer.isPlaying()) {
                    mediaPlayer.reset(); // 停止播放
                    initMediaPlayer();
                }
                break;
            default:
                break;
        }
    }

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

}

当点击Play按钮时会进行判断,如果当前MediaPlayer没有正在播放音频,则调用start()方法开始播放。当点击Pause按钮时会判断,如果当前MediaPlayer正在播放音频,则调用pause()方法暂停播放。当点击Stop按钮时会判断,如果当前MediaPlayer正在播放音频,则调用reset()方法将MediaPlayer重置为刚刚创建的状态,然后重新调用一遍initMediaPlayer()方法。

最后在onDestroy()方法中,我们还需要分别调用stop()方法和release()方法,将与MediaPlayer相关的资源释放掉。

播放视频

使用VideoView类来实现的。这个类将视频的显示和控制集于一身,使得我们仅仅借助它就可以完成一个简易的视频播放器

目前找不到合适的解决办法,一直处于视频无法播放…

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import android.Manifest;
import android.content.pm.PackageManager;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import android.widget.VideoView;

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

//public class MainActivity extends AppCompatActivity implements View.OnClickListener{
//
//    private VideoView videoView;
//    @Override
//    protected void onCreate(Bundle savedInstanceState) {
//        super.onCreate(savedInstanceState);
//        setContentView(R.layout.activity_main);
//        videoView=findViewById(R.id.video_view);
//        Button play = (Button) findViewById(R.id.play);
//        Button pause = (Button) findViewById(R.id.pause);
//        Button replay = (Button) findViewById(R.id.replay);
//        play.setonClickListener(this);
//        pause.setonClickListener(this);
//        replay.setonClickListener(this);
//        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 {
//            try {
//                initVideoPath(); // 初始化VideoView
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
//        }
//    }
//
//    private void initVideoPath() throws IOException {
        AssetManager assetManager=getAssets();
        AssetFileDescriptor path=assetManager.openFd("movie.mp4");
//        File file = new File(Environment.getExternalStorageDirectory(), "movie.mp4");
//        videoView.setVideoPath(file.getPath());
//    }
//
//    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
//        switch (requestCode) {
//            case 1:
//                if (grantResults.length > 0 && grantResults[0] == PackageManager.
//                        PERMISSION_GRANTED) {
//                    try {
//                        initVideoPath();
//                    } catch (IOException e) {
//                        e.printStackTrace();
//                    }
//                } else {
//                    Toast.makeText(this, "拒绝权限将无法使用程序", Toast.LENGTH_SHORT).show();
//                    finish();
//                }
//                break;
//            default:
//        }
//    }
//    @Override
//    public void onClick(View v) {
//        switch (v.getId()){
//            case R.id.play:
//                if(!videoView.isPlaying()){
//                    videoView.start();
//                }
//                break;
//            case R.id.pause:
//                if(videoView.isPlaying()){
//                    videoView.pause();
//                }
//                break;
//            case R.id.replay:
//                if(videoView.isPlaying()){
//                    videoView.resume();
//                }
//                break;
//        }
//    }
//    protected void onDestroy() {
//        super.onDestroy();
//        if (videoView != null) {
//            videoView.suspend();
//        }
//    }
//}

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/zaji/5687416.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存