Jemy杰 2014-06-12
今天实现一个具有闹钟功能的消息栏通知,即定时向消息栏推送通知,用户下拉通知栏列表,点击通知后,跳转到指定界面,效果图如下:
收到通知界面:
实现过程如下:
(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>
参考如下文章进行修改的: