java对接天猫精灵语音助手实现对公司其下的智能设备进行控制(附上源码)

java对接天猫精灵语音助手实现对公司其下的智能设备进行控制

前言当初刚来广州 公司上一任java已经离职半年 ,项目已经跑不动了,才招人的,所以我获得的是一个连跑都跑不起来的项目源码并且对项目一无所知,一年前网上并没有对接天猫精灵的相关走路只能自己整。下面我把整个controller层代码 从授权到控制的代码给贴了出来希望对大家有帮助。(基本自己改改就能直接用目前代码还在公司服务器上跑并且没任何问题)

下面有几点需要注意。
至于在天猫精灵开发者平台哪些东西就不讲了 说一些别的。
1.SSL证书(免费的 另外我有博客写了如何部署等等)在eclipse的tomcat安装ssl证书
2.域名(几块钱一个)
3.外网IP(可以花生壳什么的或者使用别的工具内网穿透直接在开发工具上调试他不香吗,难不成每次改一点点都要去发布一遍项目??)
4.天猫精灵的token会自动过期 (要操控设备的时候就会直接报已授权过期,授权已过期 ,贼烦 所以我这边授权自动过期了它来重新获取授权的时候我还是会去数据库把以前的旧token给它 ,嘿嘿嘿永不过期 )
5. combine接口有一段逻辑根据token 查询用户信息以后 根据用户名提取文件并解析公司存储在linux服务器上的客户客户设备信息并根据天猫精灵可解析的格式返回给天猫精灵 (注意 天猫精灵发送命令也是往这个接口,获取设备信息也是)
6. 有问题可以跟我留言 (目前还对接过小度小度,若琪)
7.差点忘记说了###号的地方请替换为自己的信息
把整个类拷过去然后改一下对应的域名端口号还有ID就好了在这里插入图片描述

package com.obj.controller;import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import javax.annotation.Resource;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.oltu.oauth2.as.issuer.MD5Generator;
import org.apache.oltu.oauth2.as.issuer.OAuthIssuer;
import org.apache.oltu.oauth2.as.issuer.OAuthIssuerImpl;
import org.apache.oltu.oauth2.as.request.OAuthAuthzRequest;
import org.apache.oltu.oauth2.as.request.OAuthTokenRequest;
import org.apache.oltu.oauth2.as.response.OAuthASResponse;
import org.apache.oltu.oauth2.common.OAuth;
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.apache.oltu.oauth2.common.message.OAuthResponse;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.xml.sax.SAXException;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.obj.entity.Device;
import com.obj.entity.user;
import com.obj.entity.Token;
import com.obj.service.ControlService;
import com.obj.service.MqttMessageService;
import com.obj.service.ResponseService;
import com.obj.service.deviceService;
import com.obj.service.userService;import utils.AnalysisXML;@Controller
@RequestMapping("/Test")
public class testController {@Resourcepublic userService userservice;@Resourcepublic deviceService deviceservice;@Resourcepublic MqttMessageService mqttService;@Resourcepublic ResponseService responseService;@Resourcepublic ControlService controlService;String grant_type = "authorization_code";String clientId = "###";// String clientSecret = "###";// String userInfoUrl = null;String response_type = "code";String code = null;String cutURL = "https://####:9443/genie/merchantHTML/login.jsp?";//String OAuthURL = "https://####:9443/genie/Test/responseCode.do?";//int cutlength = cutURL.length();int num=0;String s = new String("");@RequestMapping("/userlogin")public String userlogin(HttpServletRequest request, HttpServletResponse response)throws IOException, OAuthSystemException, ServletException {String url = request.getHeader("referer");String username = request.getParameter("username");String password = request.getParameter("password");ServletContext context = request.getSession().getServletContext();context.setAttribute("username", username);user IdentifyUsername = userservice.IdentifyUsername(username);user IdentifyPassword = userservice.IdentifyPassword(username, password);if (IdentifyUsername != null) {if (IdentifyPassword != null) {String outURL = java.net.URLDecoder.decode(url, "UTF-8");int outlength = outURL.length();String responseURL = outURL.substring(cutlength, outlength);System.out.println("截取到的内容:"+responseURL+ "\n 长度:"+responseURL.length());num=responseURL.length();s=responseURL;OAuthURL = OAuthURL +responseURL;return "redirect:" + OAuthURL;} else {System.out.println("密码错误!");}} else {System.out.println("用户名不存在!");}return "error";}@RequestMapping("/responseCode")public Object toShowUser(Model model, HttpServletRequest request) throws IOException {try {// 构建OAuth 授权请求OAuthAuthzRequest oauthRequest = new OAuthAuthzRequest(request);oauthRequest.getClientId();oauthRequest.getResponseType();oauthRequest.getRedirectURI();String token=null;String state=null;String[] strarray=s.split("&"); token =strarray[1].substring(6,strarray[1].length());state =strarray[4].substring(6,strarray[4].length());if (oauthRequest.getClientId() != null && oauthRequest.getClientId() != "") {// 设置授权码String authorizationCode = UUID.randomUUID().toString().replace("-", "").substring(0,18);System.out.println("授权码UUID=" + authorizationCode);// 利用oauth授权请求设置responseType,目前仅支持CODE,另外还有TOKEN// String responseType = oauthRequest.getParam(OAuth.OAUTH_RESPONSE_TYPE);// 进行OAuth响应构建OAuthASResponse.OAuthAuthorizationResponseBuilder builder = OAuthASResponse.authorizationResponse(request, HttpServletResponse.SC_FOUND);// 设置授权码builder.setParam("token",java.net.URLDecoder.decode(token, "UTF-8"));builder.setParam("state", state);builder.setCode(authorizationCode);// 得到到客户端重定向地址String redirectURI = oauthRequest.getParam(OAuth.OAUTH_REDIRECT_URI);// 构建响应OAuthResponse response = builder.location(redirectURI).buildQueryMessage();System.out.println("服务端/responseCode内,返回的回调路径:" + response.getLocationUri() + "\n");String responceUri = response.getLocationUri();// 根据OAuthResponse返回ResponseEntity响应HttpHeaders headers = new HttpHeaders();try {headers.setLocation(new URI(response.getLocationUri()));} catch (URISyntaxException e) {e.printStackTrace();}String strURL = "https://####/genie/Test/responseAccessToken.do?grant_type=authorization_code&client_id=####&client_secret=####&redirect_uri=https://open.bot.tmall.com/oauth/callback&code="+ authorizationCode;URL url = new URL(strURL);HttpURLConnection connection = (HttpURLConnection) url.openConnection();connection.setDoOutput(true);connection.setDoInput(true);connection.setUseCaches(false);connection.setInstanceFollowRedirects(true);connection.setRequestMethod("POST"); // 设置请求方式connection.setRequestProperty("Accept", "application/json"); // 设置接收数据的格式connection.setRequestProperty("Content-Type", "application/json"); // 设置发送数据的格式connection.connect();System.out.println("redirect:" + responceUri);token=null;state=null;return "redirect:" + responceUri;// https://open.bot.tmall.com/oauth/callback?skillId=18105&code=0b58444322e04d9c8e&state=11&token=MjM0MDgzODYwMEFGRUhJTkZEVlE%3D}} catch (OAuthSystemException e) {e.printStackTrace();} catch (OAuthProblemException e) {e.printStackTrace();}return null;}@RequestMapping(value = "/responseAccessToken", method = RequestMethod.POST)public HttpEntity<String> token(HttpServletRequest request) throws OAuthSystemException {JSONObject jsonObject = new JSONObject();SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm");//设置日期格式System.out.println("--------天猫精灵服务端/responseAccessToken---------------------"+df.format(new Date())+"---------------------");OAuthIssuer oauthIssuerImpl = null;OAuthResponse response = null;// 构建OAuth请求try {OAuthTokenRequest oauthRequest = new OAuthTokenRequest(request);String clientSecret = oauthRequest.getClientSecret();String token = oauthRequest.getRefreshToken();String accessToken=null;String refreshToken=null;int AccessToken=0;/** accessToken存进数据库,过期时间3天 绑定user用户*/ServletContext context = request.getSession().getServletContext();String username = (String) context.getAttribute("username");if (clientSecret != null && clientSecret != "") {if(token==null && username!=null) {//绑定 赋予授权// 生成Access TokenoauthIssuerImpl = new OAuthIssuerImpl(new MD5Generator());accessToken = oauthIssuerImpl.accessToken();refreshToken = oauthIssuerImpl.refreshToken();/*	判断 数据库是否有相同token 有则继续取新的*/boolean l=true;  do {  String name=userservice.SelectByToken(accessToken);  String name2=userservice.SelectRefreshToken(refreshToken);if(name==null&&name2==null) {l=false;}else {accessToken=oauthIssuerImpl.accessToken();refreshToken = oauthIssuerImpl.refreshToken();}} while (l);jsonObject.put("access_token", accessToken);jsonObject.put("refresh_token", refreshToken);jsonObject.put("expires_in", 259200);AccessToken = userservice.update(accessToken, username,refreshToken);if(AccessToken!=0) {System.out.println("授权成功");}else {System.out.println("授权失败");}response = OAuthASResponse.tokenResponse(HttpServletResponse.SC_OK).setAccessToken(accessToken).setRefreshToken(refreshToken).setExpiresIn("259200").setParam("expires_in", "259200").setParam("example_parameter", "example_value").buildJSONMessage();// 根据OAuthResponse生成ResponseEntityreturn new ResponseEntity<String>(response.getBody(), HttpStatus.valueOf(response.getResponseStatus()));}else if(token!=null) { //天猫主动刷新授权System.out.println("授权过期 天猫精灵自动获取授权!");Token  userToken=userservice.SelectToken(token); //凭着带过来的tokenif(userToken.getTokenid()!=null&&userToken.getRefresh_tokenTM()!=null&&userToken.getUser()!=null) {//如果本身就拥有token 则取出数据库中的token 再返回给天猫精灵refreshToken=userToken.getRefresh_tokenTM();accessToken=userToken.getTokenid();System.out.println("天猫精灵主动发起授权刷新,数据库存在token 将其返回");// 生成OAuth响应response = OAuthASResponse.tokenResponse(HttpServletResponse.SC_OK).setAccessToken(accessToken).setRefreshToken(refreshToken).setExpiresIn("259200").setParam("expires_in", "259200").setParam("example_parameter", "example_value").buildJSONMessage();// 根据OAuthResponse生成ResponseEntityreturn new ResponseEntity<String>(response.getBody(), HttpStatus.valueOf(response.getResponseStatus()));}else {//生成新的token 返回给天猫精灵// 生成Access TokenoauthIssuerImpl = new OAuthIssuerImpl(new MD5Generator());accessToken = oauthIssuerImpl.accessToken();refreshToken = oauthIssuerImpl.refreshToken();/*	判断 数据库是否有相同token 有则继续取新的*/boolean l=true;  do {  String name=userservice.SelectByToken(accessToken);  String name2=userservice.SelectRefreshToken(refreshToken);if(name==null&&name2==null) {l=false;}else {accessToken=oauthIssuerImpl.accessToken();refreshToken = oauthIssuerImpl.refreshToken();}} while (l);jsonObject.put("access_token", accessToken);jsonObject.put("refresh_token", refreshToken);jsonObject.put("expires_in", 259200);AccessToken = userservice.update(accessToken, userToken.getUser(),refreshToken);if(AccessToken!=0) {System.out.println("授权成功");}else {System.out.println("授权失败");}// 生成OAuth响应response = OAuthASResponse.tokenResponse(HttpServletResponse.SC_OK).setAccessToken(accessToken).setRefreshToken(refreshToken).setExpiresIn("259200").setParam("expires_in", "259200").setParam("example_parameter", "example_value").buildJSONMessage();// 根据OAuthResponse生成ResponseEntityreturn new ResponseEntity<String>(response.getBody(), HttpStatus.valueOf(response.getResponseStatus()));}}else {System.out.println("user:"+username);System.out.println("token:"+token);System.out.println("天猫精灵授权失败");response = OAuthASResponse.tokenResponse(HttpServletResponse.SC_OK).setParam("error", "101").setParam("error_description", "内部错误").buildJSONMessage();jsonObject.put("error", 101);jsonObject.put("error_dercription", "内部错误");System.out.println(jsonObject.toString());return new ResponseEntity<String>(response.getBody(), HttpStatus.valueOf(response.getResponseStatus()));}}// 根据OAuthResponse生成ResponseEntityreturn new ResponseEntity<String>(response.getBody(), HttpStatus.valueOf(response.getResponseStatus()));} catch (OAuthSystemException e) {response = OAuthASResponse.tokenResponse(HttpServletResponse.SC_OK).setParam("error", "101").setParam("error_description", "内部错误").buildJSONMessage();jsonObject.put("error", 101);jsonObject.put("error_dercription", "内部错误");System.out.println(jsonObject.toString());return new ResponseEntity<String>(response.getBody(), HttpStatus.valueOf(response.getResponseStatus()));} catch (OAuthProblemException e) {response = OAuthASResponse.tokenResponse(HttpServletResponse.SC_OK).setParam("error", "102").setParam("error_description", "参数错误").buildJSONMessage();jsonObject.put("error", 102);jsonObject.put("error_dercription", "参数错误");System.out.println(jsonObject.toString());return new ResponseEntity<String>(response.getBody(), HttpStatus.valueOf(response.getResponseStatus()));}}/*** 设备控制与设备状态查询* http://doc-bot.tmall.com/docs/doc.htm?spm=0.7629140.0.0.21551780A5E52S&treeId=393&articleId=108268&docType=1*/@RequestMapping(value = "/combine", method = RequestMethod.POST)@ResponseBodypublic JSONObject combineDevice(HttpServletRequest request, HttpServletResponse response, BufferedReader br)throws SAXException, IOException, MqttException, InterruptedException, UnsupportedEncodingException {ServletContext context = request.getSession().getServletContext();String username = "";// 天猫精灵request的BodyString inputLine;String str = "";try {while ((inputLine = br.readLine()) != null) {str += inputLine;}br.close();} catch (IOException e) {System.out.println("IOException: " + e);}System.out.println("天猫精灵的请求体:" + str + "\n");JSONObject recieveHeader = new JSONObject();recieveHeader = JSON.parseObject(str);String str1 = recieveHeader.getString("header");String str2 = recieveHeader.getString("payload");JSONObject recieveMessageId = new JSONObject();JSONObject recievedeviceId = new JSONObject();recieveMessageId = JSON.parseObject(str1);recievedeviceId = JSON.parseObject(str2);JSONObject MerchineList = new JSONObject();// 如果请求体的accessToken与数据库的不一致,则报token错误if (userservice.SelectByToken(recievedeviceId.getString("accessToken")) == null) {return responseService.ErrorResponce(recieveMessageId, recievedeviceId);} else {System.out.println("使用token查询出来的用户名是;"+userservice.SelectByToken(recievedeviceId.getString("accessToken")));// 如果请求体的accessToken与数据库一致,则返回该token对应的用户名username = userservice.SelectByToken(recievedeviceId.getString("accessToken"));}String fileName = "/var/www/html/store/" + username + "_Devices.xml";//String fileName = "file:///F:/DSKJ_Devices.xml";AnalysisXML test = new AnalysisXML();File file = new File("/var/www/html/store/" + username + "_Devices.xml");//File file = new File("F:/DSKJ_Devices.xml");String name = recieveMessageId.getString("name");if (file.exists()) {test.setCenterID(fileName);}String topic = "MSG/" + test.getCenterID();switch (name) {case "DiscoveryDevices":// 对应:登陆天猫精灵后自动查询出的设备列表if (file.exists()) {			// 如果文件是真实存在的,再进行XML解析List<Device> Devices = deviceservice.AnalysisXML(fileName);MerchineList = responseService.DeviceResponce(recieveMessageId, Devices);} else {// 如果文件是不存在的,提供写死的test数据MerchineList = responseService.WritedeadResponce();}return MerchineList;case "TurnOn":// 对应:天猫精灵,打开某某设备System.out.println("进入了打开");MerchineList = controlService.TurnOnResponce(username, topic, recieveMessageId, recievedeviceId);return MerchineList;case "TurnOff":// 对应:天猫精灵,关闭某某设备MerchineList = controlService.TurnOffResponce(username, topic, recieveMessageId, recievedeviceId);return MerchineList;case "Pause":// 对应:天猫精灵,窗帘暂停MerchineList = controlService.PauseResponce(username, topic, recieveMessageId, recievedeviceId);return MerchineList;case "SetBrightness":// 对应:天猫精灵,调节灯光亮度String value = recievedeviceId.getString("value");String setValue = value;if (!(value.equals("max") || value.equals("min"))) {if (Integer.parseInt(value) > 100 || Integer.parseInt(value) < 0) {MerchineList = responseService.ParamsErrorResponce(recieveMessageId, recievedeviceId);return MerchineList;}}MerchineList = controlService.SetBrightnessResponce(setValue, username, topic, recieveMessageId,recievedeviceId);return MerchineList;case "SetTemperature":// 对应:天猫精灵,调节空调温度String value2 = recievedeviceId.getString("value");String setValue2 = value2;if (!(value2.equals("max") || value2.equals("min"))) {if (Integer.parseInt(value2) > 32 || Integer.parseInt(value2) < 16) {MerchineList = responseService.ParamsErrorResponce(recieveMessageId, recievedeviceId);return MerchineList;}}MerchineList = controlService.SetTemperatureResponce(setValue2, username, topic, recieveMessageId,recievedeviceId);return MerchineList;case "Query":// 对应:天猫精灵,查询空调状态MerchineList = controlService.QueryResponce(topic, recieveMessageId, recievedeviceId);return MerchineList;case "SetMode":// 对应:天猫精灵,将空调调到某某模式MerchineList = controlService.SetModeResponce(username, topic, recieveMessageId, recievedeviceId);return MerchineList;case "SetWindSpeed":// 对应:天猫精灵,空调风速调到某风MerchineList = controlService.SetWindSpeedResponce(username, topic, recieveMessageId, recievedeviceId);return MerchineList;case "AdjustUpTemperature":// 对应:天猫精灵,空调温度调高一点MerchineList = controlService.AdjustUpTemperatureResponce(username, topic, recieveMessageId,recievedeviceId);return MerchineList;case "AdjustDownTemperature":// 对应:天猫精灵,空调温度调低一点MerchineList = controlService.AdjustDownTemperatureResponce(username, topic, recieveMessageId,recievedeviceId);return MerchineList;case "AdjustUpWindSpeed":// 对应:天猫精灵,空调风速调高一点MerchineList = controlService.AdjustUpWindSpeedResponce(username, topic, recieveMessageId, recievedeviceId);return MerchineList;case "AdjustDownWindSpeed":// 对应:天猫精灵,空调风速调低一点MerchineList = controlService.AdjustDownWindSpeedResponce(username, topic, recieveMessageId,recievedeviceId);return MerchineList;default:return MerchineList;}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/49381.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

天猫精灵智能设备对接(7) OAuth2.0

在开始之前先放两篇参考&#xff0c;一篇英文http://bshaffer.github.io/oauth2-server-php-docs/cookbook/&#xff0c;一篇中文https://www.cnblogs.com/endv/p/7868549.html&#xff0c;中文博客里的内容基本上是把英文官方文档翻译一遍。到这里如果你不知道OAuth2.0是啥可以…

天猫精灵对接2(OAuth 搭建)

根据 接入方式及流程 中的说明&#xff0c;可知&#xff0c;搭建过程中&#xff0c;我们需要自己整一个 OAuth 的授权平台&#xff0c;具体说明可以参考蟋蟀大哥的文章 ASP.NET WebApi OWIN 实现 OAuth 2.0 &#xff0c;我的实际代码也是基于文章给出的源码修改的。 第一步 认…

天猫精灵对接智能设备

why to do&#xff1a;   我之前一直很喜欢智能家居&#xff0c;可惜的是现在市场上成品的智能家居实在是太贵了&#xff0c;屌丝的码农是在背不起每月高额的房贷和装修费用的基础上&#xff0c;再买成品的智能设备&#xff08;像某米那样一个智能开关&#xff0c;竟然卖那么…

从零玩转系列之SpringBoot3-核心原理

一、简介 1.前置知识 ● Java17 ● Spring、SpringMVC、MyBatis ● Maven、IDEA 2.环境要求 环境&工具版本(or later)SpringBoot3.1.xIDEA2023.xJava17Maven3.5Tomcat10.0Servlet5.0GraalVM Community22.3Native Build Tools0.9.19 二、SpringBoot3-核心原理 1.事件和监听器…

SpringBoot3【⑤ 核心原理】

1. 事件和监听器 1. 生命周期监听 场景&#xff1a;监听应用的生命周期 1. 监听器-SpringApplicationRunListener 自定义SpringApplicationRunListener来监听事件&#xff1b; 1.1. 编写SpringApplicationRunListener 这个接口的实现类 1.2. 在 META-INF/spring.factories …

开发必备,开源 or 免费的 AI 编程助手

AI 大模型的火热&#xff0c;让开发圈近来如虎添翼&#xff0c;各种各样基于 AI 技术的开发者工具和新范式不断涌现&#xff0c;尤其是 Github 和 OpenAI 共同推出的 Copilot X &#xff0c;更是一骑绝尘。本文推荐一些开源 or 免费的 AI 编程工具&#xff0c;不妨试着用起来。…

超过5000人的2年研究表明,这一活动破坏你的身心健康

Tips 原文作者&#xff1a;Minda Zetlin 原文出处&#xff1a;A 2-Year Study of More Than 5,000 People Shows This 1 Activity Destroys Your Emotional and Physical Health 阅读时&#xff0c;把文中的 Fackbook 换成微信。 国外主要用 Facebook&#xff1b; 国内主要是微…

申请阿里云服务器并搭建公网可支持数据上传下载的HTTP服务器

1. 前言 拥有一台自己的云服务器可以做很多事情。阿里云服务器毫无疑问是国内最好的。 阿里云服务器可以用于各种互联网应用的搭建和运行&#xff0c;提供稳定、高性能的服务。 阿里云服务器的用途&#xff0c;包括但不限于以下几个方面&#xff1a; 网站托管&#xff1a;可以将…

谷歌眼镜秀出时尚风采:对面的女孩看过来

摘要&#xff1a;在近日举办的纽约时尚周上&#xff0c;让身材火辣的模特带上谷歌的眼镜&#xff0c;行走在T台之上。主打时尚牌&#xff0c;进一步加固谷歌眼镜在大众消费阶层的印象&#xff0c;尤其是女性消费者。谷歌眼镜创始人Sebastian Thrun指出&#xff1a;谷歌眼镜特别…

学生台灯什么牌子好对眼睛好?专业护眼灯的学生台灯分享

据报告统计&#xff0c;2022年我国儿童青少年总体近视率为52.7%&#xff0c;其中6岁儿童为14.3%&#xff0c;小学生为35.6%&#xff0c;初中生为71.1%&#xff0c;高中生为80.5%&#xff0c;这些数据让人不寒而栗&#xff01; 专家表示&#xff0c;导致儿童青少年近视的因素&am…

【UGP VR眼镜排行榜】2018VR眼镜眼镜哪个好?什么VR眼镜值得买?综合推荐十大热品

科技的发展&#xff0c;高科技产品层出不穷&#xff0c;VR眼镜的出现使人们足不出户也能享受到高品质的观影感受。VR(Virtual Reality&#xff09;即虚拟现实&#xff0c;简称VR.虚拟现实头戴显示器设备&#xff0c;简称VR头显VR眼镜.现在&#xff0c;VR眼镜已不是什么稀奇的东…

《谷歌眼镜》新书作者:眼镜需要成为AR的载体吗?

近10年前&#xff0c;谷歌推出了首款AR眼镜Google Glass&#xff0c;尽管这款产品并没有如预期般取得成功&#xff0c;但它为后续AR硬件技术的发展奠定了基础。我们知道&#xff0c;从微软HoloLens开始&#xff0c;AR头显/眼镜产品更侧重于B端应用&#xff0c;面向C端发售的很少…

Karl Guttag:现有Micro LED/LCoS+光波导AR眼镜对比解析

轻量化是未来AR眼镜的发展趋势&#xff0c;为了缩减尺寸&#xff0c;AR眼镜厂商尝试了多种方案&#xff0c;长期来看Micro LED光机在小型化上更有优势&#xff0c;但现阶段LCoS光机的图像表现更好。在CES 2023期间&#xff0c;DigiLens、Lumus、Vuzix、OPPO、Avegant也展出了不…

偏光太阳镜测试图片软件,[专题]真假偏光太阳镜简单、实用辨别方法!

偏光太阳镜主要是通过镜片的平衡排列的结晶体原理&#xff0c;只让与晶体平衡的光波通过&#xff0c;而向其它角度震动的光波会一律被阻挡的方法(如同百叶窗的原理)制作而成。 正是利用这种原理&#xff0c;偏光太阳镜便可以有效地排除和滤除光束中的偏振光&#xff0c;使光线能…

智能眼镜的两种显示方式

to管理员&#xff1a;哪一个是广告&#xff0c;全是广告&#xff01;难不成网友的链接都不能给了&#xff1f;&#xff01;你们的评判标识是什么&#xff1f; 就现有的技术而言&#xff0c;受限于通讯及周边模块、电源的限制&#xff0c;眼镜只适合于作为显示器使用。 眼镜显示…

谷歌眼镜

谷歌眼镜(Google Project Glass)是由谷歌公司于2012年4月发布的一款“拓展现实”眼镜&#xff0c;它具有和智能手机一样的功能&#xff0c;可以通过声音控制拍照&#xff0c;视频通话和辨明方向以及上网冲浪、处理文字信息和电子邮件等。 查看精彩图册 目录 产品简介 发布信息…

微信小程序开发制作 | 小程序开发者工具功能介绍

小程序开发者工具是微信官方提供的用于开发和调试小程序的工具。它支持 Windows 和 Mac 两种操作系统&#xff0c;并提供了许多实用的功能&#xff0c;使得小程序开发者能够快速地开发和调试小程序。 下面是小程序开发者工具的主要功能介绍&#xff1a; 1.编辑器&#xff1a;…

微信里的小程序怎么制作

自小程序普及以来&#xff0c;除了公司企业&#xff0c;很多的个体户商家都会想了解微信里的小程序怎么制作的&#xff0c;毕竟小程序能解决很多经营上的需求。那么就给大家讲解微信里的小程序怎么制作的流程&#xff0c;希望大家对此能有了解。 流程一、制作小程序前准备 我…

微信小程序开发之——制作表格

一 概述 表格样式一表格样式二 二 绘制过程 外层设置display:table&#xff0c;并设置border-collapse表格边框模型表头设置display:table-row&#xff0c;单元格设置为display:table-cell每一行单元格同表头设置 三 示例代码 3.1 table.wxml(布局文件) <view class&qu…

发明了万维网的他,如今却想亲手推翻它

本文转载自 差评 他有个计划&#xff0c;一个推翻现有互联网&#xff0c;重建数字世界的计划。 看到这句话时&#xff0c;相信很多差友和差评君的第一反应一个样&#xff1a;这谁也太狂了吧&#xff1f;几个菜啊&#xff0c;喝成这样&#xff1f; 毕竟&#xff0c;就算是马云…