コード例 #1
0
  /** If there are actions, shows the button related views, and adds a button for each action. */
  private void addActionButtons(RemoteViews bigView) {
    // Remove the existing buttons in case an existing notification is being updated.
    bigView.removeAllViews(R.id.buttons);

    // Always set the visibility of the views associated with the action buttons. The current
    // visibility state is not known as perhaps an existing notification is being updated.
    int visibility = mActions.isEmpty() ? View.GONE : View.VISIBLE;
    bigView.setViewVisibility(R.id.button_divider, visibility);
    bigView.setViewVisibility(R.id.buttons, visibility);

    Resources resources = mContext.getResources();
    DisplayMetrics metrics = resources.getDisplayMetrics();
    for (Action action : mActions) {
      RemoteViews view =
          new RemoteViews(mContext.getPackageName(), R.layout.web_notification_button);

      // If there is an icon then set it and add some padding.
      if (action.iconBitmap != null || action.iconId != 0) {
        if (useMaterial()) {
          view.setInt(R.id.button_icon, "setColorFilter", BUTTON_ICON_COLOR_MATERIAL);
        }

        int iconWidth = 0;
        if (action.iconBitmap != null) {
          view.setImageViewBitmap(R.id.button_icon, action.iconBitmap);
          iconWidth = action.iconBitmap.getWidth();
        } else if (action.iconId != 0) {
          view.setImageViewResource(R.id.button_icon, action.iconId);
          BitmapFactory.Options options = new BitmapFactory.Options();
          options.inJustDecodeBounds = true;
          BitmapFactory.decodeResource(resources, action.iconId, options);
          iconWidth = options.outWidth;
        }
        iconWidth = dpToPx(Math.min(pxToDp(iconWidth, metrics), MAX_ACTION_ICON_WIDTH_DP), metrics);

        // Set the padding of the button so the text does not overlap with the icon. Flip
        // between left and right manually as RemoteViews does not expose a method that sets
        // padding in a writing-direction independent way.
        int buttonPadding =
            dpToPx(BUTTON_PADDING_START_DP + BUTTON_ICON_PADDING_DP, metrics) + iconWidth;
        int buttonPaddingLeft = LocalizationUtils.isLayoutRtl() ? 0 : buttonPadding;
        int buttonPaddingRight = LocalizationUtils.isLayoutRtl() ? buttonPadding : 0;
        view.setViewPadding(R.id.button, buttonPaddingLeft, 0, buttonPaddingRight, 0);
      }

      view.setTextViewText(R.id.button, action.title);
      view.setOnClickPendingIntent(R.id.button, action.intent);
      bigView.addView(R.id.buttons, view);
    }
  }
コード例 #2
0
 @Override
 public void setViewPadding(int viewId, int left, int top, int right, int bottom) {
   mRemoteViews.setViewPadding(viewId, left, top, right, bottom);
 }
コード例 #3
0
  @Override
  public Notification build() {
    // A note about RemoteViews and updating notifications. When a notification is passed to the
    // {@code NotificationManager} with the same tag and id as a previous notification, an
    // in-place update will be performed. In that case, the actions of all new
    // {@link RemoteViews} will be applied to the views of the old notification. This is safe
    // for actions that overwrite old values such as setting the text of a {@code TextView}, but
    // care must be taken for additive actions. Especially in the case of
    // {@link RemoteViews#addView} the result could be to append new views below stale ones. In
    // that case {@link RemoteViews#removeAllViews} must be called before adding new ones.
    RemoteViews compactView = new RemoteViews(mContext.getPackageName(), R.layout.web_notification);
    RemoteViews bigView = new RemoteViews(mContext.getPackageName(), R.layout.web_notification_big);

    float fontScale = mContext.getResources().getConfiguration().fontScale;
    bigView.setInt(R.id.body, "setMaxLines", calculateMaxBodyLines(fontScale));
    int scaledPadding =
        calculateScaledPadding(fontScale, mContext.getResources().getDisplayMetrics());
    String formattedTime = "";

    // Temporarily allowing disk access. TODO: Fix. See http://crbug.com/577185
    StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
    StrictMode.allowThreadDiskWrites();
    try {
      long time = SystemClock.elapsedRealtime();
      formattedTime = DateFormat.getTimeFormat(mContext).format(new Date());
      RecordHistogram.recordTimesHistogram(
          "Android.StrictMode.NotificationUIBuildTime",
          SystemClock.elapsedRealtime() - time,
          TimeUnit.MILLISECONDS);
    } finally {
      StrictMode.setThreadPolicy(oldPolicy);
    }

    for (RemoteViews view : new RemoteViews[] {compactView, bigView}) {
      view.setTextViewText(R.id.time, formattedTime);
      view.setTextViewText(R.id.title, mTitle);
      view.setTextViewText(R.id.body, mBody);
      view.setTextViewText(R.id.origin, mOrigin);
      view.setImageViewBitmap(R.id.icon, getNormalizedLargeIcon());
      view.setViewPadding(R.id.title, 0, scaledPadding, 0, 0);
      view.setViewPadding(R.id.body_container, 0, scaledPadding, 0, scaledPadding);
      addWorkProfileBadge(view);

      int smallIconId = useMaterial() ? R.id.small_icon_overlay : R.id.small_icon_footer;
      view.setViewVisibility(smallIconId, View.VISIBLE);
      if (mSmallIconBitmap != null) {
        view.setImageViewBitmap(smallIconId, mSmallIconBitmap);
      } else {
        view.setImageViewResource(smallIconId, mSmallIconId);
      }
    }
    addActionButtons(bigView);
    configureSettingsButton(bigView);

    // Note: this is not a NotificationCompat builder so be mindful of the
    // API level of methods you call on the builder.
    Notification.Builder builder = new Notification.Builder(mContext);
    builder.setTicker(mTickerText);
    builder.setContentIntent(mContentIntent);
    builder.setDeleteIntent(mDeleteIntent);
    builder.setDefaults(mDefaults);
    builder.setVibrate(mVibratePattern);
    builder.setWhen(mTimestamp);
    builder.setOnlyAlertOnce(!mRenotify);
    builder.setContent(compactView);

    // Some things are duplicated in the builder to ensure the notification shows correctly on
    // Wear devices and custom lock screens.
    builder.setContentTitle(mTitle);
    builder.setContentText(mBody);
    builder.setSubText(mOrigin);
    builder.setLargeIcon(getNormalizedLargeIcon());
    setSmallIconOnBuilder(builder, mSmallIconId, mSmallIconBitmap);
    for (Action action : mActions) {
      addActionToBuilder(builder, action);
    }
    if (mSettingsAction != null) {
      addActionToBuilder(builder, mSettingsAction);
    }
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
      // Notification.Builder.setPublicVersion was added in Android L.
      builder.setPublicVersion(createPublicNotification(mContext));
    }

    Notification notification = builder.build();
    notification.bigContentView = bigView;
    return notification;
  }