Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 初探Android N 那些讓人感興趣的東西--通知的好用功能

初探Android N 那些讓人感興趣的東西--通知的好用功能

編輯:關於Android編程

上周寫完那篇Blog之後就一直做著被分配到的Web任務,也就沒繼續捯饬N那些事,然後今天還在看Notification這部分,然後看到了LNotification這個包,讀完源碼之後繼續給大家做簡單的分析,因為源碼涉及翻牆所以代碼和自己加的注釋丟到Git了

安理下我的收納庫:Android">https://github.com/ddwhan0123/Useful-Open-Source-Android

首先我們來看下這個項目在哪個目錄下
這裡寫圖片描述

地址如下:https://developer.android.com/samples/LNotifications/index.html

跟我們上次的Messaging Service是鄰居。

那我們來看下演示效果(部分)

他在桌面icon也有 類似 待處理事件的通知
這裡寫圖片描述

實現點擊觸發復雜事件以及通知排序<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPjxpbWcgYWx0PQ=="這裡寫圖片描述" src="/uploadfile/Collfiles/20160531/20160531090328117.jpg" title="\" />

這裡寫圖片描述

OK,因為是Sample所以好看難看我們不管,我們來看看分別能做什麼,有3個功能塊(都是Fragment)的,一個一個來分析


首先是HeadsUpNotificationFragment(這部分注釋很詳細了,就不過多分析了)

主要是實現這一點 用戶點擊通知會在Activity Task中生成一個新的實例

/**
 * Fragment that demonstrates options for displaying Heads-Up Notifications.
 * 這種模式下,用戶點擊通知會在Activity Task中生成一個新的實例
 */
public class HeadsUpNotificationFragment extends Fragment {

    /**
     * NotificationId用於從此Fragment的通知。
     */
    private static final int NOTIFICATION_ID = 1;

    private NotificationManager mNotificationManager;

    /**
     * 按鈕用於點擊顯示通知
     */
    private Button mShowNotificationButton;

    /**
     * 如果選中,該Fragment創建的通知將顯示為Heads-Up通知。
     */
    private CheckBox mUseHeadsUpCheckbox;

    /**
     * 使用此工廠方法來創建新實例
     * 該Fragment使用提供的參數。
     *
     * @return 新的HeadsUpNotificationFragment的實例.
     */
    public static HeadsUpNotificationFragment newInstance() {
        HeadsUpNotificationFragment fragment = new HeadsUpNotificationFragment();
        fragment.setRetainInstance(true);
        return fragment;
    }

