老板发言:

现在需要你做一个根据安卓的app。app的功用是:用户能够在app上设置提示事项,提示事项包括时刻和提示内容,然后在APP页面能够看到提示时刻的倒计时,然后在设置的提示事项时刻到了之后,能够完成在手机上进行弹窗提示,就像ios里面的软件提示事项一样。

咱们将运用Kotlin言语和Android Studio进行开发。

1.创立一个新的安卓项目

首先,翻开Android Studio并创立一个新项目。挑选”Empty Activity”模板,为项目命名(例如:”ReminderApp”),并设置项目的其他详细信息,如包名和保存位置。然后,挑选Kotlin作为开发言语,并保证最小API等级符合您的需求。

2.增加所需的权限

AndroidManifest.xml文件中,增加以下权限:

<uses-permission android:name="android.permission.SET_ALARM"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>

安卓版的提醒事项软件开发

3.规划UI 在activity_main.xml文件中

规划一个简略的用户界面,包括一个EditText输入提示内容、一个TimePicker挑选提示时刻,一个Button设置提示,以及一个TextView显示倒计时。

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp"
    tools:context=".MainActivity">
    <EditText
        android:id="@+id/reminderText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="提示内容" />
    <TimePicker
        android:id="@+id/reminderTimePicker"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:timePickerMode="spinner" />
    <Button
        android:id="@+id/setReminderButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="设置提示" />
    <TextView
        android:id="@+id/countdownTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="倒计时:" />
</LinearLayout>

安卓版的提醒事项软件开发

4.编写MainActivity 在MainActivity.kt文件中

处理用户输入和设置提示。

import android.app.AlarmManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
import android.widget.TimePicker
import java.util.*
class MainActivity : AppCompatActivity() {
    private lateinit var reminderText: EditText
    private lateinit var timePicker: TimePicker
    private lateinit var setReminderButton: Button
    private lateinit var countdownTextView: TextView
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        reminderText = findViewById(R.id.reminderText)
        timePicker = findViewById(R.id.reminderTimePicker)
        setReminderButton = findViewById(R.id.setReminderButton)
        countdownTextView = findViewById(R.id.countdownTextView)
        setReminderButton.setOnClickListener {
            setReminder()
        }
    }
    private fun setReminder() {
        val reminderTime = Calendar.getInstance()
        val currentTime = Calendar.getInstance()
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            reminderTime.set(Calendar.HOUR_OF_DAY, timePicker.hour)
            reminderTime.set(Calendar.MINUTE, timePicker.minute)
        } else {
            reminderTime.set(Calendar.HOUR_OF_DAY, timePicker.currentHour)
            reminderTime.set(Calendar.MINUTE, timePicker.currentMinute)
        }
        reminderTime.set(Calendar.SECOND, 0)
        if (reminderTime.before(currentTime)) {
            reminderTime.add(Calendar.DATE, 1)
        }
        setAlarm(reminderTime.timeInMillis)
        updateCountdownTextView(reminderTime.timeInMillis - currentTime.timeInMillis)
    }
    private fun setAlarm(timeInMillis: Long) {
        val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
        val intent = Intent(this, ReminderBroadcastReceiver::class.java)
        intent.putExtra("reminderText", reminderText.text.toString())
        val pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
        alarmManager.setExact(AlarmManager.RTC_WAKEUP, timeInMillis, pendingIntent)
    }
    private fun updateCountdownTextView(timeDifference: Long) {
        val hours = timeDifference / (60 * 60 * 1000)
        val minutes = (timeDifference / (60 * 1000)) % 60
        countdownTextView.text = String.format("倒计时:%02d:%02d", hours, minutes)
    }
}

安卓版的提醒事项软件开发

5.创立ReminderBroadcastReceiver 创立一个名为ReminderBroadcastReceiver.kt的新文件,并编写以下代码:

import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.Build
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
class ReminderBroadcastReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        val reminderText = intent.getStringExtra("reminderText")
        createNotificationChannel(context)
        val builder = NotificationCompat.Builder(context, "reminderChannel")
            .setSmallIcon(R.drawable.ic_launcher_foreground)
            .setContentTitle("提示事项")
            .setContentText(reminderText)
            .setPriority(NotificationCompat.PRIORITY_HIGH)
        val notificationManager = NotificationManagerCompat.from(context)
        notificationManager.notify(1, builder.build())
    }
    private fun createNotificationChannel(context: Context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val name = "Reminder Channel"
            val descriptionText = "Channel for Reminder notifications"
            val importance = NotificationManager.IMPORTANCE_HIGH
            val channel = NotificationChannel("reminderChannel", name, importance).apply {
                description = descriptionText
            }
            val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannel(channel)
        }
    }
}

