web项目接入支付宝开发"超详细"

  • 前言
    • 接入开发前准备
    • 代码开发
    • 项目测试

版权声明:本文为博主原创文章,未经博主允许不得转载。

前言

 最近公司项目涉及到支付宝支付的接入,说简单也挺简单,说难也挺复杂的。自己做了总结,供大家参考学习。

接入开发前准备

  1. 支付宝接入所需要的参数可以参考支付宝文档 “https://alipay.open.taobao.com/doc2/detail.htm?treeId=270&articleId=105901&docType=1#s0”
  2. 其实开发时不需要那么多的参数
    这是个人所总结的必须参数
    1、公共参数
# 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
alipay.app_id=2016092700608222
# 商户私钥,您的PKCS8格式RSA2私钥
alipay.privateKey=MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCT9FGhs6lslzLvKrjzoglEJYfj3KqdNHN6bEy0uQabTaos+eU4YMw/fr14hADziuLhgPG1/GQEHQHOujiNJUSw6N++E5Wc1p3rOC1a2tnRj7JncgKUoyfEdroaeBBg/WosuhCWor+TFXs5oB8sUscJBNqzeM1cdzjxj9Du6YcCirDU4+61vuAfaladd5WsvMr3kPnkazDOnAiB3FS9tOGExMF2DW44XJtYX69fI7KTAp8HQwf6pyvvorHBArKim1bi8UiOCYCILbgmP5rQzHoRbdL2UeL1PwadfFtwMxQDcuhwOt01VVTKF5rI5NqsZSmQgvpXyL87O/bs+1AgMBAAECggEAKz76rV0qZIc9aBMAxJXUR4sA0WWqqRCvwFTvhtOeTr7Awyy4B2ajzNtq3lMXRBiQgIGEJUGEqn8gDCD6bqc6EMvAunpW/OTue9aLy0a07EAoUXxNrMyTzyU0+I+nmfH4muI3/w/LF17sCcf31KjNbKFym4rv29stVc5Hr82qnN8hYPiWpHveYpaB0r+NtvuXqSPswzmIELussvpCu7AhzHZ8LqvUS2knl+YnjDfMWdjFZyXZRxsjvcsStUI7E3Ygm8OGWimnYXQalDBpV03Z+RSCgwzA50DvGa53nwu+EFizl86hb17o96+RpHk6Emao2WbJSGnHN2GlDnXFjcXwAQKBgQDqFvH4XcVWtqH+wOlKsITwoBonv1WDJOAe1L85YbJVisQuQwlnNozaIQLiw+SErkufyrSiupBYbhvDKkZa/Ur+pMgmqXOFTyWXFcQNrd3Hha/LY+jjTODOOLmI962t0Kl8QfEPh6zv2WFGZ7ZNPTzs/5lFN+PCEXut84KoMYc/AQKBgQChzXl6XYAnVqYt73X23YRdx566GeG6ka6wqCf9Lyz4iZSxR4rpB0xR9ehNmQIank3afEduGODYcis7ytZg/Lpm+b0gNgx/Lb2S2Kpgp7GHx6r+CoL1xMasWcJS/xrRwQDb3ow9AeHuUpgZ4s3jnA8LoLdJ13kkGrsKaUF4IRNEtQKBgQCg9KHvyloT44PDbNV7+5+M7CjPx6l+gO5xhIrvY5OBaea2gHWIuGNk4Gnhjhwkdsuc1X4anfj+NMd2DC1QBvV33cmZe83ojaElH1wso63osK1NRictkwDICwzXdqW+68h9ncGokfuA95EBHfKlbUPlGWJDy8gY+nh2BQeDqnp6AQKBgQCLk0qVag7g4Hhd69Gg8Rn8I/UiqKz2WjGNpqFIYOe0RkqEWyjTOD53/V81gSY1fBXAwbCEouVjEamF3MXtyFWr+wdQwA8rrnN4N3tSAZa9gFpa5wptpB+WEZ/2JKYoBwwMnv/uqK8S/SDEQ8hD7h10dGFoS33uzThIFOArFq0eeQKBgF2kiybVUrEqiXpr6ADLrulsrfkxlqGoiPR9jZrxXomdgutbBTZ/J5G8sFT5mP7/oJxpMMzOg6AdmtQQTkPJEAvW/XWWfxn2rTP39E0TTA0gY6NqLTTLhlhhxShNDPwucHgslMsPqZ6pl1u1HjWAHIpbSthhJ8L5nH7G2zUAUCnb
# 支付宝公钥,查看地址:https://openhome.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
alipay.publicKey=MIIBIjANBgkqhkiG9w0BAQEFCAQ8AMIIBCgKCAQEAx4j7DP30zl7+WahLyJRydSwcayJsEavQ7S1fPWqmHTK6TTVeNSMrcG/blXv42p7Eib3KeXvVIMOnNyoKXoIoOfSBYOvTyPH6cs60W31A0TanTc9aMlGof8X4WaDSDz78T34elagX+cpigV8mqLB/umkl1WoGIAkX7r3Bau+HWnPgftYPmzpL5G1/XdSEgoklGGsLGiiSGfE2KtV035+vJiViLRTiCEIKhygKTOROq36O5BsSIfgapLz08lzPT3ik9g26Jwq/7oEACcO8zg9LkcqHTnxV9LiSVg4+ay1huSmvxRE2vm21iNFNzIo6v+JEoc+cZJ0b9E7RZWKDE1ZXvQIDAQAB
# 服务器异步通知页面路径需http://格式的完整路径,不能加?id=123这类自定义参数  必须是外网才能访问的页面
alipay.notify_url=http://ruv6tc.natappfree.cc
# 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数
alipay.return_url=http://localhost:8080/returnUrl
# 签名方式
alipay.sign_type=RSA2
# 字符编码格式
alipay.charset=utf-8
# 支付宝网关
alipay.gatewayUrl=https://openapi.alipaydev.com/gateway.do
# 支付宝网关
alipay.logPath="C:\\"

2请求参数

/*** 商户订单号,必填**/private String out_trade_no;/*** 订单名称,必填*/private String subject;/*** 付款金额,必填* 根据支付宝接口协议,必须使用下划线*/private String total_amount;/*** 商品描述,可空*/private String body;/*** 超时时间参数*/private String timeout_express= "5m";/*** 产品编号*/private String product_code= "FAST_INSTANT_TRADE_PAY";
  1. 开发环境:开发测试时,我们一般选用 支付宝的沙箱环境进行开发测试 “https://auth.alipay.com/login/ant_sso_index.htm?goto=https%3A%2F%2Fopenhome.alipay.com%2Fplatform%2Fhome.htm”
    登录开通后 点右上角的管理中心

    再在导航栏中找到 开发中心------>研发服务

4.进入沙箱,进行注册 私钥和公钥

代码开发

这里使用sprinboot 做测试
1.使用idea快速创建一个springboot项目

一直Next到

然后点Next----finish
2.项目创建完成打开 pom文件 添加两个依赖

  <!-- alipay 支付宝SDk--><dependency><groupId>com.alipay.sdk</groupId><artifactId>alipay-sdk-java</artifactId><version>3.1.0</version></dependency><!-- fastjson --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.48</version></dependency></dependencies>

3.在resources创建alipay.properties文件

内容:

# 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
alipay.app_id=2016092700608222
# 商户私钥,您的PKCS8格式RSA2私钥
alipay.privateKey=MIIEvgIBADANBgkqhkiG9wAQEFAASCBKgwggSkAgEAAoIBAQCT9FGhs6lslzLvKrjzoglEJYfj3KqdNHN6bEy0uQabTaos+eU4YMw/fr14hADziuLhgPG1/GQEHQHOujiNJUSw6N++E5Wc1p3rOC1a2tnRj7JncgKUoyfEdroaeBBg/WosuhCWor+TFXs5oB8sUscJBNqzeM1cdzjxj9Du6YcCirDU4+61vuAfaladd5WsvMr3kPnkazDOnAiB3FS9tOGExMF2DW44XJtYXzvw6U169fI7KTAp8HQwf6pyvvorHBArKim1bi8UiOCYCILbgmP5rQzHoRbdL2UeL1PwadfFtwMxQDcuhwOt01VVTKF5rI5NqsZSmQgvpXyL87O/bs+1AgMBAAECggEAKz76rV0qZIc9aBMAxJXUR4sA0WWqqRCvwFTvhtOeTr7Awyy4B2ajzNtq3lMXRBiQgIGEJUGEqn8gDCD6bqc6EMvAunpW/OTue9aLy0a07EAoUXxNrMyTzyU0+I+nmfH4muI3/w/LF17sCcf31KjNbKFym4rv29stVc5Hr82qnN8hYPiWpHveYpaB0r+NtvuXqSPswzmIELussvpCu7AhzHZ8LqvUS2knl+YnjDfMWdjFZyXZRxsjvcsStUI7E3Ygm8OGWimnYXQalDBpV03Z+RSCgwzA50DvGa53nwu+EFizl86hb17o96+RpHk6Emao2WbJSGnHN2GlDnXFjcXwAQKBgQDqFvH4XcVWtqH+wOlKsITwoBonv1WDJOAe1L85YbJVisQuQwlnNozaIQLiw+SErkufyrSiupBYbhvDKkZa/Ur+pMgmqXOFTyWXFcQNrd3Hha/LY+jjTODOOLmI962t0Kl8QfEPh6zv2WFGZ7ZNPTzs/5lFN+PCEXut84KoMYc/AQKBgQChzXl6XYAnVqYt73X23YRdx566GeG6ka6wqCf9Lyz4iZSxR4rpB0xR9ehNmQIank3afEduGODYcis7ytZg/Lpm+b0gNgx/Lb2S2Kpgp7GHx6r+CoL1xMasWcJS/xrRwQDb3ow9AeHuUpgZ4s3jnA8LoLdJ13kkGrsKaUF4IRNEtQKBgQCg9KHvyloT44PDbNV7+5+M7CjPx6l+gO5xhIrvY5OBaea2gHWIuGNk4Gnhjhwkdsuc1X4anfj+NMd2DC1QBvV33cmZe83ojaElH1wso63osK1NRictkwDICwzXdqW+68h9ncGokfuA95EBHfKlbUPlGWJDy8gY+nh2BQeDqnp6AQKBgQCLk0qVag7g4Hhd69Gg8Rn8I/UiqKz2WjGNpqFIYOe0RkqEWyjTOD53/V81gSY1fBXAwbCEouVjEamF3MXtyFWr+wdQwA8rrnN4N3tSAZa9gFpa5wptpB+WEZ/2JKYoBwwMnv/uqK8S/SDEQ8hD7h10dGFoS33uzThIFOArFq0eeQKBgF2kiybVUrEqiXpr6ADLrulsrfkxlqGoiPR9jZrxXomdgutbBTZ/J5G8sFT5mP7/oJxpMMzOg6AdmtQQTkPJEAvW/XWWfxn2rTP39E0TTA0gY6NqLTTLhlhhxShNDPwucHgslMsPqZ6pl1u1HjWAHIpbSthhJ8L5nH7G2zUAUCnb
# 支付宝公钥,查看地址:https://openhome.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
alipay.publicKey=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx4j7DP30zl7+WahLyJRydSwcayJsEavQ7S1fPWqmHTK6TTVeMrcG/blXv42p7Eib3KeXvVIMOnNyoKXoIoOfSBYOvTyPH6cs60W31A0TanTc9aMlGof8X4WaDSDz78T34elagX+cpigV8mqLB/umkl1WoGIAkX7r3Bau+HWnPgftYPmzpL5G1/XdSEgoklGGsLGiiSGfE2KtV035+vJiViLRTiCEIKhygKTOROq36O5BsSIfgapLz08lzPT3ik9g26Jwq/7oEACcO8zg9LkcqHTnxV9LiSVg4+ay1huSmvxRE2vm21iNFNzIo6v+JEoc+cZJ0b9E7RZWKDE1ZXvQIDAQAB
# 服务器异步通知页面路径需http://格式的完整路径,不能加?id=123这类自定义参数  必须是外网才能访问的页面
alipay.notify_url=http://ruv6tc.natappfree.cc
# 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数
alipay.return_url=http://localhost:8080/returnUrl
# 签名方式
alipay.sign_type=RSA2
# 字符编码格式
alipay.charset=utf-8
# 支付宝网关
alipay.gatewayUrl=https://openapi.alipaydev.com/gateway.do
# 支付宝网关
alipay.logPath="C:\\"

4.创建包,本人的包结构

4.在model下建两个类(一个实体类,一个配置类)
1AlipayProperties (配置类,作用:把alipay.properties文件加载到类中)

package com.example.alipay.model;import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;@Component
@PropertySource(value={"classpath:alipay.properties"})
@ConfigurationProperties(prefix = "alipay")
public class AlipayProperties {private String app_id;private String privateKey;private String publicKey;private String notify_url;private String return_url;private String sign_type;private String charset;private String gatewayUrl;private String logPath;@Overridepublic String toString() {return "AlipayProperties{" +"app_id='" + app_id + '\'' +", privateKey='" + privateKey + '\'' +", publicKey='" + publicKey + '\'' +", notify_url='" + notify_url + '\'' +", return_url='" + return_url + '\'' +", sign_type='" + sign_type + '\'' +", charset='" + charset + '\'' +", gatewayUrl='" + gatewayUrl + '\'' +", logPath='" + logPath + '\'' +'}';}public String getApp_id() {return app_id;}public void setApp_id(String app_id) {this.app_id = app_id;}public String getPrivateKey() {return privateKey;}public void setPrivateKey(String privateKey) {this.privateKey = privateKey;}public String getPublicKey() {return publicKey;}public void setPublicKey(String publicKey) {this.publicKey = publicKey;}public String getNotify_url() {return notify_url;}public void setNotify_url(String notify_url) {this.notify_url = notify_url;}public String getReturn_url() {return return_url;}public void setReturn_url(String return_url) {this.return_url = return_url;}public String getSign_type() {return sign_type;}public void setSign_type(String sign_type) {this.sign_type = sign_type;}public String getCharset() {return charset;}public void setCharset(String charset) {this.charset = charset;}public String getGatewayUrl() {return gatewayUrl;}public void setGatewayUrl(String gatewayUrl) {this.gatewayUrl = gatewayUrl;}public String getLogPath() {return logPath;}public void setLogPath(String logPath) {this.logPath = logPath;}}
 2、AlipayBean(实体类 作用:接收请求参数)
package com.example.alipay.model;/*** 支付实体对象* 根据支付宝接口协议,其中的属性名,必须使用下划线,不能修改* @author Louis* @date Dec 12, 2018*/
public class AlipayBean {/*** 商户订单号,必填**/private String out_trade_no;/*** 订单名称,必填*/private String subject;/*** 付款金额,必填* 根据支付宝接口协议,必须使用下划线*/private String total_amount;/*** 商品描述,可空*/private String body;/*** 超时时间参数*/private String timeout_express= "5m";/*** 产品编号*/private String product_code= "FAST_INSTANT_TRADE_PAY";public String getOut_trade_no() {return out_trade_no;}public void setOut_trade_no(String out_trade_no) {this.out_trade_no = out_trade_no;}public String getSubject() {return subject;}public void setSubject(String subject) {this.subject = subject;}public String getTotal_amount() {return total_amount;}public void setTotal_amount(String total_amount) {this.total_amount = total_amount;}public String getBody() {return body;}public void setBody(String body) {this.body = body;}public String getTimeout_express() {return timeout_express;}public void setTimeout_express(String timeout_express) {this.timeout_express = timeout_express;}public String getProduct_code() {return product_code;}public void setProduct_code(String product_code) {this.product_code = product_code;}}

5.在service.impl下建Alipay类
接入支付中最主要代码
内容

package com.example.alipay.service.impl;import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.example.alipay.model.AlipayBean;
import com.example.alipay.model.AlipayProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.util.Date;
import java.util.UUID;@Component
public class Alipay {/*** 支付接口* @param alipayBean* @return* @throws AlipayApiException*/@AutowiredAlipayProperties alipayProperties;public String pay(AlipayBean alipayBean) throws AlipayApiException {// 1、获得初始化的AlipayClientString serverUrl = alipayProperties.getGatewayUrl();String appId = alipayProperties.getApp_id();String privateKey = alipayProperties.getPrivateKey();String format = "json";String charset = alipayProperties.getCharset();String alipayPublicKey = alipayProperties.getPublicKey();String signType = alipayProperties.getSign_type();String returnUrl = alipayProperties.getReturn_url();String notifyUrl = alipayProperties.getNotify_url();AlipayClient alipayClient = new DefaultAlipayClient(serverUrl, appId, privateKey, format, charset, alipayPublicKey, signType);// 2、设置请求参数AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();// 页面跳转同步通知页面路径alipayRequest.setReturnUrl(returnUrl);// 服务器异步通知页面路径alipayRequest.setNotifyUrl(notifyUrl);//账户订单号String out_trade_no = new Date().getTime()+ UUID.randomUUID().toString();alipayBean.setOut_trade_no(out_trade_no);// 封装参数alipayRequest.setBizContent(JSON.toJSONString(alipayBean));// 3、请求支付宝进行付款,并获取支付结果String result = alipayClient.pageExecute(alipayRequest).getBody();// 返回付款信息return result;}
}

6.在controller下建OrderController类
内容

package com.example.alipay.controller;import com.alipay.api.AlipayApiException;
import com.example.alipay.model.AlipayBean;
import com.example.alipay.service.impl.Alipay;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;@Controller
public class OrderController {@AutowiredAlipay alipay;@PostMapping(value = "alipay")@ResponseBody
//    String outTradeNo, String subject, String totalAmount, String bodypublic String alipay(AlipayBean alipayBean) throws AlipayApiException {return alipay.pay(alipayBean);}
}

7.最后在static下建一个测试的html页面(index.html)

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<H1>支付测试</H1>
<hr>
<div class="form-container"><form id="form" action="http://localhost:8080/alipay" method="post"><!--   *商户订单 :-->*订单名称 :<input type="text" name="subject" value="快乐风男"><br>*付款金额 :<input type="text" name="total_amount" value="300" ><br>*商品描述 :<input type="text" name="body" value="移动的300元"><br><input type="submit" value="支付宝支付" ></form>
</div>
</body><style>.form-container {padding-top:10px;}input {margin:10px;}
</style>
</html>

到此 代码就完成了

项目测试

1.在浏览器输入 localhost:8080

2点击支付宝支付

3.注意:因为我们是用沙箱环境测试开发的,所有在这里是需要下载一个沙箱般的支付宝手机app 才能扫码支付(沙箱般的是做测试用的,不会涉及到财产)
沙箱下载:

最后本人乃是小白一个如有不好的,请大家多多指教

web项目接入支付宝开发(超详细)相关推荐

  1. Eclipse导入和调试别人的Java web项目完整教程(超详细,包括报错解决)

    本文详细介绍了如何导入一个外部的Java Web项目,如果看了本文还是不会调试,可以问我 个人主页的其他分类专栏也有一些比较好的项目 1.主要工作 (1)保证电脑有java 环境配置以及JDK 文件. ...

  2. web百度离线地图开发(详细教程)2019

    web百度离线地图开发(详细教程) 需求情景 主要参考 开发步骤 一.JS API文件下载 二.修改API文件 1.屏蔽ak验证 2.设置引用本地资源路径 3.下载本地资源 4.引用本地资源 三.加载 ...

  3. Java Web实现登录注册(超详细附代码)

    Java Web实现登录注册(超详细附代码) 文章目录 Java Web实现登录注册(超详细附代码) 1.前言 2.登录注册设计流程 3.注册的数据流程 4.登录的数据流程 5.部分代码的展示 5.1 ...

  4. Pyside2 学习系列三:PyInstaller打包项目瘦身(超详细的Pyside2 攻略)

    继上一篇文章打包后,发现包太大了,我们现在开始进行瘦身优化. 本项目的所有演示代码:github可在这里下载. 打包只用的工具为PyInstaller. 不想细看的朋友 可以直接跳到 最后 方法对比 ...

  5. 支付宝交易查询接口分析及实现----springboot项目接入支付宝(四)

    一.API说明 springboot项目接入支付宝(一) springboot项目接入支付宝(二) springboot项目接入支付宝(三) API地址 二.service /*** @Descrip ...

  6. 配置沙箱应用环境----springboot项目接入支付宝(一)

    1.入口 登录支付宝的开放平台 2.生成密钥 3.加签管理 然后将前面的应用公钥粘贴进去后确认. 4.后续 springboot项目接入支付宝(二) springboot项目接入支付宝(三) 注:能力 ...

  7. Android接入支付宝开发

    Android接入支付宝接口主要分为以下几大步奏: 作为程序员,其实我们只是做了第五步的工作,假如你需要自己一个人都完成上述的操作,详细的步骤请看支付宝移动支付的官网: https://cshall. ...

  8. Java接入支付宝支付超级详细教程——从入门到精通

    ​ Java接入支付宝支付教程 源码下载 源码获取:点击获取源码 本文介绍了"二维码付款"的代码.其他支付方式的代码都在源码中. 一.创建应用 1.登录支付宝开放平台 支付宝开放平 ...

  9. 服务器项目部署总结(超详细)

    系列文章目录 Linux操作系统笔记[超详细] 本篇文章主要从准备篇.项目开发.项目打包.项目部署四个部分去介绍如何把前后端分离的项目部署到阿里云服务器,在服务器上去玩自己的项目. 项目最终效果图:输 ...

最新文章

  1. 编程珠玑:对DAO层的一点修改
  2. sublime 经验总结 主题有 less2css
  3. dojo 官方翻译 dojo/_base/array 版本1.10
  4. 《Java 核心技术卷1 第10版》学习笔记------日志
  5. redhat7基本命令操作
  6. LeetCode 894. 所有可能的满二叉树(递归)
  7. Java的主流加密方式——简介
  8. 易恢复Ontrack EasyRecovery15绿色版
  9. html-菜鸟--书架仿饿了么首页—Html学习(1)
  10. 创世神曲java官网_创世神曲内购官方手机版
  11. 如何快速查询手机号码归属地和运营商
  12. 7-5 判断某整数是正整数、负整数还是零 (6分)
  13. 职称计算机初级应知应会书,职称计算机考试用书
  14. 放大器输入级的差动放大 + 电流镜
  15. php+供应商管理系统,供应商管理系统
  16. 计算机右键括号内的字母,排序快捷键 excel|关于EXCEL的。如图,括号里面的字母是不是代表快捷键的意思?怎么快捷?...
  17. 光线通过三棱镜模拟matlab仿真
  18. 难忘的聚会,美好的时光(1957--1962)
  19. CMake Error at CMakeLists.txt:97 (ADD_TARGET_DEFINITIONS): Unknown CMake command ADD_TARGET_DEFIN
  20. 多项新规重磅发布,微信视频号近期需要关注这几点

热门文章

  1. Enhanced Deep Residual Networks for Single Image Super-Resolution
  2. find函数用法详解
  3. 大学java学习封魔路线(总有一条适合你)
  4. 51nod 1244 莫比乌斯函数之和(积性函数前缀和)
  5. chrome调试手机网页
  6. 学校人力资源管理系统可行性研究和需求分析
  7. 软件架构模式之分层模式
  8. 史蒂夫·乔布斯语录(Steve Jobs Quotes)
  9. SSTI/沙盒逃逸详细总结
  10. android sleep