今天实现一个具有闹钟功能的消息栏通知,即定时向消息栏推送通知,用户下拉通知栏列表,点击通知后,跳转到指定界面,效果图如下:
收到通知界面:
实现过程如下:
(1)闹钟主界面:
package com.example.alarmmanagerdemo;
import java.util.Calendar;
import java.util.TimeZone;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TimePicker;
import android.widget.Toast;
/**
*
* @ClassName: MainActivity
* @Description: 主界面
* @author HuHood
* @date 2013-11-25 下午4:01:19
*
*/
public class MainActivity extends Activity {
private static final String TAG = MainActivity.class.getSimpleName();
private TimePicker mTimePicker;
private Button mButton1;
private Button mButton2;
private Button mButtonCancel;
private int mHour = -1;
private int mMinute = -1;
public static final long DAY = 1000L * 60 * 60 * 24;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 获取当前时间
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(TimeZone.getTimeZone("GMT+8"));
if(mHour == -1 && mMinute == -1) {
mHour = calendar.get(Calendar.HOUR_OF_DAY);
mMinute = calendar.get(Calendar.MINUTE);
}
/**
* 时间日期控件
*/
mTimePicker = (TimePicker)findViewById(R.id.timePicker);
mTimePicker.setCurrentHour(mHour);
mTimePicker.setCurrentMinute(mMinute);
mTimePicker.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() {
@Override
public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
mHour = hourOfDay;
mMinute = minute;
}
});
/**
* 设置简单闹铃(当前时间的10S后就闹)
*/
mButton1 = (Button)findViewById(R.id.normal_button);
mButton1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, AlarmReceiver.class);
intent.setAction(Constants.ALARM_ACTION);//指定一下广播类型
PendingIntent sender = PendingIntent.getBroadcast(MainActivity.this, 0, intent, 0);
// 过10s 执行这个闹铃
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.setTimeZone(TimeZone.getTimeZone("GMT+8"));
calendar.add(Calendar.SECOND, 10);//当前时间加10s
// 进行闹铃注册
AlarmManager manager = (AlarmManager)getSystemService(ALARM_SERVICE);
manager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), sender);
Toast.makeText(MainActivity.this, "设置简单闹铃成功,10秒后闹铃!", Toast.LENGTH_LONG).show();
}
});
/**
* 设置重复闹铃(指定时间重复闹)
*/
mButton2 = (Button)findViewById(R.id.repeating_button);
mButton2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, AlarmReceiver.class);
intent.setAction(Constants.ALARM_ACTION);//指定一下广播类型
PendingIntent sender = PendingIntent.getBroadcast(MainActivity.this, 0, intent, 0);
long firstTime = SystemClock.elapsedRealtime(); // 开机之后到现在的运行时间(包括睡眠时间)
long systemTime = System.currentTimeMillis();
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.setTimeZone(TimeZone.getTimeZone("GMT+8")); // 这里时区需要设置一下,不然会有8个小时的时间差
calendar.set(Calendar.MINUTE, mMinute);
calendar.set(Calendar.HOUR_OF_DAY, mHour);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
// 选择的每天定时时间
long selectTime = calendar.getTimeInMillis();
// 如果当前时间大于设置的时间,那么就从第二天的设定时间开始
if(systemTime > selectTime) {
Toast.makeText(MainActivity.this, "设置的时间小于当前时间", Toast.LENGTH_SHORT).show();
calendar.add(Calendar.DAY_OF_MONTH, 1);
selectTime = calendar.getTimeInMillis();
}
// 计算现在时间到设定时间的时间差
long time = selectTime - systemTime;
firstTime += time;
// 进行闹铃注册
AlarmManager manager = (AlarmManager)getSystemService(ALARM_SERVICE);
manager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
firstTime, 10*1000, sender);
Log.i(TAG, "time ==== " + time + ", selectTime ===== "
+ selectTime + ", systemTime ==== " + systemTime + ", firstTime === " + firstTime);
Toast.makeText(MainActivity.this, "设置重复闹铃成功,每天定时闹铃! ", Toast.LENGTH_LONG).show();
}
});
/**
* 取消闹铃
*/
mButtonCancel = (Button)findViewById(R.id.cancel_button);
mButtonCancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, AlarmReceiver.class);
PendingIntent sender = PendingIntent.getBroadcast(MainActivity.this,
0, intent, 0);
// 取消闹铃
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
am.cancel(sender);
}
});
}
}
(2)广播接收器:
package com.example.alarmmanagerdemo;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;
/**
*
* @ClassName: AlarmReceiver
* @Description: 闹铃时间到了会进入这个广播,这个时候可以做一些该做的业务。
* @author HuHood
* @date 2013-11-25 下午4:44:30
*
*/
public class AlarmReceiver extends BroadcastReceiver {
private String TAG = getClass().getName();
/**
* 是具体的状态栏通知对象,可以设置icon、文字、提示声音、振动等等参数。
*/
private Notification notification;
/**
* 状态栏通知的管理类,负责发通知、清楚通知等,是一个系统Service,必须通过 getSystemService()方法来获取。
*/
private NotificationManager nmManager;
private static final int ID=1;
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "闹铃响了, 可以做点事情了~~", Toast.LENGTH_LONG).show();
String action = intent.getAction();
Log.d(TAG , "闹铃,action====>" + action);
if(Constants.ALARM_ACTION.equals(action)){//过滤一下广播类型
/**
* 这里接收到闹钤事件后,进行如下操作:
* 获取到通知管理器然后新建一个通知,然后发送这个通知!
*
* (可以在百度上搜索“状态栏通知Notification、NotificationManager详解”解读更多内容)
*
* 用户也可以根据需要自行定义操作的事件
*/
nmManager = (NotificationManager)context.getSystemService(context.NOTIFICATION_SERVICE);
/**
* Notification notification = new Notificatio(drawable,tickerText,System.currentTimeMillis());
*
* 其中第一个参数代表图标
* 第二个参数代表提示的内容
* 第三个参数是指要显示的时间,一般是当即显示,故填入系统当前时间。
*/
String tickerText ="Test Notification";
notification = new Notification(R.drawable.chicken,tickerText,System.currentTimeMillis());
/**
* 设定声音 ,使用系统的消息通知声音
*/
notification.defaults |= Notification.DEFAULT_SOUND;
Intent temp = new Intent(context,SecondActivity.class);
PendingIntent pi = PendingIntent.getActivity(context, 0, temp, 0);
notification.setLatestEventInfo(context, "通知栏title", "通知栏content", pi);
nmManager.notify(ID,notification);
}
}
}
(3)点击通知后跳转的测试界面:
package com.example.alarmmanagerdemo;
import android.app.Activity;
import android.os.Bundle;
public class SecondActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
}
}
(4)常量类:
package com.example.alarmmanagerdemo;
/**
* 常量
*
* @author chenwenbiao
* @date 2014-6-12 下午1:19:23
* @version V1.0
*/
public class Constants {
public static final String ALARM_ACTION = "com.example.alarmmanagerdemo.alarmAction";
}
(5) 布局文件activity_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <TimePicker android:id="@+id/timePicker" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Button android:id="@+id/normal_button" android:layout_marginTop="20dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/timePicker" android:text="设置简单闹铃" /> <Button android:id="@+id/repeating_button" android:layout_marginTop="20dp" android:layout_marginLeft="20dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/timePicker" android:layout_toRightOf="@id/normal_button" android:text="设置重复闹铃" /> <Button android:id="@+id/cancel_button" android:layout_marginTop="20dp" android:layout_marginLeft="-50dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/repeating_button" android:layout_toRightOf="@id/normal_button" android:text="取消闹铃" /> </RelativeLayout>
(6) 测试界面布局activity_second.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="点击通知栏跳转过来的界面" /> </RelativeLayout>
(7) AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.alarmmanagerdemo" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="18" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.example.alarmmanagerdemo.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!-- 广播接收器 --> <receiver android:name="com.example.alarmmanagerdemo.AlarmReceiver" android:process=":remote"/> <activity android:name="com.example.alarmmanagerdemo.SecondActivity" android:screenOrientation="portrait" /> </application> </manifest>
参考如下文章进行修改的: