下面列出了android.app.PendingIntent#getService ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
public void setAlarm() {
long retry_in = (long) sleepTime();
Log.d("DataCollectionService", "Next packet should be available in " + (retry_in / (60 * 1000)) + " minutes");
Calendar calendar = Calendar.getInstance();
AlarmManager alarm = (AlarmManager) getSystemService(ALARM_SERVICE);
long wakeTime = calendar.getTimeInMillis() + retry_in;
Log.d(this.getClass().getName() , "ArmTimer waking at: "+ new Date(wakeTime) +" in " + (wakeTime - calendar.getTimeInMillis())/60000d + " minutes");
if (wakeIntent != null)
alarm.cancel(wakeIntent);
wakeIntent = PendingIntent.getService(this, 0, new Intent(this, this.getClass()), 0);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
alarm.setAlarmClock(new AlarmManager.AlarmClockInfo(wakeTime, wakeIntent), wakeIntent);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarm.setExact(AlarmManager.RTC_WAKEUP, wakeTime, wakeIntent);
} else {
alarm.set(AlarmManager.RTC_WAKEUP, wakeTime, wakeIntent);
}
}
private void showNotification() {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "Sent: " + mLastResponse);
}
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setContentTitle(getString(R.string.eliza))
.setContentText(mLastResponse)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.bg_eliza))
.setSmallIcon(R.drawable.bg_eliza)
.setPriority(NotificationCompat.PRIORITY_MIN);
Intent intent = new Intent(ACTION_RESPONSE);
PendingIntent pendingIntent = PendingIntent.getService(this, 0, intent,
PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_CANCEL_CURRENT);
Notification notification = builder
.extend(new NotificationCompat.WearableExtender()
.addAction(new NotificationCompat.Action.Builder(
R.drawable.ic_full_reply, getString(R.string.reply), pendingIntent)
.addRemoteInput(new RemoteInput.Builder(EXTRA_REPLY)
.setLabel(getString(R.string.reply))
.build())
.build()))
.build();
NotificationManagerCompat.from(this).notify(0, notification);
}
private NotificationCompat.Action play(Context context) {
Intent prevIntent = new Intent(context, MusicPlaybackService.class);
prevIntent.setAction(ACTION_PLAY);
PendingIntent prevPendingIntent = PendingIntent.getService(context,
PLAY_PENDING_INTENT_ID,
prevIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
return new NotificationCompat.Action(R.drawable.ic_play_notif, "Play", prevPendingIntent);
}
@SuppressLint("DefaultLocale")
@Override
protected void installApkFiles(ApkSource aApkSource) {
cleanOldSessions();
PackageInstaller.Session session = null;
try (ApkSource apkSource = aApkSource) {
PackageInstaller.SessionParams sessionParams = new PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL);
sessionParams.setInstallLocation(PreferencesHelper.getInstance(getContext()).getInstallLocation());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
sessionParams.setInstallReason(PackageManager.INSTALL_REASON_USER);
int sessionID = mPackageInstaller.createSession(sessionParams);
mSessionsMap.put(sessionID, getOngoingInstallation().getId());
session = mPackageInstaller.openSession(sessionID);
int currentApkFile = 0;
while (apkSource.nextApk()) {
try (InputStream inputStream = apkSource.openApkInputStream(); OutputStream outputStream = session.openWrite(String.format("%d.apk", currentApkFile++), 0, apkSource.getApkLength())) {
IOUtils.copyStream(inputStream, outputStream);
session.fsync(outputStream);
}
}
Intent callbackIntent = new Intent(getContext(), RootlessSAIPIService.class);
PendingIntent pendingIntent = PendingIntent.getService(getContext(), 0, callbackIntent, 0);
session.commit(pendingIntent.getIntentSender());
} catch (Exception e) {
Log.w(TAG, e);
dispatchCurrentSessionUpdate(InstallationStatus.INSTALLATION_FAILED, getContext().getString(R.string.installer_error_rootless, Utils.throwableToString(e)));
installationCompleted();
} finally {
if (session != null)
session.close();
}
}
public static void cancelCourseAlarm(Context context, int id, boolean isVibrate) {
Intent intent = new Intent(context, CourseAlarmService.class);
Bundle bundle = new Bundle();
bundle.putBoolean("mode", isVibrate);
intent.putExtras(bundle);
PendingIntent pendingIntent =
PendingIntent.getService(context, id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarm = (AlarmManager) context.getSystemService(Service.ALARM_SERVICE);
alarm.cancel(pendingIntent);
}
/**
* 停止启轮询服务
*/
@TargetApi(Build.VERSION_CODES.CUPCAKE)
public static void stopAlarmService(Context context, Class<?> cls, String action) {
Intent intent = new Intent(context, cls);
intent.setAction(action);
PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
stopAlarmIntent(context, pendingIntent);
}
/**
* 显示下载错误的通知,点击继续下载
*
* @param context 上下文
* @param icon 图标
* @param title 标题
* @param content 内容
*/
public static void showErrorNotification(Context context, int icon, String title, String content) {
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
afterO(manager);
}
Intent intent = new Intent(context, DownloadService.class);
PendingIntent pi = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = builderNotification(context, icon, title, content)
.setAutoCancel(true)
.setOngoing(false)
.setContentIntent(pi)
.setDefaults(Notification.DEFAULT_SOUND);
manager.notify(requireManagerNotNull().getNotifyId(), builder.build());
}
public static void cancelBusAlarm(Context context, String endStation, String time, int id) {
Intent intent = new Intent(context, BusAlarmService.class);
Bundle bundle = new Bundle();
bundle.putString("endStation", endStation);
bundle.putString("Time", time);
intent.putExtras(bundle);
PendingIntent pendingIntent =
PendingIntent.getService(context, id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarm = (AlarmManager) context.getSystemService(Service.ALARM_SERVICE);
alarm.cancel(pendingIntent);
}
private NotificationCompat.Action next(Context context) {
Intent nextIntent = new Intent(context, MusicPlaybackService.class);
nextIntent.setAction(ACTION_NEXT);
PendingIntent nextPendingIntent = PendingIntent.getService(context,
PLAY_NEXT_PENDING_INTENT_ID,
nextIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
return new NotificationCompat.Action(R.drawable.ic_skip_next_notif, "Next", nextPendingIntent);
}
private void registerIntent() {
if (mRecognitionPendingIntent == null) {
Intent intent = new Intent(mApplicationContext, SKActivityRecognitionIntentService.class);
mRecognitionPendingIntent = PendingIntent.getService(mApplicationContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
mActivityRecognition.requestActivityUpdates(mClient, 0, mRecognitionPendingIntent);
}
protected PendingIntent buildPendingIntent(Context context, final String action, final ComponentName serviceName) {
Intent intent = new Intent(action);
intent.setComponent(serviceName);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
return PendingIntent.getForegroundService(context, 0, intent, 0);
} else {
return PendingIntent.getService(context, 0, intent, 0);
}
}
/**
* Show the notification. Either the regular notification with wearable features
* added to enhance, or trigger the full micro app on the wearable.
*
* @param cityId The city to trigger the notification for
* @param microApp If the micro app should be triggered or just enhanced notifications
*/
private void showNotification(String cityId, boolean microApp) {
List<Attraction> attractions = ATTRACTIONS.get(cityId);
if (microApp) {
// If micro app we first need to transfer some data over
sendDataToWearable(attractions);
}
// The first (closest) tourist attraction
Attraction attraction = attractions.get(0);
// Limit attractions to send
int count = attractions.size() > Constants.MAX_ATTRACTIONS ?
Constants.MAX_ATTRACTIONS : attractions.size();
// Pull down the tourist attraction images from the network and store
HashMap<String, Bitmap> bitmaps = new HashMap<>();
try {
for (int i = 0; i < count; i++) {
bitmaps.put(attractions.get(i).name,
Glide.with(this)
.load(attractions.get(i).imageUrl)
.asBitmap()
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.into(Constants.WEAR_IMAGE_SIZE, Constants.WEAR_IMAGE_SIZE)
.get());
}
} catch (InterruptedException | ExecutionException e) {
Log.e(TAG, "Error fetching image from network: " + e);
}
// The intent to trigger when the notification is tapped
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
DetailActivity.getLaunchIntent(this, attraction.name),
PendingIntent.FLAG_UPDATE_CURRENT);
// The intent to trigger when the notification is dismissed, in this case
// we want to clear remote notifications as well
PendingIntent deletePendingIntent =
PendingIntent.getService(this, 0, getClearRemoteNotificationsIntent(this), 0);
// Construct the main notification
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setStyle(new NotificationCompat.BigPictureStyle()
.bigPicture(bitmaps.get(attraction.name))
.setBigContentTitle(attraction.name)
.setSummaryText(getString(R.string.nearby_attraction))
)
.setLocalOnly(microApp)
.setContentTitle(attraction.name)
.setContentText(getString(R.string.nearby_attraction))
.setSmallIcon(R.drawable.ic_stat_maps_pin_drop)
.setContentIntent(pendingIntent)
.setDeleteIntent(deletePendingIntent)
.setColor(getResources().getColor(R.color.colorPrimary))
.setCategory(Notification.CATEGORY_RECOMMENDATION)
.setAutoCancel(true);
if (!microApp) {
// If not a micro app, create some wearable pages for
// the other nearby tourist attractions.
ArrayList<Notification> pages = new ArrayList<Notification>();
for (int i = 1; i < count; i++) {
// Calculate the distance from current location to tourist attraction
String distance = Utils.formatDistanceBetween(
Utils.getLocation(this), attractions.get(i).location);
// Construct the notification and add it as a page
pages.add(new NotificationCompat.Builder(this)
.setContentTitle(attractions.get(i).name)
.setContentText(distance)
.setSmallIcon(R.drawable.ic_stat_maps_pin_drop)
.extend(new NotificationCompat.WearableExtender()
.setBackground(bitmaps.get(attractions.get(i).name))
)
.build());
}
builder.extend(new NotificationCompat.WearableExtender().addPages(pages));
}
// Trigger the notification
NotificationManagerCompat.from(this).notify(
Constants.MOBILE_NOTIFICATION_ID, builder.build());
}
@Override
public void onCreate() {
Log.i(TAG, "Create version=" + Util.getSelfVersionName(this) + "/" + Util.getSelfVersionCode(this));
startForeground(NOTIFY_WAITING, getWaitingNotification());
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
if (jni_context != 0) {
Log.w(TAG, "Create with context=" + jni_context);
jni_stop(jni_context);
synchronized (jni_lock) {
jni_done(jni_context);
jni_context = 0;
}
}
// Native init
jni_context = jni_init(Build.VERSION.SDK_INT);
Log.i(TAG, "Created context=" + jni_context);
boolean pcap = prefs.getBoolean("pcap", false);
setPcap(pcap, this);
prefs.registerOnSharedPreferenceChangeListener(this);
Util.setTheme(this);
super.onCreate();
HandlerThread commandThread = new HandlerThread(getString(R.string.app_name) + " command", Process.THREAD_PRIORITY_FOREGROUND);
HandlerThread logThread = new HandlerThread(getString(R.string.app_name) + " log", Process.THREAD_PRIORITY_BACKGROUND);
HandlerThread statsThread = new HandlerThread(getString(R.string.app_name) + " stats", Process.THREAD_PRIORITY_BACKGROUND);
commandThread.start();
logThread.start();
statsThread.start();
commandLooper = commandThread.getLooper();
logLooper = logThread.getLooper();
statsLooper = statsThread.getLooper();
commandHandler = new CommandHandler(commandLooper);
logHandler = new LogHandler(logLooper);
statsHandler = new StatsHandler(statsLooper);
// Listen for user switches
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
IntentFilter ifUser = new IntentFilter();
ifUser.addAction(Intent.ACTION_USER_BACKGROUND);
ifUser.addAction(Intent.ACTION_USER_FOREGROUND);
registerReceiver(userReceiver, ifUser);
registeredUser = true;
}
// Listen for idle mode state changes
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
IntentFilter ifIdle = new IntentFilter();
ifIdle.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
registerReceiver(idleStateReceiver, ifIdle);
registeredIdleState = true;
}
// Listen for added/removed applications
IntentFilter ifPackage = new IntentFilter();
ifPackage.addAction(Intent.ACTION_PACKAGE_ADDED);
ifPackage.addAction(Intent.ACTION_PACKAGE_REMOVED);
ifPackage.addDataScheme("package");
registerReceiver(packageChangedReceiver, ifPackage);
registeredPackageChanged = true;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
try {
listenNetworkChanges();
} catch (Throwable ex) {
Log.w(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
listenConnectivityChanges();
}
else
listenConnectivityChanges();
// Monitor networks
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
cm.registerNetworkCallback(
new NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET).build(),
networkMonitorCallback);
// Setup house holding
Intent alarmIntent = new Intent(this, ServiceSinkhole.class);
alarmIntent.setAction(ACTION_HOUSE_HOLDING);
PendingIntent pi;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
pi = PendingIntent.getForegroundService(this, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
else
pi = PendingIntent.getService(this, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
am.setInexactRepeating(AlarmManager.RTC, SystemClock.elapsedRealtime() + 60 * 1000, AlarmManager.INTERVAL_HALF_DAY, pi);
}
private NotificationCompat.Builder recreateBuilderWithBigTextStyle() {
// Main steps for building a BIG_TEXT_STYLE notification (for more detailed comments on
// building this notification, check MainActivity.java)::
// 0. Get your data
// 1. Build the BIG_TEXT_STYLE
// 2. Set up main Intent for notification
// 3. Create additional Actions for the Notification
// 4. Build and issue the notification
// 0. Get your data (everything unique per Notification).
MockDatabase.BigTextStyleReminderAppData bigTextStyleReminderAppData =
MockDatabase.getBigTextStyleData();
// 1. Retrieve Notification Channel for O and beyond devices (26+). We don't need to create
// the NotificationChannel, since it was created the first time this Notification was
// created.
String notificationChannelId = bigTextStyleReminderAppData.getChannelId();
// 2. Build the BIG_TEXT_STYLE.
BigTextStyle bigTextStyle = new NotificationCompat.BigTextStyle()
.bigText(bigTextStyleReminderAppData.getBigText())
.setBigContentTitle(bigTextStyleReminderAppData.getBigContentTitle())
.setSummaryText(bigTextStyleReminderAppData.getSummaryText());
// 3. Set up main Intent for notification
Intent notifyIntent = new Intent(this, BigTextMainActivity.class);
notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent notifyPendingIntent =
PendingIntent.getActivity(
this,
0,
notifyIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
// 4. Create additional Actions (Intents) for the Notification
// Snooze Action
Intent snoozeIntent = new Intent(this, BigTextIntentService.class);
snoozeIntent.setAction(BigTextIntentService.ACTION_SNOOZE);
PendingIntent snoozePendingIntent = PendingIntent.getService(this, 0, snoozeIntent, 0);
NotificationCompat.Action snoozeAction =
new NotificationCompat.Action.Builder(
R.drawable.ic_alarm_white_48dp,
"Snooze",
snoozePendingIntent)
.build();
// Dismiss Action
Intent dismissIntent = new Intent(this, BigTextIntentService.class);
dismissIntent.setAction(BigTextIntentService.ACTION_DISMISS);
PendingIntent dismissPendingIntent = PendingIntent.getService(this, 0, dismissIntent, 0);
NotificationCompat.Action dismissAction =
new NotificationCompat.Action.Builder(
R.drawable.ic_cancel_white_48dp,
"Dismiss",
dismissPendingIntent)
.build();
// 5. Build and issue the notification.
// Notification Channel Id is ignored for Android pre O (26).
NotificationCompat.Builder notificationCompatBuilder =
new NotificationCompat.Builder(
getApplicationContext(), notificationChannelId);
GlobalNotificationBuilder.setNotificationCompatBuilderInstance(notificationCompatBuilder);
notificationCompatBuilder
.setStyle(bigTextStyle)
.setContentTitle(bigTextStyleReminderAppData.getContentTitle())
.setContentText(bigTextStyleReminderAppData.getContentText())
.setSmallIcon(R.drawable.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(
getResources(),
R.drawable.ic_alarm_white_48dp))
.setContentIntent(notifyPendingIntent)
.setColor(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary))
.setCategory(Notification.CATEGORY_REMINDER)
.setPriority(bigTextStyleReminderAppData.getPriority())
.setVisibility(bigTextStyleReminderAppData.getChannelLockscreenVisibility())
.addAction(snoozeAction)
.addAction(dismissAction);
return notificationCompatBuilder;
}
private static Notification buildForegroundNotification(
Context context,
SoundProfile[] profiles,
VolumeControl control,
List<Integer> volumeTypesToShow
) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, staticNotificationId);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.notification_view);
if (profiles != null) {
remoteViews.removeAllViews(R.id.notifications_user_profiles);
for (SoundProfile profile : profiles) {
RemoteViews profileViews = new RemoteViews(context.getPackageName(), R.layout.notification_profile_name);
profileViews.setTextViewText(R.id.notification_profile_title, profile.name);
Intent i = getIntentForProfile(context, profile);
PendingIntent pendingIntent;
int requestId = PROFILE_ID_PREFIX + profile.id;
pendingIntent = PendingIntent.getService(context, requestId, i, 0);
profileViews.setOnClickPendingIntent(R.id.notification_profile_title, pendingIntent);
remoteViews.addView(R.id.notifications_user_profiles, profileViews);
}
}
if (volumeTypesToShow != null) {
remoteViews.removeAllViews(R.id.volume_sliders);
for (AudioType notificationType : AudioType.getAudioTypes(true)) {
if (volumeTypesToShow.contains(notificationType.audioStreamName)) {
remoteViews.addView(R.id.volume_sliders, buildVolumeSlider(context, control, notificationType.audioStreamName, context.getString(notificationType.nameId)));
}
}
remoteViews.setOnClickPendingIntent(R.id.remove_notification_action, PendingIntent.getService(context, 100, getStopIntent(context), 0));
}
builder
.setContentTitle(context.getString(R.string.app_name))
.setOngoing(true)
.setContentText(context.getString(R.string.notification_widget))
.setSmallIcon(R.drawable.notification_icon)
.setTicker(context.getString(R.string.app_name))
.setContentIntent(PendingIntent.getActivity(context, 0, new Intent(context, MainActivity.class), 0));
if ((volumeTypesToShow != null && volumeTypesToShow.size() > 0) || (profiles != null && profiles.length > 0)) {
builder.setContentText(context.getString(R.string.notification_widget_featured))
.setCustomBigContentView(remoteViews);
}
return builder.build();
}
private void showFailedNotification(final WeiboSendTask task) {
Notification.Builder builder = new Notification.Builder(SendReplyToCommentService.this)
.setTicker(getString(R.string.send_failed))
.setContentTitle(getString(R.string.send_faile_click_to_open)).setContentText(content)
.setOnlyAlertOnce(true).setAutoCancel(true)
.setSmallIcon(R.drawable.send_failed).setOngoing(false);
Intent notifyIntent = WriteReplyToCommentActivity.startBecauseSendFailed(SendReplyToCommentService.this,
account, content, oriMsg, replyDraftBean,
repostContent, e.getError());
PendingIntent pendingIntent = PendingIntent.getActivity(SendReplyToCommentService.this, 0, notifyIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(pendingIntent);
Notification notification;
if (Utility.isJB()) {
Notification.BigTextStyle bigTextStyle = new Notification.BigTextStyle(builder);
bigTextStyle.setBigContentTitle(getString(R.string.send_faile_click_to_open));
bigTextStyle.bigText(content);
bigTextStyle.setSummaryText(account.getUsernick());
builder.setStyle(bigTextStyle);
Intent intent = new Intent(SendReplyToCommentService.this, SendReplyToCommentService.class);
intent.putExtra("oriMsg", oriMsg);
intent.putExtra("content", content);
intent.putExtra(Constants.TOKEN, token);
intent.putExtra(Constants.ACCOUNT, account);
intent.putExtra("repostContent", repostContent);
intent.putExtra("lastNotificationId", tasksNotifications.get(task));
PendingIntent retrySendIntent = PendingIntent.getService(SendReplyToCommentService.this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
builder.addAction(R.drawable.send_light, getString(R.string.retry_send), retrySendIntent);
notification = builder.build();
} else {
notification = builder.getNotification();
}
final int id = tasksNotifications.get(task);
NotificationUtility.show(notification, id);
handler.postDelayed(new Runnable() {
@Override
public void run() {
stopServiceIfTasksAreEnd(task);
}
}, 3000);
}
@VisibleForTesting
public static PendingIntent getRemoveAllIncognitoTabsIntent(Context context) {
Intent intent = new Intent(context, IncognitoNotificationService.class);
intent.setAction(ACTION_CLOSE_ALL_INCOGNITO);
return PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_ONE_SHOT);
}
protected final PendingIntent pending(Intent intent) {
return PendingIntent.getService(mContext, 0, intent, 0);
}
private PendingIntent getChancelPendingIntent() {
Intent intent = new Intent(this, DownloadService.class);
intent.setAction(DownloadService.cancelAction);
return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
private PendingIntent getPendingIntent() {
return PendingIntent.getService(this, 0,
getBackgroundSubscribeServiceIntent(), PendingIntent.FLAG_UPDATE_CURRENT);
}