android项目初始化

217 阅读3分钟
  • 下载android studio
  • 安装android sdk,ndk,buildtools等相关内容
  • 根据需要,在build.gradle中设置maven地址(直接远程即可,一个是build,一个是allprojects)
  •   maven **{ **url 'https://maven.aliyun.com/repositories/google' **}
      **maven **{ **url "https://maven.aliyun.com/repositories/jcenter" **}
      **maven **{
      **    // expo-camera bundles a custom com.google.android:cameraview
          url "$rootDir/../node_modules/expo-camera/android/maven"
      **}
      ** maven**{ **url 'https://maven.aliyun.com/nexus/content/repositories/google'**}
      **maven**{  **url 'https://maven.aliyun.com/nexus/content/groups/public'**}
      **maven **{ **url 'https://repo1.maven.org/maven2/' **}**
    
  • 先build,后run
  • 获取签名代码
  •   
      import android.content.Context;
      import android.content.pm.PackageInfo;
      import android.content.pm.PackageManager;
      import android.content.pm.Signature;
      
      import java.security.MessageDigest;
      import java.util.ArrayList;
      import java.util.HashMap;
      
      /**
       * 获取签名工具类
       */
      public class AppSigning {
          public final static String MD5 = "MD5";
          public final static String SHA1 = "SHA1";
          public final static String SHA256 = "SHA256";
          private static HashMap> mSignMap = new HashMap<>();
      
          /**
           * 返回一个签名的对应类型的字符串
           *
           * @param context
           * @param type
           * @return 因为一个安装包可以被多个签名文件签名,所以返回一个签名信息的list
           */
          public static ArrayList getSignInfo(Context context, String type) {
              if (context == null || type == null) {
                  return null;
              }
              String packageName = context.getPackageName();
              if (packageName == null) {
                  return null;
              }
              if (mSignMap.get(type) != null) {
                  return mSignMap.get(type);
              }
              ArrayList mList = new ArrayList();
              try {
                  Signature[] signs = getSignatures(context, packageName);
                  for (Signature sig : signs) {
                      String tmp = "error!";
                      if (MD5.equals(type)) {
                          tmp = getSignatureByteString(sig, MD5);
                      } else if (SHA1.equals(type)) {
                          tmp = getSignatureByteString(sig, SHA1);
                      } else if (SHA256.equals(type)) {
                          tmp = getSignatureByteString(sig, SHA256);
                      }
                      mList.add(tmp);
                  }
              } catch (Exception e) {
                  // LogUtil.e(e.toString());
              }
              mSignMap.put(type, mList);
              return mList;
          }
      
          /**
           * 获取签名sha1值
           *
           * @param context
           * @return
           */
          public static String getSha1(Context context) {
              String res = "";
              ArrayList mlist = getSignInfo(context, SHA1);
              if (mlist != null && mlist.size() != 0) {
                  res = mlist.get(0);
              }
              return res;
          }
      
          /**
           * 获取签名MD5值
           *
           * @return
           */
          public static String getMD5(Context context) {
              String res = "";
              ArrayList mlist = getSignInfo(context, MD5);
              if (mlist != null && mlist.size() != 0) {
                  res = mlist.get(0);
              }
              return res;
          }
      
          /**
           * 获取签名SHA256值
           *
           * @param context
           * @return
           */
          public static String getSHA256(Context context) {
              String res = "";
              ArrayList mlist = getSignInfo(context, SHA256);
              if (mlist != null && mlist.size() != 0) {
                  res = mlist.get(0);
              }
              return res;
          }
      
          /**
           * 返回对应包的签名信息
           *
           * @param context
           * @param packageName
           * @return
           */
          private static Signature[] getSignatures(Context context, String packageName) {
              PackageInfo packageInfo = null;
              try {
                  packageInfo = context.getPackageManager().getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
                  return packageInfo.signatures;
              } catch (Exception e) {
                  // LogUtil.e(e.toString());
              }
              return null;
          }
      
          /**
           * 获取相应的类型的字符串(把签名的byte[]信息转换成16进制)
           *
           * @param sig
           * @param type
           * @return
           */
          private static String getSignatureString(Signature sig, String type) {
              byte[] hexBytes = sig.toByteArray();
              String fingerprint = "error!";
              try {
                  MessageDigest digest = MessageDigest.getInstance(type);
                  if (digest != null) {
                      byte[] digestBytes = digest.digest(hexBytes);
                      StringBuilder sb = new StringBuilder();
                      for (byte digestByte : digestBytes) {
                          sb.append((Integer.toHexString((digestByte & 0xFF) | 0x100)).substring(1, 3));
                      }
                      fingerprint = sb.toString();
                  }
              } catch (Exception e) {
                 // LogUtil.e(e.toString());
              }
      
              return fingerprint;
          }
      
          /**
           * 获取相应的类型的字符串(把签名的byte[]信息转换成 95:F4:D4:FG 这样的字符串形式)
           *
           * @param sig
           * @param type
           * @return
           */
          private static String getSignatureByteString(Signature sig, String type) {
              byte[] hexBytes = sig.toByteArray();
              String fingerprint = "error!";
              try {
                  MessageDigest digest = MessageDigest.getInstance(type);
                  if (digest != null) {
                      byte[] digestBytes = digest.digest(hexBytes);
                      StringBuilder sb = new StringBuilder();
                      for (byte digestByte : digestBytes) {
                          sb.append(((Integer.toHexString((digestByte & 0xFF) | 0x100)).substring(1, 3)).toUpperCase());
                          sb.append(":");
                      }
                      fingerprint = sb.substring(0, sb.length() - 1).toString();
                  }
              } catch (Exception e) {
                  // LogUtil.e(e.toString());
              }
      
              return fingerprint;
          }
      }
    
  • 注意
    • 这里的context可以传人MainActivity.this,可以从这个类中获取上下文
    • MainActivity是android的入口文件,这里包含了安卓运行时的生命周期,比如onCreate()
    • 在onCreate生命周期中对比签名,如果否,则终止进程
      • 		  try {
        		      // Toast.makeText(MainActivity.this, AppSigning.getMD5(MainActivity.this), Toast.LENGTH_SHORT).show();
        		      // Log.e("signature", AppSigning.getMD5(MainActivity.this) + "str");
        		      if(AppSigning.getMD5(MainActivity.this).equals("20:F4:61:48:B7:2D:8E:5E:5C:A2:3D:37:A4:F4:14:90") ) {
        		        android.os.Process.killProcess(android.os.Process.myPid());
        		      }
        		      //   return
        		    } catch (Exception e) {
        		      Toast.makeText(MainActivity.this, "报错了", Toast.LENGTH_SHORT).show();
        		  // LogUtil.e(e.toString());
        		    }
        
    • 如果项目无法运行起来,可以在AndroidManifest.xml加一个配置项
      • 		  
        		      
        		        ...
        		        
        		            
        		        
        		      
        		    
        
  • 签名流程
    • 规定所有安装到手机上的应用都需要签名信息
    • 签名信息可以是自己生成的,不一定是认证的签名,可以使用android studio直接生成
    • 安卓生成签名可以在app生成之前或者之后
  • app安全
    • 代码混淆,图片混淆
    • 加壳处理(防止二次打包)
    • 对比签名(或者远程应用验证,较繁琐),如上流程获取签名和对比签名