Android开发之闹钟

闹钟开发:

1、需要时间选择器TimePicker

2、需要Calendar类对日期时间进行操作

3、需要AlarmManager//闹钟管理实质是一个全局定时器, 是Android中常用的一种系统级别的提示服务,在指定时间或周期性启动其它组件(包括Activity,Service,BroadcastReceiver)。

4、PendingIntent的理解

PendingIntent 可以看作是对intent的包装,通常通过getActivity,getBroadcast ,getService来得到pendingintent的实例,当前activity并不能马上启动它所包含的intent,而是在外部执行 pendingintent时,调用intent的。正由于pendingintent中 保存有当前App的Context,使它赋予外部App一种能力,使得外部App可以如同当前App一样的执行pendingintent里的 Intent, 就算在执行时当前App已经不存在了,也能通过存在pendingintent里的Context照样执行Intent。另外还可以处理intent执行后的操作。常和alermanger 和notificationmanager一起使用。 
Intent一般是用作Activity、Sercvice、BroadcastReceiver之间传递数据,而Pendingintent,一般用在 Notification上,可以理解为延迟执行的intent,PendingIntent是对Intent一个包装。

PendingIntent参数

public static PendingIntent getBroadcast(Context context, int requestCode, Intent intent, int flags)

public static PendingIntent getActivity(Context context, int requestCode, Intent intent, int flags)

public static PendingIntent getService(Context context, int requestCode, Intent intent, int flags)

第一个参数为当前Activity.this

第二个参数为请求码,可通过第二个参数判断是哪个PendingIntent。(一般认为没有作用)

第三个参数较为复杂:

FLAG_CANCEL_CURRENT:如果当前系统中已经存在一个相同的PendingIntent对象,那么就将先将已有的PendingIntent取消,然后重新生成一个PendingIntent对象。

FLAG_NO_CREATE:如果当前系统中不存在相同的PendingIntent对象,系统将不会创建该PendingIntent对象而是直接返回null。

FLAG_ONE_SHOT:该PendingIntent只作用一次。在该PendingIntent对象通过send()方法触发过后,PendingIntent将自动调用cancel()进行销毁,那么如果你再调用send()方法的话,系统将会返回一个SendIntentException。

FLAG_UPDATE_CURRENT:如果系统中有一个和你描述的PendingIntent对等的PendingInent,那么系统将使用该PendingIntent对象,但是会使用新的Intent来更新之前PendingIntent中的Intent对象数据,例如更新Intent中的Extras。

FLAG_CANCEL_CURRENT和FLAG_UPDATE_CURRENT的区别在于能否新new一个Intent,FLAG_CANCEL_CURRENT能够新new一个Intent,而FLAG_UPDATE_CURRENT则不能,只能使用第一次的Intent。 还有一个问题就是怎么区分PendingIntent,主要取消的时候要用到,requestCode可以区分,但系统还是根据Intent的Action去区分的,如果Intent设置了Class,classData,取消的时候Intent一定要设置要相同的,不然取消不掉就可能出现取消后,Alarm还会响的问题

1、TimePicker与Calendar的用法

TimePicker一个可以选取时间的控件,对其设置监听获得所选的时间

 1  MainActivity.this.tp.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() {
 2             @Override
 3             public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
 4                 MainActivity.this.calendar = Calendar.getInstance();//获得一个Calendar的实例
 5                 MainActivity.this.calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);//HOUR_OF_DAY是24小时制
 6                 MainActivity.this.calendar.set(Calendar.MINUTE, minute);
 7                 MainActivity.this.calendar.set(Calendar.SECOND, 0);
 8                 //先保存起来,更新textview时可以用
 9                 MainActivity.this.hourofday = hourOfDay;
10                 MainActivity.this.minute = minute;
11
12             }
13         });

2、AlarmManager的用法