安卓版的提醒事项软件开发

6.在AndroidManifest.xml中注册广播接收器 将以下代码增加到AndroidManifest.xml文件中的<application>标签内,以注册ReminderBroadcastReceiver

<receiver android:name=".ReminderBroadcastReceiver"/>

安卓版的提醒事项软件开发

至此,您现已完成了一个简略的提示事项运用程序。用户能够在运用程序中设置提示事项(包括时刻和内容),然后在主页面上看到提示事项。

老板:继续改动app,在app页面里每个提示事项作为一个独自的模块展现,模块能够增加和删除,用户能够更改每一模块的背景图片,并设置提示的铃声。

为了完成这个功用,咱们需要对现有的运用进行一些改进。咱们将运用RecyclerView来展现每个提示事项作为一个独自的模块。咱们还需要创立一个自界说的Adapter和一个新的Activity来处理增加和修改提示事项。

以下是完成这些更改的过程:

1.增加依靠项 在build.gradle (Module: app)文件中,增加以下依靠项并同步项目:

implementation 'androidx.recyclerview:recyclerview:1.2.1'
implementation 'com.google.android.material:material:1.4.0'

安卓版的提醒事项软件开发

2.更新activity_main.xml以包括一个RecyclerView和一个悬浮操作按钮(FloatingActionButton):

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/reminderRecyclerView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>
    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/addReminderButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="16dp"
        android:layout_marginBottom="16dp"
        android:src="@android:drawable/ic_input_add"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

安卓版的提醒事项软件开发

3.创立一个新的布局文件reminder_item.xml以界说提示事项的模块布局:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="16dp"
    tools:context=".MainActivity">
    <TextView
        android:id="@+id/reminderTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="提示事项标题" />
    <TextView
        android:id="@+id/reminderDateTime"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="提示时刻" />
    <ImageView
        android:id="@+id/reminderBackground"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:scaleType="centerCrop"
        tools:src="@tools:sample/backgrounds/scenic" />
    <ImageButton
        android:id="@+id/deleteReminderButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@android:drawable/ic_delete" />
</LinearLayout>

安卓版的提醒事项软件开发

4.创立一个新的数据类ReminderItem来表明提示事项:

data class ReminderItem(
    val id: Int,
    val title: String,
    val dateTime: Long,
    val background: String?,
    val ringtone: String?
)

安卓版的提醒事项软件开发

5.创立一个自界说的RecyclerView.Adapter

class ReminderAdapter(
    private val reminders: List<ReminderItem>,
    private val onDeleteReminder: (ReminderItem) -> Unit
) : RecyclerView.Adapter<ReminderAdapter.ViewHolder>() {
    inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val reminderTitle: TextView = view.findViewById(R.id.reminderTitle)
        val reminderDateTime: TextView = view.findViewById(R.id.reminderDateTime)
        val reminderBackground: ImageView = view.findViewById(R.id.reminderBackground)
        val deleteReminderButton: ImageButton = view.findViewById(R.id.deleteReminderButton)
    }
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.reminder_item, parent, false)
        return ViewHolder(view)
    }
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val reminder = reminders[position]
        holder.reminderTitle.text = reminder.title
        holder.reminderDateTime.text = SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.getDefault()).format(reminder.dateTime)
        if (reminder.background != null) {
            // Load image from URL or resource using a library such as Glide or Picasso
        }
        holder.deleteReminderButton.setOnClickListener {
            onDeleteReminder(reminder)
        }
    }
    override fun getItemCount(): Int {
        return reminders.size
    }
}

安卓版的提醒事项软件开发

6.更新MainActivity.kt,以便运用新的RecyclerView和适配器:

class MainActivity : AppCompatActivity() {
    private lateinit var reminderRecyclerView: RecyclerView
    private lateinit var addReminderButton: FloatingActionButton
    private val reminders = mutableListOf<ReminderItem>()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        reminderRecyclerView = findViewById(R.id.reminderRecyclerView)
        addReminderButton = findViewById(R.id.addReminderButton)
        reminderRecyclerView.layoutManager = LinearLayoutManager(this)
        reminderRecyclerView.adapter = ReminderAdapter(reminders) { reminder ->
            deleteReminder(reminder)
        }
        addReminderButton.setOnClickListener {
            startActivity(Intent(this, AddEditReminderActivity::class.java))
        }
    }
    private fun deleteReminder(reminder: ReminderItem) {
        // Remove the reminder from the list and update the adapter
        reminders.remove(reminder)
        reminderRecyclerView.adapter?.notifyDataSetChanged()
    }
}

安卓版的提醒事项软件开发

