Android6.x新API介绍(二)

Android6.x新API介绍(二)

作者:李旺成
时间:2016年4月20日


接上篇:Android6.x新API介绍(一)

五、 Text Selection

先看下效果:

TextSelection 示例

简介

Android 6.x 提供了 Text Selection,在选择文本后,可以显示一个浮动工具栏,一般可以提供剪切、拷贝、粘贴等操作,这个 TextSelection 的交互过程和实现 与 contextual action bar 的实现一样。

注意:
如果使用的是 Android Support Library revision 22.2,需要注意浮动工具栏不向后兼容且因为 appcompat 默认接管 ActionMode 对象,阻止了浮动工具栏被显示。为了在 AppCompatActivity 中支持 ActionMode,需要调用getDelegate()方法,之后对返回的 AppCompatDelegate 对象调用setHandleNativeActionModesEnabled() 方法,并设置输入参数为 false,该调用将ActionMode对象的控制交还给系统框架层。在 Android6.0(API level 23) 的设备上,框架层支持 ActionBar 或浮动工具栏模式,在 Android 5.1(API level 22) 及以下的设备上,只支持 ActionBar 模式。

简单使用

演示代码很简单,直接看代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
@TargetApi(23)
private void initData() {
mCallback2 = new ActionMode.Callback2() {
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
if (inflater == null) {
return false;
}
inflater.inflate(R.menu.actionmode_menu, menu);
return true;
}

@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}

@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
Toast.makeText(TextSelectionActivity.this, item.getTitle(), Toast.LENGTH_LONG).show();
mode.finish();
return false;
}

@Override
public void onDestroyActionMode(ActionMode mode) {

}

// 控制浮动菜单的位置
@Override
public void onGetContentRect(ActionMode mode, View view, Rect outRect) {
super.onGetContentRect(mode, view, outRect);
}

};
this.mTestTV.setCustomSelectionActionModeCallback(mCallback2);
}

注意事项

实现选择文字后的浮动工具栏,在app代码中需要做如下修改:

  1. 在View 或 Activity对象
    ActionMode的调用从startActionMode(Callback) 变为 startActionMode(Callback, ActionMode.TYPE_FLOATING)
  2. 替换原有的ActionMode.Callback为ActionMode.Callback2
  3. 重写OnGetContentRect()方法,提供内容Rect对象(文本选择的矩形框)在view中的位置
  4. 在矩形框作为唯一的元素不再有效时,调用invalidateContentRect() 方法

(参考自:值得你关注的Android6.0上的重要变化(一)

相机 API

先看 Demo 效果:

Camera TorchMode 演示

Android 6 提供了 setTorchMode() 方法来直接控制闪光灯,并且可以监听闪光灯的开光状态。这里演示一下闪关灯控制以及监听闪关灯状态,主要使用了 CameraManager 中的方法:

CameraManager 类

代码很简单,直接看代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
public class CameraTestActivity extends AppCompatActivity {

private Switch mTorchModeSwitch;
private TextView mShowTorchModeTV;

private CameraManager mCameraManager;
private CameraManager.TorchCallback mTorchCallback;
private String[] mCameraIdList;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cameratest);

initView();
initData();
initListener();

}

private void initView() {
this.mTorchModeSwitch = (Switch) this.findViewById(R.id.switch_torchmode);
this.mShowTorchModeTV = (TextView) this.findViewById(R.id.tv_showtorchmode);
}

@TargetApi(23)
private void initData() {
mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
mTorchCallback = new CameraManager.TorchCallback() {
@Override
public void onTorchModeChanged(String cameraId, boolean enabled) {
super.onTorchModeChanged(cameraId, enabled);
mShowTorchModeTV.setText("Camera:" + cameraId + " TorchMode change :" + enabled);
}

@Override
public void onTorchModeUnavailable(String cameraId) {
super.onTorchModeUnavailable(cameraId);
}
};
try {
mCameraIdList = mCameraManager.getCameraIdList();
} catch (CameraAccessException e) {
mCameraIdList = null;
e.printStackTrace();
}
// 注册回调监听
mCameraManager.registerTorchCallback(mTorchCallback, new Handler());
}

private void initListener() {
this.mTorchModeSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (mCameraIdList == null) return;
changeTorchMode(isChecked);
}
});
}

@TargetApi(23)
private void changeTorchMode(boolean isChecked) {
try {
mCameraManager.setTorchMode(mCameraIdList[0], isChecked);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}

@TargetApi(23)
@Override
protected void onDestroy() {
super.onDestroy();
mCameraManager.unregisterTorchCallback(mTorchCallback);
}
}

支持主题化的 ColorStateLists

先看 Demo 的效果:

ColorStateList 使用演示

简介

使用 context.getColorStateList(int id) 可以获取当前主题对应的 ColorStateLists,使用 ColorStateList,就能为按钮的每个状态提供不同的颜色。

ColorStateList 并不是个新东西,看官方介绍:

ColorStateList 类

文档中说 ColorStateList 是从 xml 创建的,在 Resources 类中提供了如下方法:

1
2
3
4
5
6
7
8
9
10
11
@Deprecated
getColorStateList(@ColorRes int id)

getColorStateList(@ColorRes int id, @Nullable Theme theme)
```

Android 6 在 Context 类中添加了 getColorStateList() 方法:
```java
public final ColorStateList getColorStateList(int id) {

return getResources().getColorStateList(id, getTheme());
}

其实还是调的 Resources 中的相关方法。

简单使用

使用很简单,直接看代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
@TargetApi(23)
private void testGetColorStateList() {
ColorStateList csl = getColorStateList(R.color.text_selector1);
if (csl != null) {
mTestBtn.setTextColor(csl);
}

Resources resources = getResources();
ColorStateList csl2 = resources.getColorStateList(R.color.text_selector2);
if (csl2 != null) {
mTestBtn2.setTextColor(csl2);
}
}

App Linking

简介

这是一个把 APP 和网页直接打通的技术,能够让 APP 能够直接来处理你的网站普通的 URL 链接,来展示你对应的网站内容。这绝对是一个值得关注的改进,Web 和 APP 之间缝隙将越来越小。这对既有网站又有 APP 的应用来说非常有利,例如知乎和淘宝等。

有点类似于之前的 APP 的 Deep link,可以通过特殊的Schema也可以让 APP 直接打开对应的内容。APP Linking 的特点是,只要使用传统的 URL 就可以,而且是根据 URL 的域名对应特定的 APP 的。

开发者需要做的是在AndroidManifest.xml做一下对应的声明即可。如果需要让系统默认用你的 APP 打开对应的 URL 的话,还需要网站配合提供assetlinks.json。详情可以参考这里
(参考自:Android 6.0 中的新技术总结

简单使用

鉴于手头的资源不够,没有服务器上传 web-app关联文(statements.json),所以这里就不做实验了。

有几篇文章我认为讲解得挺详细了,有兴趣的建议去看看:
Android M 的"App Links"实现详解
Android M DeepLinks AppLinks 详解
Android M App Links: 实现, 缺陷以及解决办法

其他

还有很多新 API 以及改动的 API 没有介绍,这里也不打算介绍了。前后两篇文章挑了 Android 6.x 中新提供的几个比较重要和我感兴趣的 API,简单的做了个 Demo。

虽然,不打算继续介绍其余的新 API,这里做个简单的记录,以后用到了再去详细了解:

  • 指纹解锁:FingerprintManager
  • 支持蓝牙触控笔
  • 新的省电模式:Doze 和 App Standby
  • APP 数据自动备份
  • 通知(Notifications):移除了Notification.setLatestEventInfo()
  • AudioManager Changes:setStreamSolo()方法过时和setStreamMute()方法过时
  • Browser Bookmark Changes:移除了全局书签的支持、Browser.getAllBookmarks()移除、Browser.saveBookmark()移除、READ_HISTORY_BOOKMARKS权限移除、WRITE_HISTORY_BOOKMARKS权限移除
  • Android KeyStore变化:Android Keystore provider 不再支持DSA,仍旧支持ECDSA
  • Wi-If和网络变化:只能修改你自己创建的WifiConfiguration对象的状态,添加 multinetwork APIs
  • 相机服务变化:改为基于优先级的访问方式
  • 企业Android的变化
  • 数据流量统计(Data Usage)
  • 全局设置变化:不再能通过setGlobalSettings()来设置,现在能通过setGlobalSettings()来设置
  • Runtime:可以恰当的实现newInstance()的访问规则

小结

关于 Android 6.x 的新 API 介绍就到这里了,下一篇开始介绍 Android 6.x 的新控件。
未完待续…

项目地址

GitHub

附件

Andoid6思维导图

揭秘Android 6.0之Text Selection
值得你关注的Android6.0上的重要变化(一)
Android M新特性Doze and App Standby模式详解
Android学习 之 ColorStateList按钮文字变色
Android ColorStateList使用方法
Android 6.0 中的新技术总结
Android M 的"App Links"实现详解
Android M App Links: 实现, 缺陷以及解决办法

坚持原创技术分享,您的支持将鼓励我继续创作!