Android笔记(十七):PendingIntent简介

这篇具有很好参考价值的文章主要介绍了Android笔记(十七):PendingIntent简介。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

PendingIntent翻译成中文为“待定意图”,这个翻译很好地表示了它的涵义。PendingIntent描述了封装Intent意图以及该意图要执行的目标操作。PendingIntent封装Intent的目标行为的执行是必须满足一定条件,只有条件满足,才会触发意图的目标操作。

一.获取PendingIntent对象

获取PendingIntent对象有以下几种方式:

  • PendingIntent.getActivity(Context, int, Intent, int):启动活动
  • PendingIntent.getActivities(Context, int, Intent[], int):启动多个活动,意图中为数组
  • PendingIntent.getBroadcast(Context, int, Intent, int):启动广播
  • PendingIntent.getService(Context, int, Intent, int):启动服务

参数说明:

  • Context:context上下文,PendingIntent启动活动的上下文
  • int:requestCode请求码 ,发送者发送的请求码
  • Intent:intent意图:要加载活动的意图
  • int:flags 标记

对于其中的标记可以定义为下列形式

  • FLAG_ONE_SHOT:PendingIntent对象仅使用一次;
  • FLAG_NO_CREATE:如果PendingIntent对象不存在则返回null
  • FLAG_CANCEL_CURRENT:如果PendingIntent对象已存在,则取消原有的对象,创建新的PendingIntent对象
  • FLAG_UPDATE_CURRENT:如果PendingIntent对象已存在,则保留原有的对象,修改原有对象的属性数据
  • FLAG_IMMUTABLE:PendingIntent对象是不可变的
  • FLAG_MUTABLE:PendingIntent对象是可变的
  • 另外其他Intent中支持的标记都可以在标记参数中使用。

二、应用实例

例如:在MainActivity启动前台服务播放音乐,利用前台服务的通知提供的内容跳转到其他活动例如SongActivity介绍歌曲。界面如下所示。
android pendingintent,android,笔记
点击第一张图的播放,会播放音频,同时发布通知如第二张图所示。在第二张图的红色箭头区域点击,可以屏幕会跳转到第三张图。在第三张图中点击“返回”,则返回主活动。

1. AndroidManifest.xml清单配置权限

  <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
  <uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />

2. 定义MusicService

class MusicService : Service() {
    lateinit var mediaPlayer: MediaPlayer
    override fun onCreate() {
        super.onCreate()
        mediaPlayer = MediaPlayer.create(this,R.raw.song3)
    }

    override fun onBind(intent: Intent): IBinder? {
        postNotification()
        playMusic()
        return null
    }

    override fun onUnbind(intent: Intent?): Boolean {
        stopMusic()
        return super.onUnbind(intent)
    }

    /**
     * 播放音乐
     */
    private fun playMusic(){
        mediaPlayer.setOnPreparedListener {
            mediaPlayer.start()
        }
        mediaPlayer.setOnCompletionListener {
            mediaPlayer.release()
        }
    }

    /**
     * 停止播放
     */
    private fun stopMusic(){
        if(mediaPlayer.isPlaying){
            mediaPlayer.stop()
            mediaPlayer.release()
        }
    }
    /**
     * 创建通知渠道
     * @param id String
     * @param name String
     */
    private fun createNotificationChannel(id:String,name:String){
        //创建通知管理器
        val notificationManager =
            getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        //定义通知渠道
        val channel = NotificationChannel(id,name,NotificationManager.IMPORTANCE_DEFAULT)
        //创建通知渠道
        notificationManager.createNotificationChannel(channel)
    }

    /**
     * 发布通知
     */
    private fun postNotification(){
        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O) {
            createNotificationChannel("music_service","歌曲")
        }
      
        //定义跳转SongActivity的PendingIntent
        val descPendingIntent = getSongPendingIntent()
        //定义启动控制音乐播放广播接受器的PendingIntent
        val playPendingIntent = getPlayPendingIntent()
        //定义启动控制音乐停止播放广播接受器的PendingIntent
        val stopPendingIntent = getStopPendingIntent()
        //定义动作
        val playAction = NotificationCompat.Action(android.R.drawable.ic_media_play,"播放",playPendingIntent)
        val stopAction = NotificationCompat.Action(android.R.drawable.ic_media_pause,"停止",stopPendingIntent)
        //创建通知
        val notification = NotificationCompat.Builder(this,"music_service").apply{
            setOngoing(true)
            setOnlyAlertOnce(true)
            setContentTitle("播放音乐")
            setContentText("正在播放歌曲...")
            setSmallIcon(R.mipmap.ic_launcher)
            setColorized(true)
            color = resources.getColor(R.color.teal_200,null)

            setContentIntent(descPendingIntent)

//            addAction(android.R.drawable.ic_media_play,"播放",playPendingIntent) //android23开始不支持
//            addAction(android.R.drawable.ic_media_pause,"停止",stopPendingIntent)//android23开始不支持
            addAction(playAction)
            addAction(stopAction)

        }.build()

        startForeground(1,notification)
    }

    /**
     * 跳转到歌曲介绍的界面
     * @return PendingIntent
     */
    private fun getSongPendingIntent():PendingIntent{
        //定义启动服务的意图
        val intent = Intent(this,SongActivity::class.java)
        //定义PendingIntent
        return PendingIntent.getActivity(this,1,
                intent,PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE)
    }

    private fun getPlayPendingIntent(): PendingIntent {
        //创建意图过滤器
        val intentFilter = IntentFilter()
        //增加动作
        intentFilter.addAction("PLAY_ACTION")
        //创建音乐播放广播接受器
        val playReceiver = object: BroadcastReceiver(){
            override fun onReceive(context: Context?, intent: Intent?) {
                playMusic()
            }
        }
        //注册播放音乐广播器
        registerReceiver(playReceiver,intentFilter)
        //创建播放意图
        val intent = Intent("PLAY_ACTION")
        return PendingIntent.getBroadcast(this,
            2,intent,PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT)
    }

    private fun getStopPendingIntent():PendingIntent{
        //创建意图过滤器
        val intentFilter = IntentFilter()
        //增加动作
        intentFilter.addAction("STOP_ACTION")
        //创建停止播放广播接受器
        val stopReceiver = object: BroadcastReceiver(){
            override fun onReceive(context: Context?, intent: Intent?) {
                stopMusic()
            }
        }
        //注册广播接收器
        registerReceiver(stopReceiver,intentFilter)
        //创建意图
        val intent = Intent("STOP_ACTION")
        return PendingIntent.getBroadcast(this,
            3,intent,
            PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT)
    }
}

3.定义主活动MainActivity

class MainActivity : ComponentActivity() {
    lateinit var intent1:Intent
    val conn = object:ServiceConnection{
        override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
        }

        override fun onServiceDisconnected(name: ComponentName?) {
        }

    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        intent1 = Intent(this,MusicService::class.java)

        requestNotificationPermission()
        setContent {
            Lab03Theme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    MainScreen(playAction=::playMusic,stopAction=::stopMusic)
                }
            }
        }
    }

    /**
     * 请求通知权限
     */
    private fun requestNotificationPermission(){
        if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.TIRAMISU) {
            ActivityCompat.requestPermissions(
                this,
                arrayOf(android.Manifest.permission.POST_NOTIFICATIONS),
                0
            )
        }
    }

    /**
     * 绑定播放音频的服务
     */
    private fun playMusic(){
        bindService(intent1,conn, Context.BIND_AUTO_CREATE)
    }

    /**
     * 解除绑定
     */
    private fun stopMusic(){
        unbindService(conn)
    }
}

@Composable
fun MainScreen(playAction:()->Unit,stopAction:()->Unit) {
    Column(horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center){
        Row{
          TextButton(onClick = {
              playAction.invoke()
          }){
              Row{
                  Icon(imageVector = Icons.Filled.PlayArrow,contentDescription = "play")
                  Text("播放")
              }
          }
          TextButton(onClick = {
              stopAction.invoke()
          }){
                Row{
                    Icon(imageVector = Icons.Filled.Stop,contentDescription = "play")
                    Text("停止")
                }
          }
        }
    }
}

4.定义显示歌曲介绍的SongActivity

class SongActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent{
            Column{
                Text("正在播放歌曲,歌曲介绍内容描述暂时没有定义")
                TextButton(onClick = {
                    //结束当前活动
                    finish()
                }){
                    Text("返回")
                }
            }
        }
    }
}

参考文献

1.PendingIntent
https://developer.android.google.cn/reference/android/app/PendingIntent文章来源地址https://www.toymoban.com/news/detail-760584.html