    public HeadsUpNotificationFragment() {
        // 空構造
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //初始化NotificationManager
        mNotificationManager = (NotificationManager) getActivity().getSystemService(Context
                .NOTIFICATION_SERVICE);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // 填充UI
        return inflater.inflate(R.layout.fragment_heads_up_notification, container, false);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        mShowNotificationButton = (Button) view.findViewById(R.id.show_notification_button);
        //點擊按鈕就Toast一段話,告知用戶已經觸發點擊事件
        mShowNotificationButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mNotificationManager.notify(NOTIFICATION_ID, createNotification(
                        mUseHeadsUpCheckbox.isChecked()));
                Toast.makeText(getActivity(), "Show Notification clicked", Toast.LENGTH_SHORT).show();
            }
        });
        mUseHeadsUpCheckbox = (CheckBox) view.findViewById(R.id.use_heads_up_checkbox);
    }

    /**
     * 創建一個新的取決於參數的通知。
     *
     * @param makeHeadsUpNotification 一個布爾值判斷是否通知將作為heads-up通知來創建。
     *                                
  • *
    • true : heads-up通知
    • *
      • false : 普通通知
      • *
      * @return 一個Notification 實例. */ //@VisibleForTesting Notification createNotification(boolean makeHeadsUpNotification) { //這裡就是一些普通的配置 Notification.Builder notificationBuilder = new Notification.Builder(getActivity()) .setSmallIcon(R.drawable.ic_launcher_notification) .setPriority(Notification.PRIORITY_DEFAULT) .setCategory(Notification.CATEGORY_MESSAGE) .setContentTitle("Sample Notification") .setContentText("This is a normal notification."); //如果是heads-up通知 if (makeHeadsUpNotification) { Intent push = new Intent(); push.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); push.setClass(getActivity(), LNotificationActivity.class); PendingIntent fullScreenPendingIntent = PendingIntent.getActivity(getActivity(), 0, push, PendingIntent.FLAG_CANCEL_CURRENT); notificationBuilder .setContentText("Heads-Up Notification on Android L or above.") .setFullScreenIntent(fullScreenPendingIntent, true); } return notificationBuilder.build(); } }

      然後是 VisibilityMetadataFragment

      **主要行為是 在鎖屏條件下Notification的各種現實情況,Public Private Secret
      可應對與所需的一些業務場景,諸如需要輸入一些pin 密碼什麼的才可以做操作的功能**

      /**
       * Fragment that demonstrates how notifications with different visibility metadata differ on
       * a lockscreen.
       *在鎖屏情況下不同的通知,默認PUBLIC
       */
      public class VisibilityMetadataFragment extends Fragment {
      
          private NotificationManager mNotificationManager;
      
          /**
           * {@link RadioGroup} that has Visibility RadioButton in its children.
           */
          //用於選擇模式
          private RadioGroup mRadioGroup;
      
          /**
           * 構建不同的ID,讓他被區別對待
           */
          private Integer mIncrementalNotificationId = Integer.valueOf(0);
      
          /**
           * 按鈕,顯示通知用
           */
          private Button mShowNotificationButton;
      
          /**
           * 使用此工廠方法來創建使用提供的參數,該Fragment的新實例。
           *
           * @return 一個新的NotificationFragment的實例.
           */
          public static VisibilityMetadataFragment newInstance() {
              VisibilityMetadataFragment fragment = new VisibilityMetadataFragment();
              fragment.setRetainInstance(true);
              return fragment;
          }
      
          public VisibilityMetadataFragment() {
              // Required empty public constructor
          }
      
          @Override
          public void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              mNotificationManager = (NotificationManager) getActivity().getSystemService(Context
                      .NOTIFICATION_SERVICE);
          }
      
          @Override
          public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                   Bundle savedInstanceState) {
              // Inflate the layout for this fragment
              return inflater.inflate(R.layout.fragment_visibility_metadata_notification, container, false);
          }
      
          @Override
          public void onViewCreated(View view, Bundle savedInstanceState) {
              super.onViewCreated(view, savedInstanceState);
              mShowNotificationButton = (Button) view.findViewById(R.id.show_notification_button);
              mShowNotificationButton.setOnClickListener(new View.OnClickListener() {
                  @Override
                  public void onClick(View view) {
                      NotificationVisibility visibility = getVisibilityFromSelectedRadio(mRadioGroup);
                      showNotificationClicked(visibility);
                  }
              });
              mRadioGroup = (RadioGroup) view.findViewById(R.id.visibility_radio_group);
          }
      
          /**
           * 創建一個具有不同級別可視性的通知。
           *
           * @param visibility 要創建的通知的可見性
           * @return 通知的實例.
           */
          //@VisibleForTesting
          Notification createNotification(NotificationVisibility visibility) {
              Notification.Builder notificationBuilder = new Notification.Builder(getActivity())
                      .setContentTitle("Notification for Visibility metadata");
      
              notificationBuilder.setVisibility(visibility.getVisibility());
              notificationBuilder.setContentText(String.format("Visibility : %s",
                      visibility.getDescription()));
              notificationBuilder.setSmallIcon(visibility.getNotificationIconId());
      
              return notificationBuilder.build();
          }
      
          /**
           * Returns a {@link NotificationVisibility} depending on which RadioButton in the radiogroup
           * is selected.
           *
           * @param radiogroup The RadioGroup.
           * @return The instance of {@link NotificationVisibility} corresponding to RadioButton.
           */
          private NotificationVisibility getVisibilityFromSelectedRadio(RadioGroup radiogroup) {
              switch (radiogroup.getCheckedRadioButtonId()) {
                  case R.id.visibility_public_radio_button:
                      return NotificationVisibility.PUBLIC;
                  case R.id.visibility_private_radio_button:
                      return NotificationVisibility.PRIVATE;
                  case R.id.visibility_secret_radio_button:
                      return NotificationVisibility.SECRET;
                  default:
                      //If not selected, returns PUBLIC as default.
                      return NotificationVisibility.PUBLIC;
              }
          }
      
          /**
           * Invoked when {@link #mShowNotificationButton} is clicked.
           * Creates a new notification with a different visibility level.
           *
           * @param visibility The visibility of the notification to be created.
           */
          private void showNotificationClicked(NotificationVisibility visibility) {
              // Assigns a unique (incremented) notification ID in order to treat each notification as a
              // different one. This helps demonstrate how a notification with a different visibility
              // level differs on the lockscreen.
              mIncrementalNotificationId = new Integer(mIncrementalNotificationId + 1);
              mNotificationManager.notify(mIncrementalNotificationId, createNotification(visibility));
              Toast.makeText(getActivity(), "Show Notification clicked", Toast.LENGTH_SHORT).show();
          }
      
          /**
           * Enum indicating possible visibility levels for notifications and related data(String
           * representation of visibility levels, an icon ID to create a notification) to
           * create a notification.
           */
          //@VisibleForTesting
           enum NotificationVisibility {
              PUBLIC(Notification.VISIBILITY_PUBLIC, "Public", R.drawable.ic_public_notification),
              PRIVATE(Notification.VISIBILITY_PRIVATE, "Private", R.drawable.ic_private_notification),
              SECRET(Notification.VISIBILITY_SECRET, "Secret", R.drawable.ic_secret_notification);
      
              /**
               * Visibility level of the notification.
               */
              private final int mVisibility;
      
              /**
               * String representation of the visibility.
               */
              private final String mDescription;
      
              /**
               * Id of an icon used for notifications created from the visibility.
               */
              private final int mNotificationIconId;
      
              NotificationVisibility(int visibility, String description, int notificationIconId) {
                  mVisibility = visibility;
                  mDescription = description;
                  mNotificationIconId = notificationIconId;
              }
      
              public int getVisibility() {
                  return mVisibility;
              }
      
              public String getDescription() {
                  return mDescription;
              }
      
              public int getNotificationIconId() {
                  return mNotificationIconId;
              }
          }
      }
      

      還有個就是我們截圖中的類OtherMetadataFragment

      他可以根據用戶操作做一些列諸如郵件,電話,鬧鐘提示等功能,並對通知進行輕重緩急的排序

      /**
       * Fragment that demonstrates how to attach metadata introduced in Android L, such as
       * priority data, notification category and person data.
       * 通知列表會根據優先級高低進行排序
       */
      public class OtherMetadataFragment extends Fragment {
      
          private static final String TAG = OtherMetadataFragment.class.getSimpleName();
      
          /**
           * 用於采摘聯系人請求的代碼。
           */
          public static final int REQUEST_CODE_PICK_CONTACT = 1;
      
          /**
           * Incremental Integer used for ID for notifications so that each notification will be
           * treated differently.
           * 構建不同的ID,讓他被區別對待
           */
          private Integer mIncrementalNotificationId = Integer.valueOf(0);
      
          private NotificationManager mNotificationManager;
      
          /**
           * 按鈕,顯示通知用
           */
          private Button mShowNotificationButton;
      
          /**
           * Spinner that holds possible categories used for a notification as
           * {@link Notification.Builder#setCategory(String)}.
           * 設置類型的下拉選擇欄
           */
          private Spinner mCategorySpinner;
      
          /**
           * Spinner that holds possible priorities used for a notification as
           * {@link Notification.Builder#setPriority(int)}.
           * 設置優先級的下拉選擇欄
           */
          private Spinner mPrioritySpinner;
      
          /**
           * Holds a URI for the person to be attached to the notification.
           * 持有的URI的人要附加到該通知。
           */
          //@VisibleForTesting
          Uri mContactUri;
      
          /**
           * 使用此工廠方法來創建使用提供的參數,該Fragment的新實例。
           *
           * @return 1個新的NotificationFragment的實例.
           */
          public static OtherMetadataFragment newInstance() {
              OtherMetadataFragment fragment = new OtherMetadataFragment();
              fragment.setRetainInstance(true);
              return fragment;
          }
      
          public OtherMetadataFragment() {
              // Required empty public constructor
          }
      
          @Override
          public void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              mNotificationManager = (NotificationManager) getActivity().getSystemService(Context
                      .NOTIFICATION_SERVICE);
          }
      
          @Override
          public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                   Bundle savedInstanceState) {
              // Inflate the layout for this fragment
              return inflater.inflate(R.layout.fragment_other_metadata, container, false);
          }
      
          @Override
          public void onViewCreated(View view, Bundle savedInstanceState) {
              super.onViewCreated(view, savedInstanceState);
              mShowNotificationButton = (Button) view.findViewById(R.id.show_notification_button);
              mShowNotificationButton.setOnClickListener(new View.OnClickListener() {
                  @Override
                  public void onClick(View view) {
                      //往spinner裡填東西,然後發送通知
                      Priority selectedPriority = (Priority) mPrioritySpinner.getSelectedItem();
                      Category selectedCategory = (Category) mCategorySpinner.getSelectedItem();
                      showNotificationClicked(selectedPriority, selectedCategory, mContactUri);
                  }
              });
              //填充數據
              mCategorySpinner = (Spinner) view.findViewById(R.id.category_spinner);
              ArrayAdapter categoryArrayAdapter = new ArrayAdapter(getActivity(),
                      android.R.layout.simple_spinner_item, Category.values());
              categoryArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
              mCategorySpinner.setAdapter(categoryArrayAdapter);
      
              mPrioritySpinner = (Spinner) view.findViewById(R.id.priority_spinner);
              ArrayAdapter priorityArrayAdapter = new ArrayAdapter(getActivity(),
                      android.R.layout.simple_spinner_item, Priority.values());
              priorityArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
              mPrioritySpinner.setAdapter(priorityArrayAdapter);
      
              view.findViewById(R.id.attach_person).setOnClickListener(new View.OnClickListener() {
                  @Override
                  public void onClick(View view) {
                      findContact();
                  }
              });
      
              view.findViewById(R.id.contact_entry).setVisibility(View.GONE);
          }
      
          @Override
          public void onActivityResult(int requestCode, int resultCode, Intent data) {
              super.onActivityResult(requestCode, resultCode, data);
              switch (requestCode) {
                  case REQUEST_CODE_PICK_CONTACT:
                      if (resultCode == Activity.RESULT_OK) {
                          Uri contactUri = data.getData();
                          mContactUri = contactUri;
                          updateContactEntryFromUri(contactUri);
                      }
                      break;
              }
          }
      
          /**
           * Invoked when {@link #mShowNotificationButton} is clicked.
           * Creates a new notification and sets metadata passed as arguments.
           *
           * @param priority   The priority metadata.
           * @param category   The category metadata.
           * @param contactUri The URI to be added to the new notification as metadata.
           * @return A Notification instance.
           */
          //@VisibleForTesting
          Notification createNotification(Priority priority, Category category, Uri contactUri) {
              Notification.Builder notificationBuilder = new Notification.Builder(getActivity())
                      .setContentTitle("Notification with other metadata")
                      .setSmallIcon(R.drawable.ic_launcher_notification)
                      .setPriority(priority.value)
                      .setCategory(category.value)
                      .setContentText(String.format("Category %s, Priority %s", category.value,
                              priority.name()));
              if (contactUri != null) {
                  notificationBuilder.addPerson(contactUri.toString());
                  Bitmap photoBitmap = loadBitmapFromContactUri(contactUri);
                  if (photoBitmap != null) {
                      notificationBuilder.setLargeIcon(photoBitmap);
                  }
              }
              return notificationBuilder.build();
          }
      
          /**
           * Invoked when {@link #mShowNotificationButton} is clicked.
           * Creates a new notification and sets metadata passed as arguments.
           *
           * @param priority   The priority metadata.
           * @param category   The category metadata.
           * @param contactUri The URI to be added to the new notification as metadata.
           */
          private void showNotificationClicked(Priority priority, Category category, Uri contactUri) {
              // Assigns a unique (incremented) notification ID in order to treat each notification as a
              // different one. This helps demonstrate how a priority flag affects ordering.
              mIncrementalNotificationId = new Integer(mIncrementalNotificationId + 1);
              mNotificationManager.notify(mIncrementalNotificationId, createNotification(priority,
                      category, contactUri));
              Toast.makeText(getActivity(), "Show Notification clicked", Toast.LENGTH_SHORT).show();
          }
      
          private void findContact() {
              Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
              startActivityForResult(intent, REQUEST_CODE_PICK_CONTACT);
          }
      
          /**
           * Returns a {@link Bitmap} from the Uri specified as the argument.
           *
           * @param contactUri The Uri from which the result Bitmap is created.
           * @return The {@link Bitmap} instance retrieved from the contactUri.
           */
          private Bitmap loadBitmapFromContactUri(Uri contactUri) {
              if (contactUri == null) {
                  return null;
              }
              Bitmap result = null;
              Cursor cursor = getActivity().getContentResolver().query(contactUri, null, null, null,
                      null);
              if (cursor != null && cursor.moveToFirst()) {
                  int idx = cursor.getColumnIndex(ContactsContract.Contacts.PHOTO_ID);
                  String hasPhoto = cursor.getString(idx);
                  Uri photoUri = Uri.withAppendedPath(contactUri, ContactsContract.Contacts.Photo
                          .CONTENT_DIRECTORY);
                  if (hasPhoto != null) {
                      try {
                          result = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver()
                                  , photoUri);
                      } catch (IOException e) {
                          Log.e(TAG, String.format("Failed to load resource. Uri %s", photoUri), e);
                      }
                  } else {
                      Drawable defaultContactDrawable = getActivity().getResources().getDrawable(R
                              .drawable.ic_contact_picture);
                      result = ((BitmapDrawable) defaultContactDrawable).getBitmap();
                  }
              }
              return result;
          }
      
          /**
           * Updates the Contact information on the screen when a contact is picked.
           *
           * @param contactUri The Uri from which the contact is retrieved.
           */
          private void updateContactEntryFromUri(Uri contactUri) {
              Cursor cursor = getActivity().getContentResolver().query(contactUri, null, null, null,
                      null);
              if (cursor != null && cursor.moveToFirst()) {
                  int idx = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
                  String name = cursor.getString(idx);
                  idx = cursor.getColumnIndex(ContactsContract.Contacts.PHOTO_ID);
                  String hasPhoto = cursor.getString(idx);
      
                  Uri photoUri = Uri.withAppendedPath(contactUri, ContactsContract.Contacts.Photo
                          .CONTENT_DIRECTORY);
                  ImageView contactPhoto = (ImageView) getActivity().findViewById(R.id.contact_photo);
                  if (hasPhoto != null) {
                      contactPhoto.setImageURI(photoUri);
                  } else {
                      Drawable defaultContactDrawable = getActivity().getResources().getDrawable(R
                              .drawable.ic_contact_picture);
                      contactPhoto.setImageDrawable(defaultContactDrawable);
                  }
                  TextView contactName = (TextView) getActivity().findViewById(R.id.contact_name);
                  contactName.setText(name);
      
                  getActivity().findViewById(R.id.contact_entry).setVisibility(View.VISIBLE);
                  getActivity().findViewById(R.id.attach_person).setVisibility(View.GONE);
                  getActivity().findViewById(R.id.click_to_change).setOnClickListener(new View.OnClickListener() {
                      @Override
                      public void onClick(View view) {
                          findContact();
                      }
                  });
                  Log.i(TAG, String.format("Contact updated. Name %s, PhotoUri %s", name, photoUri));
              }
          }
      
          /**
           * Enum indicating possible categories in {@link Notification} used from
           * {@link #mCategorySpinner}.
           */
           enum Category {
              ALARM("alarm"),
              CALL("call"),
              EMAIL("email"),
              ERROR("err"),
              EVENT("event"),
              MESSAGE("msg"),
              PROGRESS("progress"),
              PROMO("promo"),
              RECOMMENDATION("recommendation"),
              SERVICE("service"),
              SOCIAL("social"),
              STATUS("status"),
              SYSTEM("sys"),
              TRANSPORT("transport");
      
              private final String value;
      
              Category(String value) {
                  this.value = value;
              }
      
              @Override
              public String toString() {
                  return value;
              }
          }
      
          /**
           * Enum indicating possible priorities in {@link Notification} used from
           * {@link #mPrioritySpinner}.
           */
          //@VisibleForTesting
           enum Priority {
              DEFAULT(Notification.PRIORITY_DEFAULT),
              MAX(Notification.PRIORITY_MAX),
              HIGH(Notification.PRIORITY_HIGH),
              LOW(Notification.PRIORITY_LOW),
              MIN(Notification.PRIORITY_MIN);
      
              private final int value;
      
              Priority(int value) {
                  this.value = value;
              }
          }
      }
      

      這部分的代碼比較長,沒有對每一部分進行翻譯OR解釋,在這裡大致描述下。
      首先聲明了2個枚舉,一個操作類型,一個操作排序的次序。

      測試的時候分別對,默認,最高和最低進行了測試,結果也如大家所看到的,最高就會在最上面,最低就出現在通知欄最下面了,然後就是行為類型,用戶在產生通知之前需要選擇他的行為類型以及該類型所需的一些參數諸如通訊錄聯系人的號碼啊,郵箱地址什麼的,有些需要圖片操作的源碼裡也做了相應實現大家需要的可以調用就行了。(因為測試機沒通訊錄,所以沒有測的很深,大家可以自己插卡試試,這部分如何暫時保留意見,但是排序是絕對有效的)

      以上是對這個包裡3個實現Fragment的簡單分析,然後提一下注意點,使用場景在 安卓 L 就是 棒棒糖版本版本過低的有問題就是自己適配了。

      最重要的一點是 這些通知 都會在桌面的應用 ICON產生 1 2 3這類未讀數的統計

      源碼地址:https://github.com/ddwhan0123/BlogSample/blob/master/LNotifications.zip?raw=true

       

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved