您的位置:首页 > 移动开发 > Android开发

Android N For Developers 笔记 (一)

2016-04-13 18:22 609 查看
本篇主要介绍Android N系统改动中的多窗口模式跟消息推送的特性与修改。写在这里一是帮助自己理解,二是分享给有需要的开发者们

一、支持多窗口模式(Multi-window support)

多窗口模式顾名思义就是在界面上同事显示两个界面的应用界面。这种模式使用场景常用于你在看视频,或者玩游戏 这时候弹出了一个消息需要查看和回复。

多窗口模式分为以下模式:

Side-By-Side 模式:两个 App 瓜分一个屏幕

One-above-the-other 模式:一个 App 浮动在另一个 App 之上

Android Tv上还有一种picture In picture模式。

分屏时应用会有一条分界面,用户可以拖动分界线来让其中一个应用占据更多的屏幕,另外那个看起来就要小一点。

进入多窗口模式有如下两种方法:

1.进入手机最近任务界面,找到需要显示的应用界面,长按住使它突出来,然后拖到上或者下(左或右)进入多窗口模式。

2.长按手机最近任务的按钮,即可进入多窗口模式,当前显示的界面占据多窗口模式的一半屏幕。



开发者们需要注意以下几点:

1.虽然有两个应用界面同时显示,但是在多窗口模式的生命周期中只有一个最近跟用户交互的应用界面才是活跃的,而其他应用的Activity,哪怕是可见的也是处于onPause状态,只有用户重新与另外那个界面产生交互,他才会调用onResume(). 这里需要程序员注意的是,比如你的应用的播放视频的界面,以前是在onPause()里执行了视频的暂停,并在onResume()里继续播放;那么现在你的应用可能是在多窗口模式的另外一个可见区域,这时候视频暂停就会产生不好的体验,可以把视频的播放与暂停放在onStart()和onStop()里面进行。

2.当用户把你的应用拖入多窗口模式的时候,你的一些配置、布局属性等都会发生改变,甚至重建,如: 从竖屏切换到横屏等。要妥善处理这些重建行为,Activity 必须通过常规的Activity 生命周期恢复其以前的状态,在 Activity 生命周期中,Android 会在销毁 Activity 之前调用 onSaveInstanceState(),以便您保存有关应用状态的数据。 然后,您可以在 onCreate() 或
onRestoreInstanceState() 期间恢复 Activity 状态。更多具体的变化可以参考 Handling
Runtime Changes。

3.程序员们需要在Manifest文件里配置

android:resizeableActivity=["true" | "false"]
来确定你的应用是否支持多窗口模式。(TargetSDK为Android N时,即使不设置,该属性默认开启)

resizeableActivity需要配置在<Application>或者<Activity>里。如果把这个属性配置在某个根Activity上,那么他所有的任务堆栈里的Activity都拥有该属性。

targetSDK低于Android N的应用运行在Android N设备上时,如果应用是多方向的(可横屏可竖屏),当用户尝试在多窗口模式操作这个应用时,将会被弹窗警告,并且系统会强制重新调整界面;而如果是固定方向的应用,如果用户试图将其拖入多窗口模式,应用不会被重新调整,但是会直接全屏显示。

4. Android N还在Manifest的Layout 中添加了4个属性:

android:defaultWidth Activity在自由模式下启动的默认宽度

android:defaultHeight Activity在自由模式下启动的默认高度

android:gravity Activity在自由模式下启动的初始化位置

android:minimalSize Activity在自由模式和多窗口模式下的最小宽高 (这里需要注意:用户如果拖动分界线将你的应用减小,那么系统将以用户拖动后的宽高为准,该参数此时不起作用)

代码示例:

<activity android:name=".MyActivity">
<layout android:defaultHeight="500dp"
android:defaultWidth="600dp"
android:gravity="top|end"
android:minimalSize="450dp" />
</activity>

Activity中新增以下方法:

Activity.inMultiWindow() 查询Activity是否处于多窗口模式

Activity.inPictureInPicture() 查询Activity是否处于picture-in-picture模式(Android
Tv多窗口模式中的一种特定模式,该方法返回true的时候,Activity.inMultiWindow()肯定返回true)

Activity.onMultiWindowChanged() Activity进入/退出 多窗口模式时调用此方法

Activity.onPictureInPictureChanged() Activity进入/退出 picture-in-picture模式时调用此方法

以上方法在Fragment同样存在

应用适配Android N多窗口模式需要注意的就上面这些。

更多关于多窗口模式中启动一个新的Activity和支持应用之间数据拖放(drag and drop)的相关方法 可以查看官方文档http://developer.android.com/intl/zh-cn/preview/features/multi-window.html#running

二、消息推送增强

Android N中,系统使用
NotificationCompat.Builder.setGroup()
方法可以将相似的一些推送消息捆绑成一个通知。并且用户可以展开通知群中的每一个消息,单独地进行回复或者清除。

