前提・実現したいこと
高校の課題研究で、スマホの使い過ぎを防ぐためのアンドロイドアプリの開発をしています。使用言語はKotlinです。
下のような遷移を実装したいです。
######完成形の遷移
①端末にインストール済みアプリのRecyclerView
↓
②タップしたアプリの使用時間を選択する画面
↓
③タップしたアプリを起動
現在までの工程
0. 下のサイトの通りにホームアプリを完成させた(①→③の遷移ができた)
超シンプルなホームアプリ(ランチャーアプリ)を作る
0. 他のアプリを起動する前に②の画面に遷移させるため、修正をしたが、遷移せずエラーも発生した。
##工程1で実装済みのホームアプリのコード
######AppAdapter.kt
Kotlin
1 2package com.example.... 3 4import android.view.LayoutInflater 5import android.view.View 6import android.view.ViewGroup 7import android.widget.ImageView 8import android.widget.TextView 9import androidx.recyclerview.widget.RecyclerView 10import androidx.recyclerview.widget.RecyclerView.ViewHolder 11 12class AppAdapter( 13 private val inflater: LayoutInflater, 14 private val list: List<AppInfo>, 15 private val onClick: (view: View, info: AppInfo) -> Unit 16) : RecyclerView.Adapter<AppAdapter.AppViewHolder>() { 17 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AppViewHolder = 18 AppViewHolder(inflater.inflate(R.layout.li_application, parent, false)) 19 20 override fun getItemCount(): Int = list.size 21 22 override fun onBindViewHolder(holder: AppViewHolder, position: Int) { 23 val info = list[position] 24 holder.itemView.setOnClickListener { onClick(it, info) } 25 holder.icon.setImageDrawable(info.icon) 26 holder.label.text = info.label 27 holder.packageName.text = info.componentName.packageName 28 } 29 30 class AppViewHolder(itemView: View) : ViewHolder(itemView) { 31 val icon: ImageView = itemView.findViewById(R.id.icon) 32 val label: TextView = itemView.findViewById(R.id.label) 33 val packageName: TextView = itemView.findViewById(R.id.packageName) 34 } 35}
######AppInfo.kt
Kotlin
1package com.example.... 2 3import android.content.ActivityNotFoundException 4import android.content.ComponentName 5import android.content.Context 6import android.content.Intent 7import android.graphics.drawable.Drawable 8 9data class AppInfo( 10 val icon: Drawable, 11 val label: String, 12 val componentName: ComponentName 13) { 14 fun launch(context: Context) { 15 try { 16 val intent = Intent(Intent.ACTION_MAIN).also { 17 it.flags = Intent.FLAG_ACTIVITY_NEW_TASK or 18 Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED 19 it.addCategory(Intent.CATEGORY_LAUNCHER) 20 it.component = componentName 21 } 22 context.startActivity(intent) 23 } catch (e: ActivityNotFoundException) { 24 } 25 } 26} 27
######AppInfoList.kt
Kotlin
1package com.example.... 2 3import android.content.ComponentName 4import android.content.Context 5import android.content.Intent 6import android.content.pm.PackageManager 7import android.graphics.drawable.Drawable 8import android.os.Build 9import androidx.annotation.RequiresApi 10 11object AppInfoList{ 12 @RequiresApi(Build.VERSION_CODES.LOLLIPOP) 13 fun create(context: Context): List<AppInfo> { 14 val pm = context.packageManager 15 val intent = Intent(Intent.ACTION_MAIN) 16 .also { it.addCategory(Intent.CATEGORY_LAUNCHER) } 17 return pm.queryIntentActivities(intent, PackageManager.MATCH_ALL) 18 .asSequence() 19 .mapNotNull { it.activityInfo } 20 .filter { it.packageName != context.packageName } 21 .map { 22 AppInfo( 23 it.loadIcon(pm) ?: getDefaultIcon(context), 24 it.loadLabel(pm).toString(), 25 ComponentName(it.packageName, it.name) 26 ) 27 } 28 .sortedBy { it.label } 29 .toList() 30} 31 @RequiresApi(Build.VERSION_CODES.LOLLIPOP) 32 private fun getDefaultIcon(context: Context): Drawable { 33 return context.resources.getDrawable(R.mipmap.ic_launcher, null) 34 } 35} 36 37
######LauncherActivity.kt
Kotlin
1package com.example.... 2 3import android.os.Build 4import androidx.appcompat.app.AppCompatActivity 5import android.os.Bundle 6import androidx.annotation.RequiresApi 7import androidx.recyclerview.widget.LinearLayoutManager 8import kotlinx.android.synthetic.main.activity_main.* 9 10class LauncherActivity : AppCompatActivity() { 11 @RequiresApi(Build.VERSION_CODES.LOLLIPOP) 12 override fun onCreate(savedInstanceState: Bundle?) { 13 super.onCreate(savedInstanceState) 14 setContentView(R.layout.activity_main) 15 val adapter = AppAdapter(layoutInflater, AppInfoList.create(this)) { view, info -> 16 info.launch(this)} 17 recyclerView.adapter = adapter 18 recyclerView.layoutManager = LinearLayoutManager(this) 19 20 } 21 }
試したこと
- 画面②のActivityとlayoutを追加した
- 書籍でRecyclerViewについて調べた。
Androidアプリ開発の教科書 Kotlin対応
0. AppInfo.ktのTry-Catch構文のtryでLaunchという関数が使われていたため、その関数が他のアプリを起動するためのコードだと考えた。よってその部分を画面②へ遷移するためのコードに修正した。
######AppInfo.kt//エラーをコードの中にメモしています
Kotlin
1package com.example.... 2 3import android.content.ActivityNotFoundException 4import android.content.ComponentName 5import android.content.Context 6import android.content.Intent 7import android.graphics.drawable.Drawable 8import android.view.View 9import androidx.core.content.ContextCompat.startActivity 10 11data class AppInfo( 12 val icon: Drawable, 13 val label: String, 14 val componentName: ComponentName 15) { 16 17 private inner class ItemClickListener : View.OnClickListener{ 18 19//Unit defined in android.view.View.OnClickListener 20 21 fun launch(context: Context) { 22 try { 23 override fun onClick(view: View){ 24 25//Modifier 'override' is not applicable to 'local function' 26 27 val appNames = label.text.toString() 28 29//Unresolved reference: text 30 31 val intent = Intent(applicationContext, ReleaseScreen::class.java) 32 33//Unresolved reference: applicationContext 34 35 intent.putExtra("appNames", appNames) 36 startActivity(intent) 37 38//Type mismatch: inferred type is Intent but Context was expected 39 40 } 41 42 } catch (e: ActivityNotFoundException) { 43 } 44 } 45 } 46 47} 48
######ReleaseScreen.kt追加 エラーなし
Kotlin
1package com.example.... 2 3import android.os.Bundle 4import android.widget.TextView 5import androidx.appcompat.app.AppCompatActivity 6import kotlinx.android.synthetic.main.activity_release_screen.* 7 8class ReleaseScreen : AppCompatActivity() { 9 override fun onCreate(savedInstanceState: Bundle?) { 10 super.onCreate(savedInstanceState) 11 setContentView(R.layout.activity_release_screen) 12 13 14 val appNames = intent.getStringExtra("appNames") 15 val installed = findViewById<TextView>(R.id.installed) 16 17 installed.text = appNames 18 19 n0.minValue = 0 20 n0.maxValue = 24 21 n0.value = 0 22 n1.minValue = 0 23 n1.maxValue = 5 24 n1.value = 0 25 n2.minValue = 0 26 n2.maxValue = 9 27 n2.value = 0 28 } 29}
######LauncherActivity.kt//エラーをコードの中にメモしています
Kotlin
1package com.example.... 2 3import android.content.Intent 4import android.os.Build 5import androidx.appcompat.app.AppCompatActivity 6import android.os.Bundle 7import android.view.View 8import android.widget.AdapterView 9import android.widget.TextView 10import androidx.annotation.RequiresApi 11import androidx.core.content.ContextCompat.startActivity 12import androidx.recyclerview.widget.LinearLayoutManager 13import kotlinx.android.synthetic.main.activity_main.* 14import kotlinx.android.synthetic.main.li_application.* 15 16class LauncherActivity : AppCompatActivity() { 17 @RequiresApi(Build.VERSION_CODES.LOLLIPOP) 18 override fun onCreate(savedInstanceState: Bundle?) { 19 super.onCreate(savedInstanceState) 20 setContentView(R.layout.activity_main) 21 val adapter = AppAdapter(layoutInflater, AppInfoList.create(this)) { view, info -> 22 info.launch(this)} 23 24//Unresolved reference: launch 25 26 recyclerView.adapter = adapter 27 recyclerView.layoutManager = LinearLayoutManager(this) 28 } 29 30 31} 32
補足情報(FW/ツールのバージョンなど)
Windows10
Android Studio4.0.1