360全景图的展示
# Android上360全景图的展示
# 终极解决方案: 基于web
Android的Googe vr sdk无法通过手势放大缩小,且视野宽度较小,交互体验很差,基本不具备可用性,相关sdk谷歌也已经停更多年.
api 'com.google.vr:sdk-panowidget:1.180.0'
因此,我们使用Pannellum.js库,用webview加载:
# html代码:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>A simple example</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/pannellum@2.5.6/build/pannellum.css"/>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/pannellum@2.5.6/build/pannellum.js"></script>
<style>
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
#panorama {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="panorama"></div>
<script>
// 手动解析URL参数
function getUrlParam(name) {
// 去除URL中的"?",并按"&"分割成参数数组
const params = window.location.search.substr(1).split('&');
for (let i = 0; i < params.length; i++) {
// 分割键值对(如 "page=1" → ["page", "1"])
const pair = params[i].split('=');
// 解码参数名和值(处理空格、中文等编码后的字符)
const key = decodeURIComponent(pair[0]);
const value = decodeURIComponent(pair[1] || '');
if (key === name) {
return value;
}
}
// 未找到参数时返回null
return null;
}
// 示例:假设URL是 https://example.com?name=张三&age=20
console.log("uri参数:"+getUrlParam('uri')); // 输出: "张三"
var uri0 = getUrlParam('uri')
if(uri0===null || uri0===undefined || uri0===""){
uri0 = 'https://pannellum.org/images/alma.jpg';
}
pannellum.viewer('panorama', {
"type": "equirectangular",
"panorama": uri0,
"autoLoad": true,
"autoRotate": -2,
"showFullscreenCtrl":false,
"showZoomCtrl":false,
"compass":false,
"showControls":false,
"minHfov": 15, // 自定义最大缩放级别(数值越小,缩放越大,建议 15-30 之间)
"hfov": 30, // 初始视角 = 最小 Hfov(直接进入最大缩放状态)
});
</script>
</body>
</html>
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
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
# webview加载本地文件的方法
文件路径path作为参数传入网页,不要加file://协议
(用这file://协议直接被webview内核拦截)
String url = "";
if(path.startsWith("content://")){
path = path.replace("content://","/content-providerxxy/");
}
url = "https://search.hss01248.tech/pannellum.html"+"?uri="+ UrlEncodeUtil.encode(path);
1
2
3
4
5
2
3
4
5
上面的代码提供了一个功能性的html页面 (opens new window),用于加载本地或远程的360全景图.
远程url,会自动下载
页面右下角提供按钮选择文件并载入到浏览器本地
webview的client加上拦截处理:
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
Uri url1 = request.getUrl();
String path = url1.getPath();
if(TextUtils.isEmpty(path)){
return super.shouldInterceptRequest(view, request);
}
if(path.startsWith("/storage/emulated/")){
InputStream inputStream = null;
try {
inputStream = new FileInputStream(path);
} catch (FileNotFoundException e) {
LogUtils.w(e);
return null;
}
String mimeType = getMimeType(path); // 获取文件MIME类型
return new WebResourceResponse(mimeType, "UTF-8", inputStream);
}else if(path.startsWith("/content-providerxxy/")){
path = path.replace("/content-providerxxy/","content://");
InputStream inputStream = null;
Uri uri = Uri.parse(path);
try {
inputStream = Utils.getApp().getContentResolver().openInputStream(uri);
} catch (FileNotFoundException e) {
LogUtils.w(e);
return null;
}
String mimeType = Utils.getApp().getContentResolver().getType(uri);
if(TextUtils.isEmpty(mimeType)){
mimeType = "image/jpeg";
}
return new WebResourceResponse(mimeType, "UTF-8", inputStream);
}
return super.shouldInterceptRequest(view, request);
}
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
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
为安全起见,可加上域名白名单判断,只允许指定域名下的path能如此操作.
编辑 (opens new window)