本文章仅作为个人笔记

截止发文在网上找了一圈支付宝登录的,大部分都是照搬官方的demo,没什么实际用处,官方的demo大家应该都看过了,对于Android来讲问题应该不大,后台就gg了,这里主写后台与Android对接心得。
因为实在被支付宝折腾的厉害,所以这里就不写什么注册处签约什么的流程了,心累,上些干货(代码),作为中国人自己的开放平台,文档还整理成这个样子需要自己琢磨代码的估计也就这一家了。也有可能是楼主自己语文或者检索能力不过关哦,如果看客发现有不规范或者不对的地方还望指出,这里先谢过了。
蚂蚁金服开放平台官网
支付宝Android官方接入文档
支付宝IOS官方接入文档
Android客户端demo&sdk下载地址(1.5.5)
IOS客户端demo&sdk下载地址(1.5.7)
服务器端接入官方文档
登录结果返回参数说明
支付结果返回参数说明
  • IOS端

    • 引入官方库(于Podfile文件加入如下内容并运行 pod install)

      pod 'AlipaySDK-iOS'
    • 于头文件添加如下内容,不知道什么是头文件的建议参考支付宝IOS官方接入文档

      #import 
    • 添加 URL Schemes ,设置为aliauth 并设置值为某一唯一值,如 包名.aliauth。设置为alipay 并设置值为某一唯一值,如 包名.alipay。

    • 与Localizable.strings 添加 "aliauthback" = ""//这里需要保持与上面的URL Schemes aliauth值一致。添加 "alipayback" = ""//这里需要保持与上面的URL Schemes alipay值一致。

    • 创建AliPayUtils工具文件

              class AliPayUtils {                    private static var aliAuthBack: AliPayBack?            private static var aliPayBack: AliPayBack?                    static func login(signStr: String, aliAuthBack: AliPayBack?) {                AliPayUtils.aliAuthBack = aliAuthBack                AlipaySDK().auth_V2(withInfo: signStr, fromScheme: NSLocalizedString("aliauthback", comment: ""), callback: { (resp) in                    loginBack(resultDic: resp as! [NSObject: AnyObject])                })            }                    static func loginBack(resultDic: [NSObject: AnyObject]) {                if let Alipayjson: [String: AnyObject] = resultDic as? [String: AnyObject] {                    let resultStatus = Alipayjson["resultStatus"] as! String                    print("loginBack resultStatus=\(resultStatus)")                    if resultStatus == "9000" {//   请求处理成功                        aliAuthBack?.finish(Alipayjson["result"] as? String)                    } else {                        aliAuthBack?.failed()                    }                }            }                    static func pay(signStr: String, aliPayBack: AliPayBack?) {                AliPayUtils.aliPayBack = aliPayBack                AlipaySDK().payOrder(signStr, fromScheme: NSLocalizedString("alipayback", comment: ""), callback: { (resp) in                    payBack(resultDic: resp as! [NSObject: AnyObject])                })            }                    static func payBack(resultDic: [NSObject: AnyObject]) {                if let Alipayjson: [String: AnyObject] = resultDic as? [String: AnyObject] {                    let resultStatus = Alipayjson["resultStatus"] as! String                    print("payBack resultStatus=\(resultStatus)")                    if resultStatus == "9000" || resultStatus == "8000" {//   订单支付成功或正在处理中                        aliPayBack?.finish(Alipayjson["result"] as? String)                    } else {                        aliPayBack?.failed()                    }                }            }                }                protocol AliPayBack {            func finish(_ result: String?)                    func failed()        }
    • 于AppDelegate添加回调(这里贴主要代码)

              @UIApplicationMain        class AppDelegate: UIResponder, UIApplicationDelegate {                    func application(_ application: UIApplication, handleOpen url: URL) -> Bool {                switch url.scheme {                case NSLocalizedString("aliauthback", comment: ""):                    AlipaySDK().processAuth_V2Result(url) { (back) in                        AliPayUtils.loginBack(resultDic: back as! [NSObject: AnyObject])                    }                case NSLocalizedString("alipayback", comment: ""):                    AlipaySDK().processOrder(withPaymentResult: url) { (back) in                        AliPayUtils.payBack(resultDic: back as! [NSObject: AnyObject])                    }                default:                    print("handleOpenUrl1")                }                print("handleOpenUrl11=\(url.scheme)")                return true            }                    func application(_ application: UIApplication, open url: URL                    , sourceApplication: String?, annotation: Any) -> Bool {                switch url.scheme {                case NSLocalizedString("aliauthback", comment: ""):                    AlipaySDK().processAuth_V2Result(url) { (back) in                        AliPayUtils.loginBack(resultDic: back as! [NSObject: AnyObject])                    }                case NSLocalizedString("alipayback", comment: ""):                    AlipaySDK().processOrder(withPaymentResult: url) { (back) in                        AliPayUtils.payBack(resultDic: back as! [NSObject: AnyObject])                    }                default:                    print("handleOpenUrl2")                }                print("handleOpenUrl12=\(url.scheme)")                return true            }        }
    • 登录调用(这里写部分伪代码):

              //从服务器获取签名字符串,这里后面服务器开发会贴出,客户端可以不用管。        var signStr = getSignStrFromService()        AliPayUtils.login(signStr: result!, aliAuthBack: AliAuthBack())        //创建AliPayBack实例        struct AliAuthBack: AliPayBack {                    func finish(_ result: String?) {                //登录成功,直接将获取的结果上传至服务器处理,服务器返回用户信息即可。            }                    func failed() {                //登录失败            }        }
  • Android端

    • 接入前奏,注册签约的可另行百度,这里主要写代码部分

    • 下载jar包并导入(这里使用的是alipaySdk-20180601.jar)

    • 放入项目libs文件夹下

    • 与build.gradle导入jar(这里贴部分关键代码)

          dependencies {        implementation fileTree(dir: 'libs', include: ['*.jar'])        implementation files('libs/alipaySdk-20180601.jar')    }
    • 于AndroidManifest.xml注册权限及activity(这里贴出部分关键代码)

                                                      
      • 创建AliPayUtils工具文件(AuthResult/PayResult文件会后面贴出)

                  import android.app.Activity;          import android.text.TextUtils;          import android.util.Log;                    import com.alipay.sdk.app.AuthTask;          import com.alipay.sdk.app.EnvUtils;          import com.alipay.sdk.app.PayTask;                    import java.util.Map;                    public class AliPayUtils {                        public interface Back {                  public void success(String result);                            public void failed();              }                        public static void startPay(final Activity activity, final String orderInfo, final Back back) {                  if (orderInfo == null || back == null) {                      return;                  }                  new Thread(new Runnable() {                      @Override                      public void run() {          //                EnvUtils.setEnv(EnvUtils.EnvEnum.SANDBOX);//测试使用此设置                          EnvUtils.setEnv(EnvUtils.EnvEnum.ONLINE);//正式环境使用此设置                          PayTask alipay = new PayTask(activity);                          Map result = alipay.payV2(orderInfo, true);                          PayResult payResult = new PayResult(result);                          String resultStatus = payResult.getResultStatus();                          if (TextUtils.equals(resultStatus, "9000")) {                              back.success(payResult.getResult());                          } else {                              back.failed();                          }                      }                  }).start();              }                        public static void login(final Activity activity, final String authInfo, final Back back) {                  if (authInfo == null || back == null) {                      return;                  }                  new Thread(new Runnable() {                      @Override                      public void run() {                          AuthTask authTask = new AuthTask(activity);                          Map result = authTask.authV2(authInfo, true);                          AuthResult authResult = new AuthResult(result, true);                          String resultStatus = authResult.getResultStatus();                          if (TextUtils.equals(resultStatus, "9000")                                  && TextUtils.equals(authResult.getResultCode(), "200")) {                              back.success(authResult.getResult());                          } else {                              back.failed();                          }                      }                  }).start();              }                    }
    • 创建AuthResult工具文件

                  import android.text.TextUtils;                        import java.util.Map;                        public class AuthResult {                            private String resultStatus;                private String result;                private String memo;                private String resultCode;                private String authCode;                private String alipayOpenId;                            public AuthResult(Map rawResult, boolean removeBrackets) {                    if (rawResult == null) {                        return;                    }                                for (String key : rawResult.keySet()) {                        if (TextUtils.equals(key, "resultStatus")) {                            resultStatus = rawResult.get(key);                        } else if (TextUtils.equals(key, "result")) {                            result = rawResult.get(key);                        } else if (TextUtils.equals(key, "memo")) {                            memo = rawResult.get(key);                        }                    }                                String[] resultValue = result.split("&");                    for (String value : resultValue) {                        if (value.startsWith("alipay_open_id")) {                            alipayOpenId = removeBrackets(getValue("alipay_open_id=", value), removeBrackets);                            continue;                        }                        if (value.startsWith("auth_code")) {                            authCode = removeBrackets(getValue("auth_code=", value), removeBrackets);                            continue;                        }                        if (value.startsWith("result_code")) {                            resultCode = removeBrackets(getValue("result_code=", value), removeBrackets);                            continue;                        }                    }                            }                            private String removeBrackets(String str, boolean remove) {                    if (remove) {                        if (!TextUtils.isEmpty(str)) {                            if (str.startsWith("\"")) {                                str = str.replaceFirst("\"", "");                            }                            if (str.endsWith("\"")) {                                str = str.substring(0, str.length() - 1);                            }                        }                    }                    return str;                }                            @Override                public String toString() {                    return "resultStatus={" + resultStatus + "};memo={" + memo + "};result={" + result + "}";                }                            private String getValue(String header, String data) {                    return data.substring(header.length(), data.length());                }                            /**                 * @return the resultStatus                 */                public String getResultStatus() {                    return resultStatus;                }                            /**                 * @return the memo                 */                public String getMemo() {                    return memo;                }                            /**                 * @return the result                 */                public String getResult() {                    return result;                }                            /**                 * @return the resultCode                 */                public String getResultCode() {                    return resultCode;                }                            /**                 * @return the authCode                 */                public String getAuthCode() {                    return authCode;                }                            /**                 * @return the alipayOpenId                 */                public String getAlipayOpenId() {                    return alipayOpenId;                }            }  
    • 创建PayResult工具文件

                  import android.text.TextUtils;                        import java.util.Map;                        public class PayResult {                private String resultStatus;                private String result;                private String memo;                            public PayResult(Map rawResult) {                    if (rawResult == null) {                        return;                    }                                for (String key : rawResult.keySet()) {                        if (TextUtils.equals(key, "resultStatus")) {                            resultStatus = rawResult.get(key);                        } else if (TextUtils.equals(key, "result")) {                            result = rawResult.get(key);                        } else if (TextUtils.equals(key, "memo")) {                            memo = rawResult.get(key);                        }                    }                }                            @Override                public String toString() {                    return "resultStatus={" + resultStatus + "};memo={" + memo                            + "};result={" + result + "}";                }                            /**                 * @return the resultStatus                 */                public String getResultStatus() {                    return resultStatus;                }                            /**                 * @return the memo                 */                public String getMemo() {                    return memo;                }                            /**                 * @return the result                 */                public String getResult() {                    return result;                }            }
    • AliPayUtils登录使用方式:

        //于服务器获取登录签名字符串(这里为伪代码),具体代码后面服务器先关会贴出。        String signStr = getSignStr();        //调用AliPayUtils登录方法        AliPayUtils.login(DemoActivity.this, signStr, new AliPayUtils.Back() {                @Override                public void success(String result) {                    //登录成功,可将result上传至服务器处理。                }                        @Override                public void failed() {                    //登录失败                }            });
  • 服务器端
    • Android客户端demo中写的“真实App里,privateKey等数据严禁放在客户端,加签过程务必要放在服务端完成;”相信大家都看到了,也正是因为这句话楼主连appId都没有放客户端,但是官方并没有给出明确的解决方案。Android客户端jar包引入low到居然要下载jar文件放入,连gradle引入都不支持,无力吐槽。
    • 为了解决安全问题楼主不得不将加签所有过程放服务器端,那么问题来了:
      • 客户端的签名代码用的是客户端jar包,服务器端用的服务器jar包,且服务器根本没有签名示例代码。

      • 为此楼主只有强行将客户端部分代码照搬至服务器端,不管是否规范,至少签名在服务器这边处理是做到了。代码如下(代码真心多,但是为了一个类完成所有功能,只能勉强放一起了。):

              import com.alipay.api.AlipayApiException;      import com.alipay.api.AlipayClient;      import com.alipay.api.DefaultAlipayClient;      import com.alipay.api.domain.AlipayTradeAppPayModel;      import com.alipay.api.domain.AlipayTradePrecreateModel;      import com.alipay.api.internal.util.AlipaySignature;      import com.alipay.api.request.*;      import com.alipay.api.response.*;            import java.io.UnsupportedEncodingException;      import java.net.URLEncoder;      import java.security.KeyFactory;      import java.security.PrivateKey;      import java.security.Security;      import java.security.spec.PKCS8EncodedKeySpec;      import java.util.*;            public class AliPayUtils {          private static final String APP_ID = "";//这个就不强调了,这个都找不到相比开发难度很大,我这文笔很难帮到你了。          private static final String PID = "";//在开放平台内点击右上角那里点击密钥管理,然后点击左边mapi网关产品密钥就能看到pid了。          private static final String APP_PRIVATE_KEY = "";//下面的这些信息在应用信息里边基本能看到,有些可能需要上传设置。          private static final String RSA2_PRIVATE = "";//rsa2私钥          private static final String ALIPAY_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnzG+wSFicJ1BAP+/51vY8Zn4ZVNMgWuJCTAvfUh48QjixfJwYdr0lX8aOOHVLiC4zOBMdKi0Ale/R/myl1duCnWhCz9XgxMG/x5MpuxESU0SY6HZimW                wQGxoRmKsM3ICa7zmBa58nOig0cKY1ipJ6VXmTGSeiwF7TReKAGU8PeyYTZvnTgmIKofD7L8oAQF2xom3RlFbtzkjf4UaYbr+7m52dktPp6t7PwVKbbAiqDfVIoswrBaAPDmBWrf1Uaj8kt3KVzsiJzpN1xT0oRFikKj9KuMbIMI+ESpDr1674ToJa46AjI+0O8WxfQrebMuE/              xkUCG0WaQCXllLjtRXc7wIDAQAB";          private static final String CHARSET = "UTF-8";                public static boolean alipayCallBack(Map requestParams) {              Boolean isPay = false;              // 获取支付宝POST过来反馈信息              Map params = new HashMap<>();              for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {                  String name = (String) iter.next();                  String[] values = requestParams.get(name);                  String valueStr = "";                  for (int i = 0; i < values.length; i++) {                      valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";                  }                  params.put(name, valueStr);              }              try {                  boolean flag = AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY, CHARSET, "RSA2");                  if (flag) {                      String tradeStatus = params.get("trade_status");                      if ("TRADE_SUCCESS".equals(tradeStatus)                              || "TRADE_FINISHED".equals(tradeStatus)) {                          String outTradeNo = params.get("out_trade_no");// 商户订单号                          String tradeNo = params.get("trade_no");// 商户订单号                          String gmtPayment = params.get("gmt_payment");// 支付时间                          String gmtCreate = params.get("gmt_create");// 创建时间                            }                  }              } catch (AlipayApiException e) {                  e.printStackTrace();              }              return false;          }          public static AlipayTradeQueryResponse getPayInfo(String outTradeNo, String tradeNo) {              AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do"                      , APP_ID, APP_PRIVATE_KEY, "json", CHARSET, ALIPAY_PUBLIC_KEY, "RSA2");              AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();              request.setBizContent("{" +                      "\"out_trade_no\":\"" + outTradeNo + "\"," +                      "\"trade_no\":\"" + tradeNo + "\"," +                      "\"org_pid\":\"" + PID + "\"" +                      "  }");              try {                  return alipayClient.execute(request);              } catch (AlipayApiException e) {                  return null;              }          }                public static String getPayStr(String totalAmount, String subject, String outTradeNo) {              AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do"                      , APP_ID, APP_PRIVATE_KEY, "json", CHARSET, ALIPAY_PUBLIC_KEY, "RSA2");              AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();              AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();              model.setSubject(subject);              model.setOutTradeNo(outTradeNo);              model.setTimeoutExpress("10m");              model.setTotalAmount(totalAmount);              model.setProductCode("QUICK_MSECURITY_PAY");              request.setBizModel(model);              request.setNotifyUrl("");//这里记得放支付回调地址              try {                  AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);                  if (response.isSuccess()) {                      return response.getBody();                  } else {                      throw new BaseException(BaseResultEnum.ALIPAY_SIGN_ERROR);                  }              } catch (AlipayApiException e) {                  throw new BaseException(BaseResultEnum.ALIPAY_SIGN_ERROR);              }          }                public static AlipayUserInfoShareResponse signAuthStr(String authCode) throws AlipayApiException {              AlipayClient alipayClient = new DefaultAlipayClient(                      "https://openapi.alipay.com/gateway.do", APP_ID                      , APP_PRIVATE_KEY, "json", CHARSET, ALIPAY_PUBLIC_KEY                      , "RSA2");              AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();              request.setGrantType("authorization_code");              request.setCode(authCode);              AlipayUserInfoShareRequest userInfoRequest = new AlipayUserInfoShareRequest();              AlipaySystemOauthTokenResponse response =                      alipayClient.execute(request);              if (response.isSuccess()) {                  AlipayUserInfoShareResponse userInfoResponse                          = alipayClient.execute(userInfoRequest, response.getAccessToken());                  if (userInfoResponse.isSuccess()) {                      return userInfoResponse;                  }                  System.out.println("signAuthStr调用成功");              } else {                  System.out.println("signAuthStr 调用失败");              }              return null;          }                public static String getAuthStr() {              Map authInfoMap = buildAuthInfoMap();              String info = buildOrderParam(authInfoMap);              String sign = getSign(authInfoMap, RSA2_PRIVATE, true);              return info + "&" + sign;          }                private static String buildOrderParam(Map map) {              List keys = new ArrayList(map.keySet());              StringBuilder sb = new StringBuilder();              for (int i = 0; i < keys.size() - 1; i++) {                  String key = keys.get(i);                  String value = map.get(key);                  sb.append(buildKeyValue(key, value, true));                  sb.append("&");              }              String tailKey = keys.get(keys.size() - 1);              String tailValue = map.get(tailKey);              sb.append(buildKeyValue(tailKey, tailValue, true));              return sb.toString();          }                private static Map buildAuthInfoMap() {              Map keyValues = new HashMap();              keyValues.put("app_id", APP_ID);              keyValues.put("pid", PID);              keyValues.put("apiname", "com.alipay.account.auth");              keyValues.put("app_name", "mc");              keyValues.put("biz_type", "openservice");              keyValues.put("product_id", "APP_FAST_LOGIN");              keyValues.put("scope", "kuaijie");              keyValues.put("target_id", String.valueOf(System.currentTimeMillis())                      + new Random().nextInt(10000));              keyValues.put("auth_type", "AUTHACCOUNT");              keyValues.put("sign_type", "RSA2");              return keyValues;          }                private static String getSign(Map map, String rsaKey                  , boolean rsa2) {              List keys = new ArrayList(map.keySet());              Collections.sort(keys);              StringBuilder authInfo = new StringBuilder();              for (int i = 0; i < keys.size() - 1; i++) {                  String key = keys.get(i);                  String value = map.get(key);                  authInfo.append(buildKeyValue(key, value, false));                  authInfo.append("&");              }              String tailKey = keys.get(keys.size() - 1);              String tailValue = map.get(tailKey);              authInfo.append(buildKeyValue(tailKey, tailValue, false));              String oriSign = sign(authInfo.toString(), rsaKey, rsa2);              String encodedSign = "";              try {                  encodedSign = URLEncoder.encode(oriSign, "UTF-8");              } catch (UnsupportedEncodingException e) {                  e.printStackTrace();              }              return "sign=" + encodedSign;          }                private static String buildKeyValue(String key, String value, boolean isEncode) {              StringBuilder sb = new StringBuilder();              sb.append(key);              sb.append("=");              if (isEncode) {                  try {                      sb.append(URLEncoder.encode(value, "UTF-8"));                  } catch (UnsupportedEncodingException e) {                      sb.append(value);                  }              } else {                  sb.append(value);              }              return sb.toString();          }                private static final String ALGORITHM = "RSA";                private static final String SIGN_ALGORITHMS = "SHA1WithRSA";                private static final String SIGN_SHA256RSA_ALGORITHMS = "SHA256WithRSA";                private static final String DEFAULT_CHARSET = "UTF-8";                private static String getAlgorithms(boolean rsa2) {              return rsa2 ? SIGN_SHA256RSA_ALGORITHMS : SIGN_ALGORITHMS;          }                private static String sign(String content, String privateKey, boolean rsa2) {              try {                  PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(                          Base64.getDecoder().decode(privateKey));                  Security.addProvider(                          new org.bouncycastle.jce.provider.BouncyCastleProvider());                  KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM, "BC");                  PrivateKey priKey = keyFactory.generatePrivate(priPKCS8);                  java.security.Signature signature = java.security.Signature                          .getInstance(getAlgorithms(rsa2));                  signature.initSign(priKey);                  signature.update(content.getBytes(DEFAULT_CHARSET));                  byte[] signed = signature.sign();                  return Base64.getEncoder().encodeToString(signed);              } catch (Exception e) {                  e.printStackTrace();              }              return null;          }            }
      • 贴完代码可能会有人代码报错,很正常,因为里边用到了官方没有说的代码(原始代码用的Android的jdk没问题,但是服务器端的部分jdk代码和客户端有差异,所以就报错了),解决方案:

         # gradle用户在build.gardle加入: "org.bouncycastle:bcprov-jdk16:1.45", # mvn用户在pom.xml加入:    org.bouncycastle   bcprov-jdk16   1.45 
      • 这样服务器端签名代码就写好(只是签名字符串),调用getAuthStr()方法就能返回了。

      • 首先将获得的realResult上传至服务器。然后我这边贴下服务器端的处理代码(首先是getAlipayAuthCode()方法,传入的是realResult,返回的是authCode,让后将获得的authCode传入signAuthStr()方法就获得了用户信息了,具体的信息可以参考官方文档):

                      private final String ALIPAY_AUTH_CODE_START = "auth_code=";              private final String ALIPAY_AUTH_CODE_END = "&";              private String getAlipayAuthCode(String response) {                  String result = response.substring(response.indexOf(ALIPAY_AUTH_CODE_START)                          + ALIPAY_AUTH_CODE_START.length(), response.length() - 1);                  return result.substring(0, result.indexOf(ALIPAY_AUTH_CODE_END));              }              public static AlipayUserInfoShareResponse signAuthStr(String authCode) throws AlipayApiException {                  AlipayClient alipayClient = new DefaultAlipayClient(                          "https://openapi.alipay.com/gateway.do", APP_ID                          , APP_PRIVATE_KEY, "json", CHARSET, ALIPAY_PUBLIC_KEY                          , "RSA2");                  AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();                  request.setGrantType("authorization_code");                  request.setCode(authCode);                  AlipayUserInfoShareRequest userInfoRequest = new AlipayUserInfoShareRequest();                  AlipaySystemOauthTokenResponse response =                          alipayClient.execute(request);                  if (response.isSuccess()) {                      AlipayUserInfoShareResponse userInfoResponse                              = alipayClient.execute(userInfoRequest, response.getAccessToken());                      if (userInfoResponse.isSuccess()) {                          return userInfoResponse;                      }                      System.out.println("signAuthStr调用成功");                  } else {                      System.out.println("signAuthStr 调用失败");                  }                  return null;              }
      • 获得了支付宝用户信息整个登录流程也基本结束了,剩下的就是自己业务逻辑的处理了,因为整个流程实在太复杂,写的可能有很多不详细的地方,还望谅解,发现不对的地方还望及时指正,有问题也可以评论指出。

更多相关文章

  1. android的 网络下载和数据持久化
  2. Android支付宝支付的示例代码
  3. Android卸载监听之后访问后台或者弹出一个网页
  4. android在更新ADT以后报java.lang.NoClassDefFound的解决办法
  5. amdroid push
  6. 【Android快捷开发笔记系列】——Data Binding
  7. Android开发之adb && 破解开屏图案 && 代码判断当前是否处于锁屏
  8. Android平台实现双向证书(https)验证简单说明
  9. Android(安卓)启动另一个App/apk中的Activity实现代码

随机推荐

  1. Android下pm 命令详解
  2. android linux 基础知识总结
  3. Android:java.lang.SecurityException: P
  4. Android按钮事件响应顺序
  5. Android(安卓)P签名机制和系统权限
  6. Android成长之路-Android组件_EditView例
  7. 遇到的Android(安卓)eclipse 问题
  8. android.os.NetworkOnMainThreadExceptio
  9. Android(安卓)SDK开发包国内下载地址
  10. android phone电话拨出上层java流程