到了这里,关于Android笔记(十七):PendingIntent简介的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 学习Android的第十七天

    目录 Android ListView 添加插入数据 添加记录 在指定位置插入数据 Android ListView 删除数据 ListView 删除数据 ListView 清空数据 Android ListView 更改数据 ListView 数据更新 Android ListView 查询数据 ListView 数据查询 我们在顶部添加一个按钮,每次点击添加一条记录,并且数据为空时提示用户

    2024年02月22日
    浏览(50)
  • Android Audio开发——录音(十七)

            AudioRecord 是安卓多媒体框架中用于录制音频的工具。它支持录制原始音频数据,即 PCM 数据,PCM 数据不能被播放器直接播放,需要编码压缩成常见音频格式才能被播放器识别。而我们之前分析的原生 api 中的 AudioTrack 可以直接播放 PCM 数据。         AudioRecord

    2024年02月11日
    浏览(43)
  • android 如何分析应用的内存(十七)——使用MAT查看Android堆

    前一篇文章,介绍了使用Android profiler中的memory profiler来查看Android的堆情况。 如Android 堆中有哪些对象,这些对象的引用情况是什么样子的。 可是我们依然面临一个比较严峻的挑战:不管是app开发者,还是内存分析者而言,堆中的对象,非常之多,不仅有Android 原生的类,还

    2024年02月13日
    浏览(73)
  • Android14之Android Rust模块编译语法(一百八十七)

    简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏: Audio工程师进阶系列 【 原创干货持续更新中…… 】🚀 优质专栏: 多媒体系统工程师系列 【 原创干货持续更新中…… 】🚀 人生格言: 人生从来没有捷径

    2024年02月22日
    浏览(78)
  • Android OpenCV(七十七):官方指南方式编译 OpenCV Android SDK.md

    众所周知😳, OpenCV 4.9.0 罕见的在 Android 平台上做出调整,具体更新内容请移步难得一见的 Android OpenCV ChangeLog。然而,近期笔者在查阅 OpenCV Github Wiki 时,又发现了新东西🤡,一篇名为 \\\"Custom OpenCV Android SDK and AAR package build\\\"的 Wiki。以前我们编译 SDK 采用的是CMake方式,具体可

    2024年01月21日
    浏览(48)
  • Android OpenCV(三十七):轮廓外接多边形

    参数四:closed,逼近曲线是否闭合的标志,true表示封闭,false,表示不封闭。 该方法使用的是 Douglas-Peucker algorithm(道格拉斯-普克算法) 。 Douglas-Peukcer算法 由D.Douglas和T.Peueker于1973年提出,也称为 拉默-道格拉斯-普克算法 、 迭代适应点算法 、 分裂与合并算法 、 D-P算法

    2024年04月13日
    浏览(69)
  • Android内存泄漏分析及检测工具LeakCanary简介,Android进阶

    @Synchronized override fun expectWeaklyReachable( watchedObject: Any, description: String ) { if (!isEnabled()) { return } removeWeaklyReachableObjects() val key = UUID.randomUUID() .toString() val watchUptimeMillis = clock.uptimeMillis() val reference = KeyedWeakReference(watchedObject, key, description, watchUptimeMillis, queue) SharkLog.d { \\\"Watching \\\" +

    2024年04月25日
    浏览(41)
  • Android系统架构简介

    Android的系统架构主要分为五层,见下图: 从下至上依次是: Linux内核: Android基于Linux,由Linux提供核心系统服务,如安全、内存管理、进程管理、网络堆栈、驱动模型等等; 除了标准的Linux内核之外,Android还增加了内核的驱动程序,如显示驱动、音频驱动、 Binder驱动、输入

    2024年02月10日
    浏览(33)
  • Android 开发简介

    Android 是由 Google 领导的开放手机联盟开发的基于 Linux 的开源移动操作系统。有关一般详细信息,请参阅 Android 主网站。 Android 开发与其他平台的开发有很大不同。因此,在开始针对 Android 编程之前,我们建议您确保熟悉以下关键主题: Java 编程语言是 Android 操作系统的主要

    2024年01月16日
    浏览(46)
  • Android UT开发简介

            Android UT(Unit Testing)开发是指在 Android 应用程序中进行单元测试的开发过程。单元测试是一种软件测试方法,用于测试应用程序中的最小可测试单元(通常是函数或方法)的正确性。 Android UT 开发的主要目标是确保应用程序的各个单元在不同情况下能够按照预期

    2024年02月09日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包