老板发言:
现在需要你做一个根据安卓的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设备上的提示事项运用。
好了,拜~