[趣味開発]タスク管理通知アプリの開発 アプリ編
はじめに
https://qiita.com/yydevelop/items/d81b0a9fe0595a7956c4
の続き
チェックリスト管理画面の追加
MainActivity.kt
package com.example.taskreminder
import android.appwidget.AppWidgetManager
import android.content.ComponentName
import android.content.Context
import android.content.SharedPreferences
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.example.taskreminder.ui.theme.TaskReminderTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
TaskReminderTheme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
TaskInputScreen(
modifier = Modifier.padding(innerPadding),
sharedPreferences = getSharedPreferences("TaskReminderPrefs", Context.MODE_PRIVATE)
)
}
}
}
}
}
@Composable
fun TaskInputScreen(modifier: Modifier = Modifier, sharedPreferences: SharedPreferences) {
var task by remember { mutableStateOf("") }
val context = LocalContext.current
Column(
modifier = modifier
.fillMaxSize()
.padding(16.dp),
verticalArrangement = Arrangement.Center
) {
TextField(
value = task,
onValueChange = { task = it },
label = { Text("タスクを入力") },
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(8.dp))
Button(
onClick = {
val editor = sharedPreferences.edit()
editor.putString("task", task)
editor.apply()
// ウィジェットを更新
val appWidgetManager = AppWidgetManager.getInstance(context)
val widgetComponent = ComponentName(context, TaskReminderWidget::class.java)
val appWidgetIds = appWidgetManager.getAppWidgetIds(widgetComponent)
for (appWidgetId in appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId, task)
}
task = ""
},
modifier = Modifier.fillMaxWidth()
) {
Text("タスクを追加")
}
}
}
@Preview(showBackground = true)
@Composable
fun TaskInputScreenPreview() {
// プレビュー用のダミーのSharedPreferencesを使う
val context = LocalContext.current
val sharedPreferences = context.getSharedPreferences("TaskReminderPrefs", Context.MODE_PRIVATE)
TaskReminderTheme {
TaskInputScreen(sharedPreferences = sharedPreferences)
}
}
画面確認
入力したテキストをウィジェットに反映
MainActivity.kt
package com.example.taskreminder
import android.appwidget.AppWidgetManager
import android.content.ComponentName
import android.content.Context
import android.content.SharedPreferences
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.example.taskreminder.ui.theme.TaskReminderTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
TaskReminderTheme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
TaskInputScreen(
modifier = Modifier.padding(innerPadding),
sharedPreferences = getSharedPreferences("TaskReminderPrefs", Context.MODE_PRIVATE)
)
}
}
}
}
}
@Composable
fun TaskInputScreen(modifier: Modifier = Modifier, sharedPreferences: SharedPreferences) {
var task by remember { mutableStateOf("") }
val context = LocalContext.current
Column(
modifier = modifier
.fillMaxSize()
.padding(16.dp),
verticalArrangement = Arrangement.Center
) {
TextField(
value = task,
onValueChange = { task = it },
label = { Text("タスクを入力") },
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(8.dp))
Button(
onClick = {
val editor = sharedPreferences.edit()
editor.putString("task", task)
editor.apply()
// ウィジェットを更新
val appWidgetManager = AppWidgetManager.getInstance(context)
val widgetComponent = ComponentName(context, TaskReminderWidget::class.java)
val appWidgetIds = appWidgetManager.getAppWidgetIds(widgetComponent)
for (appWidgetId in appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId) // 修正箇所: task引数を削除
}
task = ""
},
modifier = Modifier.fillMaxWidth()
) {
Text("タスクを追加")
}
}
}
@Preview(showBackground = true)
@Composable
fun TaskInputScreenPreview() {
// プレビュー用のダミーのSharedPreferencesを使う
val context = LocalContext.current
val sharedPreferences = context.getSharedPreferences("TaskReminderPrefs", Context.MODE_PRIVATE)
TaskReminderTheme {
TaskInputScreen(sharedPreferences = sharedPreferences)
}
}
TaskReminderWidget.kt
package com.example.taskreminder
import android.app.PendingIntent
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProvider
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.widget.RemoteViews
import android.widget.Toast
class TaskReminderWidget : AppWidgetProvider() {
override fun onReceive(context: Context, intent: Intent) {
super.onReceive(context, intent)
if (intent.action == "TASK_COMPLETED") {
// タスク完了時に SharedPreferences に完了状態を保存
val sharedPreferences = context.getSharedPreferences("TaskReminderPrefs", Context.MODE_PRIVATE)
val editor = sharedPreferences.edit()
editor.putBoolean("taskCompleted", true) // タスクが完了したことを保存
editor.apply()
val appWidgetManager = AppWidgetManager.getInstance(context)
val thisAppWidget = ComponentName(context.packageName, javaClass.name)
val appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidget)
for (appWidgetId in appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId)
}
// タスク完了の通知をユーザーに表示
Toast.makeText(context, "タスクが完了しました", Toast.LENGTH_SHORT).show()
}
}
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
for (appWidgetId in appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId)
}
}
override fun onEnabled(context: Context) {
// 初回ウィジェット追加時の処理
}
override fun onDisabled(context: Context) {
// 最後のウィジェットが削除された時の処理
}
}
internal fun updateAppWidget(context: Context, appWidgetManager: AppWidgetManager, appWidgetId: Int) {
val views = RemoteViews(context.packageName, R.layout.task_reminder_widget)
// SharedPreferencesからタスクと完了状態を取得
val sharedPreferences = context.getSharedPreferences("TaskReminderPrefs", Context.MODE_PRIVATE)
val task = sharedPreferences.getString("task", "今日のタスク: 未設定")
val taskCompleted = sharedPreferences.getBoolean("taskCompleted", false)
// 完了状態に応じて表示を変更
if (taskCompleted) {
views.setTextViewText(R.id.widgetTaskText, "$task - 完了")
} else {
views.setTextViewText(R.id.widgetTaskText, task)
}
// 完了ボタンのPendingIntentを設定
val intent = Intent(context, TaskReminderWidget::class.java)
intent.action = "TASK_COMPLETED"
val pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
views.setOnClickPendingIntent(R.id.completeTaskButton, pendingIntent)
appWidgetManager.updateAppWidget(appWidgetId, views)
}
画面確認
ウィジェットに連携がされるように