7.创立一个新的Activity,用于增加和修改提示事项。这个Activity应包括挑选背景图片和铃声的功用。你能够运用startActivityForResult来完成图片和铃声挑选。创立一个名为AddEditReminderActivity.kt的新文件,其中包括处理增加和修改提示事项的逻辑:

class AddEditReminderActivity : AppCompatActivity() {
    private lateinit var titleEditText: EditText
    private lateinit var datePicker: DatePicker
    private lateinit var timePicker: TimePicker
    private lateinit var chooseBackgroundButton: Button
    private lateinit var chooseRingtoneButton: Button
    private lateinit var saveReminderButton: Button
    private var selectedBackgroundUri: Uri? = null
    private var selectedRingtoneUri: Uri? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_add_edit_reminder)
        titleEditText = findViewById(R.id.titleEditText)
        datePicker = findViewById(R.id.datePicker)
        timePicker = findViewById(R.id.timePicker)
        chooseBackgroundButton = findViewById(R.id.chooseBackgroundButton)
        chooseRingtoneButton = findViewById(R.id.chooseRingtoneButton)
        saveReminderButton = findViewById(R.id.saveReminderButton)
        chooseBackgroundButton.setOnClickListener {
            chooseBackgroundImage()
        }
        chooseRingtoneButton.setOnClickListener {
            chooseRingtone()
        }
        saveReminderButton.setOnClickListener {
            saveReminder()
        }
    }
    private fun chooseBackgroundImage() {
        val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
        startActivityForResult(intent, REQUEST_CODE_PICK_IMAGE)
    }
    private fun chooseRingtone() {
        val intent = Intent(RingtoneManager.ACTION_RINGTONE_PICKER)
        intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_ALARM)
        intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, "挑选铃声")
        startActivityForResult(intent, REQUEST_CODE_PICK_RINGTONE)
    }
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode == Activity.RESULT_OK) {
            when (requestCode) {
                REQUEST_CODE_PICK_IMAGE -> {
                    selectedBackgroundUri = data?.data
                }
                REQUEST_CODE_PICK_RINGTONE -> {
                    selectedRingtoneUri = data?.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI)
                }
            }
        }
    }
    private fun saveReminder() {
        // Save the reminder and add it to the list in MainActivity
        val title = titleEditText.text.toString()
        val dateTime = getDateTimeFromPicker()
        val background = selectedBackgroundUri?.toString()
        val ringtone = selectedRingtoneUri?.toString()
        val reminder = ReminderItem(0, title, dateTime, background, ringtone)
        // Add the reminder to the list and notify the adapter
    }
    private fun getDateTimeFromPicker(): Long {
        val calendar = Calendar.getInstance()
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            calendar.set(Calendar.HOUR_OF_DAY, timePicker.hour)
            calendar.set(Calendar.MINUTE, timePicker.minute)
        } else {
            calendar.set(Calendar.HOUR_OF_DAY, timePicker.currentHour)
            calendar.set(Calendar.MINUTE, timePicker.currentMinute)
        }
        calendar.set(Calendar.DAY_OF_MONTH, datePicker.dayOfMonth)
        calendar.set(Calendar.MONTH, datePicker.month)
        calendar.set(Calendar.YEAR, datePicker.year)
        return calendar.timeInMillis
    }
    companion object {
        private const val REQUEST_CODE_PICK_IMAGE = 1
        private const val REQUEST_CODE_PICK_RINGTONE = 2
    }
}

安卓版的提醒事项软件开发

8.创立一个新的布局文件activity_add_edit_reminder.xml,用于AddEditReminderActivity

<!-- activity_add_edit_reminder.xml -->
<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".AddEditReminderActivity">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="16dp">
        <EditText
            android:id="@+id/titleEditText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="提示事项标题" />
        <DatePicker
            android:id="@+id/datePicker"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:calendarViewShown="false" />
        <TimePicker
            android:id="@+id/timePicker"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:timePickerMode="spinner" />
        <Button
            android:id="@+id/chooseBackgroundButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="挑选背景图片" />
        <Button
            android:id="@+id/chooseRingtoneButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="挑选铃声" />
        <Button
            android:id="@+id/saveReminderButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="保存提示" />
    </LinearLayout>
</ScrollView>

安卓版的提醒事项软件开发

至此,现已完成了根据安卓的提示事项运用的开发。这个运用答使用户设置提示事项,包括时刻和提示内容。在设置的提示事项时刻到了之后,能够完成在手机上进行弹窗提示。此外,用户还能够更改每个提示事项的背景图片,并设置提示的铃声。这个运用能够在安卓设备上运转,类似于iOS设备上的提示事项运用。

好了,拜~