diff --git a/doc/代码标注/AlarmAlertActivity.java b/doc/代码标注/AlarmAlertActivity.java deleted file mode 100644 index cd14c0c..0000000 --- a/doc/代码标注/AlarmAlertActivity.java +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * - * @ProjectName: $MiNotes$ - * @Package: $ui$ - * @ClassName: $AlarmAlertActivity.java$ - * @Description: 该类主要构建了一个闹铃提醒页面,以及用户不同选择的解决方案 - * @Author: 石兆羲 - * @CreateDate: $2023/12/21$ - */ - -package net.micode.notes.ui; - -import android.app.Activity; -import android.app.AlertDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; -import android.content.DialogInterface.OnDismissListener; -import android.content.Intent; -import android.media.AudioManager; -import android.media.MediaPlayer; -import android.media.RingtoneManager; -import android.net.Uri; -import android.os.Bundle; -import android.os.PowerManager; -import android.provider.Settings; -import android.view.Window; -import android.view.WindowManager; - -import net.micode.notes.R; -import net.micode.notes.data.Notes; -import net.micode.notes.tool.DataUtils; - -import java.io.IOException; - - -public class AlarmAlertActivity extends Activity implements OnClickListener, OnDismissListener { - private long mNoteId; //文本在数据库中存储的ID号 - private String mSnippet; //闹钟提示时出现的文本内容 - private static final int SNIPPET_PREW_MAX_LEN = 60; - MediaPlayer mPlayer; - - @Override - protected void onCreate(Bundle savedInstanceState) { - //该部分的功能是:手机锁屏后,如果到了闹钟提示时间就点亮屏幕 - super.onCreate(savedInstanceState); - //Bundle类型的数据与Map类型的数据相似,都是以key-value的形式存储数据的 - //saveInstanceState方法是用来保存Activity的状态的 - //能从onCreate的参数savedInsanceState中获得状态数据 - requestWindowFeature(Window.FEATURE_NO_TITLE); //界面显示“无标题“ - - final Window win = getWindow(); - win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); - - if (!isScreenOn()) { - win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON - //保持窗口点亮 - | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON - //点亮窗口 - | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON - //允许在点亮窗口时锁屏 - | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR); - } - - Intent intent = getIntent(); - - try { - mNoteId = Long.valueOf(intent.getData().getPathSegments().get(1)); - mSnippet = DataUtils.getSnippetById(this.getContentResolver(), mNoteId); - //根据ID从数据库中获取标签内容,其中getContentResolver()是实现数据共享,实例存储。 - mSnippet = mSnippet.length() > SNIPPET_PREW_MAX_LEN ? mSnippet.substring(0, - SNIPPET_PREW_MAX_LEN) + getResources().getString(R.string.notelist_string_info) - : mSnippet; - //判断标签片段是否达到符合长度 - - } catch (IllegalArgumentException e) { - e.printStackTrace(); - return; - } - //上述代码代码区如果有错误,就会返回所写异常的处理。 - mPlayer = new MediaPlayer(); - if (DataUtils.visibleInNoteDatabase(getContentResolver(), mNoteId, Notes.TYPE_NOTE)) { - showActionDialog(); - //弹出对话框 - playAlarmSound(); - //播放闹钟提示音 - } else { - finish(); - //结束闹钟操作 - } - } - - private boolean isScreenOn() { - //该部分功能是:判断屏幕是否锁屏,调用系统函数判断,返回值一个布尔类型值 - PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); - return pm.isScreenOn(); - } - - private void playAlarmSound() { - //播放闹钟提示音 - Uri url = RingtoneManager.getActualDefaultRingtoneUri(this, RingtoneManager.TYPE_ALARM); - //调用系统的铃声管理URI,得到闹钟提示音 - int silentModeStreams = Settings.System.getInt(getContentResolver(), - Settings.System.MODE_RINGER_STREAMS_AFFECTED, 0); - - if ((silentModeStreams & (1 << AudioManager.STREAM_ALARM)) != 0) { - //判断系统静音状态,如果静音则闹钟不响,否则响铃 - mPlayer.setAudioStreamType(silentModeStreams); - } else { - mPlayer.setAudioStreamType(AudioManager.STREAM_ALARM); - } - try { - mPlayer.setDataSource(this, url); - //该方法设置了多媒体数据来源,由前文的uri管理决定,该方法没有返回值 - mPlayer.prepare(); - //准备同步 - mPlayer.setLooping(true); - //设置是否循环播放铃声 - mPlayer.start(); - //播放铃声 - } catch (IllegalArgumentException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (SecurityException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - //e.printStackTrace()函数功能是抛出异常, 还将显示出更深的调用信息 - //System.out.println(e),这个方法打印出异常,并且输出在哪里出现的异常 - } catch (IllegalStateException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - private void showActionDialog() { - //该部分主要构建了一个响铃后的对话框,让用户决定是否关闭闹钟 - AlertDialog.Builder dialog = new AlertDialog.Builder(this); - //AlertDialog的构造方法全部是Protected的 - //所以不能直接通过new一个AlertDialog来创建出一个AlertDialog。 - //要创建一个AlertDialog,就要用到AlertDialog.Builder中的create()方法 - //如这里的dialog就是新建了一个AlertDialog - dialog.setTitle(R.string.app_name); - //设置对话框标题 - dialog.setMessage(mSnippet); - //设置对话框内容 - dialog.setPositiveButton(R.string.notealert_ok, this); - //在对话框中设置“yes”按钮 - if (isScreenOn()) { - dialog.setNegativeButton(R.string.notealert_enter, this); - }//在对话框设置“No”按钮 - dialog.show().setOnDismissListener(this); - } - - public void onClick(DialogInterface dialog, int which) { - switch (which) { - //用which来选择点击后的操作 - case DialogInterface.BUTTON_NEGATIVE: - //如果点击了“No”按钮,就取消操作 - Intent intent = new Intent(this, NoteEditActivity.class); - //类间数据传输 - intent.setAction(Intent.ACTION_VIEW); - //设置动作属性 - intent.putExtra(Intent.EXTRA_UID, mNoteId); - //实现key-value对,EXTRA_UID为key;mNoteId为键 - startActivity(intent); - //开始执行动作 - break; - default: - //确定操作 - break; - } - } - - public void onDismiss(DialogInterface dialog) { - //用户选择忽略闹钟的操作 - stopAlarmSound(); - //停止响铃 - finish(); - } - - private void stopAlarmSound() { - //用户选择停止响铃 - if (mPlayer != null) { - mPlayer.stop(); - //停止播放 - mPlayer.release(); - //释放多媒体对象MediaPlayer - mPlayer = null; - } - } -} diff --git a/doc/代码标注/AlarmInitReceiver.java b/doc/代码标注/AlarmInitReceiver.java deleted file mode 100644 index b1a9529..0000000 --- a/doc/代码标注/AlarmInitReceiver.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * - * @ProjectName: $MiNotes$ - * @Package: $ui$ - * @ClassName: $AlarmInitReciver.java$ - * @Description: 该类主要功能是根据数据库里的闹钟时间创建一个闹钟机制 - * @Author: 石兆羲 - * @CreateDate: $2023/12/23$ - */ - -package net.micode.notes.ui; - -import android.app.AlarmManager; -import android.app.PendingIntent; -import android.content.BroadcastReceiver; -import android.content.ContentUris; -import android.content.Context; -import android.content.Intent; -import android.database.Cursor; - -import net.micode.notes.data.Notes; -import net.micode.notes.data.Notes.NoteColumns; - - -public class AlarmInitReceiver extends BroadcastReceiver { - - private static final String [] PROJECTION = new String [] { - NoteColumns.ID, - NoteColumns.ALERTED_DATE - }; - //对数据库的操作,作用是调用ID和设定的闹钟时间 - private static final int COLUMN_ID = 0; - private static final int COLUMN_ALERTED_DATE = 1; - - @Override - public void onReceive(Context context, Intent intent) { - long currentDate = System.currentTimeMillis(); - //System.currentTimeMillis()函数的作用是产生一个当前的毫秒 - //毫秒数是自1970年1月1日0时起的毫秒数 - Cursor c = context.getContentResolver().query(Notes.CONTENT_NOTE_URI, - //Cursor在这里的作用是通过查找数据库中的标签内容,找到和当前系统时间相等的标签 - //通过 context.getContentResolver() 获取当前应用程序的 ContentResolver 对象 - //使用 query() 方法对系统中的 Notes 数据库进行查询操作。 - //其中,Notes.CONTENT_NOTE_URI 是一个常量,表示 Notes 数据库中的笔记表对应的 Uri 地址。 - PROJECTION,//字符串数组,包含查询结果的列名 - NoteColumns.ALERTED_DATE + ">? AND " + NoteColumns.TYPE + "=" + Notes.TYPE_NOTE, - //这里定义了两个查询条件: - //笔记的提醒日期晚于某个特定时间; - //笔记的类型为 Notes.TYPE_NOTE - new String[] { String.valueOf(currentDate) }, - //将long变量currentDate转化为字符串 - null); - - if (c != null) { - if (c.moveToFirst()) { - do { - long alertDate = c.getLong(COLUMN_ALERTED_DATE); - Intent sender = new Intent(context, AlarmReceiver.class); - //Intent用于在不同组件之间传递消息、启动服务、启动活动等。 - sender.setData(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, c.getLong(COLUMN_ID))); - PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, sender, 0); - //PendingIntent通常用于在未来的某个时间点执行某项操作,比如在特定的时刻启动一个 Activity、发送一个广播或者启动一个服务。 - AlarmManager alermManager = (AlarmManager) context - .getSystemService(Context.ALARM_SERVICE); - alermManager.set(AlarmManager.RTC_WAKEUP, alertDate, pendingIntent); - //AlarmManager用于在指定的时间点触发某个操作。它可以用来实现定时任务、闹钟提醒、周期性任务等功能。 - //通过网上查找资料发现,对于闹钟机制的启动,通常需要上面的几个步骤,如新建Intent、PendingIntent以及AlarmManager等 - } while (c.moveToNext()); - } - c.close(); - } - } -} diff --git a/doc/代码标注/AlarmReceiver.java b/doc/代码标注/AlarmReceiver.java deleted file mode 100644 index d58a500..0000000 --- a/doc/代码标注/AlarmReceiver.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * - * @ProjectName: $MiNotes$ - * @Package: $ui$ - * @ClassName: $AlarmReciver.java$ - * @Description: 该类主要功能启动、实现闹钟功能 - * @Author: 石兆羲 - * @CreateDate: $2023/12/25$ - */ -package net.micode.notes.ui; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; - -public class AlarmReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - intent.setClass(context, AlarmAlertActivity.class); - //启动AlarmAlertActivity - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - //activity要存在于activity的栈中,而非activity的途径启动activity时必然不存在一个activity的栈 - //所以要新起一个栈装入启动的activity - context.startActivity(intent); - } -} diff --git a/doc/代码标注/DateTimePicker.java b/doc/代码标注/DateTimePicker.java deleted file mode 100644 index 5977568..0000000 --- a/doc/代码标注/DateTimePicker.java +++ /dev/null @@ -1,533 +0,0 @@ -/* - * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * - * @ProjectName: $MiNotes$ - * @Package: $ui$ - * @ClassName: $DateTimePicker.java$ - * @Description: 该类主要功能是实现设置闹钟过程中涉及时间变化部分的具体操作 - * @Author: 石兆羲 - * @CreateDate: $2023/12/25$ - */ -package net.micode.notes.ui; - -import java.text.DateFormatSymbols; -import java.util.Calendar; - -import net.micode.notes.R; - - -import android.content.Context; -import android.text.format.DateFormat; -import android.view.View; -import android.widget.FrameLayout; -import android.widget.NumberPicker; - -public class DateTimePicker extends FrameLayout { - //FrameLayout是布局模板之一 - //所有的子元素全部在屏幕的右上方 - private static final boolean DEFAULT_ENABLE_STATE = true; - - private static final int HOURS_IN_HALF_DAY = 12; - private static final int HOURS_IN_ALL_DAY = 24; - private static final int DAYS_IN_ALL_WEEK = 7; - private static final int DATE_SPINNER_MIN_VAL = 0; - private static final int DATE_SPINNER_MAX_VAL = DAYS_IN_ALL_WEEK - 1; - private static final int HOUR_SPINNER_MIN_VAL_24_HOUR_VIEW = 0; - private static final int HOUR_SPINNER_MAX_VAL_24_HOUR_VIEW = 23; - private static final int HOUR_SPINNER_MIN_VAL_12_HOUR_VIEW = 1; - private static final int HOUR_SPINNER_MAX_VAL_12_HOUR_VIEW = 12; - private static final int MINUT_SPINNER_MIN_VAL = 0; - private static final int MINUT_SPINNER_MAX_VAL = 59; - private static final int AMPM_SPINNER_MIN_VAL = 0; - private static final int AMPM_SPINNER_MAX_VAL = 1; - //以上语句的作用都是用于初始化控件 - private final NumberPicker mDateSpinner; - private final NumberPicker mHourSpinner; - private final NumberPicker mMinuteSpinner; - private final NumberPicker mAmPmSpinner; - //NumberPicker是数字选择器,定义上述四个变量用于表示设置闹钟时需要选择的变量(时、分、秒、日期等) - private Calendar mDate; - //定义了Calendar类型的变量mDate,用于操作时间 - private String[] mDateDisplayValues = new String[DAYS_IN_ALL_WEEK]; - - private boolean mIsAm; - - private boolean mIs24HourView; - - private boolean mIsEnabled = DEFAULT_ENABLE_STATE; - - private boolean mInitialising; - - private OnDateTimeChangedListener mOnDateTimeChangedListener; - - private NumberPicker.OnValueChangeListener mOnDateChangedListener = new NumberPicker.OnValueChangeListener() { - @Override - public void onValueChange(NumberPicker picker, int oldVal, int newVal) { - mDate.add(Calendar.DAY_OF_YEAR, newVal - oldVal); - updateDateControl(); - //OnValueChangeListener,这是时间改变监听器,这里主要是对日期的监听 - //将现在日期的值传递给mDate;updateDateControl是同步操作 - - onDateTimeChanged(); - //这段代码是一个事件回调方法 onValueChange 的实现。它是在 NumberPicker 控件的值发生改变时被调用的。 - //在这个方法中,首先根据新旧值的差异,使用 mDate.add(Calendar.DAY_OF_YEAR, newVal - oldVal) 方法来更新 mDate 对应的 Calendar 对象,即将日期增加或减少相应的天数。 - //接下来,调用 updateDateControl() 方法来更新与日期相关的控件,更新显示日期的文本或者刷新界面等操作。 - //最后,调用 onDateTimeChanged() 方法来处理日期时间的变化。 - } - }; - - private NumberPicker.OnValueChangeListener mOnHourChangedListener = new NumberPicker.OnValueChangeListener() { - //这里是对 小时(Hour) 的监听 - @Override - public void onValueChange(NumberPicker picker, int oldVal, int newVal) { - boolean isDateChanged = false; - Calendar cal = Calendar.getInstance(); - //声明一个Calendar的变量cal,便于后续的操作 - if (!mIs24HourView) { - if (!mIsAm && oldVal == HOURS_IN_HALF_DAY - 1 && newVal == HOURS_IN_HALF_DAY) { - cal.setTimeInMillis(mDate.getTimeInMillis()); - cal.add(Calendar.DAY_OF_YEAR, 1); - isDateChanged = true; - //这段代码是对于12小时制时,当从晚上的 11 点切换到早上的 12 点时,会将日期向后推一天。 - } else if (mIsAm && oldVal == HOURS_IN_HALF_DAY && newVal == HOURS_IN_HALF_DAY - 1) { - cal.setTimeInMillis(mDate.getTimeInMillis()); - cal.add(Calendar.DAY_OF_YEAR, -1); - isDateChanged = true; - } - //这段代码和之前的类似,但是是当从早上的 12 点切换到晚上的 11 点时,会将日期向前推一天。 - if (oldVal == HOURS_IN_HALF_DAY - 1 && newVal == HOURS_IN_HALF_DAY || - oldVal == HOURS_IN_HALF_DAY && newVal == HOURS_IN_HALF_DAY - 1) { - mIsAm = !mIsAm; - updateAmPmControl(); - //当在凌晨 11 点和中午 12 点之间进行切换时,会切换上午和下午的状态,并更新相关的显示控件。 - } - } else { - if (oldVal == HOURS_IN_ALL_DAY - 1 && newVal == 0) { - cal.setTimeInMillis(mDate.getTimeInMillis()); - cal.add(Calendar.DAY_OF_YEAR, 1); - isDateChanged = true; - //当从一天的最后一小时切换到第二天的第一小时时,会将日期向后推一天。 - } else if (oldVal == 0 && newVal == HOURS_IN_ALL_DAY - 1) { - cal.setTimeInMillis(mDate.getTimeInMillis()); - cal.add(Calendar.DAY_OF_YEAR, -1); - isDateChanged = true; - //当从第二天的第一小时切换到一天的最后一小时时,会将日期向前推一天。 - } - - } - int newHour = mHourSpinner.getValue() % HOURS_IN_HALF_DAY + (mIsAm ? 0 : HOURS_IN_HALF_DAY); - //通过数字选择器对newHour的赋值 - mDate.set(Calendar.HOUR_OF_DAY, newHour); - //通过set函数将新的Hour值传给mDate - onDateTimeChanged(); - if (isDateChanged) { - setCurrentYear(cal.get(Calendar.YEAR)); - setCurrentMonth(cal.get(Calendar.MONTH)); - setCurrentDay(cal.get(Calendar.DAY_OF_MONTH)); - }//这段代码是在日期发生变化时,将新的日期设置为当前的年月日。 - } - }; - - private NumberPicker.OnValueChangeListener mOnMinuteChangedListener = new NumberPicker.OnValueChangeListener() { - @Override - //对分钟(Minute)改变的监听 - public void onValueChange(NumberPicker picker, int oldVal, int newVal) { - int minValue = mMinuteSpinner.getMinValue(); - int maxValue = mMinuteSpinner.getMaxValue(); - //获取分钟数字选择器中的最大值和最小值 - int offset = 0; - //设置offset,作为小时改变的一个记录数据 - if (oldVal == maxValue && newVal == minValue) { - offset += 1; - //如果原值为59,新值为0,则offset加1 - } else if (oldVal == minValue && newVal == maxValue) { - offset -= 1; - //如果原值为0,新值为59,则offset减1 - - } - if (offset != 0) { - //如果 offset 不等于 0,表示需要进行偏移操作。接下来的代码会根据偏移值更新日期和小时的值。 - mDate.add(Calendar.HOUR_OF_DAY, offset);//偏移日期,将小时增加或减少。 - mHourSpinner.setValue(getCurrentHour());//小时的选择器设置为当前的小时值。 - updateDateControl();//更新日期相关的显示控件。 - int newHour = getCurrentHourOfDay(); - if (newHour >= HOURS_IN_HALF_DAY) { - mIsAm = false; - updateAmPmControl(); - } else { - mIsAm = true; - updateAmPmControl(); - }//根据 newHour 的值判断是否超过半天。若超过半天,则将 mIsAm 设置为 false,否则设置为 true。 - //然后调用 updateAmPmControl() 更新上午/下午的显示控件。 - } - mDate.set(Calendar.MINUTE, newVal);//将选择器中的分钟值设置为 newVal,即新选择的分钟值。 - onDateTimeChanged(); - } - }; - - private NumberPicker.OnValueChangeListener mOnAmPmChangedListener = new NumberPicker.OnValueChangeListener() { - //对AM和PM的监听 - @Override - public void onValueChange(NumberPicker picker, int oldVal, int newVal) {//是在上午/下午选择器的值发生变化时的处理逻辑。 - mIsAm = !mIsAm; - if (mIsAm) {//如果 mIsAm 是 true,表示用户选择了上午。前调12小时 - mDate.add(Calendar.HOUR_OF_DAY, -HOURS_IN_HALF_DAY); - } else {//如果 mIsAm 是 false,表示用户选择了下午。后调12小时 - mDate.add(Calendar.HOUR_OF_DAY, HOURS_IN_HALF_DAY); - } - updateAmPmControl();//更新上/下午显示控件 - onDateTimeChanged(); - - } - }; - - public interface OnDateTimeChangedListener { - //用来监听日期选择器的变化。 - void onDateTimeChanged(DateTimePicker view, int year, int month, - int dayOfMonth, int hourOfDay, int minute); - /*view:表示触发事件的日期时间选择器。 - year:表示选择的年份。 - month:表示选择的月份,范围是 0-11(0 表示一月)。 - dayOfMonth:表示选择的日期。 - hourOfDay:表示选择的小时数,范围是 0-23。 - minute:表示选择的分钟数,范围是 0-59。*/ - } - - public DateTimePicker(Context context) { - this(context, System.currentTimeMillis()); - //通过对数据库的访问,获取当前的系统时间 - } - - public DateTimePicker(Context context, long date) { - this(context, date, DateFormat.is24HourFormat(context)); - }//上面函数的得到的是一个天文数字(1970至今的秒数),需要DateFormat将其变得有意义 - - public DateTimePicker(Context context, long date, boolean is24HourView) { - super(context); - //获取系统时间 - mDate = Calendar.getInstance(); - mInitialising = true; - mIsAm = getCurrentHourOfDay() >= HOURS_IN_HALF_DAY; - inflate(context, R.layout.datetime_picker, this); - //如果当前Activity里用到别的layout,比如对话框layout - //还要设置这个layout上的其他组件的内容,就必须用inflate()方法先将对话框的layout找出来 - //然后再用findViewById()找到它上面的其它组件 - mDateSpinner = (NumberPicker) findViewById(R.id.date); - mDateSpinner.setMinValue(DATE_SPINNER_MIN_VAL); - mDateSpinner.setMaxValue(DATE_SPINNER_MAX_VAL); - mDateSpinner.setOnValueChangedListener(mOnDateChangedListener); - - mHourSpinner = (NumberPicker) findViewById(R.id.hour); - mHourSpinner.setOnValueChangedListener(mOnHourChangedListener); - mMinuteSpinner = (NumberPicker) findViewById(R.id.minute); - mMinuteSpinner.setMinValue(MINUT_SPINNER_MIN_VAL); - mMinuteSpinner.setMaxValue(MINUT_SPINNER_MAX_VAL); - mMinuteSpinner.setOnLongPressUpdateInterval(100); - mMinuteSpinner.setOnValueChangedListener(mOnMinuteChangedListener); - - String[] stringsForAmPm = new DateFormatSymbols().getAmPmStrings(); - mAmPmSpinner = (NumberPicker) findViewById(R.id.amPm); - mAmPmSpinner.setMinValue(AMPM_SPINNER_MIN_VAL); - mAmPmSpinner.setMaxValue(AMPM_SPINNER_MAX_VAL); - mAmPmSpinner.setDisplayedValues(stringsForAmPm); - mAmPmSpinner.setOnValueChangedListener(mOnAmPmChangedListener); - //可以看到原有的注释,意思是初始化日期时间选择器中的三个数字选择器和一个上午/下午选择器。 - // update controls to initial state - updateDateControl(); - updateHourControl(); - updateAmPmControl(); - - set24HourView(is24HourView); - //设置当前时间 - // set to current time - setCurrentDate(date); - - setEnabled(isEnabled()); - //设置内容描述(目的是提高访问性) - // set the content descriptions - mInitialising = false; - } - - @Override - public void setEnabled(boolean enabled) { - if (mIsEnabled == enabled) { - return; - } - super.setEnabled(enabled); - mDateSpinner.setEnabled(enabled); - mMinuteSpinner.setEnabled(enabled); - mHourSpinner.setEnabled(enabled); - mAmPmSpinner.setEnabled(enabled); - mIsEnabled = enabled; - }//这段代码定义了一个名为 setEnabled() 的方法,用于启用或禁用日期时间选择器。 - - @Override - public boolean isEnabled() { - return mIsEnabled; - } - - /** - * Get the current date in millis - * - * @return the current date in millis - */ - public long getCurrentDateInTimeMillis() { - return mDate.getTimeInMillis(); - }//得到当前秒数 - - /** - * Set the current date - * - * @param date The current date in millis - */ - public void setCurrentDate(long date) { - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(date); - setCurrentDate(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), - cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE)); - }//设置当前时间,参数date - - /** - * Set the current date - * - * @param year The current year - * @param month The current month - * @param dayOfMonth The current dayOfMonth - * @param hourOfDay The current hourOfDay - * @param minute The current minute - */ - public void setCurrentDate(int year, int month, - int dayOfMonth, int hourOfDay, int minute) { - setCurrentYear(year); - setCurrentMonth(month); - setCurrentDay(dayOfMonth); - setCurrentHour(hourOfDay); - setCurrentMinute(minute); - }//设置当前时间 - - /** - * Get current year - * - * @return The current year - */ - public int getCurrentYear() { - return mDate.get(Calendar.YEAR); - } - - /** - * Set current year - * - * @param year The current year - */ - public void setCurrentYear(int year) { - if (!mInitialising && year == getCurrentYear()) { - return; - } - mDate.set(Calendar.YEAR, year); - updateDateControl(); - onDateTimeChanged(); - } - - /** - * Get current month in the year - * - * @return The current month in the year - */ - public int getCurrentMonth() { - return mDate.get(Calendar.MONTH); - } - - /** - * Set current month in the year - * - * @param month The month in the year - */ - public void setCurrentMonth(int month) { - if (!mInitialising && month == getCurrentMonth()) { - return; - } - mDate.set(Calendar.MONTH, month); - updateDateControl(); - onDateTimeChanged(); - } - - /** - * Get current day of the month - * - * @return The day of the month - */ - public int getCurrentDay() { - return mDate.get(Calendar.DAY_OF_MONTH); - } - - /** - * Set current day of the month - * - * @param dayOfMonth The day of the month - */ - public void setCurrentDay(int dayOfMonth) { - if (!mInitialising && dayOfMonth == getCurrentDay()) { - return; - } - mDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); - updateDateControl(); - onDateTimeChanged(); - } -//上述一大段代码实现的功能是得到year、month、day等值 - /** - * Get current hour in 24 hour mode, in the range (0~23) - * @return The current hour in 24 hour mode - */ - public int getCurrentHourOfDay() { - return mDate.get(Calendar.HOUR_OF_DAY); - } - - private int getCurrentHour() { - if (mIs24HourView){ - return getCurrentHourOfDay(); - } else { - int hour = getCurrentHourOfDay(); - if (hour > HOURS_IN_HALF_DAY) { - return hour - HOURS_IN_HALF_DAY; - } else { - return hour == 0 ? HOURS_IN_HALF_DAY : hour; - } - } - } - - /** - * Set current hour in 24 hour mode, in the range (0~23) - * - * @param hourOfDay - */ - public void setCurrentHour(int hourOfDay) { - if (!mInitialising && hourOfDay == getCurrentHourOfDay()) { - return; - } - mDate.set(Calendar.HOUR_OF_DAY, hourOfDay); - if (!mIs24HourView) { - if (hourOfDay >= HOURS_IN_HALF_DAY) { - mIsAm = false; - if (hourOfDay > HOURS_IN_HALF_DAY) { - hourOfDay -= HOURS_IN_HALF_DAY; - } - } else { - mIsAm = true; - if (hourOfDay == 0) { - hourOfDay = HOURS_IN_HALF_DAY; - } - } - updateAmPmControl(); - } - mHourSpinner.setValue(hourOfDay); - onDateTimeChanged(); - } - - /** - * Get currentMinute - * - * @return The Current Minute - */ - public int getCurrentMinute() { - return mDate.get(Calendar.MINUTE); - } - - /** - * Set current minute - */ - public void setCurrentMinute(int minute) { - if (!mInitialising && minute == getCurrentMinute()) { - return; - } - mMinuteSpinner.setValue(minute); - mDate.set(Calendar.MINUTE, minute); - onDateTimeChanged(); - } - - /** - * @return true if this is in 24 hour view else false. - */ - public boolean is24HourView () { - return mIs24HourView; - } - - /** - * Set whether in 24 hour or AM/PM mode. - * - * @param is24HourView True for 24 hour mode. False for AM/PM mode. - */ - public void set24HourView(boolean is24HourView) { - if (mIs24HourView == is24HourView) { - return; - } - mIs24HourView = is24HourView; - mAmPmSpinner.setVisibility(is24HourView ? View.GONE : View.VISIBLE); - int hour = getCurrentHourOfDay(); - updateHourControl(); - setCurrentHour(hour); - updateAmPmControl(); - } - - private void updateDateControl() { - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(mDate.getTimeInMillis()); - cal.add(Calendar.DAY_OF_YEAR, -DAYS_IN_ALL_WEEK / 2 - 1); - mDateSpinner.setDisplayedValues(null); - for (int i = 0; i < DAYS_IN_ALL_WEEK; ++i) { - cal.add(Calendar.DAY_OF_YEAR, 1); - mDateDisplayValues[i] = (String) DateFormat.format("MM.dd EEEE", cal); - } - mDateSpinner.setDisplayedValues(mDateDisplayValues); - mDateSpinner.setValue(DAYS_IN_ALL_WEEK / 2); - mDateSpinner.invalidate(); - }//一个关于星期几的算法 - - private void updateAmPmControl() { - if (mIs24HourView) { - mAmPmSpinner.setVisibility(View.GONE); - } else { - int index = mIsAm ? Calendar.AM : Calendar.PM; - mAmPmSpinner.setValue(index); - mAmPmSpinner.setVisibility(View.VISIBLE); - } - }//判断上午下午的算法 - - private void updateHourControl() { - if (mIs24HourView) { - mHourSpinner.setMinValue(HOUR_SPINNER_MIN_VAL_24_HOUR_VIEW); - mHourSpinner.setMaxValue(HOUR_SPINNER_MAX_VAL_24_HOUR_VIEW); - } else { - mHourSpinner.setMinValue(HOUR_SPINNER_MIN_VAL_12_HOUR_VIEW); - mHourSpinner.setMaxValue(HOUR_SPINNER_MAX_VAL_12_HOUR_VIEW); - }//小时的算法 - } - - /** - * Set the callback that indicates the 'Set' button has been pressed. - * @param callback the callback, if null will do nothing - */ - public void setOnDateTimeChangedListener(OnDateTimeChangedListener callback) { - mOnDateTimeChangedListener = callback; - } - - private void onDateTimeChanged() { - if (mOnDateTimeChangedListener != null) { - mOnDateTimeChangedListener.onDateTimeChanged(this, getCurrentYear(), - getCurrentMonth(), getCurrentDay(), getCurrentHourOfDay(), getCurrentMinute()); - } - } -} diff --git a/doc/软件工程课程实践成果汇报.pptx b/doc/软件工程课程实践成果汇报.pptx new file mode 100644 index 0000000..0a7f785 Binary files /dev/null and b/doc/软件工程课程实践成果汇报.pptx differ