Android 学习监督app开发

“Study”app介绍

这是本学期的一个大作业,简单记录一下,还有很多不足。
首先感谢博主 “请叫我大苏” ,正是在他的基础上我完成了这个不成熟的app
https://www.cnblogs.com/dasusu/p/5470635.html

实现极简番茄时钟:https://www.ctolib.com/topics-123941.html

一、开发说明

开发工具:AndroidStudio

sdk版本号

minSdkVersion 15
targetSdkVersion 29

二、 主要功能

1、强制学习功能

1.1 说明

开启start按钮后程序启动,当你点击非系统app和本app,就会触发闪退功能,同时弹出toast,奉上精辟的短句。

1.2 实现

Android 辅助功能(AccessibilityService) 为我们提供了一系列的事件回调,帮助我们指示一些用户界面的状态变化。 我们可以派生辅助功能类,进而对不同的 AccessibilityEvent 进行处理。 同样的,这个服务就可以用来判断当前的前台应用。判断完打开了什么app后,只要模拟“home”键效果,就能制造闪退功能。同时连接网上的”精辟短句“接口,跳出toast就完成。

注:需要要用户开启辅助功能

1.3 代码

派生 ACCESSIBILITY SERVICE,创建窗口状态探测服务

public class DetectService extends AccessibilityService {

    private static String mForegroundPackageName;
    private static DetectService mInstance = null;
    private NotificationManager mNotificationManager;
    private PendingIntent pendingIntent;
    private Intent mIntent;
    private NotificationCompat.Builder mBuilder;
    private Context mContext;
    private Notification notification;
    private static final int NOTICATION_ID = 0x1;

    public DetectService() {
    }

    public static DetectService getInstance() {
        if (mInstance == null) {
            synchronized (DetectService.class) {
                if (mInstance == null) {
                    mInstance = new DetectService();
                }
            }
        }
        return mInstance;
    }
    /**
     * 监听窗口焦点,并且获取焦点窗口的包名,并进行判断
     *
     */
    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
            if (Features.showForeground) {
                mForegroundPackageName = event.getPackageName().toString();
                PackageManager pckMan = getPackageManager();
                List<PackageInfo> packs = pckMan.getInstalledPackages(0);
                int count = packs.size();
                int installedNum = 0;
                for (int i = 0; i < count; i++) {
                    //判断是否为系统app和自身
                    PackageInfo p = packs.get(i);
                    if (p.packageName.equals(mForegroundPackageName)) {

                        ApplicationInfo appInfo = p.applicationInfo;

                        if ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) > 0) {
                            Log.d("study", "系统" + mForegroundPackageName);
                        } else if (p.packageName.equals("com.example.w.study")) {
                            Log.d("study", "我自己" + mForegroundPackageName);
                        } else {
                            Log.d("study", "外界" + mForegroundPackageName);
                            Intent intent = new Intent();
                            intent.setPackage(getPackageName());
                            intent.setAction("org.crazyit");
                            intent.putExtra("msg", "home");
                            sendBroadcast(intent);
                            Log.d("study", "发射");
                        }
                    }
                }

            }
        }
    }


    @Override
    public void onInterrupt() {
    }

    public String getForegroundPackage() {
        return mForegroundPackageName;
    }


    /**
     * 此方法用来判断当前应用的辅助功能服务是否开启
     *
     */
    public static boolean isAccessibilitySettingsOn(Context context) {
        int accessibilityEnabled = 0;
        try {
            accessibilityEnabled = Settings.Secure.getInt(context.getContentResolver(),
                    android.provider.Settings.Secure.ACCESSIBILITY_ENABLED);
        } catch (Settings.SettingNotFoundException e) {
            Log.d("study", e.getMessage());
        }

        if (accessibilityEnabled == 1) {
            String services = Settings.Secure.getString(context.getContentResolver(),
                    Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
            if (services != null) {
                return services.toLowerCase().contains(context.getPackageName().toLowerCase());
            }
        }
        return false;
    }

}

模拟“home"键效果

public class MyService  extends Service {
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    public void onCreate() {
        super.onCreate();
        Log.d("study", "home");
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.addCategory(Intent.CATEGORY_HOME);
        startActivity(intent);

    }
}

判断应用是否在前台

public  boolean getFromAccessibilityService(Context context, String packageName) {
        if (DetectService.isAccessibilitySettingsOn(context) == true) {
            Log.d("study", "开始" );
           detectService = DetectService.getInstance();
            foreground = detectService.getForegroundPackage();
            Log.d("study", "**方法五** App处于" + foreground);

            return foreground.equals(packageName);
        } else {
         //打开辅助功能,引导至辅助功能设置页面
            Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(intent);
            Toast.makeText(context, com.example.w.study.R.string.accessbiliityNo, Toast.LENGTH_SHORT).show();
            return false;
        }
    }

2、倒计时功能和学习记录

2.1说明

用户可以为自己学习时间立一个倒计时,app将记录时间

2.2 实现

自定义view,用数据库记录每次时间,存入时每次更新最近7天记录,每次调取时取最近七天数据,柱状图绘制是导入了网上一个包。

2.3 代码

自定义view

public class ClockView extends View {
    private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private Paint timePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private int mColor = Color.parseColor("#D1D1D1");
    private int centerX;
    private int centerY;
    private int radius;
    private RectF mRectF = new RectF();
    public static final float START_ANGLE = -90;
    public static final int MAX_TIME = 60;
    private float sweepVelocity = 0;
    private String textTime = "00:00";
    private DBHelper dbHelper;
    //分钟
    private int time;
    //倒计时
    private int countdownTime;
    private float touchX;
    private float touchY;
    private float offsetX;
    private float offsetY;
    private boolean isStarted;
    private Context context;

    public ClockView(Context context) {
        super(context);
        dbHelper = DBHelper.getInstance(context);
    }

    public ClockView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        dbHelper = DBHelper.getInstance(context);
        this.context=context;
    }

    public ClockView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

    }
    //存入数据库
    protected void saveToDBhelper()
    {
        String date;
        for(int i=-7;i<=-1;i++)
        {
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.DATE, i);
            Date dat = calendar.getTime();
            date=(dat.getYear()+1900)+"年"+(dat.getMonth()+1)+"月"+dat.getDate()+"日";
            dbHelper.insertData(date,0);
        }
        date=(new Date().getYear()+1900)+"年"+(new Date().getMonth()+1)+"月"+new Date().getDate()+"日";
        dbHelper.insertData(date,time);
    }

    public static float dpToPixel(float dp) {
        DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
        return dp * metrics.density;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        int width = MeasureSpec.getSize(widthMeasureSpec);
        centerX = width / 2;
        centerY = height / 2;
        radius = (int) dpToPixel(120);
        setMeasuredDimension(width, height);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mRectF.set(centerX - radius, centerY - radius, centerX + radius, centerY + radius);
        //黑圆
        canvas.save();
        mPaint.setColor(Color.BLACK);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(dpToPixel(5));
        canvas.drawCircle(centerX, centerY, radius, mPaint);
        canvas.restore();
        //灰圆
        canvas.save();
        mPaint.setColor(mColor);
        canvas.drawArc(mRectF, START_ANGLE, 360 * sweepVelocity, false, mPaint);
        canvas.restore();
        //时间
        canvas.save();
        timePaint.setColor(Color.BLACK);
        timePaint.setStyle(Paint.Style.FILL);
        timePaint.setTextSize(dpToPixel(40));
        canvas.drawText(textTime, centerX - timePaint.measureText(textTime) / 2,
                centerY - (timePaint.ascent() + timePaint.descent()) / 2, timePaint);
        canvas.restore();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (isStarted) {
            return true;
        }
        float x = event.getX();
        float y = event.getY();
        boolean isContained = isContained(x, y);
        switch (event.getActionMasked()) {
            case MotionEvent.ACTION_DOWN:
                if (isContained) {
                    touchX = x;
                    touchY = y;
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if (isContained) {
                    offsetX = x - touchX;
                    offsetY = y - touchY;
                    time = (int) (offsetY / 2 / radius * MAX_TIME);
                    if (time <= 0) {
                        time = 0;
                    }
                    textTime = formatTime(time);
                    countdownTime = time * 60;
                    invalidate();
                }
                break;
        }
        return true;
    }

    private boolean isContained(float x, float y) {
        if (Math.sqrt((x - centerX) * (x - centerX) + (y - centerY) * (y - centerY)) > radius) {
            return false;
        } else {
            return true;
        }
    }

    private String formatTime(int time) {
        StringBuilder sb = new StringBuilder();
        if (time < 10) {
            sb.append("0" + time + ":00");
        } else {
            sb.append(time + ":00");
        }
        return sb.toString();
    }

    private String formatCountdownTime(int countdownTime) {
        StringBuilder sb = new StringBuilder();
        int minute = countdownTime / 60;
        int second = countdownTime - 60 * minute;
        if (minute < 10) {
            sb.append("0" + minute + ":");
        } else {
            sb.append(minute + ":");
        }
        if (second < 10) {
            sb.append("0" + second);
        } else {
            sb.append(second);
        }
        return sb.toString();
    }
    //先画一个黑圆以及显示时间文本,传入一个时间值后,可以实现倒计时功能。
    // 实现倒计时需要用到CountDownTimer,因此只要在该类的onTick中不断重绘就行了
    public void start(){
        if (countdownTime == 0 || isStarted) {
            return;
        }
        isStarted = true;
        ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1.0f);
        valueAnimator.setDuration(countdownTime * 1000);
        valueAnimator.setInterpolator(new LinearInterpolator());
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                sweepVelocity = (float) animation.getAnimatedValue();
                mColor = Color.parseColor("#D1D1D1");
                invalidate();
            }
        });
        valueAnimator.start();

        new CountDownTimer(countdownTime * 1000 + 1000, 1000) {
            @Override
            public void onTick(long millisUntilFinished) {
                countdownTime = (countdownTime * 1000 - 1000) / 1000;
                textTime = formatCountdownTime(countdownTime);
                invalidate();
            }

            @Override
            public void onFinish() {
                mColor = Color.BLACK;
                sweepVelocity = 0;
                isStarted = false;
                invalidate();
            }
        }.start();
        saveToDBhelper();
        dbHelper.close();

    }

}

数据库

public class DBHelper extends SQLiteOpenHelper {
    //表名
    private static String TableName = "times";
    //数据库名
    private static String DBName = "test.db";
    //数据库版本号
    private static int DBVersion = 1;
    private Context context;
    //数据库实例
    private SQLiteDatabase database;
    //此类自己的实例
    public static DBHelper dbHelper;
    //创建数据库的语句
    private String createDBSql =
            "create table times ("
                    + "tododate String primary key , "
                    + "todotime int)";

    public DBHelper(Context context){
        super(context, DBName, null, DBVersion);
        this.context = context;
    }

    //DBHepler单例模式,节省资源,防止访问冲突
    public static synchronized DBHelper getInstance(Context context){
        if(dbHelper == null){
            dbHelper = new DBHelper(context);
        }
        return dbHelper;
    }
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(createDBSql);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            db.execSQL("drop table if exists times");
            onCreate(db);

    }

    //插入数据,使用ContentValues方式传入
    public void insertData(String date, int time){
        ContentValues contentValues = new ContentValues();
        database = getWritableDatabase();
        if(findByDate(date)!=0) {
            time += findByDate(date);
            database.delete(TableName,"tododate=?",new String[]{date});
        }
        contentValues.put("tododate",date);
        contentValues.put("todotime", time);
            database.insert(TableName, null, contentValues);
    }

    public  boolean delete(String da) {
        database = getReadableDatabase();
        database.delete(TableName, "tododate=?", new String[] { da });
        return true;
    }
    int findByDate(String date)
    {
        database = getReadableDatabase();
        String selectSql = "select * from times where tododate ='"+date +"'";
//        Toast.makeText(context, selectSql, Toast.LENGTH_SHORT).show();
        Cursor cursor = database.rawQuery(selectSql, null);
        while (cursor.moveToNext()){
//           Toast.makeText(context, "找到了", Toast.LENGTH_SHORT).show();
           return cursor.getInt(cursor.getColumnIndex("todotime"));
        }
//        Toast.makeText(context, "没找到", Toast.LENGTH_SHORT).show();
        return 0;
    }

    //查询最近七天数据
    public List<Map<String, Integer>> queryAll(){
        List<Map<String,Integer>> list = new ArrayList<Map<String,Integer>>();
        //这里需要可读的数据库
        database = getReadableDatabase();
        Cursor cursor = database.query(TableName, null, null, null, null, null, null, null);
        if (cursor.getCount() > 0) {
            int j=1;
            cursor.moveToLast();
            Map<String, Integer> map = new HashMap<String, Integer>();
            map.put(cursor.getString(cursor.getColumnIndex("tododate")), cursor.getInt(cursor.getColumnIndex("todotime")));
            list.add(map);
            while (cursor.moveToPrevious()&&j<7){
                 map = new HashMap<String, Integer>();
                map.put(cursor.getString(cursor.getColumnIndex("tododate")), cursor.getInt(cursor.getColumnIndex("todotime")));
                list.add(map);
                j++;
            }
        }
        return list;
    }

}

