当前位置: 首页 > news >正文

安卓多任务闹钟实现

效果图

下面全部代码

MainActivity.java
package com.franzliszt.androidtimedtasks;import android.app.TimePickerDialog;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;import androidx.activity.EdgeToEdge;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;import java.util.ArrayList;
import java.util.List;import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;public class MainActivity extends AppCompatActivity {private static final String TAG = "MainActivity";private static final String PREFS_NAME = "TaskPrefs";private static final String TASK_LIST_KEY = "taskList";private static final String TASK_ID_COUNTER_KEY = "taskIdCounter";private RecyclerView taskRecyclerView;private TaskAdapter taskAdapter;private List<TaskManager.Task> taskList;private FloatingActionButton addTaskButton;private int taskIdCounter = 0;// 添加广播接收器private BroadcastReceiver taskReminderReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String taskName = intent.getStringExtra(AlarmReceiver.EXTRA_TASK_NAME);String taskMessage = intent.getStringExtra(AlarmReceiver.EXTRA_TASK_MESSAGE);String reminderText = "任务提醒: " + taskName + " - " + taskMessage;Snackbar.make(findViewById(R.id.main), reminderText, Snackbar.LENGTH_LONG).show();}};@RequiresApi(api = Build.VERSION_CODES.TIRAMISU)@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initViews();setupListeners();registerReceiver(taskReminderReceiver,new IntentFilter(AlarmReceiver.ACTION_TASK_REMINDER),Context.RECEIVER_NOT_EXPORTED);loadTasksFromPreferences();}private void initViews() {taskList = new ArrayList<>();taskRecyclerView = findViewById(R.id.taskRecyclerView);taskRecyclerView.setLayoutManager(new LinearLayoutManager(this));taskAdapter = new TaskAdapter(taskList, this);taskRecyclerView.setAdapter(taskAdapter);addTaskButton = findViewById(R.id.addTaskButton);}private void setupListeners() {addTaskButton.setOnClickListener(v -> showAddTaskDialog());}private void showAddTaskDialog() {showTaskDialog(null);}public void showEditTaskDialog(TaskManager.Task task) {showTaskDialog(task);}private void showTaskDialog(TaskManager.Task task) {AlertDialog.Builder builder = new AlertDialog.Builder(this);LayoutInflater inflater = this.getLayoutInflater();View dialogView = inflater.inflate(R.layout.dialog_add_task, null);builder.setView(dialogView);EditText taskNameEditText = dialogView.findViewById(R.id.taskNameEditText);EditText taskMessageEditText = dialogView.findViewById(R.id.taskMessageEditText);TimePicker timePicker = dialogView.findViewById(R.id.timeTextView);CheckBox[] dayCheckBoxes = new CheckBox[7];dayCheckBoxes[0] = dialogView.findViewById(R.id.sundayCheckBox);dayCheckBoxes[1] = dialogView.findViewById(R.id.mondayCheckBox);dayCheckBoxes[2] = dialogView.findViewById(R.id.tuesdayCheckBox);dayCheckBoxes[3] = dialogView.findViewById(R.id.wednesdayCheckBox);dayCheckBoxes[4] = dialogView.findViewById(R.id.thursdayCheckBox);dayCheckBoxes[5] = dialogView.findViewById(R.id.fridayCheckBox);dayCheckBoxes[6] = dialogView.findViewById(R.id.saturdayCheckBox);timePicker.setIs24HourView(false);timePicker.setDescendantFocusability(TimePicker.FOCUS_BLOCK_DESCENDANTS);if (task != null) {taskNameEditText.setText(task.name);taskMessageEditText.setText(task.message);timePicker.setHour(task.hour);timePicker.setMinute(task.minute);for (int i = 0; i < 7; i++) {dayCheckBoxes[i].setChecked(task.daysOfWeek[i]);}}builder.setTitle(task == null ? "添加新任务" : "编辑任务").setPositiveButton("保存", (dialog, which) -> {String taskName = taskNameEditText.getText().toString().trim();String taskMessage = taskMessageEditText.getText().toString().trim();if (taskName.isEmpty() || taskMessage.isEmpty()) {Toast.makeText(this, "请填写任务名称和消息", Toast.LENGTH_SHORT).show();return;}boolean[] selectedDays = new boolean[7];boolean hasSelectedDay = false;for (int i = 0; i < 7; i++) {selectedDays[i] = dayCheckBoxes[i].isChecked();if (selectedDays[i]) hasSelectedDay = true;}if (!hasSelectedDay) {Toast.makeText(this, "请至少选择一天", Toast.LENGTH_SHORT).show();return;}// 从TimePicker获取时间int selectedHour = timePicker.getHour();int selectedMinute = timePicker.getMinute();if (task == null) {// 添加新任务TaskManager.Task newTask = new TaskManager.Task(taskName,taskMessage,selectedDays,selectedHour,selectedMinute,taskIdCounter++);taskList.add(newTask);taskAdapter.notifyItemInserted(taskList.size() - 1);TaskManager.scheduleTask(this, newTask);// 保存任务到SharedPreferencessaveTasksToPreferences();Log.d(TAG, "已安排任务: " + taskName + " 在 " + selectedHour + ":" + selectedMinute);Toast.makeText(this, "任务已安排: " + taskName, Toast.LENGTH_SHORT).show();} else {// 更新现有任务TaskManager.cancelTask(this, task);task.name = taskName;task.message = taskMessage;task.daysOfWeek = selectedDays;task.hour = selectedHour;task.minute = selectedMinute;TaskManager.scheduleTask(this, task);taskAdapter.notifyDataSetChanged();saveTasksToPreferences();Log.d(TAG, "已更新任务: " + taskName + " 在 " + selectedHour + ":" + selectedMinute);Toast.makeText(this, "任务已更新: " + taskName, Toast.LENGTH_SHORT).show();}}).setNegativeButton("取消", (dialog, which) -> dialog.dismiss());AlertDialog dialog = builder.create();dialog.show();}// 保存任务列表到SharedPreferencespublic void saveTasksToPreferences() {SharedPreferences prefs = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);SharedPreferences.Editor editor = prefs.edit();Gson gson = new Gson();String taskListJson = gson.toJson(taskList);editor.putString(TASK_LIST_KEY, taskListJson);editor.putInt(TASK_ID_COUNTER_KEY, taskIdCounter);editor.apply();}private void loadTasksFromPreferences() {SharedPreferences prefs = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);String taskListJson = prefs.getString(TASK_LIST_KEY, null);taskIdCounter = prefs.getInt(TASK_ID_COUNTER_KEY, 0);if (taskListJson != null) {Gson gson = new Gson();Type listType = new TypeToken<List<TaskManager.Task>>(){}.getType();List<TaskManager.Task> savedTasks = gson.fromJson(taskListJson, listType);if (savedTasks != null) {taskList.clear();taskList.addAll(savedTasks);taskAdapter.notifyDataSetChanged();// 重新安排所有任务for (TaskManager.Task task : taskList) {TaskManager.scheduleTask(this, task);}}}}@Overrideprotected void onDestroy() {super.onDestroy();unregisterReceiver(taskReminderReceiver);}
}

布局

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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:id="@+id/main"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><com.google.android.material.appbar.AppBarLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"><androidx.appcompat.widget.Toolbarandroid:id="@+id/toolbar"android:layout_width="match_parent"android:layout_height="?attr/actionBarSize"android:background="?attr/colorPrimary"app:title="定时任务"app:titleTextColor="@android:color/white" /></com.google.android.material.appbar.AppBarLayout><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/taskRecyclerView"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_marginTop="?attr/actionBarSize"android:padding="8dp" /><com.google.android.material.floatingactionbutton.FloatingActionButtonandroid:id="@+id/addTaskButton"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="bottom|end"android:layout_margin="16dp"android:src="@android:drawable/ic_input_add"app:tint="@android:color/white" /></androidx.coordinatorlayout.widget.CoordinatorLayout>
dialog_add_task.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="16dp"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><com.google.android.material.textfield.TextInputLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginBottom="16dp"android:hint="任务名称"><EditTextandroid:id="@+id/taskNameEditText"android:layout_width="match_parent"android:layout_height="wrap_content" /></com.google.android.material.textfield.TextInputLayout><com.google.android.material.textfield.TextInputLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginBottom="24dp"android:hint="提醒消息"><EditTextandroid:id="@+id/taskMessageEditText"android:layout_width="match_parent"android:layout_height="wrap_content" /></com.google.android.material.textfield.TextInputLayout><!-- 时间选择区域 --><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="时间"android:textSize="18sp"android:textStyle="bold"android:layout_marginBottom="12dp" /><TimePickerandroid:id="@+id/timeTextView"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="08:00"android:textSize="24sp"android:gravity="center"android:timePickerMode="spinner"android:layout_marginBottom="24dp" /><!-- 星期选择区域 --><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="重复"android:textSize="18sp"android:textStyle="bold"android:layout_marginBottom="12dp" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:weightSum="7"><CheckBoxandroid:id="@+id/sundayCheckBox"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="日"android:gravity="center"android:button="@null"android:background="@drawable/day_checkbox_background"android:padding="8dp"android:layout_margin="4dp" /><CheckBoxandroid:id="@+id/mondayCheckBox"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="一"android:gravity="center"android:button="@null"android:background="@drawable/day_checkbox_background"android:padding="8dp"android:layout_margin="4dp" /><CheckBoxandroid:id="@+id/tuesdayCheckBox"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="二"android:gravity="center"android:button="@null"android:background="@drawable/day_checkbox_background"android:padding="8dp"android:layout_margin="4dp" /><CheckBoxandroid:id="@+id/wednesdayCheckBox"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="三"android:gravity="center"android:button="@null"android:background="@drawable/day_checkbox_background"android:padding="8dp"android:layout_margin="4dp" /><CheckBoxandroid:id="@+id/thursdayCheckBox"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="四"android:gravity="center"android:button="@null"android:background="@drawable/day_checkbox_background"android:padding="8dp"android:layout_margin="4dp" /><CheckBoxandroid:id="@+id/fridayCheckBox"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="五"android:gravity="center"android:button="@null"android:background="@drawable/day_checkbox_background"android:padding="8dp"android:layout_margin="4dp" /><CheckBoxandroid:id="@+id/saturdayCheckBox"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="六"android:gravity="center"android:button="@null"android:background="@drawable/day_checkbox_background"android:padding="8dp"android:layout_margin="4dp" /></LinearLayout></LinearLayout></ScrollView>

