HeightWrapListView,HeightWrapListViewUtils
说明:高度自适应的ListVive
package com.ruidonghy.widget.listview;import android.content.Context;import android.util.AttributeSet;import android.widget.ListView;/** * Created by zhou on 2017/12/21. */public class HeightWrapListView extends ListView { public HeightWrapListView(Context context) { super(context); } public HeightWrapListView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); }}package com.ruidonghy.widget.listview;import android.view.View;import android.view.ViewGroup;import android.widget.ListAdapter;import android.widget.ListView;/** * Created by zhou on 2017/12/21. */public class HeightWrapListViewUtils { public static void setListViewHeightBasedOnChildren(ListView listView) { // 获取ListView对应的Adapter ListAdapter listAdapter = listView.getAdapter(); if (listAdapter == null) { return; } int totalHeight = 0; for (int i = 0; i < listAdapter.getCount(); i++) { // listAdapter.getCount()返回数据项的数目 View listItem = listAdapter.getView(i, null, listView); listItem.measure(0, 0); // 计算子项View 的宽高 totalHeight += listItem.getMeasuredHeight(); // 统计所有子项的总高度 } ViewGroup.LayoutParams params = listView.getLayoutParams(); params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1)); // listView.getDividerHeight()获取子项间分隔符占用的高度 // params.height最后得到整个ListView完整显示需要的高度 listView.setLayoutParams(params); }}复制代码
数据解释类
说明:为空断网加载中等
package com.ruidonghy.widget.prompt;import android.content.Context;import android.support.annotation.Nullable;import android.util.AttributeSet;import android.widget.ImageView;import android.widget.TextView;import com.ruidonghy.widget.R;import com.ruidonghy.zbase.base.BaseWidget;/** * Created by zhou on 2017/12/22. */public class DataNullView extends BaseWidget implements IChildView{ private ImageView mDataNullIcon; private TextView mDataNullContent; public DataNullView(Context context) { super(context); } public DataNullView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); } @Override public void initView() { mDataNullIcon = getView().findViewById(R.id.datanull_icon); mDataNullContent = getView().findViewById(R.id.datanull_content); } @Override public void initInnerEvent() { } public void setDataNullIcon(int dataNullDrawable){ mDataNullIcon.setImageResource(dataNullDrawable); } public void setDataNullTip(int dataNullTip){ mDataNullContent.setText(dataNullTip); } @Override public int getLayoutId() { return R.layout.view_datanull; } @Override public void gone() { setVisibility(GONE); } @Override public void show() { setVisibility(VISIBLE); }}package com.ruidonghy.widget.prompt;/** * Created by zhou on 2017/12/22. */public interface IChildView { void gone(); void show();}package com.ruidonghy.widget.prompt;import android.support.annotation.DrawableRes;import android.support.annotation.StringRes;import android.view.View;/** * Created by abbott on 2017/12/7. */public interface IPromptView { /** * 初始化 提示控件 * @param loadingTips * @param dataNullTips * @param dataNullDrawable * @param onNoNetClickListener */ void init(int loadingTips,int dataNullTips,int dataNullDrawable,View.OnClickListener onNoNetClickListener); void init(View.OnClickListener onNoNetClickListener); /** * 显示加载中 */ void showLoading(); /** * 显示数据为空 */ void showDataNull(); /** * 显示网络错误 */ void showNetError(); /** * 隐藏提示弹窗 */ void hidden();}package com.ruidonghy.widget.prompt;import android.content.Context;import android.support.annotation.Nullable;import android.util.AttributeSet;import android.widget.ImageView;import android.widget.TextView;import com.ruidonghy.widget.R;import com.ruidonghy.zbase.base.BaseWidget;/** * Created by zhou on 2017/12/22. */public class LoadingView extends BaseWidget implements IChildView{ private RotateLoading mLoading; private TextView mLoadingTips; public LoadingView(Context context) { super(context); } public LoadingView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); } @Override public void initView() { mLoading = getView().findViewById(R.id.rotate_view); mLoadingTips = getView().findViewById(R.id.loading_tips); } @Override public void initInnerEvent() { } public void setLoadingTips(int loadingTips){ mLoadingTips.setText(loadingTips); } @Override public int getLayoutId() { return R.layout.view_loading; } @Override public void gone() { if(mLoading.isStart()){ mLoading.stop(); } setVisibility(GONE); } @Override public void show() { setVisibility(VISIBLE); if(!mLoading.isStart()){ mLoading.start(); } }}package com.ruidonghy.widget.prompt;import android.content.Context;import android.support.annotation.Nullable;import android.util.AttributeSet;import android.widget.TextView;import com.ruidonghy.widget.R;import com.ruidonghy.zbase.base.BaseWidget;/** * Created by zhou on 2017/12/22. */public class NetErrorView extends BaseWidget implements IChildView{ private TextView mNeterrorRefresh; public NetErrorView(Context context) { super(context); } public NetErrorView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); } @Override public void initView() { mNeterrorRefresh = getView().findViewById(R.id.neterror_refresh); } @Override public void initInnerEvent() { } @Override public int getLayoutId() { return R.layout.view_neterror; } public void setNetErrorClickListener(OnClickListener netErrorClickListener){ mNeterrorRefresh.setOnClickListener(netErrorClickListener); } @Override public void gone() { setVisibility(GONE); } @Override public void show() { setVisibility(VISIBLE); }}package com.ruidonghy.widget.prompt;import android.content.Context;import android.support.annotation.Nullable;import android.util.AttributeSet;import com.ruidonghy.widget.R;import com.ruidonghy.zbase.base.BaseWidget;import java.util.ArrayList;/** * 公共提示加载、缺省view * Created by yunlong on 2017/12/7. * * 修改此类by zhou 2017-12-22 * * * 提示文字初始化一次,有则用新的,没有则用默认的 * 网络错点击刷新监听需要开始时初始化。 */public class PromptView extends BaseWidget implements IPromptView { private DataNullView mDataNullView; private NetErrorView mNetErrorView; private LoadingView mLoadingView; private ArrayListmViewList; public PromptView(Context context) { super(context); } public PromptView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); } @Override public void initView() { mViewList = new ArrayList<>(); mDataNullView = getView().findViewById(R.id.datanull_view); mNetErrorView = getView().findViewById(R.id.neterror_view); mLoadingView = getView().findViewById(R.id.loading_view); mViewList.add(mDataNullView); mViewList.add(mNetErrorView); mViewList.add(mLoadingView); } @Override public void initInnerEvent() { } @Override public void init(OnClickListener onNoNetClickListener) { mNetErrorView.setNetErrorClickListener(onNoNetClickListener); } @Override public void init(int loadingTips, int dataNullTips, int dataNullDrawable, OnClickListener onNoNetClickListener) { mLoadingView.setLoadingTips(loadingTips); mDataNullView.setDataNullTip(dataNullTips); mDataNullView.setDataNullIcon(dataNullDrawable); mNetErrorView.setNetErrorClickListener(onNoNetClickListener); } @Override public void showLoading() { setVisibility(VISIBLE); show(mLoadingView); } @Override public void showDataNull() { setVisibility(VISIBLE); show(mDataNullView); } @Override public void showNetError() { setVisibility(VISIBLE); show(mNetErrorView); } @Override public void hidden() { mLoadingView.gone(); setVisibility(GONE); } @Override public int getLayoutId() { return R.layout.view_prompt; } /** * 内部方法,show传进来的参数,gone其他。 * @param childView */ private void show(IChildView childView){ childView.show(); for(int i=0;i 360) { topDegree = topDegree - 360; } if (bottomDegree > 360) { bottomDegree = bottomDegree - 360; } if (changeBigger) { if (arc < 160) { arc += speedOfArc; invalidate(); } } else { if (arc > speedOfDegree) { arc -= 2 * speedOfArc; invalidate(); } } if (arc >= 160 || arc <= 10) { changeBigger = !changeBigger; invalidate(); } } public void setLoadingColor(int color) { this.color = color; } public int getLoadingColor() { return color; } public void start() { startAnimator(); isStart = true; invalidate(); } public void stop() { stopAnimator(); invalidate(); } public boolean isStart() { return isStart; } private void startAnimator() { ObjectAnimator scaleXAnimator = ObjectAnimator.ofFloat(this, "scaleX", 0.0f, 1); ObjectAnimator scaleYAnimator = ObjectAnimator.ofFloat(this, "scaleY", 0.0f, 1); scaleXAnimator.setDuration(300); scaleXAnimator.setInterpolator(new LinearInterpolator()); scaleYAnimator.setDuration(300); scaleYAnimator.setInterpolator(new LinearInterpolator()); AnimatorSet animatorSet = new AnimatorSet(); animatorSet.playTogether(scaleXAnimator, scaleYAnimator); animatorSet.start(); } private void stopAnimator() { ObjectAnimator scaleXAnimator = ObjectAnimator.ofFloat(this, "scaleX", 1, 0); ObjectAnimator scaleYAnimator = ObjectAnimator.ofFloat(this, "scaleY", 1, 0); scaleXAnimator.setDuration(300); scaleXAnimator.setInterpolator(new LinearInterpolator()); scaleYAnimator.setDuration(300); scaleYAnimator.setInterpolator(new LinearInterpolator()); AnimatorSet animatorSet = new AnimatorSet(); animatorSet.playTogether(scaleXAnimator, scaleYAnimator); animatorSet.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { isStart = false; } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } }); animatorSet.start(); } public int dpToPx(Context context, float dpVal) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpVal, context.getResources().getDisplayMetrics()); }}view_datanull.xml view_loading.xml neterror_refresh.xml view_prompt.xml attrs.xml 复制代码
RoundShadowDrawable
说明:圆角Drawable
package com.ruidonghy.widget.shadow;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.ColorFilter;import android.graphics.Paint;import android.graphics.Path;import android.graphics.PixelFormat;import android.graphics.Rect;import android.graphics.RectF;import android.graphics.drawable.Drawable;/** * Created by zcz */public class RoundShadowDrawable extends Drawable { Paint paint; Paint paintShadow; Path path; RectF rectF; int x = 20; int y = 20; int radius = 20; public RoundShadowDrawable() { paint = new Paint(); paint.setColor(Color.WHITE); paint.setAntiAlias(true); paintShadow = new Paint(); paintShadow.setColor(Color.WHITE); paintShadow.setAntiAlias(true); path = new Path(); } public void setColor(int color) { // 设定阴影(柔边, X 轴位移, Y 轴位移, 阴影颜色) paintShadow.setShadowLayer(20, 0, 2, color); invalidateSelf(); } public void setRadius(int radius) { this.radius = radius; invalidateSelf(); } @Override public void draw(Canvas canvas) { canvas.drawPath(path, paintShadow); } @Override protected void onBoundsChange(Rect bounds) { super.onBoundsChange(bounds); path.reset(); rectF = new RectF(x, y+2, bounds.width() - x, bounds.height()-y); path.addRoundRect(rectF, new float[]{radius, radius, radius, radius, radius, radius, radius, radius}, Path.Direction.CW); } @Override public void setAlpha(int i) { } @Override public void setColorFilter(ColorFilter colorFilter) { } @Override public int getOpacity() { return PixelFormat.TRANSLUCENT; }}复制代码
WillUriRouter
说明:自己写的启动其他组件的Router
package com.ruidonghy.zbase.utils;import android.app.Activity;import android.content.Context;import android.content.Intent;import android.net.Uri;import android.os.Parcelable;import android.support.v4.app.Fragment;/** * Created by zhou on 2017/11/6 16:30 . */public class WillUriRouter { //启动activity public staticvoid startAct(Context context,String action, T message){ Intent intent = new Intent(action); intent.putExtra("data",message); if(context instanceof Activity){//为了后面添加动画,暂时还没添加 ((Activity)context).startActivity(intent); }else{ context.startActivity(intent); } } //启动activity public static void startActForFlags(Context context,String action, T message){ Intent intent = new Intent(action); intent.putExtra("data",message); intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); if(context instanceof Activity){//为了后面添加动画,暂时还没添加 ((Activity)context).startActivity(intent); }else{ context.startActivity(intent); } } //启动activity public static void startAct(Context context,String action, T message,int other){ Intent intent = new Intent(action); intent.putExtra("data",message); intent.putExtra("other",other); if(context instanceof Activity){//为了后面添加动画,暂时还没添加 ((Activity)context).startActivity(intent); }else{ context.startActivity(intent); } } //启动activity以startActivityForResult的方式 public static void startActForResult(Activity context,String action, T message,int requestCode){ Intent intent = new Intent(action); intent.putExtra("data",message); if(context instanceof Activity){//为了后面添加动画,暂时还没添加 ((Activity)context).startActivityForResult(intent,requestCode); }else{ context.startActivityForResult(intent,requestCode); } } //启动activity以startActivityForResult的方式 public static void startActForResult(Fragment fragment,String action, T message,int requestCode){ Intent intent = new Intent(action); intent.putExtra("data",message); fragment.startActivityForResult(intent,requestCode); }// // // uri.getQueryParameter("message");}复制代码// // // //
WillRequestUtil ,CommParamsModel ,
说明:程序中用到的公参的处理方式
- 加密
- 公参获取
- 公参传递
package com.ruidonghy.zbase.utils;import com.ruidonghy.zbase.data.CommParamsModel;import java.util.HashMap;import java.util.Map;/** * Created by zhou on 2017/11/8 11:35 . */public class WillRequestUtil { /** * 即需要公参也需要加密 * @param params * @return */ public static MapgetAppCommParamsASecurity(Map params){ return getSecurity(getCommParams(params));//先增加公参,后安全认证 } /** * 公参获取方法 * @param params * @return */ private static Map getCommParams(Map params){ params.put("app_imei", CommParamsModel.instance().getAppImei()); params.put("app_type",CommParamsModel.instance().getAppType()); params.put("app_version",CommParamsModel.instance().getAppVersion()); return params; } /** * 公共加密方法 * @param params * @return */ private static Map getSecurity(Map params){ Map map = new HashMap (); String json = WillJsonParseUtils.obj2JsonStr(params, ""); LogUtils.d("okhttp请求入参--->json=",json); //随机生成16位的AES密钥key String aesKey = RandomUtil.getRandom(16); //将json加密 先加密然后Base64转码,然后返回data String data = null; try { data = AESUtils.encodeAES(json, aesKey); } catch (Exception e) { e.printStackTrace(); LogUtils.e("AES encode error"); } //将AES密钥key用rsa加密 String dataKey = null; try {// dataKey = new String(Base64.encode(RSAUtils.encrypt(aesKey.getBytes(), RSAUtils.getPublicKey(AppConstants.PUBLICKEY_SERVER)),Base64.DEFAULT),"UTF-8"); LogUtils.d("aesKey="+aesKey); dataKey = RsaUtils.encryptByPublic(aesKey); } catch (Exception e) { e.printStackTrace(); } map.put("data_key", dataKey); map.put("data", data); return map; }}package com.ruidonghy.zbase.data;/** * 定义此类为了不让程序多次进行imei 和appversion的获取 * Created by zhou on 2017/11/13 10:42 . */public class CommParamsModel { private CommParamsModel(){} private static class ParamsHolder{ private static final CommParamsModel instance = new CommParamsModel(); } public static final CommParamsModel instance(){ return ParamsHolder.instance; } private String appImei; private String appType; private String appVersion; public void initCommParams(String imei,String type,String version){ this.appImei = imei; this.appType = type; this.appVersion = version; } public String getAppImei() { return appImei; } public String getAppType() { return appType; } public String getAppVersion() { return appVersion; }}//初始化公参, imei {apptype 1,android} appVersionCommParamsModel.instance().initCommParams(PhoneUtils.getIMEI(),"1", AppInfo.appVersionName());package com.ruidonghy.zbase.utils;import android.text.TextUtils;import com.google.gson.Gson;import com.google.gson.JsonSyntaxException;import org.json.JSONArray;import org.json.JSONException;import org.json.JSONObject;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;/** * 捕捉Json解析异常,避免出现由此引起 的crash * @author wjian * */public class WillJsonParseUtils{ private static Gson gson; static { gson = new Gson(); } public static Gson getGson() { return gson; } /** * 对象转成json * @param */ public static String obj2JsonStr(T t, String def) { try { return gson.toJson(t); } catch (Exception e) { e.printStackTrace(); LogUtils.e("json解析异常"+t,e.getMessage()); } return def; } /** * json转成对象 * * @param */ public static T json2Obj(String json, Class clazz) { try { return gson.fromJson(json, clazz); } catch (JsonSyntaxException e) { e.printStackTrace(); LogUtils.e("json解析异常"+json,e.getMessage()); } return null; } /** * json字符串直接转成List * @param clazz Bean[].class * @param json String json串 * @param * @return */// public static final List json2List(final Class clazz, final String json)// {// final T[] jsonToObject;// try{// jsonToObject = gson.fromJson(json, clazz);// }catch (Exception e){// e.printStackTrace();// return new ArrayList ();// }// return Arrays.asList(jsonToObject);// } /** * json字符直接转成json对象 */ public static T json2Object(String jsonString, Class cls) { T t = null; try { Gson gson = new Gson(); t = gson.fromJson(jsonString, cls); } catch (Exception e) { e.printStackTrace(); LogUtils.e("json解析异常"+jsonString,e.getMessage()); } return t; } public static String getString(JSONObject json, String key) { return getString(json, key, ""); } public static String getString(JSONObject json, String key, String def) { String value = def; if (canParse(json, key)) { try { value = json.getString(key); } catch (JSONException e) { LogUtils.e("getString=" + e.getMessage()); LogUtils.e("json解析异常"+json,e.getMessage()); } } return value; } public static int getInt(JSONObject json, String key) { return getInt(json, key, -1); } public static int getInt(JSONObject json, String key, int def) { int value = def; if (canParse(json, key)) { try { value = json.getInt(key); } catch (JSONException e) { LogUtils.e("getInt=" + e.getMessage()); } } return value; } public static long getLong(JSONObject json, String key) { return getLong(json, key, -1); } public static long getLong(JSONObject json, String key, long def) { long value = def; if (canParse(json, key)) { try { value = json.getLong(key); } catch (JSONException e) { LogUtils.e("getInt=" + e.getMessage()); } } return value; } public static JSONObject getJSONObject(JSONArray array, int index) { return getJSONObject(array, index, new JSONObject()); } public static JSONObject getJSONObject(JSONArray array, int index, JSONObject def) { JSONObject returnObj = def; if (array != null && array.length() > 0) { try { returnObj = array.getJSONObject(index); } catch (JSONException e) { LogUtils.e("getJSONObject=" + e.getMessage()); } } return returnObj; } public static JSONObject getJSONObject(JSONObject json, String key) { return getJSONObject(json, key, new JSONObject()); } public static JSONObject getJSONObject(JSONObject json, String key, JSONObject def) { JSONObject returnObj = def; if (canParse(json, key)) { try { returnObj = json.getJSONObject(key); } catch (JSONException e) { LogUtils.e("getJSONObject=" + e.getMessage()); } } return returnObj; } public static JSONArray getJSONArray(JSONObject json, String key) { return getJSONArray(json, key, new JSONArray()); } public static JSONArray getJSONArray(JSONObject json, String key, JSONArray def) { JSONArray array = def; if (canParse(json, key)) { try { array = json.getJSONArray(key); } catch (JSONException e) { LogUtils.e("getJSONArray=" + e.getMessage()); } } return array; } public static JSONObject getJSONObject(byte[] json) { return getJSONObject(StringUtils.bytesToString(json,"UTF-8")); } public static JSONObject getJSONObject(String json) { return getJSONObject(json, new JSONObject()); } public static JSONObject getJSONObject(String json, JSONObject def) { JSONObject jsonObject = def; try { jsonObject = new JSONObject(json); } catch (Exception e) { //不只是JsonException,还可能是别的异常 e.printStackTrace(); } return jsonObject; } public static JSONArray getJSONArray(String json) { return getJSONArray(json, new JSONArray()); } public static JSONArray getJSONArray(String json, JSONArray def) { JSONArray jsonArray = def; try { jsonArray = new JSONArray(json); } catch (JSONException e) { e.printStackTrace(); } return jsonArray; } /** * 判断数据是否可以解析,可以则return true; * */ private static boolean canParse(JSONObject json, String key) { if (json == null || TextUtils.isEmpty(key)) { return false; } return true; } public static List parseJsonArray2List(JSONArray jsonArray, Class clazz) { List list = new ArrayList (); if(jsonArray==null) return list; for (int i = 0; i < jsonArray.length(); i++) { JSONObject jsonObject = getJSONObject(jsonArray, i, null); if(jsonObject==null) continue; T t = (T) json2Obj(jsonObject.toString(),clazz); list.add(t); } return list; } public static List parseJsonArray2IntegerList(JSONArray jsonArray) { List list = new ArrayList (); if(jsonArray==null) return list; for (int i = 0; i < jsonArray.length(); i++) { int anInt = 0; try { anInt = jsonArray.getInt(i); } catch (JSONException e) { e.printStackTrace(); } list.add(anInt); } return list; } public static void putValue(JSONObject json, String key, Object value) { try { json.put(key,value); } catch (JSONException e) { e.printStackTrace(); } } public static Map jsonToMap(String jsonString) throws JSONException { JSONObject jsonObject = new JSONObject(jsonString); Map resultMap = new HashMap (); Iterator iter = jsonObject.keys(); String key=null; Object value=null; while (iter.hasNext()) { key=iter.next(); value=jsonObject.get(key); resultMap.put(key, value); } return resultMap; } public static Map json2Map(String jsonString) throws JSONException { JSONObject jsonObject = new JSONObject(jsonString); Map resultMap = new HashMap (); Iterator iter = jsonObject.keys(); String key=null; String value=null; while (iter.hasNext()) { key=iter.next(); value=jsonObject.get(key).toString(); resultMap.put(key, value); } return resultMap; } /** * map转json * * @param map * @return * @throws JSONException */ public static String map2Json(Map map) throws JSONException { Gson gson = new Gson(); String jsonStr = gson.toJson(map); return jsonStr; }}package com.ruidonghy.zbase.utils;import java.util.Random;/** * Created by zhou on 2017/11/8 11:32. */public class RandomUtil { public static Random random = new Random(); public RandomUtil() { } public static String getRandom(int length) { StringBuilder ret = new StringBuilder(); for(int i = 0; i < length; ++i) { boolean isChar = random.nextInt(2) % 2 == 0; if(isChar) { int choice = random.nextInt(2) % 2 == 0?65:97; ret.append((char)(choice + random.nextInt(26))); } else { ret.append(Integer.toString(random.nextInt(10))); } } return ret.toString(); }}package com.ruidonghy.zbase.utils;import android.util.Base64;import javax.crypto.Cipher;import javax.crypto.spec.IvParameterSpec;import javax.crypto.spec.SecretKeySpec;/** * AES加解密 * Created by zhou on 2017/11/8 11:22. */public class AESUtils { /** * 密钥算法 */ private static final String ALGORITHM = "AES"; /** * 加解密算法/工作模式/填充方式 */ private static final String ALGORITHM_STR = "AES/CBC/PKCS5Padding"; //AES加密初始向量 public static final String VIPARA = "w2wJCnctEG09danPPI7SxQ=="; //AES 为16bytes. DES 为8byte /** * SecretKeySpec类是KeySpec接口的实现类,用于构建秘密密钥规范 */ private SecretKeySpec key; public AESUtils(String hexKey) { key = new SecretKeySpec(hexKey.getBytes(), ALGORITHM); } /** * AES加密 * * @param data * @return * @throws Exception */ public String encryptData(String data) throws Exception { Cipher cipher = Cipher.getInstance(ALGORITHM_STR); // 创建密码器 IvParameterSpec zeroIv = new IvParameterSpec(Base64.decode(VIPARA,Base64.DEFAULT)); cipher.init(Cipher.ENCRYPT_MODE, key,zeroIv);// 初始化 return new String(Base64.encode(cipher.doFinal(data.getBytes("UTF-8")),Base64.DEFAULT),"UTF-8"); } /** * AES解密 * * @return * @throws Exception */// public String decryptData(String base64Data) throws Exception {// Cipher cipher = Cipher.getInstance(ALGORITHM_STR);// cipher.init(Cipher.DECRYPT_MODE, key);// return StringUtils.bytesToString(cipher.doFinal(Base64Utils.getFromBase64(base64Data).getBytes("UTF-8")),"UTF-8");// }// /**// * hex字符串 转 byte数组// *// * @param s// * @return// */// private static byte[] hex2byte(String s) {// if (s.length() % 2 == 0) {// return hex2byte(s.getBytes(), 0, s.length() >> 1);// } else {// return hex2byte("0" + s);// }// }//// private static byte[] hex2byte(byte[] b, int offset, int len) {// byte[] d = new byte[len];// for (int i = 0; i < len * 2; i++) {// int shift = i % 2 == 1 ? 0 : 4;// d[i >> 1] |= Character.digit((char) b[offset + i], 16) << shift;// }// return d;// }// public static void main(String[] args) throws Exception {// AESUtils util = new AESUtils("abcdefghijklmnop"); // 密钥// System.out.println("cardNo:" + util.encryptData("1234")); // 加密// System.out.println("exp:" + util.decryptData("34+Jzs4KkwaCQWVyyAgwLA==")); // 解密// } public static String encodeAES(String json,String aesKey) throws Exception { AESUtils aes = new AESUtils(aesKey); return aes.encryptData(json); }}package com.ruidonghy.zbase.utils;import android.util.Base64;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.InputStream;import java.security.KeyFactory;import java.security.NoSuchAlgorithmException;import java.security.PublicKey;import java.security.spec.X509EncodedKeySpec;import javax.crypto.Cipher;/** * Created by zhou on 2017/11/10 18:50 . */public class RsaUtils { private static final String RSA_PUBLICE = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHrouGyrJsGZLqNiLtAvpOlPpe" + "UxmQdpfHSvIMqi7kHCe01VeHDFaB2wpOm9Fk2ExNELHd0BNjX7i3esvD319dJpia" + "qnXpkVesTNAnXj4+KPhUFu0Je26VpTfvBx6PSKrWrGOXPGt0S6BnIFjDL5tXxYsk" + "RZ2/2jdJMt/YjSnk2wIDAQAB"; private static final String ALGORITHM = "RSA"; /** * 得到公钥 * @param algorithm * @param bysKey * @return */ private static PublicKey getPublicKeyFromX509(String algorithm, String bysKey) throws NoSuchAlgorithmException, Exception { byte[] decodedKey = Base64.decode(bysKey,Base64.DEFAULT); X509EncodedKeySpec x509 = new X509EncodedKeySpec(decodedKey); KeyFactory keyFactory = KeyFactory.getInstance(algorithm); return keyFactory.generatePublic(x509); } /** * 使用公钥加密 * @param content * @return */ public static String encryptByPublic(String content) { try { PublicKey pubkey = getPublicKeyFromX509(ALGORITHM, RSA_PUBLICE); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.ENCRYPT_MODE, pubkey); byte plaintext[] = content.getBytes("UTF-8"); byte[] output = cipher.doFinal(plaintext); String s = new String(Base64.encode(output,Base64.DEFAULT)); return s; } catch (Exception e) { return null; } } /** * 使用公钥解密 * @param content 密文 * @return 解密后的字符串 */ public static String decryptByPublic(String content) { try { PublicKey pubkey = getPublicKeyFromX509(ALGORITHM, RSA_PUBLICE); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.DECRYPT_MODE, pubkey); InputStream ins = new ByteArrayInputStream(Base64.decode(content,Base64.DEFAULT)); ByteArrayOutputStream writer = new ByteArrayOutputStream(); byte[] buf = new byte[128]; int bufl; while ((bufl = ins.read(buf)) != -1) { byte[] block = null; if (buf.length == bufl) { block = buf; } else { block = new byte[bufl]; for (int i = 0; i < bufl; i++) { block[i] = buf[i]; } } writer.write(cipher.doFinal(block)); } return new String(writer.toByteArray(), "UTF-8"); } catch (Exception e) { return null; } }}复制代码
ServerErrorUtil
说明:
package com.ruidonghy.zbase.net;import android.widget.Toast;import com.ruidonghy.zbase.base.BaseApplication;import com.ruidonghy.zbase.base.BaseResult;import com.ruidonghy.zbase.utils.LogUtils;/** * Created by zhou on 2017/11/13 14:22 . * * 公共服务器错误雏形类,目前没有指定的需要拦截的错误码类型,日后会加 * */public class ServerErrorUtil { public static boolean isSuccess(BaseResult baseResult,boolean isShowErrorMsg){ if (baseResult.code==200){//返回200则请求成功,服务器正常给返回数据 if(baseResult.result==null){//服务器返回200结果Result数据是null,,则 1,log日志在控制台提示 2,返回false,让上层去做处理 LogUtils.e("服务器返回Result为null,请联系服务器人员!"); return false; } return true; }else{/** 200 => 'SUCCESS', 500 => '服务器内部错误', 4101 => '添加数据失败', 4201 => '请求校验失败', 4202 => 'loginkey无效', 4203 => '缺少参数', 4204 => '参数错误', 4205 => '验证码错误', 4206 => '注册失败', 4207 => '验证码获取失败', 4208 => '验证码获取频繁', 4209 => '绑定失败', 4210 => '已在其他设备登录', */ //拦截指定错误码 目前还未有指定 switch(baseResult.code){ case 500://服务器内部错误 ;break; case 4101://添加数据失败 ;break; case 4201://请求校验失败 ;break; case 4202://loginkey无效 ;break; case 4203://缺少参数 ;break; case 4204://参数错误 ;break; case 4205://验证码错误 ;break; case 4206://注册失败 ;break; case 4207://验证码获取失败 ;break; case 4208://验证码获取频繁 ;break; case 4209://绑定失败 ;break; case 4210://已在其他设备登录 ;break; case 4221://评论自己错误 ;break; } //如果上层需要显示错误信息的话,则用固定的Toast来show错误消息 if (isShowErrorMsg){ Toast.makeText(BaseApplication.instance(),baseResult.message,Toast.LENGTH_LONG).show(); } return false; } }}package com.ruidonghy.zbase.net;import java.net.ConnectException;import java.net.UnknownHostException;import retrofit2.HttpException;/** * Created by abbott on 2017/12/8. */public class ExceptionUtil { public static final int SERVER_ERROR = 9000;//服务器异常 public static final int HTTP_ERROR = 9001;//网络异常 public static int errorCode(Throwable e) { if (e instanceof HttpException || e instanceof UnknownHostException || e instanceof ConnectException) { return HTTP_ERROR; } else { return SERVER_ERROR; } }}package com.ruidonghy.zbase.net;/** * Created by zhou on 2017/11/6 16:48 . */public class URLConfig { public static final String HOST_ONLINE = "http://api.xxx.com/";//线上环境 public static final String HOST_PRE_ONLINE = "http://api.xxx.com/";//预上线环境 public static final String HOST_TEST = "http://api.xxx.com/";//测试环境 public static final String HOST_DEV = "http://api.xxx.com/";//开发环境 public static final int URL_TYPE = 3;//1是线上 2是预上线 3是测试 4是研发环境,自己随便配置的 public static String getHost() { String host = ""; switch (URL_TYPE) { case 1: host = HOST_ONLINE; break; case 2: host = HOST_PRE_ONLINE; break; case 3: host = HOST_TEST; break; case 4: host = HOST_DEV; break; default: host = HOST_ONLINE; break; } return host; } public static String JD_IMAGE_ENDSTR_MID = "?imgalias/img_mid";//?imgalias/img_mid public static String JD_IMAGE_ENDSTR_SMALL = "?imgalias/img_small";//?imgalias/img_small}package com.ruidonghy.zbase.net;import io.reactivex.Observable;import io.reactivex.Observer;import io.reactivex.disposables.Disposable;/** * Created by zhou on 2017/11/11 17:56 . */public abstract class CallBackimplements Observer { @Override public void onSubscribe(Disposable d) { } @Override public void onNext(T value) { onSuccess(value); } @Override public void onError(Throwable e) { switch (ExceptionUtil.errorCode(e)){ case ExceptionUtil.SERVER_ERROR: onServerError(); break; case ExceptionUtil.HTTP_ERROR: onHttpError(); break; } onFail(e); } @Override public void onComplete() {} public abstract void onSuccess(T data); public abstract void onFail(Throwable e); public void onServerError() {} public void onHttpError() {}}复制代码
StartIndoorRunActivity
说明:
package com.ruidonghy.zbase.data;import android.os.Parcel;import android.os.Parcelable;/** * Created by zhou on 2017/11/27 10:23 . */public class StartIndoorRunActivity implements Parcelable { public static final String ACTION = "com.ruidonghy.run.indoor.IndoorRunActivity"; /** * 0:为设置距离和时间 * 1:设置了距离 * 2:设置了时间 */ private int type; /** * 设定的距离,单位:公里 */ private float distance; /** * 设定的时间,单位:秒 */ private long time; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(this.type); dest.writeFloat(this.distance); dest.writeLong(this.time); } public StartIndoorRunActivity(int type, float distance, long time) { this.type = type; this.distance = distance; this.time = time; } protected StartIndoorRunActivity(Parcel in) { this.type = in.readInt(); this.distance = in.readFloat(); this.time = in.readLong(); } public static final Parcelable.CreatorCREATOR = new Parcelable.Creator () { @Override public StartIndoorRunActivity createFromParcel(Parcel source) { return new StartIndoorRunActivity(source); } @Override public StartIndoorRunActivity[] newArray(int size) { return new StartIndoorRunActivity[size]; } }; public int getType() { return type; } public float getDistance() { return distance; } public long getTime() { return time; }}复制代码