下面列出了android.app.Notification#Action ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* 通知経由でのActivity起動を行う(Notification.Action)
* @param context コンテキスト
* @param notificationId 通知のID
* @param contentText 通知に表示するテキスト
* @param actions Notification.Actionオブジェクトリスト
*/
public static void notify(Context context, int notificationId, String contentText, Notification.Action... actions) {
NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
if(notificationManager != null) {
Notification notification = new Notification.Builder(context, NOTIFICATION_CHANNEL_ID)
.setActions(actions)
.setContentText(contentText)
.setContentTitle(NOTIFICATION_CONTENT_TITLE)
.setWhen(System.currentTimeMillis())
.setAutoCancel(true)
.setSmallIcon(R.drawable.ic_action_labels)
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_action_labels))
.setStyle(new Notification.BigTextStyle().setBigContentTitle(NOTIFICATION_CONTENT_TITLE).bigText(contentText))
.setDeleteIntent(actions[PENDING_DECLINE_INDEX].actionIntent)
.build();
notificationManager.notify(notificationId, notification);
}
}
private void evolveShareAction() {
if (ScreenshotPreferences.SHARE_EVOLVE_TYPE_DISMISS_AFTER_SHARING ==
mPreferences.getShareEvolveType()) {
final Notification.Action shareAction = n.actions[shareActionIndex];
final Intent intent = new Intent(ACTION_SHARE_SCREENSHOT);
intent.putExtra(EXTRA_NOTIFICATION_KEY, evolving.getKey());
intent.putExtra(EXTRA_ORIGINAL_PENDING_INTENT, shareAction.actionIntent);
final PendingIntent pi = PendingIntent.getBroadcast(
context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
final Notification.Action.Builder builder = new Notification.Action.Builder(
mDeleteIcon.get(),
shareAction.title,
pi);
n.actions[shareActionIndex] = builder.build();
}
}
public static Notification.Action getReplyMessageAction(Context context, Notifiable notif) {
String replyLabel = context.getResources().getString(R.string.notification_reply_label);
RemoteInput remoteInput =
new RemoteInput.Builder(KEY_TEXT_REPLY).setLabel(replyLabel).build();
Intent replyIntent = new Intent(context, NotificationBroadcastReceiver.class);
replyIntent.setAction(INTENT_REPLY_NOTIF_ACTION);
replyIntent.putExtra(INTENT_NOTIF_ID, notif.getNotificationId());
replyIntent.putExtra(INTENT_LOCAL_IDENTITY, notif.getLocalIdentity());
PendingIntent replyPendingIntent =
PendingIntent.getBroadcast(
context,
notif.getNotificationId(),
replyIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
return new Notification.Action.Builder(
R.drawable.chat_send_over,
context.getString(R.string.notification_reply_label),
replyPendingIntent)
.addRemoteInput(remoteInput)
.setAllowGeneratedReplies(true)
.setSemanticAction(Notification.Action.SEMANTIC_ACTION_REPLY)
.build();
}
/**
* {@inheritDoc}
*/
@Nullable
@Override
public Action[] makeFor(@NonNull Notification notification) {
Notification.Action[] src = notification.actions;
if (src == null) {
return null;
}
final int length = src.length;
final Action[] dst = new Action[src.length];
for (int i = 0; i < length; i++) {
RemoteInput[] remoteInputs = getRemoteInputs(src[i]);
dst[i] = new Action(src[i].icon, src[i].title, src[i].actionIntent, remoteInputs);
}
return dst;
}
private Notification.Action stopAction() {
if (mStopAction == null) {
Intent intent = new Intent(ACTION_STOP).setPackage(getPackageName());
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1,
intent, PendingIntent.FLAG_ONE_SHOT);
mStopAction = new Notification.Action(android.R.drawable.ic_media_pause, "Stop", pendingIntent);
}
return mStopAction;
}
public static Notification.Action getCallDeclineAction(Context context, int callId) {
Intent hangupIntent = new Intent(context, NotificationBroadcastReceiver.class);
hangupIntent.setAction(INTENT_HANGUP_CALL_NOTIF_ACTION);
hangupIntent.putExtra(INTENT_NOTIF_ID, callId);
PendingIntent hangupPendingIntent =
PendingIntent.getBroadcast(
context, callId, hangupIntent, PendingIntent.FLAG_UPDATE_CURRENT);
return new Notification.Action.Builder(
R.drawable.call_hangup,
context.getString(R.string.notification_call_hangup_label),
hangupPendingIntent)
.build();
}
@Test
public void hasTitle() {
if (Build.VERSION.SDK_INT >= 16) {
final Notification.Action action = new Notification.Action(0, EXPECTED_TEXT, null);
assertThat(action).title().isEqualTo(EXPECTED_TEXT);
}
}
private void findOutActionsIndex() {
for (int i = 0; i < n.actions.length; i++) {
final Notification.Action a = n.actions[i];
if (isDeleteActionText(context, a.title)) {
deleteActionIndex = i;
} else if (isShareActionText(context, a.title)) {
shareActionIndex = i;
} else if (isEditActionText(context, a.title)) {
editActionIndex = i;
}
}
}
private Notification.Action createStopAction() {
Intent stopIntent = GnirehtetService.createStopIntent(context);
PendingIntent stopPendingIntent = PendingIntent.getService(context, 0, stopIntent, PendingIntent.FLAG_ONE_SHOT);
// the non-deprecated constructor is not available in API 21
@SuppressWarnings("deprecation")
Notification.Action.Builder actionBuilder = new Notification.Action.Builder(R.drawable.ic_close_24dp, context.getString(R.string.stop_vpn),
stopPendingIntent);
return actionBuilder.build();
}
public static Notification.Action getCallAnswerAction(Context context, int callId) {
if (Version.sdkAboveOrEqual(Version.API29_ANDROID_10)) {
return ApiTwentyNinePlus.getCallAnswerAction(context, callId);
} else if (Version.sdkAboveOrEqual(Version.API24_NOUGAT_70)) {
return ApiTwentyFourPlus.getCallAnswerAction(context, callId);
}
return null;
}
private void createNotification() {
Log.i(TAG, "Create running notification");
// Create open and pause action intents
Intent openIntent = new Intent(this, MainActivity.class);
Intent pauseIntent = new Intent(this, ActionReceiver.class);
pauseIntent.setAction(Constants.ACTION_UPDATE_STATUS);
pauseIntent.putExtra(Constants.Extra.ACTION, Constants.Action.PAUSE);
pauseIntent.putExtra(Constants.Extra.BRIGHTNESS, mBrightness);
Notification.Action pauseAction = new Notification.Action(
R.drawable.ic_wb_incandescent_black_24dp,
getString(R.string.notification_action_turn_off),
PendingIntent.getBroadcast(getBaseContext(), 0, pauseIntent, Intent.FILL_IN_DATA)
);
// Create notification
Notification.Builder builder = new Notification.Builder(getApplicationContext())
.setContentTitle(getString(R.string.notification_running_title))
.setContentText(getString(R.string.notification_running_msg))
.setSmallIcon(R.drawable.ic_brightness_2_white_36dp)
.addAction(pauseAction)
.setContentIntent(PendingIntent.getActivity(getApplicationContext(),
0, openIntent, PendingIntent.FLAG_UPDATE_CURRENT))
.setAutoCancel(false)
.setOngoing(true)
.setOnlyAlertOnce(true)
.setShowWhen(false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
builder.setChannelId(Constants.NOTIFICATION_CHANNEL_ID_RS);
}
mNotification = builder.build();
}
public static Notification.Action getReplyMessageAction(Context context, Notifiable notif) {
if (Version.sdkAboveOrEqual(Version.API29_ANDROID_10)) {
return ApiTwentyNinePlus.getReplyMessageAction(context, notif);
} else if (Version.sdkAboveOrEqual(Version.API28_PIE_90)) {
return ApiTwentyEightPlus.getReplyMessageAction(context, notif);
} else if (Version.sdkAboveOrEqual(Version.API24_NOUGAT_70)) {
return ApiTwentyFourPlus.getReplyMessageAction(context, notif);
}
return null;
}
public static NotificationCompatBase.Action getAction(Notification notif,
int actionIndex, NotificationCompatBase.Action.Factory factory,
RemoteInputCompatBase.RemoteInput.Factory remoteInputFactory) {
Notification.Action action = notif.actions[actionIndex];
Bundle actionExtras = null;
SparseArray<Bundle> actionExtrasMap = notif.extras.getSparseParcelableArray(
NotificationCompatJellybean.EXTRA_ACTION_EXTRAS);
if (actionExtrasMap != null) {
actionExtras = actionExtrasMap.get(actionIndex);
}
return NotificationCompatJellybean.readAction(factory, remoteInputFactory,
action.icon, action.title, action.actionIntent, actionExtras);
}
private static Notification.Action GenerateActionCompat(Context context, int icon, String title, int requestCode, KeypressKeyValues keypressKeyValue) {
Intent intent = new Intent(context, CommandService.class);
intent.putExtra("keypress", keypressKeyValue);
PendingIntent pendingIntent = PendingIntent.getService(context, requestCode, intent, 0);
return new Notification.Action.Builder(icon, title, pendingIntent).build();
}
public static Notification.Action getCallAnswerAction(Context context, int callId) {
Intent answerIntent = new Intent(context, NotificationBroadcastReceiver.class);
answerIntent.setAction(INTENT_ANSWER_CALL_NOTIF_ACTION);
answerIntent.putExtra(INTENT_NOTIF_ID, callId);
PendingIntent answerPendingIntent =
PendingIntent.getBroadcast(
context, callId, answerIntent, PendingIntent.FLAG_UPDATE_CURRENT);
return new Notification.Action.Builder(
R.drawable.call_audio_start,
context.getString(R.string.notification_call_answer_label),
answerPendingIntent)
.build();
}
@Override
public void onDataChanged(DataEventBuffer dataEvents) {
final List<DataEvent> events = FreezableUtils.freezeIterable(dataEvents);
dataEvents.close();
GoogleApiClient googleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.build();
ConnectionResult connectionResult = googleApiClient.blockingConnect(CONNECT_TIMEOUT_MS,
TimeUnit.MILLISECONDS);
if (!connectionResult.isSuccess()) {
Log.e(TAG, "QuizListenerService failed to connect to GoogleApiClient.");
return;
}
for (DataEvent event : events) {
if (event.getType() == DataEvent.TYPE_CHANGED) {
DataItem dataItem = event.getDataItem();
DataMap dataMap = DataMapItem.fromDataItem(dataItem).getDataMap();
if (dataMap.getBoolean(QUESTION_WAS_ANSWERED)
|| dataMap.getBoolean(QUESTION_WAS_DELETED)) {
// Ignore the change in data; it is used in MainActivity to update
// the question's status (i.e. was the answer right or wrong or left blank).
continue;
}
String question = dataMap.getString(QUESTION);
int questionIndex = dataMap.getInt(QUESTION_INDEX);
int questionNum = questionIndex + 1;
String[] answers = dataMap.getStringArray(ANSWERS);
int correctAnswerIndex = dataMap.getInt(CORRECT_ANSWER_INDEX);
Intent deleteOperation = new Intent(this, DeleteQuestionService.class);
deleteOperation.setData(dataItem.getUri());
PendingIntent deleteIntent = PendingIntent.getService(this, 0,
deleteOperation, PendingIntent.FLAG_UPDATE_CURRENT);
// First page of notification contains question as Big Text.
Notification.BigTextStyle bigTextStyle = new Notification.BigTextStyle()
.setBigContentTitle(getString(R.string.question, questionNum))
.bigText(question);
Notification.Builder builder = new Notification.Builder(this)
.setStyle(bigTextStyle)
.setSmallIcon(R.drawable.ic_launcher)
.setLocalOnly(true)
.setDeleteIntent(deleteIntent);
// Add answers as actions.
Notification.WearableExtender wearableOptions = new Notification.WearableExtender();
for (int i = 0; i < answers.length; i++) {
Notification answerPage = new Notification.Builder(this)
.setContentTitle(question)
.setContentText(answers[i])
.extend(new Notification.WearableExtender()
.setContentAction(i))
.build();
boolean correct = (i == correctAnswerIndex);
Intent updateOperation = new Intent(this, UpdateQuestionService.class);
// Give each intent a unique action.
updateOperation.setAction("question_" + questionIndex + "_answer_" + i);
updateOperation.setData(dataItem.getUri());
updateOperation.putExtra(UpdateQuestionService.EXTRA_QUESTION_INDEX,
questionIndex);
updateOperation.putExtra(UpdateQuestionService.EXTRA_QUESTION_CORRECT, correct);
PendingIntent updateIntent = PendingIntent.getService(this, 0, updateOperation,
PendingIntent.FLAG_UPDATE_CURRENT);
Notification.Action action = new Notification.Action.Builder(
questionNumToDrawableId.get(i), null, updateIntent)
.build();
wearableOptions.addAction(action).addPage(answerPage);
}
builder.extend(wearableOptions);
Notification notification = builder.build();
((NotificationManager) getSystemService(NOTIFICATION_SERVICE))
.notify(questionIndex, notification);
} else if (event.getType() == DataEvent.TYPE_DELETED) {
Uri uri = event.getDataItem().getUri();
// URI's are of the form "/question/0", "/question/1" etc.
// We use the question index as the notification id.
int notificationId = Integer.parseInt(uri.getLastPathSegment());
((NotificationManager) getSystemService(NOTIFICATION_SERVICE))
.cancel(notificationId);
}
// Delete the quiz report, if it exists.
((NotificationManager) getSystemService(NOTIFICATION_SERVICE))
.cancel(QUIZ_REPORT_NOTIF_ID);
}
googleApiClient.disconnect();
}
/**
* Get the list of inputs to be collected from the user when this action is sent.
* May return null if no remote inputs were added.
*/
@Nullable
public RemoteInput[] getRemoteInputs(@NonNull Notification.Action action) {
return null;
}
/**
* {@inheritDoc}
*/
@Nullable
public RemoteInput[] getRemoteInputs(@NonNull Notification.Action action) {
return RemoteInputUtils.toCompat(action.getRemoteInputs());
}
public void setCameraOpen(boolean cameraOpen) {
this.cameraOpen = cameraOpen;
Log.v(LOG_TAG, "Camera " + (cameraOpen ? "OPEN" : "CLOSED"));
if (cameraRemoteCallback != null) {
cameraRemoteCallback.onCameraChangedOpen(cameraOpen);
}
if (cameraOpen) {
Bitmap background = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.bg_camera);
Intent cameraIntent = new Intent(mContext, CameraRemoteActivity.class);
cameraIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent cameraPendingIntent = PendingIntent.getActivity(mContext, 0, cameraIntent, 0);
Icon cameraIcon = Icon.createWithResource(mContext, R.drawable.nic_camera);
Notification.Action cameraAction = new Notification.Action.Builder(
cameraIcon,
"Camera",
cameraPendingIntent
).build();
Notification.WearableExtender wearableExtender = new Notification.WearableExtender()
.setBackground(background)
.setContentIcon(R.drawable.nic_camera)
.setHintHideIcon(true)
.setContentAction(0)
.addAction(cameraAction);
Notification.Builder builder = new Notification.Builder(mContext)
.setSmallIcon(cameraIcon)
.setContentTitle(mContext.getString(R.string.take_photo_title))
.setContentText(mContext.getString(R.string.take_photo_text))
.setPriority(Notification.PRIORITY_MAX)
.extend(wearableExtender);
mServiceUtils.notify(null, NOTIFICATION_CAMERA, builder.build());
}
else {
mServiceUtils.cancelNotification(null, NOTIFICATION_CAMERA);
}
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void loadNoticeBar() {
Notification.Builder builder;
final String CHANNEL_ID = "URA";
final int NOTIFICATION_ID = 1;
//Oreo以上适配通知渠道
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//尽管IMPORTANCE_MIN在26中无效...
NotificationChannel notificationChannel = new NotificationChannel(CHANNEL_ID, getString(R.string.service_name), NotificationManager.IMPORTANCE_MIN);
//noinspection ConstantConditions
getSystemService(NotificationManager.class).createNotificationChannel(notificationChannel);
builder = new Notification.Builder(this, CHANNEL_ID);
//根据文档:如果非要用一个来代替的话,使用免root的锁屏
//理解错误,这个方法的作用是使用通知替代一个Shortcut,当通知出现时Shortcut一定会被隐藏
//builder.setShortcutId("ur_l");
} else
builder = new Notification.Builder(this);
builder
.setContentIntent(PendingIntent.getActivity(this, 0, getPackageManager().getLaunchIntentForPackage(getPackageName()), 0))
.setOngoing(true)
//尽管在26上不能折叠通知(需要手动设置),但可以将其放置在较低的位置(已废弃)
.setPriority(Notification.PRIORITY_MIN)
.setSmallIcon(R.drawable.small_icon)
//没有必要显示在锁屏上
.setVisibility(Notification.VISIBILITY_SECRET)
//秒表指示
.setUsesChronometer(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//启用自动折叠
builder.setStyle(new Notification.BigTextStyle()
.bigText(getString(R.string.notification_notice))
.setSummaryText(getString(R.string.accessibility_service_sunnary_hint))
.setBigContentTitle(getString(R.string.service_simple_name)));
} else {
//在Android5.1中BigTextStyle的方法可能无法显示,作为兼容
builder.setContentText(getString(R.string.notification_notice))
.setContentTitle(getString(R.string.service_simple_name));
}
//Wear OS不需要太复杂的通知
if (SpecialSupport.isAndroidWearOS(this)) {
builder.setUsesChronometer(false)
.setStyle(null)
.setContentText(getString(R.string.accessibility_service_sunnary_hint));
}
//Wear OS快捷操作
//---
List<Notification.Action> wearActions = new ArrayList<>();
//锁屏
Notification.Action.Builder lockScreenActionBuilder = new Notification.Action.Builder(android.R.drawable.ic_menu_slideshow, getString(R.string.lockscreen)
, PendingIntent.getActivity(this, 0, new Intent(this, LockScreenAssist.class)
.setAction(Intent.ACTION_ASSIST)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK), 0));
Notification.Action.WearableExtender lockScreenWearableExtender = new Notification.Action.WearableExtender();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
lockScreenActionBuilder.extend(lockScreenWearableExtender.setHintLaunchesActivity(true));
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
//setHintDisplayActionInline在P中没有明显作用,在N和O中可以给通知卡片加action,仅支持一个
lockScreenActionBuilder.extend(lockScreenWearableExtender.setHintDisplayActionInline(true));
}
wearActions.add(lockScreenActionBuilder.build());
//电源菜单
//Wear OS没有24的API Level
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1)
wearActions.add(new Notification.Action.Builder(Icon.createWithResource(this, android.R.drawable.ic_menu_preferences)
, getString(R.string.sys_power_dialog_tile_label)
, PendingIntent.getService(this, 0, new Intent(this, SPDTileEntry.class), 0))
.extend(new Notification.Action.WearableExtender().setHintDisplayActionInline(true))
.build());
builder.extend(new Notification.WearableExtender()
.addActions(wearActions));
//---
if (SpecialSupport.isMIUI()) {
//MIUI会把秒表和发出时间一同显示
builder.setShowWhen(false);
}
Notification notification = builder.build();
startForeground(NOTIFICATION_ID, notification);
}