任务管理器

TaskManager.java
package com.franzliszt.androidtimedtasks;import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.util.Log;import java.util.Calendar;
// 任务管理器
public class TaskManager {private static final String TAG = "TaskManager";public static class Task {public String name;public String message;public boolean[] daysOfWeek;public int hour;public int minute;public int taskId;public Task(String name, String message, boolean[] daysOfWeek, int hour, int minute, int taskId) {this.name = name;this.message = message;this.daysOfWeek = daysOfWeek;this.hour = hour;this.minute = minute;this.taskId = taskId;}}public static void scheduleTask(Context context, Task task) {AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);for (int day = 0; day < 7; day++) {if (task.daysOfWeek[day]) {Calendar calendar = Calendar.getInstance();calendar.set(Calendar.DAY_OF_WEEK, day + 1);calendar.set(Calendar.HOUR_OF_DAY, task.hour);calendar.set(Calendar.MINUTE, task.minute);calendar.set(Calendar.SECOND, 0);if (calendar.getTimeInMillis() <= System.currentTimeMillis()) {calendar.add(Calendar.WEEK_OF_YEAR, 1);}Intent intent = new Intent(context, AlarmReceiver.class);intent.putExtra("task_name", task.name);intent.putExtra("task_message", task.message);PendingIntent pendingIntent = PendingIntent.getBroadcast(context, task.taskId * 10 + day, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);Log.d(TAG, "已设置任务: " + task.name + " 在每周" + day + "的" + task.hour + ":" + task.minute);}}}public static void cancelTask(Context context, Task task) {AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);for (int day = 0; day < 7; day++) {Intent intent = new Intent(context, AlarmReceiver.class);PendingIntent pendingIntent = PendingIntent.getBroadcast(context, task.taskId * 10 + day, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);alarmManager.cancel(pendingIntent);pendingIntent.cancel();}Log.d(TAG, "已取消任务: " + task.name);}
}

