Upgrade to Pro — share decks privately, control downloads, hide ads and more …

AndroidにおけるNotificationのおさらい & Android16の新API P...

AndroidにおけるNotificationのおさらい & Android16の新API Progress-centric Notifications

Avatar for ぎーにょ

ぎーにょ

March 03, 2025
Tweet

More Decks by ぎーにょ

Other Decks in Programming

Transcript

  1. "OESPJEʹ͓͚Δ/PUJGJDBUJPOͷओཁͳཁૉ w 4UBUVT#BSBOE/PUJ fi DBUJPO%SBXFS w )FBETVQ/PUJ fi DBUJPO w

    1FSNJTTJPO w /PUJ fi DBUJPODIBOOFM w /PUJ fi DBUJPOJNQPSUBODF w /PUJ fi DBUJPOHSPVQ
  2. )FBETVQ/PUJGJDBUJPO w "OESPJEͰ௥Ճ w ओͳදࣔ৚݅ w ΞϓϦΛ։͍͍ͯΔ w ௨஌ͷॏཁ౓͕ߴ͍ w

    ϩοΫը໘͕ղআ͞ΕΔ "OESPJE%FWFMPQFST ௨஌ͷ֓ཁ IUUQTEFWFMPQFSBOESPJEDPNEFWFMPQVJWJFXTOPUJ fi DBUJPOT
  3. ओཁͳ/PUJGJDBUJPOTͷ࣮૷ w #BTJD/PUJ fi DBUJPOT w 8JUI"DUJPO w 8JUI%JSFDU3FQMZ w

    8JUI1SPHSFTT#BS w $POWFSTBUJPO/PUJ fi DBUJPOT w $BMM4UZMF/PUJ fi DBUJPOT w .FEJB4UZMF/PUJ fi DBUJPOT w %FDPSBUFE$VTUPN7JFX4UZMF/PUJ fi DBUJPOT
  4. #BTJD/PUJGJDBUJPOT &YQBOEBCMF ௕͍ςΩετΛ௨஌ΤϦΞͰӾཡՄೳʹ val builder = NotificationCompat.Builder(this, ɹɹɹMainActivity.NOTIFICATION_CHANNEL_ID) .setSmallIcon(R.drawable.icon) .setContentTitle("John

    Doe") .setContentText("ٱ͠ͿΓʂ࠷ۙͳʹͯ͠ΔͷʁͳΜ͔ؾ͍ͮͨΒ...") .setPriority(NotificationCompat.PRIORITY_DEFAULT) .setStyle(NotificationCompat.BigTextStyle() .bigText(“ٱ͠ͿΓʂ࠷ۙͳʹͯ͠ΔͷʁͳΜ͔ؾ͍ͮͨΒ..."))
  5. #BTJD/PUJGJDBUJPOT 8JUI"DUJPO ௨஌ʹରͯ͠ͷૢ࡞Λ࣮ߦՄೳ val builder = NotificationCompat.Builder(this, MainActivity.NOTIFICATION_CHANNEL_ID) .setSmallIcon(R.drawable.icon) .setContentTitle("λεΫͷظݶͰ͢")

    .setContentText("ॻྨΛఏग़͢Δɻ") .setPriority(NotificationCompat.PRIORITY_DEFAULT) .addAction(R.drawable.outline_acute_24, "εψʔζ", pendingIntent) .addAction(R.drawable.outline_acute_24, "׬ྃ", pendingIntent) .addAction(R.drawable.outline_acute_24, "࡟আ", pendingIntent)
  6. #BTJD/PUJGJDBUJPOT 8JUI%JSFDU3FQMZ ௨஌ΤϦΞ͔Β௚઀ฦ৴͕ՄೳͱͳΔ // RemoteInput ΠϯελϯεΛ࡞੒ val remoteInput: RemoteInput =

    RemoteInput.Builder(KEY_TEXT_REPLY).run { setLabel("ฦ৴͢Δ") build() } // ฦ৴ΞΫγϣϯ༻ͷPendingIntentΛ࡞੒ val replyIntent = Intent(this, MyBroadcastReceiver::class.java).apply { action = "REPLY" putExtra(ACTION_REPLY_NOTIFICATION_ID, 0) } val pendingIntent = PendingIntent.getBroadcast( this, 0,replyIntent, PendingIntent.FLAG_MUTABLE)
  7. #BTJD/PUJGJDBUJPOT 8JUI%JSFDU3FQMZ ௨஌ΤϦΞ͔Β௚઀ฦ৴͕ՄೳͱͳΔ // RemoteInput ΠϯελϯεΛ࡞੒ val remoteInput: RemoteInput =

    RemoteInput.Builder(KEY_TEXT_REPLY).run { setLabel("ฦ৴͢Δ") build() } // actionʹRemoteInputΛΞλον val action: NotificationCompat.Action = NotificationCompat.Action.Builder(R.drawable.icon, "ฦ৴͢Δ", pendingIntent) .addRemoteInput(remoteInput) .build() // ฦ৴ΞΫγϣϯ༻ͷPendingIntentΛ࡞੒ val replyIntent = Intent(this, MyBroadcastReceiver::class.java).apply { action = "REPLY" putExtra(ACTION_REPLY_NOTIFICATION_ID, 0) } val pendingIntent = PendingIntent.getBroadcast( this, 0,replyIntent, PendingIntent.FLAG_MUTABLE)
  8. #BTJD/PUJGJDBUJPOT 8JUI%JSFDU3FQMZ ௨஌ΤϦΞ͔Β௚઀ฦ৴͕ՄೳͱͳΔ // actionʹRemoteInputΛΞλον val action: NotificationCompat.Action = NotificationCompat.Action.Builder(R.drawable.icon,

    "ฦ৴͢Δ", pendingIntent) .addRemoteInput(remoteInput) .build() val builder = NotificationCompat.Builder(this, ɹɹɹMainActivity.NOTIFICATION_CHANNEL_ID) .setSmallIcon(R.drawable.icon) .setContentTitle("John Doe") .setContentText("ٱ͠ͿΓʂ࠷ۙͳʹͯ͠ΔͷʁͳΜ͔ؾ͍ͮͨΒ...") .setPriority(NotificationCompat.PRIORITY_DEFAULT) .addAction(action)
  9. #BTJD/PUJGJDBUJPOT 8JUI1SPHSFTT#BS ਐߦதͷΦϖϨʔγϣϯͷεςʔλεΛϢʔβʔʹ஌ΒͤΔ val PROGRESS_MAX = 100 val PROGRESS_CURRENT =

    0 val builder = NotificationCompat.Builder(this, ɹɹɹMainActivity.NOTIFICATION_CHANNEL_ID) .setSmallIcon(R.drawable.icon) .setContentTitle(“ϑΝΠϧͷμ΢ϯϩʔυ") .setContentText(“ϑΝΠϧΛμ΢ϯϩʔυதͰ͢...") .setPriority(NotificationCompat.PRIORITY_LOW) .setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false)
  10. .FTTBHJOH4UZMF/PUJGJDBUJPOT ෳ਺ͷਓʹΑΔҰ࿈ͷϝοηʔδΛදࣔ val builder = NotificationCompat.Builder( this, MainActivity.NOTIFICATION_CHANNEL_ID) .setSmallIcon(R.drawable.baseline_message_24) val

    message1 = NotificationCompat.MessagingStyle.Message( "ٱ͠ͿΓʂ࠷ۙͳʹͯ͠Δͷʁ", message1time, Person.Builder().setName("John Doe").build()) val message2 = NotificationCompat.MessagingStyle.Message( "ݩؾͩΑʂ", message2time, Person.Builder().setName("Me").build()) .setStyle( NotificationCompat .MessagingStyle( Person.Builder().setName(“John Doe").build()) .addMessage(message1) .addMessage(message2) )
  11. $BMM4UZMF/PUJGJDBUJPOT ௨࿩ʹؔ͢Δ௨஌ .setStyle( Notification.CallStyle.forIncomingCall( incomingCaller, declineIntent, answerIntent) ) val incomingCaller

    = android.app.Person.Builder() .setName("Jane Doe") .build() val builder = Notification.Builder(this, MainActivity.NOTIFICATION_CHANNEL_ID) .setContentIntent(contentIntent) .setSmallIcon(R.drawable.icon) .addPerson(incomingCaller)
  12. $BMM4UZMF/PUJGJDBUJPOT ௨࿩ʹؔ͢Δ௨஌ .setStyle( Notification.CallStyle.forOngoingCall( incomingCaller, hangUpIntent) ) val incomingCaller =

    android.app.Person.Builder() .setName("Jane Doe") .build() val builder = Notification.Builder(this, MainActivity.NOTIFICATION_CHANNEL_ID) .setContentIntent(contentIntent) .setSmallIcon(R.drawable.icon) .addPerson(incomingCaller)
  13. $BMM4UZMF/PUJGJDBUJPOT ௨࿩ʹؔ͢Δ௨஌ .setStyle( Notification.CallStyle.forScreeningCall( incomingCaller, hangUpIntent, answerIntent) ) val incomingCaller

    = android.app.Person.Builder() .setName("Jane Doe") .build() val builder = Notification.Builder(this, MainActivity.NOTIFICATION_CHANNEL_ID) .setContentIntent(contentIntent) .setSmallIcon(R.drawable.icon) .addPerson(incomingCaller)
  14. $VTUPN7JFX4UZMF/PUJGJDBUJPOT ΧελϚΠζͨ͠-BZPVUͷ௨஌΋࡞੒Մೳ 8JEHFUͰ΋࢖͏3FNPUF7JFXΛ༻͍Δ val builder = NotificationCompat.Builder( this, MainActivity.NOTIFICATION_CHANNEL_ID) .setSmallIcon(R.drawable.ic_music_note)

    val notificationLayout = RemoteViews(packageName, R.layout.custom_notification_small) val notificationLayoutExpanded = RemoteViews(packageName, R.layout.custom_notification_expanded) .setStyle( NotificationCompat.DecoratedCustomViewStyle()) .setCustomContentView(notificationLayout) .setCustomBigContentView(notificationLayoutExpanded)
  15. "OESPJE%FWFMPQFST 1SPHSFTTDFOUSJDOPUJ fi DBUJPOT IUUQTEFWFMPQFSBOESPJEDPNBCPVUWFSTJPOTGFBUVSFTQSPHSFTTDFOUSJDOPUJ fi DBUJPOT l"OESPJEͰ͸ɺϢʔβʔ͕։࢝ͨ͠ɺ࠷ॳ͔Β࠷ޙ·ͰͷδϟʔχʔΛγʔϜϨεʹ௥੻Ͱ͖Δ Α͏ʹɺਐߦঢ়گॏࢹͷ௨஌͕ಋೖ͞Ε͍ͯ·͢ɻ /PUJGJDBUJPO1SPHSFTT4UZMF

    ͸ɺਐߦঢ়گॏࢹͷ௨஌Λ࡞੒Ͱ͖Δ৽͍͠௨஌ελΠϧͰ͢ɻओͳϢ ʔεέʔεʹ͸ɺ৐ंγΣΞϦϯάɺ഑ୡɺφϏήʔγϣϯͳͲ͕͋Γ·͢ɻ /PUJGJDBUJPO1SPHSFTT4UZMF Ϋϥε಺ͰɺϙΠϯτͱηάϝϯτΛ࢖༻ͯ͠ɺϢʔβʔδϟʔχʔ ಺ͷঢ়ଶͱϚΠϧετʔϯΛࢦఆͰ͖·͢ɻz
  16. Ϣʔεέʔε 1SPHSFTTDFOUSJD/PUJ fi DBUJPOT w ϑʔυσϦόϦʔɺ഑ंαʔϏεͳͲ w ϢʔβʔδϟʔχʔͷਐḿΛ఻͑Δࣄ͕ޮՌతͳ ϓϩμΫτͱ૬ੑ͕ྑͦ͞͏ w

    ਐߦঢ়گΛසൟ͔ͭਖ਼֬ʹߋ৽͢Δࣄ͕ਪ঑ "OESPJE%FWFMPQFST 1SPHSFTTDFOUSJDOPUJ fi DBUJPOT IUUQTEFWFMPQFSBOESPJEDPNBCPVUWFSTJPOTGFBUVSFTQSPHSFTTDFOUSJDOPUJ fi DBUJPOT
  17. "OESPJE4%,ͷઃఆ android { namespace = "com.example.notificationsampleapp2025" compileSdkPreview = "Baklava" defaultConfig

    { applicationId = "com.example.notificationsampleapp2025" minSdk = 34 targetSdkPreview = "Baklava" versionCode = 1 versionName = "1.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" }
  18. "OESPJE4%,ͷઃఆ android { namespace = "com.example.notificationsampleapp2025" compileSdkPreview = "Baklava" defaultConfig

    { applicationId = "com.example.notificationsampleapp2025" minSdk = 34 targetSdkPreview = "Baklava" versionCode = 1 versionName = "1.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" }
  19. ࣮૷ํ๏ 1SPHSFTTDFOUSJD/PUJ fi DBUJPOT val builder = Notification.Builder(this, NOTIFICATION_CHANNEL_ID) val

    style = Notification.ProgressStyle() .setStyledByProgress(true) .setProgress(30) .setProgressTrackerIcon( Icon.createWithResource( applicationContext, R.drawable.penguin ) ) builder.setStyle(style)
  20. ࣮૷ํ๏4FHNFOU 1SPHSFTTDFOUSJD/PUJ fi DBUJPOT val builder = Notification.Builder(this, NOTIFICATION_CHANNEL_ID) val

    style = Notification.ProgressStyle() .setStyledByProgress(true) .setProgress(30) .setProgressTrackerIcon( Icon.createWithResource( applicationContext, R.drawable.penguin ) ) builder.setStyle(style) .setProgressSegments( listOf( Notification.ProgressStyle.Segment(40).setColor(Color.BLUE), Notification.ProgressStyle.Segment(30).setColor(Color.RED), Notification.ProgressStyle.Segment(30).setColor(Color.BLUE) ) )
  21. ࣮૷ํ๏1PJOU 1SPHSFTTDFOUSJD/PUJ fi DBUJPOT val builder = Notification.Builder(this, NOTIFICATION_CHANNEL_ID) val

    style = Notification.ProgressStyle() .setStyledByProgress(true) .setProgress(30) .setProgressTrackerIcon( Icon.createWithResource( applicationContext, R.drawable.penguin ) ) builder.setStyle(style) .setProgressSegments(…) .setProgressPoints( listOf( Notification.ProgressStyle.Point(50).setColor(Color.RED), Notification.ProgressStyle.Point(80).setColor(Color.GREEN) ) )
  22. 4FHNFOU1PJOU w 4FHNFOUT w φϏήʔγϣϯΞϓϦͰɺ໨త஍·Ͱͷ ަ௨ঢ়گΛදݱ͢ΔͳͲʹ༗༻ w 1PJOU w ϑʔυσϦόϦʔʹ͓͚Δ৯ࣄͷ४උɺ

    λΫγΞϓϦʔʹ͓͚Δ৐ंͳͲɺମݧ ʹ͓͚ΔϚΠϧετʔϯͷදݱʹ༗༻ "OESPJE%FWFMPQFST 1SPHSFTTDFOUSJDOPUJ fi DBUJPOT IUUQTEFWFMPQFSBOESPJEDPNBCPVUWFSTJPOTGFBUVSFTQSPHSFTTDFOUSJDOPUJ fi DBUJPOT
  23. ·ͱΊ w /PUJ fi DBUJPO͸ɺΞϓϦͷ֎ͷੈք͔ΒϢʔβʔʹϝοηʔδΛಧ͚ΒΕΔ ศརͳ࢓૊Έ w "OESPJEʹ͸ଟछଟ༷ͳ/PUJ fi DBUJPOͷબ୒ࢶ͕༻ҙ͞Ε͍ͯΔ

    w &WJMͳ௨஌ͷΞϓϦʹΑΓϢʔβʔͷརศੑΛଛͳΘͳ͍Α͏ɺ "OESPJEͷํͰ*NQPSUBODFͳͲͷ࢓૊Έ͕ಋೖ͞Ε͖ͯͨɻ "OESPJE04͕ਖ਼͘͠௨஌Λ൑ผͰ͖ΔΑ͏ʹ࣮૷͠Α͏ɻ w 1SPHSFTTDFOUSJD/PUJ fi DBUJPOͳͲͷ௨஌ͷ৽ػೳΛಋೖ͢Δ͜ͱͰɺ ௿޻਺ͰϦονͳମݧΛఏڙͰ͖ΔͷͰɺࠓޙ΋ཁνΣοΫʂ
  24. ࢀߟจݙ w "OESPJE%FWFMPQFST w ௨஌ͷ֓ཁ IUUQTEFWFMPQFSBOESPJEDPNEFWFMPQVJWJFXT OPUJ fi DBUJPOT w

    ਐߦঢ়گॏࢹͷ௨஌ IUUQTEFWFMPQFSBOESPJEDPNBCPVUWFSTJPOT GFBUVSFTQSPHSFTTDFOUSJDOPUJ fi DBUJPOT w "OESPJEBOEQSPHSFTTDFOUSJDOPUJ fi DBUJPOT IUUQTNFEJVNDPN !WJUPLTNJMFBOESPJEBOEQSPHSFTTDFOUSJD OPUJ fi DBUJPOTDCEEC