3、设置计划并提醒功能

3.1 说明

用户可以自己设定时间计划和提醒时间

3.2 实现

调用DatePickerDialog实现时间选择器,通过监听其选择的时间进行闹钟设置

1.获取系统服务

  1. 创建PendingIntent

    3、 设置闹钟,到时间就唤醒

    4、闹钟触发是震动20秒在 AlarmReceiver中实现,并用toast提示事件

3.3 代码

获取系统服务:

public class ClockManager {
    private static ClockManager instance = new ClockManager();

    private ClockManager() {
    }

    public static ClockManager getInstance() {
        return instance;
    }

    /**
     * 获取系统闹钟服务
     */
    private static AlarmManager getAlarmManager() {
        return (AlarmManager) MemoApplication.getContext().getSystemService(Context.ALARM_SERVICE);
    }

    /**
     * 取消闹钟
     */
    public void cancelAlarm(PendingIntent pendingIntent) {
        getAlarmManager().cancel(pendingIntent);
    }

    /**
     * 添加闹钟
     */
    public void addAlarm(PendingIntent pendingIntent, Date performTime) {
        cancelAlarm(pendingIntent);
        getAlarmManager().set(AlarmManager.RTC_WAKEUP, performTime.getTime(), pendingIntent);
    }
}

数据库

public class MySQLiteOpenHelper extends SQLiteOpenHelper {

    private static String TableName = "clock";
    //数据库名
    private static String DBName = "clock.db";
    //数据库版本号
    private static int DBVersion = 1;
    private Context context;
    //数据库实例
    private SQLiteDatabase database;
    //此类自己的实例
    public static MySQLiteOpenHelper  mySQLiteOpenHelper ;
    //创建数据库的语句
    private String createDBSql =
            "create table clock("
                    + " id varchar(16) primary key ,"
                    + "things varchar(80),"
                    + " update_time varchar(16))";
    public  MySQLiteOpenHelper (Context context){
        super(context, DBName, null, DBVersion);
        this.context = context;
    }

    public static synchronized MySQLiteOpenHelper getInstance(Context context){
        if(mySQLiteOpenHelper == null){
            mySQLiteOpenHelper = new MySQLiteOpenHelper(context);
        }
        return mySQLiteOpenHelper;
    }
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(createDBSql);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("drop table if exists clock");
        onCreate(db);

    }

    @SuppressLint("SimpleDateFormat")
    public String addClock(String dateTime,String thing) {
        database = getWritableDatabase();
        ContentValues values = new ContentValues();
        String id = dateTime;
        values.put("id", id);
        values.put("things", thing);
        values.put("update_time", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        database .insert("clock", null, values);
        return id;
    }

    public  boolean deleteClock(String id) {
        database = getReadableDatabase();
        database.delete("clock", "id=?", new String[] { id});
        return true;
    }


    public  boolean updateClock(Integer id,String isRapeat,MySQLiteOpenHelper dbOpenHelper) {
        SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
        ContentValues values = new ContentValues();
        db.update("clock", values,"id=?", new String[] { id.toString() });
        return true;
    }

    public  List<MyClock> getClockList(){

        database = getReadableDatabase();
        Cursor cursor = database.query(TableName, null, null, null, null, null, null, null);
        List<MyClock> clockList = new ArrayList<MyClock>();
       if (cursor.getCount() > 0) {
            while (cursor.moveToNext()) {
                clockList.add(new MyClock(cursor.getString(cursor.getColumnIndex("id")),
                        cursor.getString(cursor.getColumnIndex("things")),
                        cursor.getString(cursor.getColumnIndex("update_time"))));
            }
        }
        return clockList;
    }



}


显示已定的计划

public class ClockActivity extends Activity {


