webview权限适配和getUserMedia适配
# webview权限申请适配和getUserMedia适配
# getUserMedia
# 兼容性
这里标注了is not supported by default in Android webviews,原因是Android webview默认拒绝chrome内核的权限申请,需要适配
# Android内
# 兼容性
5.0以上即可支持
URTC Web SDK移动端兼容性 (opens new window)
在webchromeclient里:默认拒绝权限
public void onPermissionRequest(PermissionRequest request) {
request.deny();
}
2
3
从request可以获取以下内容
/**
* Call this method to get the origin of the web page which is trying to access
* the restricted resources.
*
* @return the origin of web content which attempt to access the restricted
* resources.
*/
public abstract Uri getOrigin();
/**
* Call this method to get the resources the web page is trying to access.
*
* @return the array of resources the web content wants to access.
*/
public abstract String[] getResources();
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
其中,resource的类型有:
其中EME, MIDI数字音乐之类的暂不处理. 只处理video和audio 采集,也就是拍照/录像和录音
/**
* Resource belongs to video capture device, like camera.
*/
public final static String RESOURCE_VIDEO_CAPTURE = "android.webkit.resource.VIDEO_CAPTURE";
/**
* Resource belongs to audio capture device, like microphone.
*/
public final static String RESOURCE_AUDIO_CAPTURE = "android.webkit.resource.AUDIO_CAPTURE";
/**
* Resource belongs to protected media identifier.
* After the user grants this resource, the origin can use EME APIs to generate the license
* requests.
*/
public final static String RESOURCE_PROTECTED_MEDIA_ID =
"android.webkit.resource.PROTECTED_MEDIA_ID";
/**
* Resource will allow sysex messages to be sent to or received from MIDI devices. These
* messages are privileged operations, e.g. modifying sound libraries and sampling data, or
* even updating the MIDI device's firmware.
*
* Permission may be requested for this resource in API levels 21 and above, if the Android
* device has been updated to WebView 45 or above.
*/
public final static String RESOURCE_MIDI_SYSEX = "android.webkit.resource.MIDI_SYSEX";
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
处理为:
private boolean isVideo(String[] resources) {
List<String> strings = Arrays.asList(resources);
return strings.contains(PermissionRequest.RESOURCE_VIDEO_CAPTURE);
}
private boolean isOnlyAudio(String[] resources) {
List<String> strings = Arrays.asList(resources);
return !strings.contains(PermissionRequest.RESOURCE_VIDEO_CAPTURE) && strings.contains(PermissionRequest.RESOURCE_AUDIO_CAPTURE);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onPermissionRequest(PermissionRequest request) {
//super.onPermissionRequest(request);
LogUtils.d(request.getOrigin(),request.getResources());
String[] resources = request.getResources();
if(isOnlyAudio(resources)){
MyPermissions.requestByMostEffort(false, true, new PermissionUtils.FullCallback() {
@Override
public void onGranted(@NonNull List<String> granted) {
LogUtils.i("onGranted");
request.grant(resources);
}
@Override
public void onDenied(@NonNull List<String> deniedForever, @NonNull List<String> denied) {
LogUtils.w("onDenied");
request.deny();
}
}, Manifest.permission.RECORD_AUDIO);
}else if(isVideo(resources)){
MyPermissions.requestByMostEffort(false, true, new PermissionUtils.FullCallback() {
@Override
public void onGranted(@NonNull List<String> granted) {
LogUtils.i("onGranted");
request.grant(resources);
}
@Override
public void onDenied(@NonNull List<String> deniedForever, @NonNull List<String> denied) {
LogUtils.w("onDenied");
request.deny();
}
}, Manifest.permission.RECORD_AUDIO,Manifest.permission.CAMERA);
}
}
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
如此即可适配权限申请.
当webview调用getUserMedia时,chrome内核会自动申请PermissionRequest.RESOURCE_VIDEO_CAPTURE这个资源,对应app则为申请camera和audio权限,申请通过后,chrome内核自然就能获取到摄像头的输入流.
测试网页:
https://webrtc.github.io/samples/src/content/getusermedia/gum/
# 定位权限的申请
# Navigator geolocation 属性
# 定义和用法
Navigator geolocation 属性返回一个 Geolocation 对象,通过这个对象可以访问到设备的位置信息,使网站或应用可以根据用户的位置提供个性化结果。
geolocation 属性只允许再 HTTPS 下使用。
geolocation 位置属性仅在用允后才可以使用。
Navigator geolocation 是只读属性。
更多内容可以参考 HTML5 地理位置 (opens new window)。
# 语法
navigator.geolocation
这个api在pc的浏览器是会弹出一个prompt,询问用户是否允许定位权限,在Android webview里呢?默认为空实现.
# 对应webview的回调
这里的origin为网页的域名,可用于弹窗文案显示
public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback)
需要实现:
最好有个权限前置弹窗,询问用户是否允许xxx网页请求定位,允许后再弹出系统权限弹窗.
LocationUtil.getLocation(Utils.getApp(), false, 10000,
false, true, new MyLocationCallback() {
@Override
public boolean configJustAskPermissionAndSwitch() {
return true;
}
@Override
public boolean configAcceptOnlyCoarseLocationPermission() {
return true;
}
@Override
public void onSuccess(Location location, String msg) {
//注意个函数,第二个参数就是是否同意定位权限,第三个是是否希望内核记住
//不要记住,因为定位权限,定位开关都可能被用户随时变更
callback.invoke(origin,true,false);
}
@Override
public void onFailed(int type, String msg, boolean isFailBeforeReallyRequest) {
callback.invoke(origin,false,false);
}
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 其他权限相关回调
均不做实现,因为Android上无法通过api主动关闭某个权限,只能用户手动操作.
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onPermissionRequestCanceled(PermissionRequest request) {
//super.onPermissionRequestCanceled(request);
}
@Override
public void onGeolocationPermissionsHidePrompt() {
super.onGeolocationPermissionsHidePrompt();
}
2
3
4
5
6
7
8
9
10