1.推送可直接回复的消息

首先,通过
RemoteInput.Builder
来创建实例,这个类的构造函数接收一个String,系统会把这个string当做文本输入的键值key,用户回复后你的应用通过这个key取回文本内容来处理。

// Key for the string that's delivered in the action's intent
private static final String KEY_TEXT_REPLY = "key_text_reply";
String replyLabel = getResources().getString(R.string.reply_label);
RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY)
.setLabel(replyLabel)
.build();


然后,用addRemoteInput()方法把RemoteInput对象附加到action上

// Create the reply action and add the remote input
Notification.Action action =
new Notification.Action.Builder(R.drawable.ic_reply_icon,
getString(R.string.label), replyPendingIntent)
.addRemoteInput(remoteInput)
.build();

最后,把action添加到Notification上推送出来就行。

/ Build the notification and add the action
Notification notification =
new Notification.Builder(mContext)
.setSmallIcon(R.drawable.ic_message)
.setContentTitle(getString(R.string.title))
.setContentText(getString(R.string.content))
.addAction(action))
.build();

// Issue the notification
NotificationManager notificationManager =
NotificationManager.from(mContext);
notificationManager.notify(notificationId, notification);

这样,当你的消息被推送到通知栏的时候,Android N系统会提示用户这条消息可以进行回复了。

2.取回用户回复的文本

如题,刚刚发出了支持用户回复的通知,接下来如何取回用户回复的文本?

从你之前定义的Action中,用户回复后的Intent跳转的Activity内部调用getResultsFromIntent()方法,该方法返回的bundle内包含用户回复的文本。

Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);

取回文本用需要到对应的key,下文是取回代码示例。

// Obtain the intent that started this activity by calling
// Activity.getIntent() and pass it into this method to
// get the associated string.

private CharSequence getMessageText(Intent intent) {
Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
if (remoteInput != null) {
return remoteInput.getCharSequence(KEY_TEXT_REPLY);
}
return null;
}

某些社交聊天应用也许希望给用户提供之前的聊天记录,这样用户能更合理的在消息栏回复,那么可以去了解下setRemoteInputHistory()方法。

3.推送消息组

Android N系统中,Google建议开发者把相关的推送都捆绑起来成一个Group,这个跟Android Wear中的Notification Stacks概念相似。

捆绑成group的通知组,还需要额外设置总结性的通知标题,用户可以逐级地展开消息通知,一直到可以展开单个消息的内容。



如何创建一个推送消息组,并把每一条相似的消息都加到消息组内呢?

首先,调用每个Notification的setGroup()方法为他们指定一个stack,给定确切的groupkey,然后就可以将消息发送到设备上了。

final static String GROUP_KEY_EMAILS = "group_key_emails";

// Build the notification, setting the group appropriately
Notification notif = new NotificationCompat.Builder(mContext)
.setContentTitle("New mail from " + sender1)
.setContentText(subject1)
.setSmallIcon(R.drawable.new_mail)
.setGroup(GROUP_KEY_EMAILS)
.build();

// Issue the notification
NotificationManagerCompat notificationManager =
NotificationManagerCompat.from(this);
notificationManager.notify(notificationId1, notif);


然后,当你把另外一个推送的通知跟上面那个一样设置相同的GroupKey的时候,它们就会被加入到同一个组里
Notification notif2 = new NotificationCompat.Builder(mContext)
.setContentTitle("New mail from " + sender2)
.setContentText(subject2)
.setSmallIcon(R.drawable.new_mail)
.setGroup(GROUP_KEY_EMAILS)
.build();

notificationManager.notify(notificationId2, notif2);


消息栈中的消息是默认按时间顺序排列的,最近发布会显示在最上面,要修改消息顺序,可以调用setSortKey()方法来实现。

就想一篇文章要有概述一样,消息组也可以用setGroupSummary()来添加一个概述的消息。

Bitmap largeIcon = BitmapFactory.decodeResource(getResources(),
R.drawable.ic_large_icon);

// Create an InboxStyle notification
Notification summaryNotification = new NotificationCompat.Builder(mContext)
.setContentTitle("2 new messages")
.setSmallIcon(R.drawable.ic_small_icon)
.setLargeIcon(largeIcon)
.setStyle(new NotificationCompat.InboxStyle()
.addLine("Alex Faaborg   Check this out")
.addLine("Jeff Chang   Launch Party")
.setBigContentTitle("2 new messages")
.setSummaryText("johndoe@gmail.com"))
.setGroup(GROUP_KEY_EMAILS)
.setGroupSummary(true)
.build();

notificationManager.notify(notificationId3, summaryNotification);

Android N中熟知的多窗口模式与消息推送的改动大概就在上面了,总结的不对的地方欢迎指正,多谢。

参考文档:http://developer.android.com/intl/zh-cn/preview/api-overview.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: