Merge pull request '2' (#5) from pxf_branch into develop
commit
b7f6fd04dc
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest package="com.ldf.mi.calendar">
|
||||
|
||||
</manifest>
|
@ -0,0 +1,11 @@
|
||||
package com.ldf.calendar;
|
||||
|
||||
// 这个类定义了一些常量,用于日历视图的布局和设定
|
||||
public class Const {
|
||||
// 表示日历视图的总列数
|
||||
public final static int TOTAL_COL = 7;
|
||||
// 表示日历视图的总行数
|
||||
public final static int TOTAL_ROW = 6;
|
||||
// 表示当前的页面索引,用于日历视图的显示
|
||||
public final static int CURRENT_PAGER_INDEX = 1000;
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
package com.ldf.calendar.component;
|
||||
|
||||
/**
|
||||
* 日历属性类
|
||||
*/
|
||||
|
||||
public class CalendarAttr {
|
||||
|
||||
// 周起始类型
|
||||
private WeekArrayType weekArrayType;
|
||||
|
||||
// 日历类型
|
||||
private CalendarType calendarType;
|
||||
|
||||
// 单元格高度
|
||||
private int cellHeight;
|
||||
|
||||
// 单元格宽度
|
||||
private int cellWidth;
|
||||
|
||||
public WeekArrayType getWeekArrayType() {
|
||||
return weekArrayType;
|
||||
}
|
||||
|
||||
public void setWeekArrayType(WeekArrayType weekArrayType) {
|
||||
this.weekArrayType = weekArrayType;
|
||||
}
|
||||
|
||||
public CalendarType getCalendarType() {
|
||||
return calendarType;
|
||||
}
|
||||
|
||||
public void setCalendarType(CalendarType calendarType) {
|
||||
this.calendarType = calendarType;
|
||||
}
|
||||
|
||||
public int getCellHeight() {
|
||||
return cellHeight;
|
||||
}
|
||||
|
||||
public void setCellHeight(int cellHeight) {
|
||||
this.cellHeight = cellHeight;
|
||||
}
|
||||
|
||||
public int getCellWidth() {
|
||||
return cellWidth;
|
||||
}
|
||||
|
||||
public void setCellWidth(int cellWidth) {
|
||||
this.cellWidth = cellWidth;
|
||||
}
|
||||
|
||||
// 周起始类型枚举
|
||||
public enum WeekArrayType {
|
||||
Sunday, Monday
|
||||
}
|
||||
|
||||
// 日历类型枚举
|
||||
public enum CalendarType {
|
||||
WEEK, MONTH
|
||||
}
|
||||
}
|
@ -0,0 +1,318 @@
|
||||
package com.ldf.calendar.component;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.util.Log;
|
||||
|
||||
import com.ldf.calendar.Const;
|
||||
import com.ldf.calendar.Utils;
|
||||
import com.ldf.calendar.interf.IDayRenderer;
|
||||
import com.ldf.calendar.interf.OnSelectDateListener;
|
||||
import com.ldf.calendar.model.CalendarDate;
|
||||
import com.ldf.calendar.view.Calendar;
|
||||
import com.ldf.calendar.view.Day;
|
||||
import com.ldf.calendar.view.Week;
|
||||
|
||||
public class CalendarRenderer {
|
||||
// 用于存储每行的日期数据,数组长度为总行数
|
||||
private Week[] weeks = new Week[Const.TOTAL_ROW];
|
||||
private Calendar calendar;// 日历对象
|
||||
private CalendarAttr attr;// 日历属性
|
||||
private IDayRenderer dayRenderer;// 日期渲染器接口
|
||||
private Context context;// 上下文
|
||||
private OnSelectDateListener onSelectDateListener;// 单元格点击回调事件
|
||||
private CalendarDate seedDate; //种子日期
|
||||
private CalendarDate selectedDate; //被选中的日期
|
||||
private int selectedRowIndex = 0;
|
||||
|
||||
public CalendarRenderer(Calendar calendar, CalendarAttr attr, Context context) {
|
||||
this.calendar = calendar;
|
||||
this.attr = attr;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
// 绘制日历
|
||||
public void draw(Canvas canvas) {
|
||||
for (int row = 0; row < Const.TOTAL_ROW; row++) {
|
||||
if (weeks[row] != null) {
|
||||
for (int col = 0; col < Const.TOTAL_COL; col++) {
|
||||
if (weeks[row].days[col] != null) {
|
||||
// 调用日期渲染器接口绘制日期
|
||||
dayRenderer.drawDay(canvas, weeks[row].days[col]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理日期点击事件
|
||||
public void onClickDate(int col, int row) {
|
||||
if (col >= Const.TOTAL_COL || row >= Const.TOTAL_ROW)
|
||||
return;
|
||||
if (weeks[row] != null) {
|
||||
if (attr.getCalendarType() == CalendarAttr.CalendarType.MONTH) {
|
||||
if (weeks[row].days[col].getState() == State.CURRENT_MONTH) {
|
||||
// 如果点击的日期是当月日期,则设置为选中状态,并触发选中日期回调事件
|
||||
weeks[row].days[col].setState(State.SELECT);
|
||||
selectedDate = weeks[row].days[col].getDate();
|
||||
CalendarViewAdapter.saveSelectedDate(selectedDate);
|
||||
onSelectDateListener.onSelectDate(selectedDate);
|
||||
seedDate = selectedDate;
|
||||
} else if (weeks[row].days[col].getState() == State.PAST_MONTH) {
|
||||
// 如果点击的日期是上个月的日期,则保存选中的日期并触发选中其他月份日期回调事件
|
||||
selectedDate = weeks[row].days[col].getDate();
|
||||
CalendarViewAdapter.saveSelectedDate(selectedDate);
|
||||
onSelectDateListener.onSelectOtherMonth(-1);
|
||||
onSelectDateListener.onSelectDate(selectedDate);
|
||||
} else if (weeks[row].days[col].getState() == State.NEXT_MONTH) {
|
||||
// 如果点击的日期是下个月的日期,则保存选中的日期并触发选中其他月份日期回调事件
|
||||
selectedDate = weeks[row].days[col].getDate();
|
||||
CalendarViewAdapter.saveSelectedDate(selectedDate);
|
||||
onSelectDateListener.onSelectOtherMonth(1);
|
||||
onSelectDateListener.onSelectDate(selectedDate);
|
||||
}
|
||||
} else {
|
||||
// 如果日历类型不是月视图,则直接设置点击的日期为选中状态,并触发选中日期回调事件
|
||||
weeks[row].days[col].setState(State.SELECT);
|
||||
selectedDate = weeks[row].days[col].getDate();
|
||||
CalendarViewAdapter.saveSelectedDate(selectedDate);
|
||||
onSelectDateListener.onSelectDate(selectedDate);
|
||||
seedDate = selectedDate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateWeek(int rowIndex) {
|
||||
CalendarDate currentWeekLastDay;
|
||||
if (attr.getWeekArrayType() == CalendarAttr.WeekArrayType.Sunday) {
|
||||
// 如果一周的起始是星期天,则当前周的最后一天是星期六
|
||||
currentWeekLastDay = Utils.getSaturday(seedDate);
|
||||
} else {
|
||||
// 如果一周的起始是星期一,则当前周的最后一天是星期天
|
||||
currentWeekLastDay = Utils.getSunday(seedDate);
|
||||
}
|
||||
int day = currentWeekLastDay.day;
|
||||
for (int i = Const.TOTAL_COL - 1; i >= 0; i--) {
|
||||
// 逐个填充当前周的日期数据
|
||||
CalendarDate date = currentWeekLastDay.modifyDay(day);
|
||||
if (weeks[rowIndex] == null) {
|
||||
weeks[rowIndex] = new Week(rowIndex);
|
||||
}
|
||||
if (weeks[rowIndex].days[i] != null) {
|
||||
// 如果日期数据已存在,则更新状态和日期
|
||||
if (date.equals(CalendarViewAdapter.loadSelectedDate())) {
|
||||
weeks[rowIndex].days[i].setState(State.SELECT);
|
||||
weeks[rowIndex].days[i].setDate(date);
|
||||
} else {
|
||||
weeks[rowIndex].days[i].setState(State.CURRENT_MONTH);
|
||||
weeks[rowIndex].days[i].setDate(date);
|
||||
}
|
||||
} else {
|
||||
// 如果日期数据不存在,则创建新的日期对象
|
||||
if (date.equals(CalendarViewAdapter.loadSelectedDate())) {
|
||||
weeks[rowIndex].days[i] = new Day(State.SELECT, date, rowIndex, i);
|
||||
} else {
|
||||
weeks[rowIndex].days[i] = new Day(State.CURRENT_MONTH, date, rowIndex, i);
|
||||
}
|
||||
}
|
||||
day--;
|
||||
}
|
||||
}
|
||||
|
||||
private void instantiateMonth() {
|
||||
// 上个月的天数
|
||||
int lastMonthDays = Utils.getMonthDays(seedDate.year, seedDate.month - 1);
|
||||
// 当前月的天数
|
||||
int currentMonthDays = Utils.getMonthDays(seedDate.year, seedDate.month);
|
||||
int firstDayPosition = Utils.getFirstDayWeekPosition(
|
||||
seedDate.year,
|
||||
seedDate.month,
|
||||
attr.getWeekArrayType());
|
||||
Log.e("ldf", "firstDayPosition = " + firstDayPosition);
|
||||
|
||||
int day = 0;
|
||||
for (int row = 0; row < Const.TOTAL_ROW; row++) {
|
||||
day = fillWeek(lastMonthDays, currentMonthDays, firstDayPosition, day, row);
|
||||
}
|
||||
}
|
||||
|
||||
private int fillWeek(int lastMonthDays,
|
||||
int currentMonthDays,
|
||||
int firstDayWeek,
|
||||
int day,
|
||||
int row) {
|
||||
for (int col = 0; col < Const.TOTAL_COL; col++) {
|
||||
int position = col + row * Const.TOTAL_COL;// 单元格位置
|
||||
if (position >= firstDayWeek && position < firstDayWeek + currentMonthDays) {
|
||||
day++;
|
||||
fillCurrentMonthDate(day, row, col);
|
||||
} else if (position < firstDayWeek) {
|
||||
instantiateLastMonth(lastMonthDays, firstDayWeek, row, col, position);
|
||||
} else if (position >= firstDayWeek + currentMonthDays) {
|
||||
instantiateNextMonth(currentMonthDays, firstDayWeek, row, col, position);
|
||||
}
|
||||
}
|
||||
return day;
|
||||
}
|
||||
|
||||
private void fillCurrentMonthDate(int day, int row, int col) {
|
||||
// 填充当前月的日期数据
|
||||
CalendarDate date = seedDate.modifyDay(day);
|
||||
if (weeks[row] == null) {
|
||||
weeks[row] = new Week(row);
|
||||
}
|
||||
if (weeks[row].days[col] != null) {
|
||||
if (date.equals(CalendarViewAdapter.loadSelectedDate())) {
|
||||
weeks[row].days[col].setDate(date);
|
||||
weeks[row].days[col].setState(State.SELECT);
|
||||
} else {
|
||||
weeks[row].days[col].setDate(date);
|
||||
weeks[row].days[col].setState(State.CURRENT_MONTH);
|
||||
}
|
||||
} else {
|
||||
if (date.equals(CalendarViewAdapter.loadSelectedDate())) {
|
||||
weeks[row].days[col] = new Day(State.SELECT, date, row, col);
|
||||
} else {
|
||||
weeks[row].days[col] = new Day(State.CURRENT_MONTH, date, row, col);
|
||||
}
|
||||
}
|
||||
if (date.equals(seedDate)) {
|
||||
selectedRowIndex = row;
|
||||
}
|
||||
}
|
||||
|
||||
private void instantiateNextMonth(int currentMonthDays,
|
||||
int firstDayWeek,
|
||||
int row,
|
||||
int col,
|
||||
int position) {
|
||||
// 创建下一个月的日期对象
|
||||
CalendarDate date = new CalendarDate(
|
||||
seedDate.year,
|
||||
seedDate.month + 1,
|
||||
position - firstDayWeek - currentMonthDays + 1);
|
||||
// 如果当前行的周对象为空,则创建新的周对象
|
||||
if (weeks[row] == null) {
|
||||
weeks[row] = new Week(row);
|
||||
}
|
||||
// 如果当前行的日对象不为空,则设置日期和状态;
|
||||
if (weeks[row].days[col] != null) {
|
||||
weeks[row].days[col].setDate(date);
|
||||
weeks[row].days[col].setState(State.NEXT_MONTH);
|
||||
}
|
||||
//否则创建新的日对象并设置日期和状态
|
||||
else {
|
||||
weeks[row].days[col] = new Day(State.NEXT_MONTH, date, row, col);
|
||||
}
|
||||
}
|
||||
|
||||
// 为当前日期视图创建上一个月的日期对象并设置相关状态,同上
|
||||
private void instantiateLastMonth(int lastMonthDays, int firstDayWeek, int row, int col, int position) {
|
||||
CalendarDate date = new CalendarDate(
|
||||
seedDate.year,
|
||||
seedDate.month - 1,
|
||||
lastMonthDays - (firstDayWeek - position - 1));
|
||||
if (weeks[row] == null) {
|
||||
weeks[row] = new Week(row);
|
||||
}
|
||||
if (weeks[row].days[col] != null) {
|
||||
weeks[row].days[col].setDate(date);
|
||||
weeks[row].days[col].setState(State.PAST_MONTH);
|
||||
} else {
|
||||
weeks[row].days[col] = new Day(State.PAST_MONTH, date, row, col);
|
||||
}
|
||||
}
|
||||
|
||||
// 设置要显示的日期
|
||||
public void showDate(CalendarDate seedDate) {
|
||||
if (seedDate != null) {
|
||||
this.seedDate = seedDate;
|
||||
} else {
|
||||
this.seedDate = new CalendarDate();
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
// 更新日期视图
|
||||
public void update() {
|
||||
// 实例化月份并使日历失效以便重新绘制
|
||||
instantiateMonth();
|
||||
calendar.invalidate();
|
||||
}
|
||||
|
||||
// 获取当前日期
|
||||
public CalendarDate getSeedDate() {
|
||||
return this.seedDate;
|
||||
}
|
||||
|
||||
// 取消选中日期的状态
|
||||
public void cancelSelectState() {
|
||||
// 遍历所有日期,将选中状态的日期重置为当前月状态并重置选中行索引
|
||||
for (int i = 0; i < Const.TOTAL_ROW; i++) {
|
||||
if (weeks[i] != null) {
|
||||
for (int j = 0; j < Const.TOTAL_COL; j++) {
|
||||
if (weeks[i].days[j].getState() == State.SELECT) {
|
||||
weeks[i].days[j].setState(State.CURRENT_MONTH);
|
||||
resetSelectedRowIndex();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 重置选中行索引
|
||||
public void resetSelectedRowIndex() {
|
||||
selectedRowIndex = 0;
|
||||
}
|
||||
|
||||
// 获取选中行索引
|
||||
public int getSelectedRowIndex() {
|
||||
return selectedRowIndex;
|
||||
}
|
||||
|
||||
// 设置选中行索引
|
||||
public void setSelectedRowIndex(int selectedRowIndex) {
|
||||
this.selectedRowIndex = selectedRowIndex;
|
||||
}
|
||||
|
||||
// 获取日历对象
|
||||
public Calendar getCalendar() {
|
||||
return calendar;
|
||||
}
|
||||
|
||||
// 设置日历对象
|
||||
public void setCalendar(Calendar calendar) {
|
||||
this.calendar = calendar;
|
||||
}
|
||||
|
||||
// 获取日期属性
|
||||
public CalendarAttr getAttr() {
|
||||
return attr;
|
||||
}
|
||||
|
||||
// 设置日期属性
|
||||
public void setAttr(CalendarAttr attr) {
|
||||
this.attr = attr;
|
||||
}
|
||||
|
||||
// 获取上下文对象
|
||||
public Context getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
// 设置上下文对象
|
||||
public void setContext(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
// 设置日期选择监听器
|
||||
public void setOnSelectDateListener(OnSelectDateListener onSelectDateListener) {
|
||||
this.onSelectDateListener = onSelectDateListener;
|
||||
}
|
||||
|
||||
// 设置日期渲染器
|
||||
public void setDayRenderer(IDayRenderer dayRenderer) {
|
||||
this.dayRenderer = dayRenderer;
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package com.ldf.calendar.component;
|
||||
|
||||
/**
|
||||
* 日历状态枚举
|
||||
*/
|
||||
public enum State {
|
||||
CURRENT_MONTH, // 当前月
|
||||
PAST_MONTH, // 过去的月份
|
||||
NEXT_MONTH, // 下一个月
|
||||
SELECT // 选中状态
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.ldf.calendar.interf;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
|
||||
import com.ldf.calendar.view.Day;
|
||||
|
||||
/**
|
||||
* 日历每日单元渲染接口
|
||||
*/
|
||||
public interface IDayRenderer {
|
||||
//刷新内容
|
||||
void refreshContent();
|
||||
|
||||
//绘制单个日期
|
||||
void drawDay(Canvas canvas, Day day);
|
||||
|
||||
//复制日历渲染器
|
||||
IDayRenderer copy();
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package com.ldf.calendar.interf;
|
||||
|
||||
// 定义了一个接口 OnAdapterSelectListener
|
||||
public interface OnAdapterSelectListener {
|
||||
|
||||
// 取消选择状态的方法声明
|
||||
void cancelSelectState();
|
||||
|
||||
// 更新选择状态的方法声明
|
||||
void updateSelectState();
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.ldf.calendar.interf;
|
||||
|
||||
import com.ldf.calendar.model.CalendarDate;
|
||||
|
||||
// 定义了一个接口 OnSelectDateListener
|
||||
public interface OnSelectDateListener {
|
||||
|
||||
// 选中日期的方法声明,接收一个 CalendarDate 对象作为参数
|
||||
void onSelectDate(CalendarDate date);
|
||||
|
||||
// 选中其它月份日期的方法声明,接收表示月份偏移量的整数作为参数
|
||||
void onSelectOtherMonth(int offset);
|
||||
}
|
@ -0,0 +1,151 @@
|
||||
package com.ldf.calendar.model;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.ldf.calendar.Utils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Calendar;
|
||||
|
||||
public class CalendarDate implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
public int year;
|
||||
public int month; //1~12
|
||||
public int day;
|
||||
// 构造方法,用指定的年、月、日来初始化对象
|
||||
public CalendarDate(int year, int month, int day) {
|
||||
if (month > 12) {
|
||||
month = 1;
|
||||
year++;
|
||||
} else if (month < 1) {
|
||||
month = 12;
|
||||
year--;
|
||||
}
|
||||
this.year = year;
|
||||
this.month = month;
|
||||
this.day = day;
|
||||
}
|
||||
// 无参构造方法,默认使用当前系统日期来初始化对象
|
||||
public CalendarDate() {
|
||||
this.year = Utils.getYear();
|
||||
this.month = Utils.getMonth();
|
||||
this.day = Utils.getDay();
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过修改当前Date对象的天数返回一个修改后的Date
|
||||
*
|
||||
* @return CalendarDate 修改后的日期
|
||||
*/
|
||||
public CalendarDate modifyDay(int day) {
|
||||
int lastMonthDays = Utils.getMonthDays(this.year, this.month - 1);
|
||||
int currentMonthDays = Utils.getMonthDays(this.year, this.month);
|
||||
|
||||
CalendarDate modifyDate;
|
||||
if (day > currentMonthDays) {
|
||||
modifyDate = new CalendarDate(this.year, this.month, this.day);
|
||||
Log.e("ldf", "移动天数过大");
|
||||
} else if (day > 0) {
|
||||
modifyDate = new CalendarDate(this.year, this.month, day);
|
||||
} else if (day > 0 - lastMonthDays) {
|
||||
modifyDate = new CalendarDate(this.year, this.month - 1, lastMonthDays + day);
|
||||
} else {
|
||||
modifyDate = new CalendarDate(this.year, this.month, this.day);
|
||||
Log.e("ldf", "移动天数过大");
|
||||
}
|
||||
return modifyDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过修改当前Date对象的所在周返回一个修改后的Date
|
||||
*
|
||||
* @return CalendarDate 修改后的日期
|
||||
*/
|
||||
public CalendarDate modifyWeek(int offset) {
|
||||
CalendarDate result = new CalendarDate();
|
||||
Calendar c = Calendar.getInstance();
|
||||
c.set(Calendar.YEAR, year);
|
||||
c.set(Calendar.MONTH, month - 1);
|
||||
c.set(Calendar.DAY_OF_MONTH, day);
|
||||
c.add(Calendar.DATE, offset * 7);
|
||||
result.setYear(c.get(Calendar.YEAR));
|
||||
result.setMonth(c.get(Calendar.MONTH) + 1);
|
||||
result.setDay(c.get(Calendar.DATE));
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过修改当前Date对象的所在月返回一个修改后的Date
|
||||
*
|
||||
* @return CalendarDate 修改后的日期
|
||||
*/
|
||||
public CalendarDate modifyMonth(int offset) {
|
||||
CalendarDate result = new CalendarDate();
|
||||
int addToMonth = this.month + offset;
|
||||
if (offset > 0) {
|
||||
if (addToMonth > 12) {
|
||||
result.setYear(this.year + (addToMonth - 1) / 12);
|
||||
result.setMonth(addToMonth % 12 == 0 ? 12 : addToMonth % 12);
|
||||
} else {
|
||||
result.setYear(this.year);
|
||||
result.setMonth(addToMonth);
|
||||
}
|
||||
} else {
|
||||
if (addToMonth == 0) {
|
||||
result.setYear(this.year - 1);
|
||||
result.setMonth(12);
|
||||
} else if (addToMonth < 0) {
|
||||
result.setYear(this.year + addToMonth / 12 - 1);
|
||||
int month = 12 - Math.abs(addToMonth) % 12;
|
||||
result.setMonth(month == 0 ? 12 : month);
|
||||
} else {
|
||||
result.setYear(this.year);
|
||||
result.setMonth(addToMonth == 0 ? 12 : addToMonth);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return year + "-" + month + "-" + day;
|
||||
}
|
||||
// 下面是获取、设置年、月、日
|
||||
public int getYear() {
|
||||
return year;
|
||||
}
|
||||
|
||||
public void setYear(int year) {
|
||||
this.year = year;
|
||||
}
|
||||
|
||||
public int getMonth() {
|
||||
return month;
|
||||
}
|
||||
|
||||
public void setMonth(int month) {
|
||||
this.month = month;
|
||||
}
|
||||
|
||||
public int getDay() {
|
||||
return day;
|
||||
}
|
||||
|
||||
public void setDay(int day) {
|
||||
this.day = day;
|
||||
}
|
||||
// 比较两个日期是否相等
|
||||
public boolean equals(CalendarDate date) {
|
||||
if (date == null) {
|
||||
return false;
|
||||
}
|
||||
return this.getYear() == date.getYear()
|
||||
&& this.getMonth() == date.getMonth()
|
||||
&& this.getDay() == date.getDay();
|
||||
}
|
||||
// 克隆当前日期对象
|
||||
public CalendarDate cloneSelf() {
|
||||
return new CalendarDate(year, month, day);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,152 @@
|
||||
package com.ldf.calendar.view;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
import com.ldf.calendar.Const;
|
||||
import com.ldf.calendar.Utils;
|
||||
import com.ldf.calendar.component.CalendarAttr;
|
||||
import com.ldf.calendar.component.CalendarRenderer;
|
||||
import com.ldf.calendar.interf.IDayRenderer;
|
||||
import com.ldf.calendar.interf.OnAdapterSelectListener;
|
||||
import com.ldf.calendar.interf.OnSelectDateListener;
|
||||
import com.ldf.calendar.model.CalendarDate;
|
||||
|
||||
@SuppressLint("ViewConstructor")
|
||||
public class Calendar extends View {
|
||||
/**
|
||||
* 日历列数
|
||||
*/
|
||||
private CalendarAttr.CalendarType calendarType;// 日历类型
|
||||
private int cellHeight; // 单元格高度
|
||||
private int cellWidth; // 单元格宽度
|
||||
|
||||
private OnSelectDateListener onSelectDateListener; // 单元格点击回调事件
|
||||
private Context context;// 上下文
|
||||
private CalendarAttr calendarAttr;// 日历属性
|
||||
private CalendarRenderer renderer;// 日历渲染器
|
||||
|
||||
private OnAdapterSelectListener onAdapterSelectListener;// 适配器选择监听器
|
||||
private float touchSlop; // 触摸阈值
|
||||
private float posX = 0;// 点击位置X坐标
|
||||
private float posY = 0;// 点击位置Y坐标
|
||||
// 构造函数
|
||||
public Calendar(Context context,
|
||||
OnSelectDateListener onSelectDateListener,
|
||||
CalendarAttr attr) {
|
||||
super(context);
|
||||
this.onSelectDateListener = onSelectDateListener;
|
||||
calendarAttr = attr;
|
||||
init(context);
|
||||
}
|
||||
// 初始化方法
|
||||
private void init(Context context) {
|
||||
this.context = context;
|
||||
touchSlop = Utils.getTouchSlop(context); // 获取触摸阈值
|
||||
initAttrAndRenderer();
|
||||
}
|
||||
// 初始化属性和渲染器
|
||||
private void initAttrAndRenderer() {
|
||||
renderer = new CalendarRenderer(this, calendarAttr, context);
|
||||
renderer.setOnSelectDateListener(onSelectDateListener);
|
||||
}
|
||||
// 绘制方法
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
renderer.draw(canvas);
|
||||
}
|
||||
// 大小改变时调用
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldW, int oldH) {
|
||||
super.onSizeChanged(w, h, oldW, oldH);
|
||||
cellHeight = h / Const.TOTAL_ROW;// 计算单元格高度
|
||||
cellWidth = w / Const.TOTAL_COL;// 计算单元格宽度
|
||||
calendarAttr.setCellHeight(cellHeight);
|
||||
calendarAttr.setCellWidth(cellWidth);
|
||||
renderer.setAttr(calendarAttr);
|
||||
}
|
||||
|
||||
/*
|
||||
* 触摸事件为了确定点击的位置日期
|
||||
*/
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
posX = event.getX();
|
||||
posY = event.getY();
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
float disX = event.getX() - posX;
|
||||
float disY = event.getY() - posY;
|
||||
if (Math.abs(disX) < touchSlop && Math.abs(disY) < touchSlop) {
|
||||
int col = (int) (posX / cellWidth);// 计算列索引
|
||||
int row = (int) (posY / cellHeight);// 计算行索引
|
||||
onAdapterSelectListener.cancelSelectState();
|
||||
renderer.onClickDate(col, row);// 调用渲染器处理点击事件
|
||||
onAdapterSelectListener.updateSelectState();
|
||||
invalidate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// 获取日历类型
|
||||
public CalendarAttr.CalendarType getCalendarType() {
|
||||
return calendarAttr.getCalendarType();
|
||||
}
|
||||
// 切换日历类型
|
||||
public void switchCalendarType(CalendarAttr.CalendarType calendarType) {
|
||||
calendarAttr.setCalendarType(calendarType);
|
||||
renderer.setAttr(calendarAttr);
|
||||
}
|
||||
// 获取单元格高度
|
||||
public int getCellHeight() {
|
||||
return cellHeight;
|
||||
}
|
||||
// 重置选中的行索引
|
||||
public void resetSelectedRowIndex() {
|
||||
renderer.resetSelectedRowIndex();
|
||||
}
|
||||
// 获取选中的行索引
|
||||
public int getSelectedRowIndex() {
|
||||
return renderer.getSelectedRowIndex();
|
||||
}
|
||||
// 设置选中的行索引
|
||||
public void setSelectedRowIndex(int selectedRowIndex) {
|
||||
renderer.setSelectedRowIndex(selectedRowIndex);
|
||||
}
|
||||
// 设置适配器选择监听器
|
||||
public void setOnAdapterSelectListener(OnAdapterSelectListener onAdapterSelectListener) {
|
||||
this.onAdapterSelectListener = onAdapterSelectListener;
|
||||
}
|
||||
// 显示指定日期
|
||||
public void showDate(CalendarDate current) {
|
||||
renderer.showDate(current);
|
||||
}
|
||||
// 更新星期数
|
||||
public void updateWeek(int rowCount) {
|
||||
renderer.updateWeek(rowCount);
|
||||
invalidate();
|
||||
}
|
||||
// 更新日历
|
||||
public void update() {
|
||||
renderer.update();
|
||||
}
|
||||
// 取消选中状态
|
||||
public void cancelSelectState() {
|
||||
renderer.cancelSelectState();
|
||||
}
|
||||
// 获取种子日期
|
||||
public CalendarDate getSeedDate() {
|
||||
return renderer.getSeedDate();
|
||||
}
|
||||
// 设置日期渲染器
|
||||
public void setDayRenderer(IDayRenderer dayRenderer) {
|
||||
renderer.setDayRenderer(dayRenderer);
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
package com.ldf.calendar.view;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.ldf.calendar.component.State;
|
||||
import com.ldf.calendar.model.CalendarDate;
|
||||
|
||||
/**
|
||||
* 表示日历中的某一天的状态和位置信息的类
|
||||
*/
|
||||
|
||||
public class Day implements Parcelable {
|
||||
public static final Parcelable.Creator<Day> CREATOR = new Parcelable.Creator<Day>() {
|
||||
@Override
|
||||
public Day createFromParcel(Parcel source) {
|
||||
return new Day(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Day[] newArray(int size) {
|
||||
return new Day[size];
|
||||
}
|
||||
};
|
||||
private State state;// 日期的状态
|
||||
private CalendarDate date;// 日期信息
|
||||
private int posRow;// 在日历中的行位置
|
||||
private int posCol;// 在日历中的列位置
|
||||
// 构造方法
|
||||
public Day(State state, CalendarDate date, int posRow, int posCol) {
|
||||
this.state = state;
|
||||
this.date = date;
|
||||
this.posRow = posRow;
|
||||
this.posCol = posCol;
|
||||
}
|
||||
// 从Parcel对象中读取数据以恢复Day对象的状态的构造方法
|
||||
protected Day(Parcel in) {
|
||||
int tmpState = in.readInt();
|
||||
this.state = tmpState == -1 ? null : State.values()[tmpState];
|
||||
this.date = (CalendarDate) in.readSerializable();
|
||||
this.posRow = in.readInt();
|
||||
this.posCol = in.readInt();
|
||||
}
|
||||
//获取和设置日期的状态、日期的信息,行列位置
|
||||
public State getState() {
|
||||
return state;
|
||||
}
|
||||
public void setState(State state) {
|
||||
this.state = state;
|
||||
}
|
||||
public CalendarDate getDate() {
|
||||
return date;
|
||||
}
|
||||
public void setDate(CalendarDate date) {
|
||||
this.date = date;
|
||||
}
|
||||
public int getPosRow() {
|
||||
return posRow;
|
||||
}
|
||||
public void setPosRow(int posRow) {
|
||||
this.posRow = posRow;
|
||||
}
|
||||
public int getPosCol() {
|
||||
return posCol;
|
||||
}
|
||||
public void setPosCol(int posCol) {
|
||||
this.posCol = posCol;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(this.state == null ? -1 : this.state.ordinal());
|
||||
dest.writeSerializable(this.date);
|
||||
dest.writeInt(this.posRow);
|
||||
dest.writeInt(this.posCol);
|
||||
}
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.shihoo.daemon" >
|
||||
|
||||
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
|
||||
|
||||
|
||||
<application
|
||||
android:label="@string/app_name"
|
||||
>
|
||||
<receiver
|
||||
android:name="com.shihoo.daemon.WakeUpReceiver"
|
||||
android:process=":watch">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.USER_PRESENT"/>
|
||||
<action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
|
||||
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<service android:name="com.shihoo.daemon.AbsWorkService$WorkNotificationService"/>
|
||||
|
||||
<!-- 广播接收者 receiver 进程-->
|
||||
<receiver
|
||||
android:name="com.shihoo.daemon.WakeUpReceiver$WakeUpAutoStartReceiver"
|
||||
android:process=":receiver">
|
||||
<!-- 手机启动 -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED"/>
|
||||
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
|
||||
</intent-filter>
|
||||
<!-- 软件安装卸载-->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.PACKAGE_ADDED"/>
|
||||
<action android:name="android.intent.action.PACKAGE_REMOVED"/>
|
||||
<data android:scheme="package"/>
|
||||
</intent-filter>
|
||||
<!-- 网络监听 -->
|
||||
<intent-filter>
|
||||
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
|
||||
<action android:name="android.net.wifi.WIFI_STATE_CJANGED"/>
|
||||
<action android:name="android.net.wifi.STATE_CHANGE"/>
|
||||
</intent-filter>
|
||||
<!-- 文件挂载 -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MEDIA_EJECT"/>
|
||||
<action android:name="android.intent.action.MEDIA_MOUNTED"/>
|
||||
<data android:scheme="file"/>
|
||||
</intent-filter>
|
||||
|
||||
</receiver>
|
||||
|
||||
|
||||
|
||||
<!-- 守护进程 watch -->
|
||||
<service
|
||||
android:name="com.shihoo.daemon.JobSchedulerService"
|
||||
android:permission="android.permission.BIND_JOB_SERVICE"
|
||||
android:enabled="true"
|
||||
android:exported="true"
|
||||
android:process=":watch"/>
|
||||
|
||||
<service
|
||||
android:name="com.shihoo.daemon.WatchDogService"
|
||||
android:process=":watch"/>
|
||||
|
||||
<service
|
||||
android:name="com.shihoo.daemon.WatchDogService$WatchDogNotificationService"
|
||||
android:process=":watch"/>
|
||||
|
||||
<activity
|
||||
android:name="com.shihoo.daemon.singlepixel.SinglePixelActivity"
|
||||
android:configChanges="keyboardHidden|orientation|screenSize|navigation|keyboard"
|
||||
android:excludeFromRecents="true"
|
||||
android:finishOnTaskLaunch="false"
|
||||
android:launchMode="singleInstance"
|
||||
android:theme="@style/SingleActivityStyle"
|
||||
android:process=":watch"/>
|
||||
|
||||
<service android:name=".PlayMusicService"
|
||||
android:process=":watch"/>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
@ -0,0 +1,32 @@
|
||||
package com.shihoo.daemon;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.ServiceConnection;
|
||||
import android.os.IBinder;
|
||||
|
||||
// 抽象类,用于定义服务连接的行为
|
||||
abstract class AbsServiceConnection implements ServiceConnection {
|
||||
|
||||
// 当前绑定的状态
|
||||
boolean mConnectedState = false;
|
||||
|
||||
// 当服务成功连接时调用
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
mConnectedState = true;
|
||||
}
|
||||
// 当服务断开连接时调用
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName name) {
|
||||
mConnectedState = false;
|
||||
onDisconnected(name);
|
||||
}
|
||||
|
||||
// 当绑定的服务死掉时调用,此时视为服务断开连接
|
||||
@Override
|
||||
public void onBindingDied(ComponentName name) {
|
||||
onServiceDisconnected(name);
|
||||
}
|
||||
// 子类必须实现的方法,用于处理服务断开连接的逻辑
|
||||
public abstract void onDisconnected(ComponentName name);
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
package com.shihoo.daemon;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.media.MediaPlayer;
|
||||
import android.os.Build;
|
||||
import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* Created by shihoo ON 2018/12/13.
|
||||
* Email shihu.wang@bodyplus.cc 451082005@qq.com
|
||||
*
|
||||
* 后台播放无声音乐
|
||||
*/
|
||||
public class PlayMusicService extends Service {
|
||||
|
||||
private boolean mNeedStop = false; //控制是否播放音频
|
||||
private MediaPlayer mMediaPlayer;
|
||||
private StopBroadcastReceiver stopBroadcastReceiver;
|
||||
|
||||
// private IBinder mIBinder;
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
// return mIBinder;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
// mIBinder = new Messenger(new Handler()).getBinder();
|
||||
|
||||
startRegisterReceiver();
|
||||
mMediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.no_notice);
|
||||
mMediaPlayer.setLooping(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
startPlayMusic();
|
||||
return START_STICKY;
|
||||
}
|
||||
|
||||
private void startPlayMusic(){
|
||||
if (mMediaPlayer!=null && !mMediaPlayer.isPlaying() && !mNeedStop) {
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Log.d("wsh-daemon", "开始后台播放音乐");
|
||||
mMediaPlayer.start();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
|
||||
private void stopPlayMusic() {
|
||||
if (mMediaPlayer != null) {
|
||||
Log.d("wsh-daemon", "关闭后台播放音乐");
|
||||
mMediaPlayer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
stopPlayMusic();
|
||||
Log.d("wsh-daemon", "----> stopPlayMusic ,停止服务");
|
||||
// 重启自己
|
||||
if (!mNeedStop) {
|
||||
Log.d("wsh-daemon", "----> PlayMusic ,重启服务");
|
||||
Intent intent = new Intent(getApplicationContext(), PlayMusicService.class);
|
||||
if (Build.VERSION.SDK_INT>Build.VERSION_CODES.O)startForegroundService(intent);
|
||||
else startService(intent);
|
||||
}
|
||||
}
|
||||
|
||||
private void startRegisterReceiver(){
|
||||
if (stopBroadcastReceiver == null){
|
||||
stopBroadcastReceiver = new StopBroadcastReceiver();
|
||||
IntentFilter intentFilter = new IntentFilter();
|
||||
intentFilter.addAction(DaemonEnv.ACTION_CANCEL_JOB_ALARM_SUB);
|
||||
registerReceiver(stopBroadcastReceiver,intentFilter);
|
||||
}
|
||||
}
|
||||
|
||||
private void startUnRegisterReceiver(){
|
||||
if (stopBroadcastReceiver != null){
|
||||
unregisterReceiver(stopBroadcastReceiver);
|
||||
stopBroadcastReceiver = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止自己
|
||||
*/
|
||||
private void stopService(){
|
||||
mNeedStop = true;
|
||||
startUnRegisterReceiver();
|
||||
stopSelf();
|
||||
}
|
||||
|
||||
class StopBroadcastReceiver extends BroadcastReceiver {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
stopService();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package com.shihoo.daemon;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
/**
|
||||
* WakeUpReceiver 是用于接收系统唤醒广播的接收器类。
|
||||
*/
|
||||
public class WakeUpReceiver extends BroadcastReceiver {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
// 当接收到系统唤醒广播时,启动 WatchDogService 服务
|
||||
DaemonEnv.startServiceSafely(context, WatchDogService.class,
|
||||
!WatchProcessPrefHelper.getIsStartDaemon(context));
|
||||
}
|
||||
|
||||
/**
|
||||
* WakeUpAutoStartReceiver 用于在应用启动时检查是否需要启动守护服务的接收器类。
|
||||
*/
|
||||
public static class WakeUpAutoStartReceiver extends BroadcastReceiver {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
// 在应用启动时检查是否需要启动守护服务,并启动 WatchDogService 服务
|
||||
DaemonEnv.startServiceSafely(context, WatchDogService.class,
|
||||
!WatchProcessPrefHelper.getIsStartDaemon(context));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
package com.shihoo.daemon.sync;
|
||||
|
||||
import android.accounts.AbstractAccountAuthenticator;
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountAuthenticatorResponse;
|
||||
import android.accounts.AccountManager;
|
||||
import android.accounts.NetworkErrorException;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
public class Authenticator extends AbstractAccountAuthenticator {
|
||||
|
||||
final Context context;
|
||||
|
||||
public Authenticator(Context context) {
|
||||
super(context);
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
// 添加账户
|
||||
@Override
|
||||
public Bundle addAccount(AccountAuthenticatorResponse response,
|
||||
String accountType, String authTokenType,
|
||||
String[] requiredFeatures, Bundle options)
|
||||
throws NetworkErrorException {
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,
|
||||
response);
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
|
||||
return bundle;
|
||||
}
|
||||
|
||||
// 确认凭据
|
||||
@Override
|
||||
public Bundle confirmCredentials(AccountAuthenticatorResponse response,
|
||||
Account account, Bundle options) throws NetworkErrorException {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 编辑属性
|
||||
@Override
|
||||
public Bundle editProperties(AccountAuthenticatorResponse response,
|
||||
String accountType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 获取访问令牌
|
||||
@Override
|
||||
public Bundle getAuthToken(AccountAuthenticatorResponse response,
|
||||
Account account, String authTokenType, Bundle options)
|
||||
throws NetworkErrorException {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 获取访问令牌标签
|
||||
@Override
|
||||
public String getAuthTokenLabel(String authTokenType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 是否具有指定特性
|
||||
@Override
|
||||
public Bundle hasFeatures(AccountAuthenticatorResponse response,
|
||||
Account account, String[] features)
|
||||
throws NetworkErrorException {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 更新凭据
|
||||
@Override
|
||||
public Bundle updateCredentials(AccountAuthenticatorResponse response,
|
||||
Account account, String authTokenType, Bundle options)
|
||||
throws NetworkErrorException {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.shihoo.daemon.sync;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
|
||||
public class SyncService extends Service {
|
||||
// 静态的同步适配器对象
|
||||
private static SyncAdapter sSyncAdapter = null;
|
||||
// 同步锁对象
|
||||
private static final Object sSyncAdapterLock = new Object();
|
||||
|
||||
public SyncService() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
synchronized (sSyncAdapterLock) {
|
||||
// 在服务创建时,实例化同步适配器对象并进行同步操作
|
||||
sSyncAdapter = new SyncAdapter(getApplicationContext(), true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
// 返回同步适配器的 Binder 对象
|
||||
return sSyncAdapter.getSyncAdapterBinder();
|
||||
}
|
||||
}
|
Binary file not shown.
@ -0,0 +1,3 @@
|
||||
<resources>
|
||||
<string name="app_name">deamon</string>
|
||||
</resources>
|
@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<style name="SingleActivityStyle" parent="android:Theme.Holo.Light.NoActionBar">
|
||||
|
||||
<item name="android:windowBackground">@android:color/transparent</item>
|
||||
<item name="android:windowFrame">@null</item>
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
<item name="android:windowIsFloating">true</item>
|
||||
<item name="android:windowContentOverlay">@null</item>
|
||||
<item name="android:backgroundDimEnabled">false</item>
|
||||
<item name="android:windowAnimationStyle">@null</item>
|
||||
<item name="android:windowDisablePreview">true</item>
|
||||
<item name="android:windowNoDisplay">false</item>
|
||||
|
||||
</style>
|
||||
</resources>
|
Loading…
Reference in new issue