安卓开发——多媒体

通知

class MainActivity : AppCompatActivity() {
    @SuppressLint("MissingInflatedId")
    @RequiresApi(Build.VERSION_CODES.O)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        // 获取系统的通知服务,以便在后续代码中创建和发送通知
        val channel = NotificationChannel("normal", "Normal",NotificationManager.IMPORTANCE_DEFAULT)
        // channel设置通知渠道,重要等级可自行设置
        manager.createNotificationChannel(channel)
        val btn:Button = findViewById(R.id.btn)
        btn.setOnClickListener {
            val intent = Intent(this, notice::class.java)
            val pi = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE)
            // 设置点击事件
            val notification = NotificationCompat.Builder(this, "normal")
                .setContentTitle("This is content title")
                .setStyle(NotificationCompat.BigTextStyle().bigText("设置长通知显示啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"))

                .setContentIntent(pi) // 设置点击后跳转的意图
                .setAutoCancel(true) // 点击后通知图标自动关闭
                .setContentText("This is content text")
                .build()
            manager.notify(1, notification)
        }
    }
}

摄像头和相册

拍照

class MainActivity : AppCompatActivity() {
    private val takePhoto = 1
    private lateinit var imageUri: Uri
    private lateinit var outputImage: File
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val takePhotoBtn:Button = findViewById(R.id.takePhotoBtn)
        takePhotoBtn.setOnClickListener {
            outputImage = File(externalCacheDir, "output_image.jpg")
            if (outputImage.exists()) {
                outputImage.delete()
            }
            outputImage.createNewFile()
            imageUri = FileProvider.getUriForFile(this, "com.example.myapplication.fileprovider", outputImage)
            // FileProvider 是一种contentProvider,提供数据保护,这里指访问文件的保护
            val intent = Intent("android.media.action.IMAGE_CAPTURE")
            // 创建拍照意图intent
            intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri)
            startActivityForResult(intent, takePhoto)
            // 将拍照后的照片的Uri添加到Intent中,以便在拍照操作完成后,系统将照片保存到指定的位置。
            // 这样,我们可以在后续的操作中获取到拍照后的照片。
        }
    }
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when (requestCode) {
            takePhoto -> {
                if (resultCode == Activity.RESULT_OK) {
                    // 如果拍照成功
                    val bitmap = BitmapFactory.decodeStream(contentResolver.openInputStream(imageUri))
                    // 从imageUri解码照片,并转换为Bitmap对象
                    val imageView:ImageView = findViewById(R.id.imageView)
                    imageView.setImageBitmap(rotateIfRequired(bitmap))
                    // 检查并旋转照片(如果需要),然后将旋转后的照片设置为ImageView的图像
                }
            }
        }
    }
    private fun rotateIfRequired(bitmap: Bitmap): Bitmap {
        val exif = ExifInterface(outputImage.path)
        // 创建一个ExifInterface对象,用于读取照片的EXIF信息。
        val orientation = exif.getAttributeInt(
            // 获取照片的方向属性
            ExifInterface.TAG_ORIENTATION,
            ExifInterface.ORIENTATION_NORMAL)
        return when (orientation) {
            // 根据照片的方向属性执行相应的旋转操作
            ExifInterface.ORIENTATION_ROTATE_90 -> rotateBitmap(bitmap, 90)
            ExifInterface.ORIENTATION_ROTATE_180 -> rotateBitmap(bitmap, 180)
            ExifInterface.ORIENTATION_ROTATE_270 -> rotateBitmap(bitmap, 270)
            else -> bitmap
        }
    }
    private fun rotateBitmap(bitmap: Bitmap, degree: Int): Bitmap {
        // 接受一个Bitmap对象和旋转角度作为参数,使用Matrix对象旋转照片,并返回旋转后的Bitmap对象
        val matrix = Matrix()
        matrix.postRotate(degree.toFloat())
        // 设置旋转角度
        val rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height,
            matrix, true)
        bitmap.recycle()
        return rotatedBitmap
    }
}

Manifest.xml:

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

files_path.xml:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path android:name="my_images" android:path="/" />
</paths>
 1. 元素定义了一个名为my_images的外部存储路径。
 2. android:path="/" 属性表示该路径指向外部存储的根目录。此处指的是SD卡

在Android应用程序中,使用Bitmap对象存储照片有以下几个原因:

  1. 内存管理:Bitmap对象可以直接在内存中操作图像数据,这使得在处理图像时可以更快地访问和修改数据。与从文件系统或其他存储方式加载图像相比,使用Bitmap对象可以减少I/O操作,提高性能。

  2. 便于操作:Bitmap对象提供了丰富的API,可以方便地对图像进行各种操作,如缩放、裁剪、旋转、滤镜等。这使得在Android应用程序中处理图像变得更加简单和高效。

  3. 兼容性:Bitmap对象是Android平台的一部分,因此它具有很好的兼容性。这意味着我们可以在不同的Android设备和版本上使用相同的Bitmap对象来处理图像。

  4. 易于传输和共享:使用Bitmap对象可以轻松地在应用程序、服务和设备之间传输和共享图像。例如,我们可以将Bitmap对象发送给其他应用程序或服务,以便它们可以访问和处理图像。这使得在应用程序之间共享和传输图像变得更加简单和高效。

  5. 节省存储空间:Bitmap对象可以直接在内存中操作图像数据,因此它们通常比文件系统中的图像文件更小。这意味着使用Bitmap对象可以节省设备的存储空间。

相册

class MainActivity : AppCompatActivity() {
    private val fromAlbum = 2
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        fromAlbumBtn.setOnClickListener {
            val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
            // 意向为打开文档,让用户选择文件
            intent.addCategory(Intent.CATEGORY_OPENABLE)
            // 向Intent对象添加一个类别,表示我们希望打开的文档应该是可打开的(即可读取的)。
            intent.type = "image/*"
            // 设置Intent对象的MIME类型为image/*,表示我们希望打开的文档应该是图像文件。
            startActivityForResult(intent, fromAlbum)
        }
    }
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when (requestCode) {
            fromAlbum -> {
                if (resultCode == Activity.RESULT_OK && data != null) {
                    data.data?.let { uri ->
                        val bitmap = getBitmapFromUri(uri)
                        imageView.setImageBitmap(bitmap)
                    }
                }
            }
        }
    }
    private fun getBitmapFromUri(uri: Uri) = contentResolver.openFileDescriptor(uri, "r")?.use {
            BitmapFactory.decodeFileDescriptor(it.fileDescriptor)
    }
}

播放多媒体文件

播放音乐

MediaPlayer的常用方法:

class MainActivity : AppCompatActivity() {

    private val mediaPlayer = MediaPlayer()
    // 操作音频相关的需要引用MediaPlayer()对象中的方法
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        initMediaPlayer()
        play.setOnClickListener {
            if (!mediaPlayer.isPlaying) {
                mediaPlayer.start() //
            }
        }
        pause.setOnClickListener {
            if (mediaPlayer.isPlaying) {
                mediaPlayer.pause() //
            }
        }
        stop.setOnClickListener {
            if (mediaPlayer.isPlaying) {
                mediaPlayer.reset() //
                initMediaPlayer()
            }
        }
    }
    private fun initMediaPlayer() {
        val assetManager = assets
        // assetManger可以读取asserts下的所有资源
        val fd = assetManager.openFd("music.mp3")
        // 将名为music.mp3的文件放在asserts目录下
        mediaPlayer.setDataSource(fd.fileDescriptor, fd.startOffset, fd.length)
        mediaPlayer.prepare()
    }
    override fun onDestroy() {
        super.onDestroy()
        mediaPlayer.stop()
        mediaPlayer.release()
    }
}

播放视频

VideoView常用方法

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val uri = Uri.parse("android.resource://$packageName/${R.raw.video}")
        videoView.setVideoURI(uri)
        play.setOnClickListener {
            if (!videoView.isPlaying) {
                videoView.start()
            }
        }
        pause.setOnClickListener {
            if (videoView.isPlaying) {
                videoView.pause()
            }
        }
        replay.setOnClickListener {
            if (videoView.isPlaying) {
                videoView.resume()
            }
        }
    }
    override fun onDestroy() {
        super.onDestroy()
        videoView.suspend()
    }
}

音频和视频播放的方法有所不同。对于音频文件,MediaPlayer类提供了一个简单的方法来直接指定文件路径或资源ID。而对于视频文件,VideoView类需要一个Uri对象来指定文件位置,以便与底层的MediaPlayer进行交互。这是因为VideoView是基于SurfaceView实现的,而SurfaceView需要一个Uri对象来确定要播放的视频文件

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值