定时任务提醒
AlarmReceiver.java
package com.franzliszt.androidtimedtasks;import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.util.Log;import androidx.core.app.NotificationCompat;// 定时任务提醒
public class AlarmReceiver extends BroadcastReceiver {private static final String CHANNEL_ID = "task_reminder_channel";private static final String TAG = "AlarmReceiver";public static final String ACTION_TASK_REMINDER = "com.franzliszt.androidtimedtasks.TASK_REMINDER";public static final String EXTRA_TASK_NAME = "task_name";public static final String EXTRA_TASK_MESSAGE = "task_message";@Overridepublic void onReceive(Context context, Intent intent) {String taskName = intent.getStringExtra("task_name");String taskMessage = intent.getStringExtra("task_message");Log.d(TAG, "收到定时任务提醒: " + taskName + " - " + taskMessage);createNotificationChannel(context);//创建通知渠道showNotification(context, taskName, taskMessage);//显示通知Intent localIntent = new Intent(ACTION_TASK_REMINDER);localIntent.putExtra(EXTRA_TASK_NAME, taskName);localIntent.putExtra(EXTRA_TASK_MESSAGE, taskMessage);context.sendBroadcast(localIntent);}private void createNotificationChannel(Context context) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {CharSequence name = "任务提醒";String description = "定时任务提醒通知";int importance = NotificationManager.IMPORTANCE_DEFAULT;NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);channel.setDescription(description);NotificationManager notificationManager = context.getSystemService(NotificationManager.class);notificationManager.createNotificationChannel(channel);}}private void showNotification(Context context, String taskName, String taskMessage) {Intent intent = new Intent(context, MainActivity.class);intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE);NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID).setSmallIcon(R.drawable.ic_launcher_foreground).setContentTitle(taskName).setContentText(taskMessage).setPriority(NotificationCompat.PRIORITY_DEFAULT).setContentIntent(pendingIntent).setAutoCancel(true);NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);notificationManager.notify((int) System.currentTimeMillis(), builder.build());}
}

列表适配器

TaskAdapter.java
package com.franzliszt.androidtimedtasks;import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;import androidx.recyclerview.widget.RecyclerView;import java.util.List;public class TaskAdapter extends RecyclerView.Adapter<TaskAdapter.TaskViewHolder> {private List<TaskManager.Task> taskList;private MainActivity mainActivity;public TaskAdapter(List<TaskManager.Task> taskList, MainActivity mainActivity) {this.taskList = taskList;this.mainActivity = mainActivity;}@Overridepublic TaskViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_task, parent, false);return new TaskViewHolder(view);}@Overridepublic void onBindViewHolder(TaskViewHolder holder, int position) {TaskManager.Task task = taskList.get(position);holder.bind(task);}@Overridepublic int getItemCount() {return taskList.size();}public class TaskViewHolder extends RecyclerView.ViewHolder {private TextView taskNameTextView;private TextView taskTimeTextView;private TextView taskDaysTextView;private Button deleteButton;private Button editButton;public TaskViewHolder(View itemView) {super(itemView);taskNameTextView = itemView.findViewById(R.id.taskNameTextView);taskTimeTextView = itemView.findViewById(R.id.taskTimeTextView);taskDaysTextView = itemView.findViewById(R.id.taskDaysTextView);deleteButton = itemView.findViewById(R.id.deleteButton);editButton = itemView.findViewById(R.id.editButton);}public void bind(TaskManager.Task task) {taskNameTextView.setText(task.name);taskTimeTextView.setText(String.format("%02d:%02d", task.hour, task.minute));StringBuilder daysBuilder = new StringBuilder("重复: ");String[] dayNames = {"日", "一", "二", "三", "四", "五", "六"};boolean hasSelected = false;for (int i = 0; i < 7; i++) {if (task.daysOfWeek[i]) {if (hasSelected) daysBuilder.append(", ");daysBuilder.append(dayNames[i]);hasSelected = true;}}taskDaysTextView.setText(daysBuilder.toString());deleteButton.setOnClickListener(v -> {TaskManager.cancelTask(mainActivity, task);int position = getAdapterPosition();taskList.remove(position);notifyItemRemoved(position);mainActivity.saveTasksToPreferences();Toast.makeText(mainActivity, "任务已删除: " + task.name, Toast.LENGTH_SHORT).show();});editButton.setOnClickListener(v -> {mainActivity.showEditTaskDialog(task);});}}
}

对应布局

item_task.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="8dp"app:cardCornerRadius="8dp"app:cardElevation="4dp"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"android:padding="16dp"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><TextViewandroid:id="@+id/taskNameTextView"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="任务名称"android:textSize="18sp"android:textStyle="bold" /><Buttonandroid:id="@+id/editButton"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="编辑"style="@style/Widget.MaterialComponents.Button.OutlinedButton"android:layout_marginEnd="8dp" /><Buttonandroid:id="@+id/deleteButton"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="删除"style="@style/Widget.MaterialComponents.Button.OutlinedButton" /></LinearLayout><TextViewandroid:id="@+id/taskTimeTextView"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="08:00"android:textSize="24sp"android:layout_marginTop="8dp" /><TextViewandroid:id="@+id/taskDaysTextView"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="重复: 一, 三, 五"android:textSize="14sp"android:layout_marginTop="8dp" /></LinearLayout></androidx.cardview.widget.CardView>

上面用到shape文件

