精华内容
下载资源
问答
  • 详述快捷支付产品功能及设计要点

    千次阅读 2017-08-03 16:18:48
    在本文中,就让我们一起来剖析快捷支付产品的功能及设计要点。 正文快捷支付指用户在电商网站上执行支付时,不需要输入卡信息,仅根据短信或者其他的验证方式确认身份后,就可以执行扣款的支付方式。 这是目前电商...

    博主说:相信大家在网上购物并进行支付的时候,大多数都是直接输入支付密码,然后就完成支付啦!这种不中断用户体验的良好支付方式,就是快捷支付。在本文中,就让我们一起来剖析快捷支付产品的功能及设计要点。

    正文

    这里写图片描述

      快捷支付指用户在电商网站上执行支付时,不需要输入卡信息,仅根据短信或者其他的验证方式确认身份后,就可以执行扣款的支付方式,这是目前电商网站采用的主要支付方式。 快捷支付分为首次支付和非首次支付,他们的流程是不一样的,区别就在于首次支付的时候,用户需要绑卡。而非首次支付则是直接使用已经绑定的卡来执行扣款,仅需做身份验证就行。注意,这里介绍的是电商网站为业务提供的快捷支付接口,而不是银行或者其他渠道提供给电商的快捷支付接口。

    1 支付场景

      快捷支付第一步是要求用户做绑卡操作。绑卡是将用户的银行卡信息提供给电商,以后电商就用这个信息去银行完成支付。绑卡实际上是一个授权,让用户允许商家自动从他的账户上扣除资金。所以绑卡也叫签约,用户和银行、商家三方签订的支付合约。 但我们知道,绑卡对用户和商户来说都存在巨大风险。如果说用户绑卡是图省事,那商户为什么要做这个事?快捷支付在支付场景上的优势在如下几个方面:

    1.1 提升支付成功率

      网银支付需要用户去银行开通网银,而对快捷支付来说,这并不是必须的。 这样使得可以使用快捷支付的用户群体得到扩展。 使用网银支付成功率在 20% 左右,银联直联成功率一般在 50% 左右,银行卡直联可以提升到 70% 左右。这是相当可观的数据。所以,当你看到绑卡送洗衣粉之类做法时,不需要担心商家会不会赔本。

    1.2 提升支付安全性

      网银是需要用户自己来保证支付环境的安全。在支付宝推出快捷支付和卡通支付之前,网银还是主要的支付方式,这导致各种的木马、钓鱼病毒肆虐,目标之一就为窃取用户的银行卡信息。银行发放 U 盘 U 盾,各种的证书,都是为了保证网银支付的安全,这也带来了各种支付的不便。哪天忘了带了,就无法完成支付。而快捷支付是由商家来保证支付信息的安全,可靠性得到保障。当然,至于商家如何保证这些信息安全,还有待商榷。总的来说,这也比个人自己抵御黑客黑产要靠谱多了。

    1.3 提升用户体验

      想想网银支付的流程,用户在跳转到银行页面后,还得插入 U 盾,各种的核对。产品经理应该知道,每增加一个操作,都会带来一定的掉单率。而快捷支付仅需在第一步完成绑卡后,以后的扣款,最多一个短信就搞定了,败家更方便。 在快捷支付中,绑卡和支付都不需要和渠道打交道,都是通过服务器来中转。而且在绑卡成功后,操作都在服务器上进行。这使得这种支付方式可以跨平台使用,手机、PC 都可以,甚至在其他终端完成绑卡后,可以在电视、嵌入式设备上做支付。

    1.4 获取可靠支付数据

      快捷支付还有一个很好的副作用,那就是得到真实用户信息,特别是身份证信息、银行卡号、手机号、验证方式、真实姓名等,再结合用户的订单信息,大家就可以知道为什么淘宝、京东等这些电商网站现在的商品推荐会这么精准了。

    2 绑卡流程

      怎么绑卡?我们知道对接银行有两种途径,直接对接银行接口和通过银联来间接对接。这两种情况下绑卡处理也不同。 直观的,电商网站会在用户后台提供一个绑卡的入口,让用户直接绑卡。以支付宝绑卡流程为例,我们可以体验下:

    ali

    这里有如下要点:

    • 只能绑自己的卡,这主要从安全角度考虑。作为自己的卡,指银行卡在银行预留的姓名和身份证与网站预留的一致。
    • 需要用户在银行侧预留的手机号进行短信验证。但不是所有银行都需要。这个时候,为了统一处理,可以考虑自己发验证短信。

    对这个入口不要指望太多,更多的用户是在支付中绑卡。也就是提交订单后,发现没有银行卡了,就开始绑卡。和纯绑卡流程不同的是,最后一步,绑卡成功后,一般都同时完成支付。有些渠道会提供绑卡并支付的接口,减少交互次数。为了保证卡的安全,绑卡有这些前置需求:

    • 用户必须已经绑定了手机号。该手机号用于修改支付密码。
    • 用户需设置了支付密码。支付密码不同于登录密码。

    针对用户不同状态,绑卡流程上有区别。当然,绑卡是安全操作,要求用户必须登录到系统中。为了避免和服务器端的交互被劫持,所有操作必须在安全协议中进行,即使用https.

    fast-bind

    2.1 输入卡号

      用户输入卡号,系统对卡号执行初步验证。验证的依据是卡 BIN 和 LUHN 算法。参见「详述银行卡支付方式」。当然,还有些系统会提供扫卡识码的功能,比如微信支付。扫码识别的准确率可以达到 99%,有些卡的卡号颜色和背景色一致的,就会识别出错。如果用户没细看,进入下一步,就会报告错误了,这种错误还比较难发现。自动识别卡号,还需要考虑在识别错误时如何圆过去的问题。

    2.2 获取卡信息

      首次绑卡需要提供卡信息。借记卡需要卡号,用户真实姓名和身份证,这个所有银行都一样(有不一样的,留言告知,谢谢) 。信用卡就复杂点,大部分信用卡还需提供 CV 码和有效期。但是如果和银行关系好,拿到合适的接口,把这两个因素都免了,也是有可能的。

    2.3 要素验证

      首先在服务器端做验证。主要是验证卡是否已经被绑过。如果一个用户有多个账户,系统还需要考虑是否支持这些账户都绑到一个卡上。接着调用银行绑卡验证接口进行绑卡。这里有一个四要素验证的概念。由于国内要求实名制,所有银行卡都是实名办理的,所以银行可以验证姓名、身份证号、银行卡号和手机号是不是一致的。如果没问题,则会发短信到手机上。这里还有几个注意点:

    • 关于手机号。大家都知道,银行预留的手机号一般都是办卡的时候留的,过了几年,换手机了,很多人就忘了同步到银行,所以很多银行就不验证手机号。
    • 关于验证短信。手机号都不是必须的,那短信就可能都不发了,这在流程设计时需要统一处理,银行不发短信就的自己发。
    • 重复绑卡问题。如果系统支持多账户,那不可避免的出现一个人绑卡到多个账号上。渠道侧绑卡,有接口支持重复绑卡,有些是不支持的,所以如果需要重复绑卡,还得在服务器端处理。

    2.4 执行绑卡

      用户输入短信验证码并确认绑卡,服务器端将用户实名信息以及短信验证码组合形成报文,发送给银行,执行签约操作。银行侧签约成功后,返回签约号给商户。 这一个处理逻辑放在支付渠道侧介绍。银行会返回如下结果:

    • 签约成功:这意味着可以建立签约关系,而签约关系在支付系统中则通过虚拟账户来表示。
    • 重复签约: 按照业务考虑是否支持重复签约,一般针对一个银行卡仅保留一个签约关系,建立一个虚拟账户。
    • 签约失败: 需要提示具体失败原因。

    3 扣款流程

      在完成签约后,支付处理就相对简单不少。扣款流程如下:

    fast-pay

    流程要点

    • 订单系统生成订单后,请求支付系统执行支付。
    • 支付服务器生成支付记录,请求渠道执行支付,如果该渠道需要短信支持,请求渠道发送短信。
    • 服务器端在生成支付记录后,请求渠道执行支付。对于需要短信验证或者其他身份验证方式的支付行为,还需要首先请求渠道发送短信,之后让用户输入短信验证码。之后将订单、短信验证码、支付金额送到渠道侧,执行支付。

    这里需要关注如下问题:

    1. 订单有效期:用户必须在订单有效期内完成支付。支付时,必须为每个订单设置有效期。这个有效期不能太长,一般不会超过一天。有效期可以从下单开始算,避免使用相对日期。在执行支付时,需要验证下订单是否还在有效期内。
    2. 同步和异步处理:银联提供的商户侧开通快捷支付接口,不同步返回最终扣款结果,而是通过异步通知的方式来返回。 异步通知会多次调用回调接口, 直到调用成功。 所以,一个订单支付成功的通知,有可能会收到多次回调。

    4 解约流程

      解约流程一般是由用户自己发起。当然,存储在本地的签约信息只是被设置为无效,而不是实际删除。 解约时,还需要注意相关的订单是否都已经完成。

    fast-unbind

    5 退款流程

      没有平白无故的退款。支付都是由交易调起的,那退款就都对应的由退货发起的。针对已经扣款成功的交易执行退款。如果交易还在进行中,比如渠道侧还没有返回结果,则执行退款会导致状态不可预知。

    fast-refund

    注意,退款的钱并不一定立即到账。不同银行、不同渠道到账时间不一样。

    6 接口概述

    一般来说,快捷支付需要提供如下接口:

    1. 签约,也叫“绑卡签约”、“开通交易”等,指用户在商户网站上开通快捷支付的功能,他需要将银行卡相关信息提供给电商。
    2. 解约,也叫“解绑卡”, 指用户取消在该网站上的快捷支付功能。一般也会删除该用户在该网站上的相关的银行卡信息。
    3. 扣款,也叫“支付”,指用户使用签约的卡来执行一笔扣款。
    4. 退款,针对已经扣款成功的交易执行退款操作,一般同时也会把用户权益或者对应的订单撤销。并不是所有订单都可以执行退款。
    5. 查单, 查询某次交易的处理状态。
    6. 签约查询,即检查某个用户是否已经开通了签约功能。

    7 备份通道

      由于快捷支付是常用的一个通道,其带来的问题是,如果这个通道出问题了,应该怎么办?回顾之前的文章,我们提到过,银行卡快捷支付不仅仅只有发卡行的通道,银联、第三方支付也都可以提供银行卡快捷支付接口。就发卡行来说,也不仅仅总行通道,很多发卡行的各省分行,由于历史因素,手头也有通道资源。 这也为我们实现通道切换提供了可能。切换支付通道最大的问题是如何解决签约。比如用户原来使用工行快捷支付接口来完成工行借记卡支付。某一天,工行通知接口要维护,不可用了,这就需要提前把工行接口切到其他备用通道,比如银联接口。当然,直接切换是不行的,和银联还没签约呢。 那如何处理备用通道?关于备用通道的签约时间。可以在用户签约到主通道时,同时签约到备用通道,这种情况要求备用通道必须是无短信验证的,否则一次签约发两条短信,用户必须会怀疑的。还可以在第一次支付的时候签约,这时候将签约支付短信一并发出,避免影响用户体验。

    8 接口实现

    一般来说,快捷支付接口可以通过封装如下通道接口来实现:

    1. 当然,首先是银行自己提供的快捷支付接口;
    2. 银行的代扣接口;
    3. 银联的客户侧开通Token接口。
    4. 第三方支付的代扣接口。

    9 安全与合规

    和银行卡对接,特别是快捷支付接口,有三个重要的合规文档,必须通读。

    • 《非银行支付机构网络支付业务管理办法》(中国人民银行公告〔2015〕第43号公布)
    • 《中国人民银行关于进一步加强银行卡风险管理的通知》(银发〔2016〕170号)

      • 严禁留存非本机构的支付敏感信息(包括银行卡磁道或芯片信息、卡片验证码、卡片有效期、银行卡密码、网络支付交易密码等),确有必要留存的应取得客户本人及账户管理机构的授权。
      • 各商业银行、支付机构应在客户端软件与服务器、服务器与服务器之间进行通道加密和双向认证,对重要信息关键字段进行散列或加密存储,保障信息传输、存储、使用安全。
      • 自 2016 年 12 月 1 日起,各商业银行、支付机构应使用支付标记化技术(Tokenization),对银行卡卡号、卡片验证码、支付机构支付账户等信息进行脱敏处理,并通过设置支付标记的交易次数、交易金额、有效期、支付渠道等域控属性,从源头控制信息泄露和欺诈交易风险。
      • 严格限制使用初始交易密码并提示客户及时修改,建立交易密码复杂度系统校验机制,避免交易密码过于简单(如“111111”、“123456”等)或与客户个人信息(如出生日期、证件号码、手机号码等)相似度过高。
    • 《网络支付报文结构及要素技术规范(V1.0版)》(银办发〔2016〕222号)


    转载声明:本文转自个人博客「凤凰牌老熊」,快捷支付产品

    展开全文
  • 微信快捷登录功能

    千次阅读 2020-05-06 12:01:15
    PC端微信快捷登录 操作文档 申请账号。https://open.weixin.qq.com/ 创建网站应用: 开通微信登录(需要认证 认证费300元)(点击二步“查看”按钮) 生成AppSecret。 控制器代码实现。(如下移动端微信...

    PC端微信快捷登录

    操作文档

     

     

    • 开通微信登录(需要认证  认证费300元)(点击二步“查看”按钮)

     

    • 生成AppSecret。
    • 控制器代码实现。(如下移动端微信快捷登录程序实现)

     

     

     

     

     

     

     

     

     

     

    移动端微信快捷登录

    操作文档

     

    • 必须使用微信公众号(服务号)。
    • 对网页进行授权。
    1. 对应开发文档:

     

     

    1. 配置授权域名:公众号设置-功能设置-网页授权域名,点击设置新增域名。

     

     

    • 注意:手机端微信快捷登录,没法获取unionId,但可以获取openId。程序要判断是手机端就走openId获取会员信息是否已经存在方法,否则就使用unionId。

     

     

     


    程序实现如下:

    (1)后台控制器层程序实现

    /**

     * @Description: 微信快捷登录

     * @param subsiteFlag

     * @param subsiteId

     * @param request

     * @return

     * Add by Bingyong.Wang at 20200424.

     */

    @RequestMapping("/wxLogin")

    public String weixinLogin(HttpServletRequest request){

    try{

    String code = request.getParameter("code");

    // 用来判断是否为移动端,主要是为了显示不同的会员界面

    String state = request.getParameter("state");

    System.out.println("webUrl==============================="+request.getParameter("webUrl"));

    //获取openId并保存到会员中,openId来源于微信第三方登录

    if (GeneralUtil.isNotNull(code)) {

    // 微信开放平台对应的appId

    String appid = "";

    // appId对应的秘钥

    String secret = "";

     

    if (HttpRequestDeviceUtils.isMobileDevice(request)){

    // 微信公众号登录

    appid = AykjConstants.APP_Id;

    secret = AykjConstants.APP_SECRET;

    } else {

    // 微信开发平台登录

    appid = AykjConstants.WXLOGIN_APPID;

    secret = AykjConstants.WXLOGIN_APPSECRET;

    }

    // 获取 token

    String url = "https://api.weixin.qq.com/sns/oauth2/access_token";

    Map<String, String> params = new HashMap<String, String>();

    params.put("appid", appid);

    params.put("secret", secret);

    params.put("code", code);

    params.put("grant_type", "authorization_code");

    // System.out.println("=========url:"+url);

    // System.out.println("=========params:"+params);

    String result = HttpUtil.post(url, params, "utf-8");

    //System.out.println("result"+result);

    if (GeneralUtil.isNotNull(result)) {

    JSONObject jsonObject = JSON.parseObject(result);

    System.out.println("jsonObject"+jsonObject);

    String openId = jsonObject.getString("openid");

    String access_token = jsonObject.getString("access_token");

    String unionid = jsonObject.getString("unionid");

     

    // 获取用户信息

    String getUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo?openid=" + openId + "&access_token=" + access_token;

    String getUserResult = HttpUtil.get(getUserInfoUrl, "utf-8");

     

    if (GeneralUtil.isNotNull(getUserResult)) {

    JSONObject json = JSON.parseObject(getUserResult);

    System.out.println("getUserResult-jsonObject--------------"+jsonObject);

    // 用户昵称

    String nickName = json.getString("nickname");

    // 用户头像(微信头像)

    String wxHeaderImg = json.getString("headimgurl");

    String headerImg = System.currentTimeMillis() + ".png";

    HttpUtil.downloadFile(wxHeaderImg, InitialListener.basePath + "temp/" + headerImg);

    System.out.println("openId==="+openId);

    System.out.println("access_token==="+access_token);

    System.out.println("unionid==="+unionid);

    System.out.println("用户昵称==="+nickName);

    System.out.println("微信头像====="+headerImg);

    Member member = null;

    if (state.equals("mobileState")) {

    //根据openId查找会员

    member = memberService.queryByOpenId(openId);

    } else {

    member = memberService.queryByUnionid(unionid);

    }

    if(member != null && GeneralUtil.isNotNull(member.getLoginId())){

    //增加登录日志

    //memberLogService.addLogin(member, request);

    request.getSession().setAttribute(AykjConstants.FONT_MEMBER, member);

    if (state.equals("mobileState")) {

    return "redirect:/member/toPage?subsiteFlag=spMb&subsiteId=2&newsClassId=80&page=member";

    }

    return "redirect:/member/toPage?subsiteFlag=spPC&subsiteId=1&newsClassId=34&page=memberHome";

    } else{

    // 如果会员不存在就创建一个新会员

    Member wxMember = new Member();

    // 保存会员头像

    Annex annex = new Annex();

    wxMember.setLoginId(GeneralUtil.isNotNull(unionid) ? unionid : openId);

    wxMember.setOpenId(openId);

    wxMember.setUnionid(unionid);

    wxMember.setName(nickName);

     

    annex.setType("image");

    annex.setObj("member");

    annex.setExt("png");

    annex.setPath("/temp/" + headerImg);

     

    memberService.saveWxMember(wxMember, annex);

    request.getSession().setAttribute(AykjConstants.FONT_MEMBER, wxMember);

    if (state.equals("mobileState")) {

    return "redirect:/member/toPage?subsiteFlag=spMb&subsiteId=2&newsClassId=80&page=member";

    }

    return "redirect:/member/toPage?subsiteFlag=spPC&subsiteId=1&newsClassId=34&page=memberHome";

    }

    }

    }

    }

     

    } catch (Exception e) {

    LoggerUtil.error("微信登录失败:"+e.getMessage());

    e.printStackTrace();

    }

    return "/error/404";

    }

     

    (2)页面js实现(PC端):

    /**

     * 微信快捷登录

     * Add by Bingyong.Wang at 20200426

     */

    function weixinLogin(){

    var wxUrl = "${webUrl}/wxLogin";

    wxUrl = encodeURIComponent(wxUrl);

    window.location.href = "https://open.weixin.qq.com/connect/qrconnect?appid=${wxLogin_appid}&redirect_uri="+wxUrl+"&response_type=code&scope=snsapi_login&state=STATE#wechat_redirect";

    }

     

    移动端:

    /*

     微信快捷登录

    */

    function wxLogin(){

    var wxUrl = encodeURIComponent('https://www.kmspzp.cn/wxLogin');

    var appid="wxa3cab9be04ff9b9e";

    if(is_weixin()) {

    window.location.href="https://open.weixin.qq.com/connect/oauth2/authorize?appid="+appid+"&redirect_uri="+wxUrl+"&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect"

    } else{

    layer.msg("请用微信浏览器打开!");

    }

     

    }

    //判断是否是微信浏览器

    function is_weixin(){

    var ua = navigator.userAgent.toLowerCase();

    if(ua.match(/MicroMessenger/i)=="micromessenger") {

    return true;

      } else {

    return false;

    }

    }

    展开全文
  • WebStorm 2019下载和安装教程(已测有用)

    万次阅读 多人点赞 2019-07-26 17:08:04
    WebStorm2019是一款功能强大的开发工具,这款强大的web前端开发神器使用为用户提供 了完善的开发必备功能和工具,让大家以更加轻松快捷的方式进行开发编辑操作,WebStorm为您提供JavaScript和编译到JavaScript语言,...

    WebStorm 2019下载和安装教程(已测有用)

    WebStorm2019是一款功能强大的开发工具,这款强大的web前端开发神器使用为用户提供 了完善的开发必备功能和工具,让大家以更加轻松快捷的方式进行开发编辑操作,WebStorm为您提供JavaScript和编译到JavaScript语言,Node.js,HTML和CSS的智能编码帮助。享受代码完成,强大的导航功能,动态错误检测以及所有这些语言的重构。并提供了强大的内置工具,用于调试,测试和跟踪客户端和Node.js应用程序。通过最少的配置和周到的IDE集成,使用WebStorm可以更轻松地完成这些任务。WebStorm目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。新版本webstorm 2019.1为JavaScript和TypeScript带来了新的智能意图,改进了对Angular的支持,更新了CSS和HTML文档,更强大的调试控制台等等,其中对于Angular的支持,WebStorm添加了17项新检查,可以帮助程序员在键入时检测应用程序中的Angular特定错误,并建议快速修复。而改进的交互式调试器现在使用树视图显示对象,支持使用CSS设置日志消息样式并使用。当然webstorm 2019.1同样增加了新的ui主题,用户现在可以选择深紫色,灰色和青色光主题,还可以自行创建主题。
    小编在这里为大家带来的是WebStorm 2019.1破解版以及汉化,并且还为大家带来了详细的安装破解图文教程,还附带了注册码以及汉化包,亲测可用,欢迎有需要的朋友们前来下载体验!

    安装包下载地址:

    链接:https://pan.baidu.com/s/1bX9DgMrzmOtr61hH2-n3Cw

    提取码:pka9

    复制这段内容后打开百度网盘手机App,操作更方便哦
    在这里插入图片描述

    软件功能
    1、JavaScript
    · 基于DOM,特定浏览器完成
    · 编码导航和用法查询
    · 支持ECMAScript
    · 支持CoffeeScript
    · 支持结点
    · JavaScript重构
    · JavaScript单元测试
    · 代码检测和快速修复
    · JSLint/JSHint
    · 基于 Mozilla的JavaScript调试器
    2、其他用途
    · 批量代码分析
    · 编码语言混合或内混
    · 拼写检查器
    · 重复代码检测器
    3、编辑语言
    · 支持HTML5
    · css/js
    · 检验和快速修复
    · Zen编码
    · 显示内容
    · 显示应用的风格
    4、便捷的环境
    · HTML5样本文件和其他Web应用程序模板
    · FTP和远程文件同步
    · 集成了版本控制系统
    · 本地记录

    软件特色
    一、智能编码辅助
    WebStorm为您提供JavaScript和编译到JavaScript语言,Node.js,HTML和CSS的智能编码帮助。享受代码完成,强大的导航功能,动态错误检测以及所有这些语言的重构。
    1、现代框架
    WebStorm为Angular, React,Vue.js和Meteor提供高级编码帮助。享受对React Native,PhoneGap,Cordova和Ionic的支持,用于移动开发,并在服务器端使用Node.js进行开发。一体化IDE!
    2、智能编辑器
    IDE会分析您的项目,以便为所有支持的语言提供最佳的代码完成结果。当您键入并建议快速修复选项时,数以百计的内置检查会报告任何可能的问题。
    3、导航和搜索
    WebStorm可帮助您更有效地绕过代码,并在处理大型项目时节省时间。只需单击一下即可跳转到方法,函数或变量定义,或搜索用法。
    二、调试,跟踪和测试
    WebStorm提供了强大的内置工具,用于调试,测试和跟踪客户端和Node.js应用程序。通过最少的配置和周到的IDE集成,使用WebStorm可以更轻松地完成这些任务。
    1、调试
    WebStorm 为您的客户端代码(适用于Chrome)和Node.js应用程序提供内置调试器。放置断点,逐步执行代码并计算表达式 - 所有这些都不需要离开IDE。
    2、测试
    由于WebStorm与Karma测试运行器,Mocha,Jest和Protractor集成,因此可以轻松执行测试。在IDE内部运行和调试测试,以漂亮可视的格式查看结果,并导航到测试代码。
    3、跟踪和分析
    WebStorm具有spy-js,这是一种内置工具,可帮助您跟踪JavaScript代码。探索文件如何与函数调用连接,并有效地识别任何可能的瓶颈。
    三、无缝工具集成
    WebStorm与用于Web开发的流行命令行工具集成,无需使用命令行即可为您提供高效,简化的开发体验。
    1、构建工具
    享受简单的统一UI,直接从IDE 运行Grunt,Gulp或 npm任务。所有任务都列在特殊工具窗口中,因此只需双击任务名称即可启动它。
    2、代码质量工具
    除了数百WebStorm自己检查的,它可以运行ESLint, JSCS,TSLint,Stylelint, JSHint或JSLint的对你的代码,并突出显示在飞行的任何问题,就在编辑器中。
    3、项目模板
    使用流行的项目模板(如Express 或Web入门套件)从欢迎屏幕启动新项目,并通过与Yeoman的集成访问更多项目生成器。
    四、IDE功能
    WebStorm建立在开源IntelliJ平台之上,我们JetBrains已经开发和完善了超过15年。享受其提供的微调但高度可定制的体验,以适应您的开发工作流程。
    1、VCS
    WebStorm提供了统一的UI,可与许多流行的版本控制系统配合使用,确保在git,GitHub,SVN,Mercurial和Perforce之间提供一致的用户体验。
    2、当地历史
    无论您是否使用VCS,本地历史记录都可以成为真正的代码保护程序。您可以随时检查特定文件或目录的历史记录,并回滚到以前的任何版本。
    3、定制
    WebStorm非常可定制。调整它以完全适合您的编码风格,从快捷方式,字体和视觉主题到工具窗口和编辑器布局。

    安装破解教程

    1、下载解压,得到webstorm 2019.1原程序、中文补丁包和注册码;

    在这里插入图片描述
    在这里插入图片描述
    2、运行“WebStorm-2019.1.exe”开始安装,安装目录默认为【C:\Program Files\JetBrains\WebStorm 2019.1】建议不更改;
    在这里插入图片描述
    3、勾选创建webstorm 2019.1桌面快捷方式,32位和64位建议都勾选,关联文件可以自行选择,建议update context menu 、create association 、 download and install jbr X86 都选择;

    在这里插入图片描述
    4、点install,开始安装,请耐心等一下;

    在这里插入图片描述
    5、安装完成后,注意先不运行软件,所以不要勾选;

    在这里插入图片描述
    6、接下来对软件进行注册破解,首先以记事本的方式打开hosts文件,将代码添加至hosts文件屏蔽网络联网;
    hosts文件默认目录【C:\Windows\System32\drivers\etc】
    0.0.0.0 account.jetbrains.com
    0.0.0.0 www.jetbrains.com

    在这里插入图片描述
    7、再运行桌面上生成的webstorm 2019.1软件图标,选择do not import settings点击ok,再选"skip…"跳过;

    在这里插入图片描述
    8、弹出注册界面,选择"activation code"输入注册码即可激活。

    在这里插入图片描述
    webstorm 2019激活码如下,请复制粘贴即可:

    在这里插入图片描述
    9、至此webstorm 2019.1破解版成功激活,但还是英文界面;在这里插入图片描述

    10、如果想汉化成中文,可以将软件包中汉化文件resources_cn.jar复制替换。
    打开安装目录下的“lib”文件夹,将原来的resources_en.jar英文版文件删除或重命名,再将webstorm 2019汉化包“resources_cn.jar”复制入内即可,默认安装路径【C:\Program Files\JetBrains\WebStorm 2019.1\lib】resources_en.jar重命名是为了返回英文界面,因为有用户说汉化不是很全面,但99%汉化好了。
    11、再次打开软件,webstorm 2019.1中文破解版已经成功激活,所有功能都可以免费使用。

    在这里插入图片描述

    [注:破解版汉化版软件使用都需要在断开网络情况下破解成功使用但是连接网络无法使用,谢谢!!! ,如果hosts文件修改就不用断网了]

    新功能

    一、JavaScript和TypeScript
    1、使用JavaScript解构
    通过解构,您可以使用非常简洁的语法将数组和对象中的值解压缩到变量中。WebStorm的新重构和意图(Alt-Enter)可以帮助您轻松地将解构引入 JavaScript或TypeScript代码。
    2、使用Promise将函数转换为async / await
    您可以自动更改返回Promise的函数,.then()并 .catch()调用使用async / await语法的异步函数。只需在功能名称上按Alt-Enter,然后选择转换为异步功能。这不仅可以在TypeScript文件中实现,还可以在JavaScript和Flow中实现。

    二、构架

    1、对Angular应用程序的新检查
    对于Angular应用程序,webstorm 2019.1添加了17项新检查,可帮助您在键入时检测应用程序中的Angular特定错误,并建议快速修复。这些检查在TypeScript和模板文件中都有效,并检查绑定,指令,组件和许多其他内容的使用。
    2、Angular项目中的导航更容易
    在Angular应用程序中,您现在可以使用相关符号…弹出窗口(Ctrl-Cmd-Up / Ctrl + Alt + Home)在不同的组件文件(如TypeScript,模板,样式和测试文件)之间快速切换。在TypeScript文件中,弹出窗口还将列出导入此文件的所有符号。
    3、改进了对Vue应用程序中TypeScript的支持
    webstorm 2019.1现在使用TypeScript语言服务以及对.vue文件中任何TypeScript代码的自己的TypeScript支持。这意味着您现在可以获得更准确的类型检查和类型信息,您将能够使用服务提供的快速修复程序,并在TypeScript工具窗口中查看当前文件中的所有TypeScript错误。
    4、React钩子的提取方法
    该提取方法重构现在与当地的功能和使用解构的返回值,使得它非常适合提取自定义作出反应挂钩。
    5、改进了道具的完成
    webstorm 2019.1现在为使用扩展运算符合并的React props提供了更好的代码完成。

    三、HTML和样式表

    1、更新文档
    CSS属性和HTML标记及属性的文档(F1)现在显示有关MDN的浏览器支持的最新描述和信息,以及指向完整MDN文章的链接。
    2、CSS的浏览器兼容性检查
    要检查目标浏览器版本是否支持您使用的所有CSS属性,可以在首选项中启用新的 浏览器兼容性检查。
    3、对CSS模块的Camel案例支持
    如果在项目中使用CSS模块,JavaScript文件中的类的代码完成现在将建议带有破折号的类名的驼峰版本。
    4、提取CSS变量
    使用新的Extract CSS变量重构,您可以使用语法将当前.css文件中值的所有用法替换 为变量var(–var-name)。

    四、测试

    1、突出显示测试中的失败行
    当您使用Jest,Karma,Mocha或Protractor运行测试并且某些测试失败时,您现在可以在编辑器中看到问题发生的位置。IDE将使用堆栈跟踪中的信息并突出显示失败的代码。在悬停时,您将看到来自测试运行器的错误消息,您可以立即开始调试测试。
    2、使用Cucumber和TypeScript进行测试
    使用Cucumber和TypeScript?现在,您可以跳到从步骤.feature文件 到它们的定义中 的.ts文件中使用速战速决(和产生缺定义Alt-Enter组合)。

    五、工具

    1、新的调试器控制台
    在JavaScript和Node.js调试工具窗口中使用新的,改进的交互式调试器控制台!它现在使用树视图显示对象,它支持使用CSS设置日志消息样式并使用console.group()和 对它们进行分组console.groupEnd()。您还可以过滤掉任何类型的日志消息。
    2、完成npm脚本
    将新脚本添加到package.json文件时,WebStorm现在会为已安装的软件包提供的可用命令提供建议。键入后 node,IDE将建议文件夹和文件名。输入后npm run,您将看到当前文件中定义的任务列表。
    3、改进了对短绒的支持
    webstorm 2019.1现在可以 在一个项目中为ESLint和TSLint运行多个进程,以确保它们在单个项目和具有多个linter配置的项目中正常工作 。
    4、支持Docker Compose
    如果使用Docker测试Node.js应用程序,现在可以使用Docker Compose文件中描述的配置从IDE 轻松运行和调试应用程序。
    5、依赖项的版本范围工具提示
    在的package.json,按命令/ Ctrl键和版本悬停的依赖关系,看看运行的时候可以安装什么版本范围 npm install或yarn install。

    六、IDE

    1、新的UI主题
    您现在可以在WebStorm中使用新的丰富多彩的UI主题作为插件。选择 深紫色,灰色和 青色光主题,或创建自己的主题 。
    2、最近的位置弹出
    在最近的位置弹出(Cmd的移-E / 按Ctrl + Shift + E)是一种新的方式 浏览各地的项目。它显示了最近在编辑器中打开的所有文件和代码行的列表。您可以开始键入以过滤结果并跳转到您需要的代码。
    3、将项目另存为模板
    通过“ 工具”菜单中的新操作“ 另存为模板 ” ,您现在可以使用项目作为在IDE欢迎屏幕上创建新项目的基础。
    4、所选文件类型的软包装
    您现在可以在编辑器中为特定文件类型启用软包装。为此,请打开“首选项/设置”| 编辑| 常规并在软包装文件字段中指定文件类型。

    展开全文
  • 想必用过Android腾讯手机管家或者做过相关研发的童鞋都会发现腾讯做了一个类似于iOS系统下的Panel功能,如下图一。 即从屏幕的底部或者侧部用手势划出快捷中心控制面板,如下图二。 有别于以前的快捷控制方案,...

    背景

    想必用过Android腾讯手机管家或者做过相关研发的童鞋都会发现腾讯做了一个类似于iOS系统下的Panel功能,如下图一。


    即从屏幕的底部或者侧部用手势划出快捷中心控制面板,如下图二。


    有别于以前的快捷控制方案,以前的快捷控制方案是在下拉的通知栏里去做控制,如下图三的360方案,这个功能算是腾讯的一个微创新,要点赞。



    设计原理

    看起来很高大上有木有。其实如果掌握了原理是非常简单的,就是运用了Android里的 WindowManager技术,这个在很多国内各色各样的手机管家技术里用到的悬浮窗、一键加速是一样一样的(这里就不扩展了,网上一搜一大把),我猜腾讯手机管家用了一个小小的魔术,是什么呢,在图二中看到的选择后出现的蓝色小方块,在退出该界面后是没有的,但是实际上仍然预留了这样一个区域,只是色值设为透明了,通过监听用户在该区域上的手势滑动,从而拖出快捷中心面板。

    实现方案

    1. 实现FloatWindowQuickCenterTouch,用于实现监听手势拖出快捷中心
    2. 实现FloatWindowQuickCenterShow,用于实现设置界面选择后的蓝色展示区域
    3. 实现FloatWindowQuickCenter,用于实现快捷中心具体的界面和逻辑
    4. 写一个FloatWindowManager管理类,实现以上几个悬浮窗的实例化和WindowManager实例与addView
    5. 在一个Service中运用TimeTask监听悬浮窗的加载状态

    代码方案

    • FloatWindowQuickCenterTouch关键代码
    FloatWindowQuickCenterTouch主要是用于建立一块在桌面端的透明区域,通过监听手势拖出我们需要的快捷中心面板
    /**
     * @Function Touch区域实例化
     */
    public FloatWindowQuickCenterTouch(Context context, int position) {
    	// TODO Auto-generated constructor stub
    	super(context);
    	this.mContext = context;
    	this.mPosition = position; //因为涉及到显示位置
    	
    	if (position != QuickCenterParams.POSITION_RIGHT 
    			&& position != QuickCenterParams.POSITION_BOTTOM) 
    		position = QuickCenterParams.POSITION_RIGHT;
    	
    	View touchView = new View(context);	
    	LinearLayout.LayoutParams touchParams = new LinearLayout.LayoutParams(
    			LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    	
    	if (position == QuickCenterParams.POSITION_RIGHT) { //支持右边和底部
    		touchParams.height = mContext.getResources().getInteger(R.dimen.quick_view_right_height);
    		touchParams.width = mContext.getResources().getInteger(R.dimen.quick_view_right_width);		
    	} else if (position == QuickCenterParams.POSITION_BOTTOM) {
    		touchParams.height = mContext.getResources().getInteger(R.dimen.quick_view_bottom_height);
    		touchParams.width = GlobalApp.screenWidth; //整个屏幕的宽度
    	}	
    	
    	touchView.setLayoutParams(touchParams);
    	touchView.setBackgroundColor(getResources().getColor(R.color.transparent)); //注意我用了透明色
    	this.addView(touchView);
    }
    上面是这个View的实例化,之后再manager类中就是通过调用这个方法来create这个View;
    之后便是手势的监听,根据手势在该View上的位移来操作快捷中心面板的拖出操作;
    /**
     * @Function 重写touchevent
     * 监听手势的位置位移,来创建快捷中心面板
     * 注意要用getRawX/Y方法,与getX/Y的区别请自行百度
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
    	// TODO Auto-generated method stub
    	switch (event.getAction()) {
    	case MotionEvent.ACTION_DOWN:
    		xInView = event.getX();
    		yInView = event.getY();
    		xInScreen = event.getRawX();
    		yInScreen = event.getRawY() - getStatusBarHeight(); //减去状态栏的高度
    		break;
    	case MotionEvent.ACTION_MOVE:
    		break;
    	case MotionEvent.ACTION_UP:
    		xOutScreen = event.getRawX();
    		yOutScreen = event.getRawY();
    		if (mContext.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) //横屏不执行拖出面板
    			return super.onTouchEvent(event);
    		if (mPosition == QuickCenterParams.POSITION_RIGHT) {
    			if (xInScreen - xOutScreen > GlobalApp.screenWidth / 5) {
    				FloatWindowManager.createQuickCenterWindow(mContext, mPosition); //这个就是之前提到的Manager类创建快捷中心的方法,之后在介绍
    			}
    		} else if (mPosition == QuickCenterParams.POSITION_BOTTOM) {
    			if (yInScreen - yOutScreen > GlobalApp.screenHeight / 6) {
    				FloatWindowManager.createQuickCenterWindow(mContext, mPosition);
    			}
    		}
    		break;
    	default:
    		break;
    	}
    	return super.onTouchEvent(event);
    }
    附送上一个获取状态栏高度的方法
    /**
     * 用于获取状态栏的高度。
     * @return 返回状态栏高度的像素值。
     */
    public int getStatusBarHeight() {
    	if (mStatusBarHeight == 0) {
    		try {
    			Class<?> c = Class.forName("com.android.internal.R$dimen");
    			Object o = c.newInstance();
    			Field field = c.getField("status_bar_height");
    			int x = (Integer) field.get(o);
    			mStatusBarHeight = getResources().getDimensionPixelSize(x);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    	return mStatusBarHeight;
    }

    • FloatWindowQuickCenterShow关键代码
    FloatWindowQuickCenterShow主要通过建立一块有色的和Touch相同大小的区域,在设置界面展示给用户
    /**
     * @Function Show区域实例化
     * 与Touch类是一样的,只是改变了颜色,并且不用实现onTouchEvent监听了
     */
    public FloatWindowQuickCenterShow(Context context, int position) {
    	super(context);
    	
    	if (position != QuickCenterParams.POSITION_RIGHT 
    			&& position != QuickCenterParams.POSITION_BOTTOM) 
    		position = QuickCenterParams.POSITION_RIGHT;
    	
    	View showView = new View(context);	
    	LinearLayout.LayoutParams showParams = new LinearLayout.LayoutParams(
    			LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    	
    	if (position == QuickCenterParams.POSITION_RIGHT) {
    		showParams.height = context.getResources().getInteger(R.dimen.quick_view_right_height);
    		showParams.width = context.getResources().getInteger(R.dimen.quick_view_right_width);		
    	} else if (position == QuickCenterParams.POSITION_BOTTOM) {
    		showParams.height = context.getResources().getInteger(R.dimen.quick_view_bottom_height);
    		showParams.width = GlobalApp.screenWidth;
    	}	
    	
    	showView.setLayoutParams(showParams);
    	showView.setBackgroundColor(getResources().getColor(R.color.blue)); //其他都一样,就是这里换成了蓝色
    	this.addView(showView);
    }

    • FloatWindowQuickCenter关键代码
    这个是面板拖出来后的主要逻辑,里面的内容点还挺多也很杂,杂主要是因为Android碎片化严重,调用系统的功能,你能兼顾各个版本吧,兼顾各个厂商吧,之后我再写一篇来讲里面可能涉及到的问题点。就先贴一下创建的代码好了。
    /**
     * @Function 快捷中心面板
     * 继承至LinearLayout,上面的几个view都是继承于它,便于简洁只写了这个,在此一并说明
     */
    public class FloatWindowQuickCenter extends LinearLayout {
    	/**
    	 * @Function 快捷中心实例化
    	 * 这里我没有动态加载view,而是用了xml布局
    	 */
    	public FloatWindowQuickCenter(Context context, int position) {
    		super(context);
    		mView = LayoutInflater.from(context).inflate(R.layout.view_floatwindow_quickcenter, this);
    		this.mPosition = position;
    		this.mContext = context;
    
    		//其他功能代码
    	}
    
    	//其他功能代码
    }

    • FloatWindowManager关键代码
    这个是自己建立的悬浮窗管理类,里面包含了创建与删除所有悬浮窗的方法,现在为了简洁只取其中一个来展示,其他都可以照猫画虎。里面的方法都采用static,方便直接调用,工具类一般如此写。
    /**
     * @Function 悬浮窗管理类
     * @author rivers
     */
    public class FloatWindowManager {
    	/**
    	 * 用于控制在屏幕上添加或移除悬浮窗
    	 */
    	private static WindowManager mWindowManager;
    
    	/**
    	 * 如果WindowManager还未创建,则创建一个新的WindowManager返回。否则返回当前已创建的WindowManager。
    	 * 
    	 * @param context
    	 *            必须为应用程序的Context.
    	 * @return WindowManager的实例,用于控制在屏幕上添加或移除悬浮窗。
    	 */
    	private static WindowManager getWindowManager(Context context) {
    		if (mWindowManager == null) {
    			mWindowManager = (WindowManager) context
    					.getSystemService(Context.WINDOW_SERVICE);
    		}
    		return mWindowManager;
    	}
    
    	/**
    	 * 快捷中心实例
    	 */
    	private static FloatWindowQuickCenter mFloatWindowQuickCenter;
    	/**
    	 * 快捷中心参数
    	 */
    	private static LayoutParams mQuickCenterParams;
    
            /**
    	 * 快捷中心create方法
    	 */
    	public static void createQuickCenterWindow(Context context, int position) {
    		mWindowManager = getWindowManager(context); //检测windowmanager是否已经创建
    		if (mFloatWindowQuickCenter == null) {
    			mFloatWindowQuickCenter = new FloatWindowQuickCenter(context, position);
    			mQuickCenterParams = new LayoutParams();
    			mQuickCenterParams.type = LayoutParams.TYPE_SYSTEM_ALERT;
    			mQuickCenterParams.format = PixelFormat.RGBA_8888;
    			mQuickCenterParams.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL;
    			mQuickCenterParams.width = android.view.ViewGroup.LayoutParams.MATCH_PARENT;
    			mQuickCenterParams.height = android.view.ViewGroup.LayoutParams.MATCH_PARENT;
    			mQuickCenterParams.x = 0;
    			mQuickCenterParams.y = 0;
    			if (position == QuickCenterParams.POSITION_RIGHT) {
    				mQuickCenterParams.windowAnimations = android.R.style.Animation_Translucent;
    			} else if (position == QuickCenterParams.POSITION_BOTTOM) {
    				mQuickCenterParams.windowAnimations = android.R.style.Animation_InputMethod;
    			}
    			mWindowManager.addView(mFloatWindowQuickCenter, mQuickCenterParams);
    		}
    	}
    
            /**
    	 * 快捷中心remove方法
    	 */
    	public static void removeQuickCenterWindow(Context context) {
    		if (mFloatWindowQuickCenter != null) {
    			mFloatWindowQuickCenter.clearAnimation();
    			mFloatWindowQuickCenter.unregisterReceiver();
    			mWindowManager.removeView(mFloatWindowQuickCenter);
    			mFloatWindowQuickCenter = null;
    		}
    	}
    
    	//其他的功能代码
    	//如show、touch都用类似的方法去执行创建和删除
    }

    需要注意的是LayoutParams这个参数,不是LinearLayout或者RelativeLayout下的LayoutParams,包全称为 android.view.WindowManager.LayoutParams,是WindowManager下的专属参数,在create方法中也看到一些参数的定义了,是很重要的,直接影响到利用WindowManager创建的这个悬浮窗的级别和呈现方法、可操作性等。下面简单的介绍一下我用到的参数,更多的可以Google。

    首先介绍LayoutParams.type
    大概就是设置你的悬浮窗的类型,实际上是一个级别,我用的是 TYPE_SYSTEM_ALERT = 2003,查阅API介绍为  Window type: system window,系统级的窗口,这样我们的所需要的窗口就能显示在界面了。
    /**
     * Start of system-specific window types.  These are not normally
     * created by applications.
     */
    public static final int FIRST_SYSTEM_WINDOW     = 2000;
    
    /**
     * Window type: the status bar.  There can be only one status bar
     * window; it is placed at the top of the screen, and all other
     * windows are shifted down so they are below it.
     * In multiuser systems shows on all users' windows.
     */
    public static final int TYPE_STATUS_BAR         = FIRST_SYSTEM_WINDOW;
    
    /**
     * Window type: the search bar.  There can be only one search bar
     * window; it is placed at the top of the screen.
     * In multiuser systems shows on all users' windows.
     */
    public static final int TYPE_SEARCH_BAR         = FIRST_SYSTEM_WINDOW+1;
    
    /**
     * Window type: phone.  These are non-application windows providing
     * user interaction with the phone (in particular incoming calls).
     * These windows are normally placed above all applications, but behind
     * the status bar.
     * In multiuser systems shows on all users' windows.
     */
    public static final int TYPE_PHONE              = FIRST_SYSTEM_WINDOW+2;
    
    /**
     * Window type: system window, such as low power alert. These windows
     * are always on top of application windows.
     * In multiuser systems shows only on the owning user's window.
     */
    public static final int TYPE_SYSTEM_ALERT       = FIRST_SYSTEM_WINDOW+3;

    接下来介绍 LayoutParams.flag
    常用的有FLAG_NOT_FOCUSABLE,FLAG_NOT_TOUCHABLE,FLAG_NOT_TOUCH_MODAL,按照我理解的意思分别为:
    1.如果使用了就touch事件就会被拦截,悬浮窗下面的view事件就不能触发了,如我在设置界面的展示区域就设置了这个flag,不然就不能操作了
    2.touch事件不能用,永远接受不到touch event
    3.即使这个窗口被聚焦了,允许事件传递到下一层,在我们定义的窗口之外,所以一般会用这个,如dialog
    以上为我的理解,不对的地方请指正,下面贴一下官方的注释
    /**
     * Window type: system window, such as low power alert. These windows
     * are always on top of application windows.
     * In multiuser systems shows only on the owning user's window.
     */
    public static final int TYPE_SYSTEM_ALERT       = FIRST_SYSTEM_WINDOW+3;
    
    
    /** Window flag: this window won't ever get key input focus, so the
     * user can not send key or other button events to it.  Those will
     * instead go to whatever focusable window is behind it.  This flag
     * will also enable {@link #FLAG_NOT_TOUCH_MODAL} whether or not that
     * is explicitly set.
     * 
     * <p>Setting this flag also implies that the window will not need to
     * interact with
     * a soft input method, so it will be Z-ordered and positioned 
     * independently of any active input method (typically this means it
     * gets Z-ordered on top of the input method, so it can use the full
     * screen for its content and cover the input method if needed.  You
     * can use {@link #FLAG_ALT_FOCUSABLE_IM} to modify this behavior. */
    public static final int FLAG_NOT_FOCUSABLE      = 0x00000008;
    
    /** Window flag: this window can never receive touch events. */
    public static final int FLAG_NOT_TOUCHABLE      = 0x00000010;
    
    /** Window flag: even when this window is focusable (its
     * {@link #FLAG_NOT_FOCUSABLE} is not set), allow any pointer events
     * outside of the window to be sent to the windows behind it.  Otherwise
     * it will consume all pointer events itself, regardless of whether they
     * are inside of the window. */
    public static final int FLAG_NOT_TOUCH_MODAL    = 0x00000020;

    再接下来是LayoutParams.windowAnimations,主要是窗口弹出的动画效果,我在项目中根据我的需求,右边我就用android.R.style.Animation_Translucent风格,位移推出快捷中心窗口,如果设置的从下拉出,则用android.R.style.Animation_InputMethod风格,类似于键盘的弹出,还有其他的风格,比如toast,dialog等,TX们可以自行google或者参看。

    至于其他的宽高,xy坐标我就不一一介绍了。

    • Service关键代码
    需用Service来创建和监听快捷中心,由于是桌面级的,我们只能用service在后台去控制manager类,并且用一个TimerTask去检测Touch区域的开启和关闭状态。
    public class FloatWindowService extends Service {
    	@Override
    	public int onStartCommand(Intent intent, int flags, int startId) {
    		// 开启定时器
    		mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    		if (timer == null) {
    			timer = new Timer();
    			RefreshTask freshTask=new RefreshTask();
    			timer.scheduleAtFixedRate(freshTask, 0, 1400);
    		}
    		return super.onStartCommand(intent, flags, startId);
    	}
    
    	class RefreshTask extends TimerTask {
    
    		@Override
    		public void run() {
    			String pckName = getRunningPck();
    			if (pckName != null && !TextUtils.isEmpty(pckName)) {
    				if (currentPkgName == null) {
    					currentPkgName = pckName;
    					doRefresh();
    				} else if (!currentPkgName.equalsIgnoreCase(pckName)) {
    					currentPkgName = pckName;
    					doRefresh();
    				}
    			}
    		}
    
    	}
    
    	public void doRefresh() {
    	    doRefreshFloat();
    	    //其他功能代码
    	}
    
    	public void doRefreshFloat() {
    		if (SharedUtil.getQuickCenterStatus()) { //检测开启状态
    			handler.post(new Runnable() {
    				
    				@Override
    				public void run() {
    					// TODO Auto-generated method stub
    					FloatWindowManager.createQuickCenterTouchArea(getApplicationContext(), SharedUtil.getQuickCenterPosition());
    				}
    			});
    			
    
    		} else {
    			FloatWindowManager.removeQuickCenterTouchArea(getApplication());
    			FloatWindowManager.removeQuickCenterWindow(getApplicationContext());
    		}
    	}
    
    	//其他功能代码
    }

    总结

    这个一整套下来,一个类似于腾讯手机关键快捷中心的快捷方式就已经算是完成了,由于个人原因大概只能写了一个思路,尽可能的贴出关键代码,如果有需要的TX可以留言交流。
    调出的原理懂了,至于快捷中心里面的东西就看需求个人发挥了,无非就是写一个布局,点击后实现功能罢了。这个我如果后面有时间会再写一片编码快捷中心面板时遇到的问题 ,由于是调用系统的功能,所以主要是碎片化的问题,包括版本适配(我从2.3适配到了5.0),以及厂商的适配等。

    遗憾

    腾讯还是很牛的,有一个效果我一直没有实现,即我是通过在Touch区域监听手势滑动然后用动画效果拖出了快捷中心面板。而腾讯手机管家,可以真正做到抽屉(Panel)的效果,即可以在做手势的同时,没有UP的情况下,快捷中心面板就跟着手势滑动出来了,佩服佩服。
    为什么佩服,做过Panel的童鞋会懂,如果你要拖出一个区域,那必须这个区域已经存在了,这样势必会覆盖住下面的东西,虽然没拖出来之前是显示空白,但是下面还是没法点击的。我百思不得其解,也研究了几天,目前仍未有答案,有相关经验的TX请告之,小弟感激不尽。

    展开全文
  • 入门学习Linux常用必会60个命令实例详解doc/txt

    千次下载 热门讨论 2011-06-09 00:08:45
    文件为doc版,可自行转成txt,在手机上看挺好的。 本资源来自网络,如有纰漏还请告知,如觉得还不错,请留言告知后来人,谢谢!!!!! 入门学习Linux常用必会60个命令实例详解 Linux必学的60个命令 Linux提供...
  • Android7.1(API Level 25)及以上系统可以自定义Shortcuts,通过在桌面上长按App Icon弹出Shortcut列表,点击某个shortcut可使用户快捷得打开App里常用的或推荐的任务。国内各个厂商基本上在安卓8.0上集成了该功能...
  • Linux总结

    千次阅读 多人点赞 2020-01-14 20:36:45
    Linux可安装在各种计算机硬件设备中,比如手机、平板电脑、路由器、视频游戏控制台、台式计算机、大型机和超级计算机。严格来讲,Linux这个词本身只表示Linux内核,但实际上人们已经习惯了用Linux来形容整个基于...
  • 移动端app开发,原生开发与混合开发的区别

    万次阅读 多人点赞 2019-09-26 18:47:01
    1、可访问手机所有功能(如GPS、摄像头等)、可实现功能齐全; 2、运行速度快、性能高,绝佳的用户体验; 3、支持大量图形和动画,不卡顿,反应快; 4、兼容性高,每个代码都经过程序员精心设计,一般不会出现...
  • 基于SSM的校园二手交易平台的设计与实现

    万次阅读 多人点赞 2018-05-06 14:24:44
    PS: Java版本:1.7 数据库:MySQL 框架:Spring + Spring MVC + MyBatis 服务器:Tomcat 前端解析框架:Thymeleaf ...下载地址:https://download.csdn.net/download/wsk1103/10395604 一、设计概...
  • matlab人脸识别论文

    万次阅读 多人点赞 2019-10-11 17:41:51
    近几年随着人们越来越关心各种复杂的情形下的人臉自动识别系统以及多功能感知研究的兴起,人脸检测与定位才作为一个独立的模式识别问题得到了较多的重视。本文主要研究人脸的特征提取与分类识别的问题。 2基于bp...
  • jQuery框架也被称为jQuery函数库,是一个快捷、简洁的JavaScript框架,里面对原生的JavaScript封装了各式各样常用的功能代码,提供一种简便的JavaScript设计模式,优化HTML文档操作、事件处理、动画设计和Ajax交互。...
  • 51单片机蓝牙小车

    万次阅读 多人点赞 2019-02-25 20:41:23
    摘要 本次设计选择基于蓝牙遥控的多功能智能小车为对象。选用STC98C52RC单片机作为主控芯片,电机驱动采用L293N ,电源部分采用两节3.7V锂电池供电.采用C语言模块化编程,提高开发效率.蓝牙控制功能.用按键或遥控...
  • python下载手机版-python3手机下载

    千次阅读 2020-10-28 20:31:28
    python3是一个在Android上运行Python3脚本引擎,python3整合了Python3解释器、Console、编辑器和SL4A库...软件介绍python3是一个安卓手机上强大的python3解析器,python3内置QPython语法高亮编辑器,提供强大的脚本...
  • 手机测试功能

    千次阅读 2017-08-28 11:12:22
    一:手机测试功能点 1.安装和卸载    2.登录 ●登录用户名和密码错误时,界面有提示信息 ●用户主动退出登录后,下次启动APP时,应该进入登录界面 ●对于支持自动登录的APP,数据交换时,是否能自动登录成功且...
  • 6.页面提交手机号和验证码,校验手机号和验证码格式后发送ajax请求调用后台代码完成登录 @RestController @RequestMapping("/login") public class MemberController { @Reference private MemberService ...
  •  用手机UC浏览器就可以下载绝大部分网页视频!(优酷,土豆,爱奇艺等有手机客户端的视频网站目前发现不可以,建议还是用在电脑端有维棠下载)    是安卓版的UC,没试过苹果版的,应该不可以,土豪们请自己尝试...
  • 华为手机翻译功能怎么使用?在我们的生活中会经常遇到翻译问题,许多外语不好的朋友该怎么办呢?华为手机已经为我们解决了这个问题,今天小编就教大家学会使用华为手机中的三种翻译技巧,需要的小伙伴可不要错过哦。...
  • 1. 下载“QQ登录”按钮图片,并将按钮放置在页面合适的位置 按钮图片下载:  点击这里下载  。 按照UI规范,将按钮放置在页面合适的位置: 点击这里查看 。 2. 为“QQ登录”按钮添加前台代码 2.1 效果...
  • C#基础教程-c#实例教程,适合初学者

    万次阅读 多人点赞 2016-08-22 11:13:24
    程序所完成的输入输出功能是通过Console类来完成的,Console是在名字空间System中已经定义好的一个类。Console类有两个最基本的方法WriteLine和ReadLine。ReadLine表示从输入设备输入数据,WriteLine则用于在输出...
  • js添加到桌面快捷方式(实现功能

    千次阅读 2019-06-04 17:32:58
    添加桌面快捷方式(实现功能) js代码如下:
  • qpython软件是非常不错的一款...qpython手机版介绍款免费且好用的小工具应用,可以在安卓设备上去运行python脚本的程序引擎,清爽简洁的界面拥有着实用的功能,支持文件的搜索以及快速的打开,包含了python的解释器...
  • 1、打开快捷指令首先打开苹果手机里面自带的"快捷指令"功能,根据自己的需求创建快捷键。2、快捷时钟每天叫醒你的是梦想吗?不是!是一遍又一遍烦人的闹钟。睡觉之前定一个闹钟,已经是很多人的习惯,防止第二天上班...
  • 今天我正式更新了「小红书...「小红书下载器」下载地址1新功能跟之前一样,「小红书下载器」快捷指令分为免费部分和解锁部分:前两个菜单,下载图片和视频即为可以免费无限使用,只要方法不失效就可以一直用下去,原...
  • 文章主要介绍了如何通过捷径(快捷指令)在移动端调用 JavaScript 修改网页元素内容。
  • 苹果iOS捷径(快捷指令)自动填写表单

    万次阅读 多人点赞 2020-10-06 11:27:33
    文章主要介绍了如何通过捷径(快捷指令)调用 JavaScript 在网页运行的方式快速填写表单。
  • Java 后台实现 发送手机短信的功能 效果截图: 一、准备阶段 (1)准备第三方平台: 发送短信肯定是需要第三方平台,并且是收费的。 本篇以【中国网建】提供的 SMS 短信平台实现,该平台新用户注册可以拥有免费 5 ...
  • 关闭华为手机屏幕下滑搜索功能

    千次阅读 2020-09-15 15:57:33
    摘自花粉俱乐部论坛 adb shell pm disable-user com.huawei.search
  • oppo手机吸引用户的不仅仅是外观和自拍,还有它特别好用的系统,就比如翻译这个功能,oppo手机自带的功能就能帮你轻松完成。 1.拍照翻译 当我们遇到什么不懂的英文图标或者是英文商品时,我们就可以利用oppo手机的...
  • Android应用创建手机桌面快捷方式

    千次阅读 2015-04-14 09:51:33
    /**Android专门提供了Intent.ShortcutIconResource.fromContext来创建快捷方式的图标,最后通过setResult来返回*/ Parcelable icon = Intent.ShortcutIconResource.fromContext(MainActivity.this, R.drawable.ic...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 45,016
精华内容 18,006
关键字:

下载手机快捷功能