    AlarmManager alarmManager = null;
    Calendar calendar = Calendar.getInstance();
    private MySQLiteOpenHelper mySQLiteOpenHelper;
    private List<Map<String, Object>> listems = new ArrayList<Map<String, Object>>();
    private String[]ids,thing;
    private MyAdapter myAdapter;
    private  Button deleteButton;
    private Button addButton;
    private ListView listView;
    private ClockManager mClockManager = ClockManager.getInstance();
    private ImageView imageView;

    private class MyAdapter extends BaseAdapter {

        @Override
        public int getCount() {
            return  Ids.length;
        }

        @Override
        public Object getItem(int position) {
            return position;
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            ViewSet viewSet = null;
            if (convertView == null) {
                viewSet = new ViewSet();
                convertView = LayoutInflater.from(getApplication()).inflate(R.layout.my_clock_list, null);
                viewSet.clockView = (TextView) convertView.findViewById(R.id.my_clock);
                viewSet.thingsView = (TextView) convertView.findViewById(R.id.my_things);
                viewSet.checkBox = (CheckBox) convertView.findViewById(R.id.listview_item_checkbox);
                convertView.setTag(viewSet);
            } else {
                viewSet = (ViewSet) convertView.getTag();
            }
            viewSet.clockView.setText( Ids[position]);
            viewSet.thingsView.setText(things[position]);
            viewSet.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    if (isChecked) {
                        checkedArray[position] = true;
                        checkedNum++;
                        if (checkedNum == 1) {
                            button.setEnabled(true);
                        }
                    } else {
                        checkedArray[position] = false;
                        checkedNum--;
                        if (checkedNum == 0) {
                            button.setEnabled(false);
                        }
                    }
                }
            });
            return convertView;
        }
        private class ViewSet{
            TextView clockView;
            TextView thingsView;
            CheckBox checkBox;
        }
        private String[] things;
        private int checkedNum = 0;
        private Button button;
        private boolean[] checkedArray;
        private String[] Ids;
        private Context context;

        public MyAdapter(Context context,String[] things,String[] Ids, Button button){
            this.context=context;
            this.button = button;
            this.Ids = Ids;
            this.things=things;
            this.checkedArray = new boolean[ Ids.length];
            for(int i=0;i< Ids.length;i++) {
                this.checkedArray[i] = false;
            }
        }
        public String[] getChecked(){
            List<String> checkedList = new ArrayList<String>();
            for(int i=0;i<checkedArray.length;i++){
                if(checkedArray[i] == true){
                    checkedList.add(Ids[i]);
                }
            }
            String[] checkedArray = new String[checkedList.size()];
            return checkedList.toArray(checkedArray);
        }
    }

    private void changeAdapter(List<Map<String, Object>>list){
        ids = new String[list.size()];
        thing=new String[list.size()];
        for(int i=0;i<list.size();i++){
            ids[i] = list.get(i).get("id").toString();
            thing[i]= list.get(i).get("things").toString();
        }
        myAdapter = new MyAdapter(ClockActivity.this,thing,ids, deleteButton);
        listView.setAdapter(myAdapter);
    }
    public List<Map<String, Object>> getClockList(){
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        Map<String, Object> map = null;
        List<MyClock> clocks = mySQLiteOpenHelper.getClockList();
        for (MyClock myClock : clocks) {
            map = new HashMap<String, Object>();
            map.put("id",myClock.getId());
            map.put("things", myClock.getThings()) ;
            list.add(map);
        }
        return list;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.clock_layout);

        mySQLiteOpenHelper = MySQLiteOpenHelper.getInstance(ClockActivity.this);
        alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        deleteButton = (Button)findViewById(R.id.delete_button);
        addButton=(Button)findViewById(R.id.setclock);
        listView = (ListView)findViewById(R.id.clocklist);
        imageView=findViewById(R.id.iv_back);
        imageView.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
                 finish();
             }
        });
        if(getClockList().size()>0) {
            changeAdapter(getClockList());
        }


        deleteButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String[] result = myAdapter.getChecked();
                for(int i=0; i<result.length; i++){
                    mySQLiteOpenHelper.deleteClock(result[i]);
                    Intent intent = new Intent(ClockActivity.this,ClockReceiver.class);    //创建Intent对象
                    intent.setAction(result[i]);//作为取消时候的标识
                    PendingIntent pi = PendingIntent.getBroadcast(ClockActivity.this, 1,
                            intent, PendingIntent.FLAG_CANCEL_CURRENT);    //创建PendingIntent
                    mClockManager.cancelAlarm(pi);
                }
                changeAdapter( getClockList());

            }
        });
        addButton. setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                Intent intent = new Intent(ClockActivity.this, AddActivity.class);
                Bundle bundle = new Bundle();
                intent.putExtras(bundle);
                startActivityForResult(intent, 0);

            }
        });

    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 0 && resultCode == Activity.RESULT_OK) {
            if(getClockList().size()>0) {
                changeAdapter( getClockList());
            }
        }
    }


}

添加计划

public class AddActivity extends Activity  {
    EditText tvRemindTime;
    EditText ed_title;
    private MySQLiteOpenHelper mySQLiteOpenHelper;
    TextView textView;

    private AlarmManager alarmManager=null;
    private ClockManager mClockManager = ClockManager.getInstance();
    public static final String DEFAULT_TIME_FORMAT = "yyyy-MM-dd HH:mm";
    ImageView imageView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.add_clock);

        mySQLiteOpenHelper = MySQLiteOpenHelper.getInstance(AddActivity.this);
        tvRemindTime = findViewById(R.id.tv_remind_time_picker);
        ed_title=findViewById(R.id.ed_title);
        textView=findViewById(R.id.tv_confirm);
        imageView=findViewById(R.id.iv_back);
        imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });

        tvRemindTime .setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                final Calendar calendar = Calendar.getInstance();
                DatePickerDialog dialog = new DatePickerDialog(AddActivity.this, new DatePickerDialog.OnDateSetListener() {
                    @Override
                    public void onDateSet(DatePicker view, final int year, final int month, final int dayOfMonth) {
                        TimePickerDialog timePickerDialog = new TimePickerDialog(AddActivity.this, new TimePickerDialog.OnTimeSetListener() {
                            @Override
                            public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
                                String time = year + "-" + StringUtil.getLocalMonth(month) + "-" + StringUtil.getMultiNumber(dayOfMonth) + " " + StringUtil.getMultiNumber(hourOfDay) + ":" + StringUtil.getMultiNumber(minute);
                                tvRemindTime.setText(time);
                            }
                        }, calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), false);
                        timePickerDialog.show();
                    }
                }, calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH));
                dialog.getDatePicker().setMinDate(calendar.getTimeInMillis());
                dialog.show();
            }
        });


        textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//                Toast.makeText(AddActivity.this, "添加中", Toast.LENGTH_SHORT).show();
                String time=tvRemindTime.getText().toString();
                String thing=ed_title.getText().toString()+"";
//                Toast.makeText(AddActivity.this, time, Toast.LENGTH_SHORT).show();
                Intent intent = new Intent(AddActivity.this,ClockReceiver.class);   //创建Intent对象
                intent.setAction(time);//作为取消时候的标识
                Bundle bundle = new Bundle();
                bundle.putString("thing", thing);
                intent.putExtras(bundle);
                PendingIntent pi = PendingIntent.getBroadcast(AddActivity.this, 1,
                        intent, PendingIntent.FLAG_CANCEL_CURRENT);    //创建PendingIntent
                mClockManager.addAlarm(pi, str2Date(time));
                mySQLiteOpenHelper.addClock(time,thing);
                Intent intent2 = getIntent();
                setResult(AppCompatActivity.RESULT_OK, intent2);
                Toast.makeText(AddActivity.this, "添加成功", Toast.LENGTH_SHORT).show();
                finish();
            }
        });

    }
    public static Date str2Date(String src)  {
        SimpleDateFormat sdf = new SimpleDateFormat(DEFAULT_TIME_FORMAT, Locale.CHINA);
        try {
            return sdf.parse(src);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }


}

提醒部分

public class ClockReceiver extends BroadcastReceiver{

   
    @Override
    public void onReceive(Context context, Intent intent) {
        WakeLockUtil.wakeUpAndUnlock();
        Bundle bundle = intent.getExtras();
        String thing=bundle.getString("thing");
        Toast toast = Toast.makeText(context, thing, Toast.LENGTH_LONG);
        toast.setGravity(Gravity.CENTER,0,0);
        toast.show();
        VibrateUtil.vibrate(context, 20000);
    }

}

4、更换背景

4.1 说明

更换主页面壁纸

image-20200507101310293
4.2 实现

用SharedPreferences记录图片

4.3 代码
public class BackGround extends Activity implements View.OnClickListener {
    private int drawableArray[] = { R.drawable.ic_img4, R.drawable.ic_img6, R.drawable.ic_img11,
            R.drawable.ic_img8, R.drawable.ic_img2, R.drawable.ic_img7, R.drawable.ic_img10,
            R.drawable.ic_img3, R.drawable.ic_img5 , R.drawable.ic_img12};
    List<HashMap<String, Object>> list = new ArrayList<HashMap<String, Object>>();

    private Button lastPhoto;
    private Button nextPhoto;
    private Button selectPhoto;
    private ImageButton backButton;
    private ImageView displayPhoto;
    private ImageView imageView;

    //显示当前图片的索引
    private int photoIndex = 0;
    //图片索引最大值(图片数-1)
    private int maxIndex = 9;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_background);
        //初始化
        imageView=findViewById(R.id.iv_back);
        imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
        init();
    }

    /**
     * 控件初始化
     */
    private void init() {
        lastPhoto = findViewById(R.id.lastPhoto);
        lastPhoto.setOnClickListener( BackGround.this);
        selectPhoto=findViewById(R.id.select);
        selectPhoto.setOnClickListener(BackGround.this);
        nextPhoto = findViewById(R.id.nextPhoto);
        nextPhoto.setOnClickListener( BackGround.this);
        displayPhoto = findViewById(R.id.displayPhoto);

//        backButton=findViewById(R.id.back_button);
//        backButton.setOnClickListener(BackGround.this);
    }

    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.lastPhoto:
                //如果当前图片是第一张,则上一张图片为最后一张图片
                if (photoIndex == 0) {
                    photoIndex = maxIndex;
                } else {
                    //否则改为上一张图片索引
                    photoIndex = photoIndex - 1;
                }
                break;
            case R.id.nextPhoto:
                //如果当前图片是最后一张,则下一张图片为第一张图片
                if (photoIndex == maxIndex) {
                    photoIndex = 0;
                } else {
                    //否则改为下一张图片索引
                    photoIndex = photoIndex + 1;
                }
                break;
            case R.id.select:
                Intent intent = getIntent();
                Bundle bundle = intent.getExtras();
                bundle.putInt("data",drawableArray[photoIndex]);
                intent.putExtras(bundle);
                setResult(AppCompatActivity.RESULT_OK, intent);
                finish();
//            case  R.id.back_button:
            default:
                break;
        }
        //显示图片
        displayPhoto.setImageResource(drawableArray[photoIndex]);
    }

}

//打开Preferences,名称为data,如果存在则打开它,否则创建新的Preferences
        SharedPreferences pref = getSharedPreferences("data",MODE_PRIVATE);
        int background = pref.getInt("background",0);
        Log.d("study", "background"+background);
        linearLayout=findViewById(R.id.bg);
        if(background==0)
             linearLayout.setBackgroundResource(Features.backGrounds);
        else {
            linearLayout.setBackgroundResource(background);
            Features.backGrounds = background;
           }

三、难点

3.1 监控程序

方法:在git上找到一个项目可以监控前台程序,项目提出六种方法,考虑到Android 辅助功能(AccessibilityService) 是是一个稳定的方法,它并非利用 Android 一些设计上的漏洞,可以长期使用的可能很大 ,并且覆盖范围广,选择了这个方法。

3.2 实现关掉其他app的功能

方法:在网上没有相关方法,跟老师交流完知道不可行。后来用模拟“home"键效果直接返回桌面实现类似效果

3.3 关闭程序

方法:一开始发现关闭app后,继承AccessibilityService的DetectService 会自己运行,导致依然无法打开其他app。后来在DetectService里加了个判断当前app是否存活,MainActivity里onDestroy()方法设置为否

//设定全局变量
public class Features {
    public static boolean showForeground = false;
    public static int  backGrounds = R.drawable.ic_img2;
}

//MainActivity里onCreate设置true,onDestroy()方法设置为false
protected void onCreate(Bundle savedInstanceState) {
        Features.showForeground = true;
}
protected void onDestroy() {
        Features.showForeground = false;
        super.onDestroy();
}
    







评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值