day_checkbox_background.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:state_checked="true"><shape android:shape="rectangle"><solid android:color="#2196F3" /><corners android:radius="4dp" /></shape></item><item><shape android:shape="rectangle"><stroke android:width="1dp" android:color="#CCCCCC" /><corners android:radius="4dp" /></shape></item>
</selector>

清单文件

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"><!-- 添加通知权限 --><uses-permission android:name="android.permission.POST_NOTIFICATIONS" /><uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" /><uses-permission android:name="android.permission.USE_EXACT_ALARM" /><applicationandroid:allowBackup="true"android:dataExtractionRules="@xml/data_extraction_rules"android:fullBackupContent="@xml/backup_rules"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.AndroidTimedTasks"><activityandroid:name=".MainActivity"android:exported="true"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><receiver android:name=".AlarmReceiver" android:enabled="true" android:exported="false" /></application></manifest>

 

这是最终的项目文件截图

项目地址:https://download.csdn.net/download/qq_41733851/91956122


文章转载自:

http://VHpALTs4.yfstt.cn
http://pcn89sfJ.yfstt.cn
http://Ks1zU0if.yfstt.cn
http://suuwhXLm.yfstt.cn
http://Otn0YIhy.yfstt.cn
http://KEEr5F9x.yfstt.cn
http://AKcC5Ajj.yfstt.cn
http://J7AN2uaI.yfstt.cn
http://5jgCWUTJ.yfstt.cn
http://yZnqWA1Q.yfstt.cn
http://vWddHXbz.yfstt.cn
http://FaVfGdJ4.yfstt.cn
http://zBN1GQvb.yfstt.cn
http://YJAPDIXR.yfstt.cn
http://XniNNECz.yfstt.cn
http://Q9o2MNBq.yfstt.cn
http://BlHo5xFT.yfstt.cn
http://5gkGt4OK.yfstt.cn
http://i8Qzg8Sc.yfstt.cn
http://EGl7UP0G.yfstt.cn
http://zzlmzBC6.yfstt.cn
http://v9MT3WaT.yfstt.cn
http://aMLxQdtD.yfstt.cn
http://ZSTPmlqc.yfstt.cn
http://3I85BtdR.yfstt.cn
http://KUJo59cz.yfstt.cn
http://ouU4dDIp.yfstt.cn
http://BygNTWE3.yfstt.cn
http://mok12WMH.yfstt.cn
http://3L7KhSSS.yfstt.cn
http://www.dtcms.com/a/388377.html

相关文章:

  • 【源码集锦】基于Java+SpringBoot+Uniapp+Mysql的租房小程序技术搭建
  • Oceanbase下使用TPC-H模式生成数据
  • 20250917让荣品RD-RK3588-MID开发板的Android13系统在刷机的时候就直接以百分比显示电池电量
  • MySQL 核心操作全解析(用户 + SHOW+DML+DCL)
  • 【前端】【React】【Zustand】[特殊字符] Zustand 系统学习大纲(实战版)
  • 在测试接口时,遇到关于时间参数的传参时,遇到类型编译器无法转换的解决方案
  • 晶圆厂为什么都采用高架地板?
  • unsloth 笔记:微调mistral-7b(纯文本数据集)
  • 【vim,Svelte】怎样使用 vim 编辑 Svelte 那些奇奇怪怪名字的文件?
  • 【AOI基板外观缺陷检测软件】基于Halcon+C#开发的AOI基板外观缺陷检测软件,全套源码,开箱即用
  • htb academy笔记-module-Password Attacks(一)
  • Java程序设计:顺序结构与分支结构
  • 铺满式水印添加教程!水印如何铺满整个详情页页面?
  • 基于SpringBoot+Vue.js开发的医疗器械管理系统
  • 职业定位:用 “能力 - 兴趣 - 需求” 模型找到赛道
  • Caffeine Expiry
  • 【C++项目】C++11重构muduo库
  • 如何选择靠谱的防伪溯源系统公司?
  • 线程池 相关知识
  • 搭建CI/CD 流水线简单说明
  • 大Key与热Key详解:概念、危害与解决方案
  • Java中的自动拆装箱原理
  • Android 入门笔记(2)
  • 程序员内功之成长性思维
  • vLLM 和 SGLang 是两个近年来备受关注的开源项目
  • CMake进阶: 路径处理指令join_paths和cmake_path
  • 算法简略速记手册
  • C语言(长期更新)第17讲内存函数
  • 【CSP-S】 基础知识与编程环境
  • Python HTTPS 教程 如何发送 HTTPS 请求、解决证书错误、实现抓包与网络调试全攻略