MainActivity.this.alarmManager = (AlarmManager) MainActivity.this.getSystemService(ALARM_SERVICE);//获得一个AlarmManager服务
 1  MainActivity.this.set.setOnClickListener(new View.OnClickListener() {
 2             @Override
 3             public void onClick(View v) {
 4               /*  AlarmManager.RTC,硬件闹钟,不唤醒休眠;
 5                 AlarmManager.RTC_WAKEUP,硬件闹钟,唤醒休眠;
 6                 AlarmManager.ELAPSED_REALTIME,真实时间流逝闹钟,不唤醒休眠;
 7                 AlarmManager.ELAPSED_REALTIME_WAKEUP,真实时间流逝闹钟,唤醒休眠;*/
 8                 Intent intent = new Intent(MainActivity.this, AlarmBroadcastReceiver.class);
 9                 intent.setAction("com.example.hxdn.naozhong");
10                 PendingIntent operation = PendingIntent.getBroadcast(MainActivity.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
11                 MainActivity.this.alarmManager.set(AlarmManager.RTC_WAKEUP, MainActivity.this.calendar.getTimeInMillis(), operation);////参数1:解释在上面。  参数二:传入时间毫秒   参数三:传入PendingIntent
12                 MainActivity.this.tv.setText("闹钟时间:" + MainActivity.this.hourofday + "时" + MainActivity.this.minute + "分" + "00秒");
13                 Toast.makeText(MainActivity.this, "闹钟设置完毕!", Toast.LENGTH_LONG);
14             }
15         });
16         MainActivity.this.cancle.setOnClickListener(new View.OnClickListener() {
17             @Override
18             public void onClick(View v) {
19                 Intent intent = new Intent(MainActivity.this, AlarmBroadcastReceiver.class);
20                 intent.setAction("com.example.hxdn.naozhong");//要与上面设置的一样,否则会出现取消掉闹钟还是响的问题。
21                 PendingIntent operation = PendingIntent.getBroadcast(MainActivity.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
22                 MainActivity.this.alarmManager.cancel(operation);
23                 MainActivity.this.tv.setText("当前闹钟未设置");
24                 Toast.makeText(MainActivity.this, "闹钟已删除!", Toast.LENGTH_SHORT).show();
25             }
26         });

机制:

通过TimePicker设置时间由Calendar获得时间,包装一个PendingIntent(即使当前Activity销毁仍然可以启动广播从而启动AlarmActivity弹出提示框和震动),由alarmManager设置。

注意点:

记得注册BroadcastReceiver和AlamActivity!

震动需要权限!

接下来贴出全部的代码:

布局代码:

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="vertical"
 6     android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
 7
 8    <TimePicker
 9        android:layout_width="wrap_content"
10        android:layout_height="wrap_content"
11        android:id="@+id/tp"/>
12     <TextView
13         android:layout_width="wrap_content"
14         android:layout_height="wrap_content"
15         android:id="@+id/tv"
16         android:layout_gravity="center"
17         android:text="闹钟时间"/>
18     <LinearLayout
19         android:layout_width="wrap_content"
20         android:layout_height="wrap_content"
21         android:orientation="horizontal">
22         <Button
23             android:layout_width="wrap_content"
24             android:layout_height="wrap_content"
25             android:id="@+id/set"
26             android:layout_marginLeft="50dp"
27             android:text="设置"/>
28         <Button
29             android:layout_width="wrap_content"
30             android:layout_height="wrap_content"
31             android:id="@+id/cancle"
32             android:layout_marginLeft="100dp"
33             android:text="取消"/>
34
35         </LinearLayout>
36
37 </LinearLayout>

MainActivity.java

  1 package com.example.hxdn.naozhong;
  2
  3 import android.app.AlarmManager;
  4 import android.app.PendingIntent;
  5 import android.content.Intent;
  6 import android.support.v7.app.AppCompatActivity;
  7 import android.os.Bundle;
  8 import android.util.Log;
  9 import android.view.Menu;
 10 import android.view.MenuItem;
 11 import android.view.View;
 12 import android.widget.Button;
 13 import android.widget.TextView;
 14 import android.widget.TimePicker;
 15 import android.widget.Toast;
 16
 17 import java.util.Calendar;
 18
 19 public class MainActivity extends AppCompatActivity {
 20
 21     private static final String TAG = "MMM";
 22     private Button set = null;
 23     private Button cancle = null;
 24     private TextView tv = null;
 25     private TimePicker tp = null;//时间选择器
 26     private Calendar calendar = null;//日期操作
 27     private AlarmManager alarmManager = null;//闹钟管理AlarmManager实质上是一个全局的定时器,
 28     private int hourofday;
 29     private int minute;
 30
 31     // 是Android中常用的一种系统级别的提示服务,在指定时间或周期性启动其它组件(包括Activity,Service,BroadcastReceiver)。
 32     @Override
 33     protected void onCreate(Bundle savedInstanceState) {
 34         super.onCreate(savedInstanceState);
 35         setContentView(R.layout.activity_main);
 36         init();
 37         initAction();
 38     }
 39
 40     @Override
 41     public boolean onCreateOptionsMenu(Menu menu) {
 42         // Inflate the menu; this adds items to the action bar if it is present.
 43         getMenuInflater().inflate(R.menu.menu_main, menu);
 44         return true;
 45     }
 46
 47     @Override
 48     public boolean onOptionsItemSelected(MenuItem item) {
 49         // Handle action bar item clicks here. The action bar will
 50         // automatically handle clicks on the Home/Up button, so long
 51         // as you specify a parent activity in AndroidManifest.xml.
 52         int id = item.getItemId();
 53
 54         //noinspection SimplifiableIfStatement
 55         if (id == R.id.action_settings) {
 56             return true;
 57         }
 58
 59         return super.onOptionsItemSelected(item);
 60     }
 61
 62     private void initAction() {
 63         MainActivity.this.tp.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() {
 64             @Override
 65             public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
 66                 MainActivity.this.calendar = Calendar.getInstance();
 67                 MainActivity.this.calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);//HOUR_OF_DAY是24小时制
 68                 MainActivity.this.calendar.set(Calendar.MINUTE, minute);
 69                 MainActivity.this.calendar.set(Calendar.SECOND, 0);
 70                 //更新textview
 71                 MainActivity.this.hourofday = hourOfDay;
 72                 MainActivity.this.minute = minute;
 73
 74             }
 75         });
 76         MainActivity.this.set.setOnClickListener(new View.OnClickListener() {
 77             @Override
 78             public void onClick(View v) {
 79               /*  AlarmManager.RTC,硬件闹钟,不唤醒休眠;
 80                 AlarmManager.RTC_WAKEUP,硬件闹钟,唤醒休眠;
 81                 AlarmManager.ELAPSED_REALTIME,真实时间流逝闹钟,不唤醒休眠;
 82                 AlarmManager.ELAPSED_REALTIME_WAKEUP,真实时间流逝闹钟,唤醒休眠;*/
 83                 Intent intent = new Intent(MainActivity.this, AlarmBroadcastReceiver.class);
 84                 intent.setAction("com.example.hxdn.naozhong");
 85                 PendingIntent operation = PendingIntent.getBroadcast(MainActivity.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
 86                 MainActivity.this.alarmManager.set(AlarmManager.RTC_WAKEUP, MainActivity.this.calendar.getTimeInMillis(), operation);
 87                 MainActivity.this.tv.setText("闹钟时间:" + MainActivity.this.hourofday + "时" + MainActivity.this.minute + "分" + "00秒");
 88                 Toast.makeText(MainActivity.this, "闹钟设置完毕!", Toast.LENGTH_LONG);
 89             }
 90         });
 91         MainActivity.this.cancle.setOnClickListener(new View.OnClickListener() {
 92             @Override
 93             public void onClick(View v) {
 94                 Intent intent = new Intent(MainActivity.this, AlarmBroadcastReceiver.class);
 95                 intent.setAction("com.example.hxdn.naozhong");
 96                 PendingIntent operation = PendingIntent.getBroadcast(MainActivity.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
 97                 MainActivity.this.alarmManager.cancel(operation);
 98                 MainActivity.this.tv.setText("当前闹钟未设置");
 99                 Toast.makeText(MainActivity.this, "闹钟已删除!", Toast.LENGTH_SHORT).show();
100             }
101         });
102     }
103
104     public void init() {
105         set = (Button) findViewById(R.id.set);
106         cancle = (Button) findViewById(R.id.cancle);
107         tv = (TextView) findViewById(R.id.tv);
108         tp = (TimePicker) findViewById(R.id.tp);
109         MainActivity.this.alarmManager = (AlarmManager) MainActivity.this.getSystemService(ALARM_SERVICE);
110     }
111
112     public void onStart()
113     {
114         Log.i(TAG, "onStart() executed ");
115         super.onStart();
116     }
117     public void onPause()
118     {
119         Log.i(TAG, "onPause() executed ");
120         super.onPause();
121
122     }
123     public void onDestroy()
124     {
125         Log.i(TAG,"onDestroy() executed ");
126         super.onDestroy();
127     }
128 }

AlarmActivity.java

 1 package com.example.hxdn.naozhong;
 2
 3 import android.app.Activity;
 4 import android.app.AlertDialog;
 5 import android.content.Context;
 6 import android.content.DialogInterface;
 7 import android.os.Bundle;
 8 import android.os.Vibrator;
 9 import android.util.Log;
10
11 import java.text.SimpleDateFormat;
12 import java.util.Date;
13
14 /**
15  * Created by hxdn on 2015/9/20.
16  */
17 public class AlarmActivity extends Activity {
18     private Vibrator vibrator=null;
19     @Override
20     protected void onCreate(Bundle savedInstanceState)
21     {
22         super.onCreate(savedInstanceState);
23         Log.i("MMM", "wocao1");
24         vibrator=(Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
25         long patten[]={100,800,100,800};
26         vibrator.vibrate(patten,2);
27         Log.i("MMM","wocao2");
28         new AlertDialog.Builder(AlarmActivity.this).setIcon(R.mipmap.ic_launcher).
29                 setTitle("闹钟提醒").
30                 setMessage("当前时间:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()))
31                 .setNegativeButton("关闭", new DialogInterface.OnClickListener() {
32                     @Override
33                     public void onClick(DialogInterface dialog, int which) {
34                         vibrator.cancel();
35                         AlarmActivity.this.finish();
36                     }
37                 }).show();
38
39     }
40 }

AlarmBroadCReceiver.java

package com.example.hxdn.naozhong;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

/**
 * Created by hxdn on 2015/9/20.
 */
public class AlarmBroadcastReceiver extends BroadcastReceiver {

    public void onReceive(Context context,Intent intent)
    {
        Intent intent1=new Intent(context,AlarmActivity.class);
        intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent1);
    }
}

AndroidManifest.xml

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 3     package="com.example.hxdn.naozhong" >
 4
 5     <application
 6         android:allowBackup="true"
 7         android:icon="@mipmap/ic_launcher"
 8         android:label="@string/app_name"
 9         android:theme="@style/AppTheme" >
10         <receiver
11             android:name=".AlarmBroadcastReceiver">
12
13             </receiver>
14         <activity
15             android:name=".MainActivity"
16             android:label="@string/app_name" >
17             <intent-filter>
18                 <action android:name="android.intent.action.MAIN" />
19
20                 <category android:name="android.intent.category.LAUNCHER" />
21             </intent-filter>
22         </activity>
23         <activity
24             android:name=".AlarmActivity"
25             android:theme="@android:style/Theme.Dialog"></activity>
26     </application>
27     <uses-permission android:name="android.permission.VIBRATE"></uses-permission>
28 </manifest>
时间: 2024-08-05 19:10:03

Android开发之闹钟的相关文章

android智能天气闹钟应用开发经过

开发这个应用的初衷是这样产生滴,和我一块租房的同学每天早上都是骑单车上班,所以手机闹钟就会定一个刚好适合骑车的起床时间点.但是呢,有一天早上起床以后发现外面下挺大雨,肯定是不能骑车去上班了,于是就只好坐公交了,可是起床的时间刚好够骑车不够坐公交呀,雨天又不好打车~~于是就华丽丽的迟到了~~ 刚好我最近在自学android开发,然后就想到了做这么一个闹钟应用,可以根据当天天气的情况来决定闹钟触发的时间,如果下雨或者下雪的话就让它提前一个时间点,比如半个小时触发,这样的话骑车的同学就省了不少心,妈妈

Android 开发第七弹:简易时钟(秒表)

本文承接,Android 开发第五弹:简易时钟(闹钟) 和 Android 开发第六弹:简易时钟(计时器),这一部分是关于秒表的. 布局 同样是新建一个类(StopWatchView)并扩展自LinearLayout,并将其用作布局. <myapplication.nomasp.com.clock.StopWatchView android : id = "@+id/tabStopWatch" android : layout_width = "match_parent

Google I/O 2014 大会总结 Android开发新方向

昨天晚上,Google I/O 2014大会召开,会上主要展示了以下几个部分的创新内容: Android L 操作系统 首先是界面,谷歌重新设计了一套 UI 规范,并称之为"Material Design",这种语言风格从一些人们常用的物品中汲取灵感,比如纸张和墨水的晕染,让屏幕空间得到最佳应用,提供尽量多的资讯信息,并且可以在智能手机.平板或桌面上提供统一的设计界面. 具体风格上看,Material Design 大量使用了圆形和圆角的扁平化设计,更多的操作是通过滑动完成而不是点击.

《Android开发从入门到精通》扶松柏.扫描版.pdf

下载地址:网盘下载 内容简介 编辑 <Android开发从入门到精通>系统讲解了Android软件开发的基础知识,图文并茂地帮助读者学习和掌握SDK.开发流程以及常用的API等.书中以讲述实战实例为导向,用一个个典型应用生动地引领读者进行项目开发实践.<Android开发从入门到精通>是一本内容翔实,理论实践紧密结合的教程. [1] 目录 编辑 第1章 走进Android世界 1.1 智能手机飞速发展 1.1.1 主流手机系统介绍 1.1.2 Android横空出世 1.2 And

Android 开发第六弹:简易时钟(计时器)

接上篇Android 开发第五弹:简易时钟(闹钟) ,这次是一个时钟类应用,目前依旧是主要的功能,长得还是很挫.当然了,核心功能是有的-- 时钟 先把简单的时钟给列出来吧,这里都写的很简单,即便要用世界各个城市的话,也只是相应的加上或减去几个小时. 新建TimeView类,并扩展自LinearLayout,然后布局文件和上一篇中那么写就好了. <myapplication.nomasp.com.clock.TimeView android : id = "@+id/tabTime"

Android开发之手机铃声代码实现

如果读到的是音频文件路径,需要先将音乐文件插入到多媒体库.如:path传入:/mnt/sdcard/mp3/a.mp3 //设置--铃声的具体方法 public void setMyRingtone(String path) { File sdfile = new File(path); ContentValues values = new ContentValues(); values.put(MediaStore.MediaColumns.DATA, sdfile.getAbsolutePa

Android开发软件架构思考以及经验总结

前言 架构设计,到底是什么呢?基于这段时间的学习和自己的一些思考,我认为架构是基于产品和技术所达成的一种共识.我不是专业的架构师,也不是经验老道的开发者.本文目的有三,一是整理这段时间的架构学习和思考以及总结这一年的开发经验教训,二是希望能够与各位朋友探讨移动端App的架构设计,三是希望我们每一个应用开发者能够拥有架构的意识.个人的水平有限,文中如果不当之处,还希望批评指正. 知识大纲 一.萌芽 二.初识架构 1.阅读<架构之美>之论架构 2.分析行业内各个APP的架构演进 (1)架构为什么需

Android开发之设置铃声

首先介绍一下Android系统支持的铃声格式.有以下几种: 64赫兹Midi,AAC.AAC+.AMR.WAV.MP3.Real Audio.WMA.OGG等格式. 将音频文件设置成铃声很简单,只需如下几步即可: 1) 获取系统音频文件的Uri Uri uri =MediaStore.Audio.Media.getContentUriForPath(file.getAbsolutePath());//获取系统音频文件的Uri 2) 将文件插入系统媒体库,并获取新的Uri Uri newUri =

50、转自知乎上android开发相见恨晚的接口

原文链接:http://www.zhihu.com/question/33636939 程序员软件开发Android 开发JavaAndroid修改 Android开发中,有哪些让你觉得相见恨晚的方法.类或接口?修改 Android(Java)开发中,有哪些方法或类(接口)很实用,但是你却没能在第一时间知道它?当有一天你发现它时,只想说一句:“What the f**k,还有这个!”修改 举报 添加评论分享• 邀请回答 按投票排序按时间排序 28 个回答 赞同123反对,不会显示你的姓名 Roc