安卓开发:NotificationListenerService和kitkat

安卓4.3版本 (API 18)引入了NotificationListenerService。我几个月前曾发帖讨论过这个接口。

安卓4.4(API 19)新加了一些特性,现在我们可以通过notification获得更多的信息(以前需要反射获取一些消息)。

比如4.3中我们需要扩展NotificationListenerService实现其两个方法:onNotificationPosted() 和 onNotificationRemoved()

public class SimpleKitkatNotificationListener extends NotificationListenerService {
        @Override
        public void onNotificationPosted(StatusBarNotification sbn) {
              //..............
        }

        @Override
        public void onNotificationRemoved(StatusBarNotification sbn) {
              //.............. 
        }
}

然后我们需要manifest文件中声明这个服务权限:BIND_NOTIFICATION_LISTENER_SERVICE,在intent-filter中定义SERVICE_INTERFACE  action

<service
      android:name="it.gmariotti.android.examples.
notificationlistener.SimpleKitkatNotificationListener"
      android:label="@string/service_name"
      android:debuggable="true"    android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" >
      <intent-filter>
           <action android:name="android.service.
                 notification.NotificationListenerService" ></action>
      </intent-filter>
 </service>

最后需要启用服务。没有这一步服务是起不来的!

路径如下: ”Settings” -> ”Security” -> ”Notification access”。

需要为用户定义Intent:

Intent intent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
    startActivity(intent);

安卓4.4引入了新的新的Notification.extras 字段,其中包含了一个元数据(metadata)集合(Bundle)。

用起来很简单:

Notification mNotification=sbn.getNotification();
   Bundle extras = mNotification.extras;

这个集合(Bundle)可以包含很多信息。你可以在Notification 中找到其关键字。例如:

/**
     * {@link #extras} key: this is the title of the notification,
     * as supplied to {@link Builder#setContentTitle(CharSequence)}.
     */
    public static final String EXTRA_TITLE = "android.title";

    /**
     * {@link #extras} key: this is the main text payload, as supplied to
     * {@link Builder#setContentText(CharSequence)}.
     */
    public static final String EXTRA_TEXT = "android.text";

    /**
     * {@link #extras} key: this is a third line of text, as supplied to
     * {@link Builder#setSubText(CharSequence)}.
     */
    public static final String EXTRA_SUB_TEXT = "android.subText";

    /**
     * {@link #extras} key: this is a bitmap to be used instead of the small icon when showing the
     * notification payload, as
     * supplied to {@link Builder#setLargeIcon(android.graphics.Bitmap)}.
     */
    public static final String EXTRA_LARGE_ICON = "android.largeIcon";

实验一下环聊(Hangouts)消息

Bundle[
     {android.title=Gabriele Mariotti, 
      android.subText=null, 
      android.showChronometer=false, 
      android.icon=2130838949, 
      android.text=Send a message with Hangouts,
      android.progress=0, 
      android.progressMax=0, 
      android.showWhen=true,     android.largeIcon=android.graphics.Bitmap@42075010, 
      android.infoText=null, 
      android.progressIndeterminate=false, 
      android.scoreModified=false}]

很方便可以得到如下数据。

String notificationTitle = extras.getString(Notification.EXTRA_TITLE);
     int notificationIcon = extras.getInt(Notification.EXTRA_SMALL_ICON);
     Bitmap notificationLargeIcon = 
                  ((Bitmap) extras.getParcelable(Notification.EXTRA_LARGE_ICON));
     CharSequence notificationText = extras.getCharSequence(Notification.EXTRA_TEXT);
     CharSequence notificationSubText = extras.getCharSequence(Notification.EXTRA_SUB_TEXT);
Also you can display them... and yes, you can get also the BigPicture (if exists).

并且你还可以将他们显示出来……是的,还可以得到大图(如果有的话)。

我实验了电子邮件

Bundle[
     {android.title=Gabriele Mariotti,
      android.subText=email@xxxx.com, 
      android.showChronometer=false, 
      android.icon=2130837697, 
      android.text=A simple subject \n A simple text, 
      android.progress=0,
      android.progressMax=0,
      android.showWhen=true,
android.largeIcon=android.graphics.Bitmap@4208ba28,
      android.infoText=null,
      android.progressIndeterminate=false,
      android.scoreModified=false}
]

通过这种方法,你可以得到很多在4.3中需要反射来得到的信息。

你可能也需要更新那些用到Notification Listener的app

代码如下:

public class SimpleKitkatNotificationListener extends NotificationListenerService {
    @Override
    public void onNotificationPosted(StatusBarNotification sbn) {
        Notification mNotification = sbn.getNotification();
        if (mNotification != null) {
            Bundle extras = mNotification.extras;
            Intent intent = new Intent(MainActivity.INTENT_ACTION_NOTIFICATION);
            intent.putExtras(mNotification.extras);
            sendBroadcast(intent);
        }
    }

    @Override
    public void onNotificationRemoved(StatusBarNotification sbn) {}
}

public class MainActivity extends Activity {
    protected MyReceiver mReceiver = new MyReceiver();
    public static String INTENT_ACTION_NOTIFICATION = "it.gmariotti.notification";

    protected TextView title;
    protected TextView text;
    protected TextView subtext;
    protected ImageView largeIcon;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Retrieve ui elements
        title = (TextView) findViewById(R.id.nt_title);
        text = (TextView) findViewById(R.id.nt_text);
        subtext = (TextView) findViewById(R.id.nt_subtext);
        largeIcon = (ImageView) findViewById(R.id.nt_largeicon);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.main, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.action_autorize:
            Intent intent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
            startActivity(intent);
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mReceiver == null)
            mReceiver = new MyReceiver();

        registerReceiver(mReceiver, new IntentFilter(INTENT_ACTION_NOTIFICATION));
    }

    @Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(mReceiver);
    }

    public class MyReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent != null) {
                Bundle extras = intent.getExtras();
                String notificationTitle = extras.getString(Notification.EXTRA_TITLE);
                Bitmap notificationLargeIcon = ((Bitmap) extras.getParcelable(Notification.EXTRA_LARGE_ICON));
                CharSequence notificationText = extras.getCharSequence(Notification.EXTRA_TEXT);
                CharSequence notificationSubText = extras.getCharSequence(Notification.EXTRA_SUB_TEXT);
                title.setText(notificationTitle);
                text.setText(notificationText);
                subtext.setText(notificationSubText);
                if (notificationLargeIcon != null) {
                    largeIcon.setImageBitmap(notificationLargeIcon);
                }
            }
        }
    }
}

也可以在GitHub中看到这些代码。

原文链接: gmariotti.blogspot 翻译: ImportNew.com - 高俊阳
译文链接: http://www.importnew.com/7663.html
[ 转载请保留原文出处、译者和译文链接。]

关于作者: 高俊阳

(新浪微博:@狐狸叔

查看高俊阳的更多文章 >>



相关文章

发表评论

Comment form

(*) 表示必填项

1 条评论

  1. leehoja 说道:

    感谢分享,用的上!!

    Thumb up 0 Thumb down 0

跳到底部
返回顶部