android 2.2 apidemos 赏析笔记 3

本文详细探讨了Android应用中警报和通知的实现过程,包括使用AlarmManager设置定时任务,PendingIntent处理响应意图,以及如何通过Notification Manager展示通知。同时介绍了动态加载权限、设置密码、锁屏及清除用户数据等高级功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[size=x-large]AlarmController.java[/size]
SEE:
1.
Intent intent = new Intent(AlarmController.this, OneShotAlarm.class);
PendingIntent sender = PendingIntent.getBroadcast(AlarmController.this,
0, intent, 0);

// We want the alarm to go off 30 seconds from now.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 30);

// Schedule the alarm!
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), sender);
SO:
PendingIntent 待响应的意图。有三个主要方法getActivity(Context, int, Intent, int), getBroadcast(Context, int, Intent, int), getService(Context, int, Intent, int); 表示可以开启三种类型的东东,设置时间与设置AlarmManager的方法如上。。。
PS:android:process=":remote",代表在应用程序里,当需要该service时,会自动创建新的进程。而如果是android:process="remote",没有“:”分号的,则创建全局进程,不同的应用程序共享该进程。

SEE:
1.
Intent intent = new Intent(AlarmController.this, RepeatingAlarm.class);
PendingIntent sender = PendingIntent.getBroadcast(AlarmController.this,
0, intent, 0);

// We want the alarm to go off 30 seconds from now.
long firstTime = SystemClock.elapsedRealtime();
firstTime += 15*1000;

// Schedule the alarm!
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
firstTime, 15*1000, sender);
SO:
setRepeating来设置重复,注意到与上面的计时方式不一样.见PS:

PS:
android.os.SystemClock
Class Overview
System.currentTimeMillis()

该时间是基于世界时间的,它返回的是从January 1, 1970 00:00:00 UTC到现在时间已经逝去了多多少millisecond,当我设置Android手机的系统时间时,会应该影响该值。

uptimeMillis()

它表示的是手机从启动到现在的运行时间,且不包括系统sleep(CPU关闭)的时间,很多系统的内部时间都是基于此,比如Thread.sleep(millls), Object.wait(millis), and System.nanoTime()

elapsedRealtime()

它表示的是手机从启动到现在的运行时间,且包括系统sleep(CPU关闭)的时间

SEE:
1.
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
am.cancel(sender);
SO:
取消重复的操作

[size=x-large]AlarmService.java[/size]
SEE:
1.
mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);

// show the icon in the status bar
showNotification();
2.
private void showNotification() {
// In this sample, we'll use the same text for the ticker and the expanded notification
CharSequence text = getText(R.string.alarm_service_started);

// Set the icon, scrolling text and timestamp
Notification notification = new Notification(R.drawable.stat_sample, text,
System.currentTimeMillis());

// The PendingIntent to launch our activity if the user selects this notification
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, AlarmService.class), 0);

// Set the info for the views that show in the notification panel.
notification.setLatestEventInfo(this, getText(R.string.alarm_service_label),
text, contentIntent);

// Send the notification.
// We use a layout id because it is a unique number. We use it later to cancel.
mNM.notify(R.string.alarm_service_started, notification);
}
3.
public void onDestroy() {
// Cancel the notification -- we use the same ID that we had used to start it
mNM.cancel(R.string.alarm_service_started);
SO:
Notification(R.drawable.stat_sample, text,System.currentTimeMillis());分别是,标题栏闪过的图片,内容,时间。PendingIntent.getActivity(this, 0,new Intent(this, AlarmService.class), 0);点击通知时的意图;notification.setLatestEventInfo(this, getText(R.string.alarm_service_label),text, contentIntent);下拉通知栏,通知的内容标签,内容,意图。mNM.notify(R.string.alarm_service_started, notification);正式的发送通知,第一个参数是ID,居然用这个字符串资源的值来做ID。懒到极点 我喜欢~

SEE:
1.
Thread thr = new Thread(null, mTask, "AlarmService_Service");
thr.start();
2.
public void run() {
// Normally we would do some work here... for our sample, we will
// just sleep for 30 seconds.
long endTime = System.currentTimeMillis() + 15*1000;
while (System.currentTimeMillis() < endTime) {
synchronized (mBinder) {
try {
mBinder.wait(endTime - System.currentTimeMillis());
} catch (Exception e) {
}
}
}

// Done with our work... stop the service!
AlarmService_Service.this.stopSelf();
}
SO:
AlarmService_Service.this.stopSelf();这个也会调用onDestory()...也就是按下start Alarm Service的时候 显示一个通知,该通知15秒后自动停止,30秒后再显示该通知。。。 蛋疼。

[size=x-large]DeviceAdminSample.java[/size]
SEE:
1.AndroidManifest.xml
<!-- Device Admin Samples -->

<activity android:name=".app.DeviceAdminSample$Controller"
android:label="@string/activity_sample_device_admin">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.SAMPLE_CODE" />
</intent-filter>
</activity>


<receiver android:name=".app.DeviceAdminSample"
android:label="@string/sample_device_admin"
android:description="@string/sample_device_admin_description"
android:permission="android.permission.BIND_DEVICE_ADMIN">
<meta-data android:name="android.app.device_admin"
android:resource="@xml/device_admin_sample" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
</intent-filter>
</receiver>
SO:
这里的DeviceAdminSample是一个receiver,不是妹子不是Activity。controller才是。所以有android:name=".app.DeviceAdminSample$Controller",protected void onCreate()纠结了 静态类不能实例化,难道activity都不实例化的?这个就分析不来 MARK 有知道的告诉声 暂且当成正常的activity...

SEE:
1.
ComponentName mDeviceAdminSample;
2.
mDeviceAdminSample = new ComponentName(Controller.this, DeviceAdminSample.class);
3.
Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
mDeviceAdminSample);
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
"Additional text explaining why this needs to be added.");
startActivityForResult(intent, RESULT_ENABLE);
4.
mDPM.removeActiveAdmin(mDeviceAdminSample);
SO:
程序动态加载权限。神器呀intent真是变换莫测。DevicePolicyManager.EXTRA_DEVICE_ADMIN="android.app.extra.DEVICE_ADMIN"
DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN="android.app.action.ADD_DEVICE_ADMIN" ,EXTRA_ADD_EXPLANATION ="android.app.extra.ADD_EXPLANATION"

SEE:
1.
mPasswordQuality = (Spinner)findViewById(R.id.password_quality);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
this, R.array.password_qualities, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mPasswordQuality.setAdapter(adapter);
mPasswordQuality.setOnItemSelectedListener(
new OnItemSelectedListener() {
public void onItemSelected(
AdapterView<?> parent, View view, int position, long id) {
setPasswordQuality(mPasswordQualityValues[position]);
}

public void onNothingSelected(AdapterView<?> parent) {
setPasswordQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
}
});
SO:
动态设置Spinner下拉菜单的选项范例。。


SEE:
1.mSetPasswordListener
Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
startActivity(intent);
2.
SO:设置密码界面

SEE:
mPasswordLength = (EditText)findViewById(R.id.password_length);
mPasswordLength.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
try {
setPasswordLength(Integer.parseInt(s.toString()));
} catch (NumberFormatException e) {
}
}
});
SO:
textView的监听范例

SEE:
boolean active = mDPM.isAdminActive(mDeviceAdminSample);
if (active) {
mDPM.setPasswordQuality(mDeviceAdminSample, pwQuality);
mDPM.setPasswordMinimumLength(mDeviceAdminSample, pwLength);
mDPM.setMaximumFailedPasswordsForWipe(mDeviceAdminSample, maxFailedPw);
}
SO:
mDPM.isAdminActive(mDeviceAdminSample)//当前设备管理器是否激活,DevicePolicyManager的相关设置


SEE:
Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
startActivity(intent);
SO:
打开密码设置界面


SEE:
if (mAM.isUserAMonkey()) {
// Don't trust monkeys to do the right thing!
AlertDialog.Builder builder = new AlertDialog.Builder(Controller.this);
builder.setMessage("You can't reset my password because you are a monkey!");
builder.setPositiveButton("I admit defeat", null);
builder.show();
return;
}
boolean active = mDPM.isAdminActive(mDeviceAdminSample);
if (active) {
mDPM.resetPassword(mPassword.getText().toString(),
DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY);
}
SO:
1.mAM.isUserAMonkey(),防止用户胡乱操作修改密码成功。。神奇的函数
[url=http://blog.sina.com.cn/s/blog_6e90fdbf0100rsqp.html](传送门)[/url]
2.AlertDialog.Builder范例
3.
mDPM.resetPassword(mPassword.getText().toString(), DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY);这就设置密码成功了。。。很危险呀,这不是想改就改了,权限不能乱给的。。手机开不开了就爽了

SEE:
mDPM.lockNow();
SO:黑屏?不,锁屏了。。。叫你随意给权限

SEE:
mDPM.wipeData(0);
SO:
清除用户数据。。数据。。。回复出厂设置吗?

这个速度权限取消了吧
==============================完
[size=x-large]
AlertDialogSamples[/size]

SEE:
1.
@Override
protected Dialog onCreateDialog(int id) {
2.
showDialog(DIALOG_YES_NO_MESSAGE);
SO:
重写方法来创建对话框 而不是直接创建对话框。。新方法

以后创建Dialog可以来这里拉代码 就不多写了

==============================完

[size=x-large]Intents.java[/size]

SEE:
1.
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("audio/*");
startActivity(Intent.createChooser(intent, "Select music"));
SO:
用来打开音乐文件的方法,如果用音乐来打开的话会出错,没有指名音乐路径。Intent.createChooser(intent, "Select music")指定相应的对话框名字。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值