فهرست منبع

1.修改Android Apex CRM增加图片选择和拍照。

Pen Li 7 سال پیش
والد
کامیت
91f8112804
22فایلهای تغییر یافته به همراه1621 افزوده شده و 30 حذف شده
  1. 132 0
      ApexDrivers/RAUtilsLibrary/src/main/java/com/usai/redant/rautils/actionSheet/ActionSheet.java
  2. 105 0
      ApexDrivers/RAUtilsLibrary/src/main/java/com/usai/redant/rautils/base/BaseDialog.java
  3. 318 0
      ApexDrivers/RAUtilsLibrary/src/main/java/com/usai/redant/rautils/base/BaseObject.java
  4. 176 0
      ApexDrivers/RAUtilsLibrary/src/main/java/com/usai/redant/rautils/button/RAButton.java
  5. 157 0
      ApexDrivers/RAUtilsLibrary/src/main/java/com/usai/redant/rautils/camera/CameraHelper.java
  6. 292 0
      ApexDrivers/RAUtilsLibrary/src/main/java/com/usai/redant/rautils/carousel/CarouselView.java
  7. 57 0
      ApexDrivers/RAUtilsLibrary/src/main/java/com/usai/redant/rautils/utils/FileManager.java
  8. 77 0
      ApexDrivers/RAUtilsLibrary/src/main/java/com/usai/redant/rautils/utils/ImageUtil.java
  9. 5 0
      ApexDrivers/RAUtilsLibrary/src/main/res/anim/dialog_in.xml
  10. 5 0
      ApexDrivers/RAUtilsLibrary/src/main/res/anim/dialog_out.xml
  11. 13 0
      ApexDrivers/RAUtilsLibrary/src/main/res/drawable/actionsheet_round_corner_highlight_bg.xml
  12. 13 0
      ApexDrivers/RAUtilsLibrary/src/main/res/drawable/actionsheet_round_corner_normal_bg.xml
  13. 13 0
      ApexDrivers/RAUtilsLibrary/src/main/res/drawable/actionsheet_round_corner_selected_bg.xml
  14. 9 0
      ApexDrivers/RAUtilsLibrary/src/main/res/layout/action_sheet.xml
  15. 2 0
      ApexDrivers/RAUtilsLibrary/src/main/res/values-zh/strings.xml
  16. 22 0
      ApexDrivers/RAUtilsLibrary/src/main/res/values/actionsheet_styles.xml
  17. 10 0
      ApexDrivers/RAUtilsLibrary/src/main/res/values/animation.xml
  18. 25 0
      ApexDrivers/RAUtilsLibrary/src/main/res/values/basic_dialog_style.xml
  19. 2 0
      ApexDrivers/RAUtilsLibrary/src/main/res/values/strings.xml
  20. 178 29
      ApexDrivers/apexcrm/src/main/java/com/usai/apex/apexcrm/MainActivity.java
  21. 6 1
      ApexDrivers/apexcrm/src/main/res/values-zh/strings.xml
  22. 4 0
      ApexDrivers/apexcrm/src/main/res/values/strings.xml

+ 132 - 0
ApexDrivers/RAUtilsLibrary/src/main/java/com/usai/redant/rautils/actionSheet/ActionSheet.java

@@ -0,0 +1,132 @@
+package com.usai.redant.rautils.actionSheet;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.graphics.Color;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.text.TextPaint;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.Button;
+import android.widget.LinearLayout;
+
+import com.usai.redant.rautils.R;
+import com.usai.redant.rautils.button.RAButton;
+
+import java.util.HashMap;
+
+public class ActionSheet extends Dialog implements View.OnClickListener {
+
+    private Context mCtx;
+    private LinearLayout mRootView;
+    private HashMap<Button,View.OnClickListener> buttonListenerMap = new HashMap<>();
+
+    public ActionSheet(@NonNull Context context) {
+        this(context,R.style.actionSheet);
+
+    }
+
+    public ActionSheet(@NonNull Context context, int themeResId) {
+        super(context, themeResId);
+
+        mCtx = context;
+        init();
+    }
+
+    protected ActionSheet(@NonNull Context context, boolean cancelable, @Nullable OnCancelListener cancelListener) {
+        super(context, cancelable, cancelListener);
+
+        mCtx = context;
+        init();
+    }
+
+    private void init() {
+        mRootView = (LinearLayout) LayoutInflater.from(mCtx).inflate(R.layout.action_sheet, null);
+        setContentView(mRootView);
+    }
+
+    public void addAction(String title, ActionType actionType, View.OnClickListener clickListener) {
+
+        RAButton button = new RAButton(mCtx);
+        button.setText(title);
+        button.setTextColor(Color.parseColor("#2577ff"));
+        button.setTextSize(TypedValue.COMPLEX_UNIT_SP,20);
+        button.setAllCaps(false);
+        button.setBackgroundResource(R.drawable.actionsheet_round_corner_normal_bg);
+        button.setOnClickListener(this);
+        if (clickListener != null) {
+            buttonListenerMap.put(button,clickListener);
+        }
+
+        button.setTitleColorForState(RAButton.RAButtonState.RAButtonStateHighlight,Color.RED);
+        button.setBackgroundDrawableForState(RAButton.RAButtonState.RAButtonStateNormal,mCtx.getResources().getDrawable(R.drawable.actionsheet_round_corner_normal_bg));
+
+        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,dp2px(mCtx,50));
+
+        int marginH = dp2px(mCtx,10);
+        int marginV = dp2px(mCtx,5);
+        switch (actionType) {
+            case ACtionTypeCancel: {
+                layoutParams.setMargins(marginH,marginV,marginH,marginV);
+
+                TextPaint tp = button.getPaint();
+                tp.setFakeBoldText(true);
+            }
+            break;
+            case ActionTypeDefault: {
+                layoutParams.setMargins(marginH,0,marginH,marginV);
+            }
+            break;
+        }
+
+        mRootView.addView(button,layoutParams);
+    }
+
+    private static int dp2px(Context context, float dpValue) {
+        float scale = context.getResources().getDisplayMetrics().density;
+        return (int) (dpValue * scale + 0.5f);
+    }
+
+    @Override
+    public void show() {
+
+        Window dialogWindow = getWindow();
+        if (dialogWindow != null) {
+
+            dialogWindow.setGravity(Gravity.BOTTOM);
+            WindowManager.LayoutParams layoutParams = dialogWindow.getAttributes(); // 获取对话框当前的参数值
+            layoutParams.x = 0; // 新位置X坐标
+            layoutParams.y = 0; // 新位置Y坐标
+            layoutParams.width = (int) mCtx.getResources().getDisplayMetrics().widthPixels; // 宽度
+            mRootView.measure(0, 0);
+            layoutParams.height = mRootView.getMeasuredHeight();
+
+            layoutParams.alpha = 9f; // 透明度
+            dialogWindow.setAttributes(layoutParams);
+        }
+
+        super.show();
+    }
+
+    @Override
+    public void onClick(View v) {
+
+        dismiss();
+
+        View.OnClickListener listener = buttonListenerMap.get(v);
+        if (listener != null) {
+            listener.onClick(v);
+        }
+    }
+
+    public enum ActionType {
+        ActionTypeDefault,
+        ACtionTypeCancel
+    }
+}

+ 105 - 0
ApexDrivers/RAUtilsLibrary/src/main/java/com/usai/redant/rautils/base/BaseDialog.java

@@ -0,0 +1,105 @@
+package com.usai.redant.rautils.base;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.support.annotation.NonNull;
+import android.view.Gravity;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+
+import com.usai.redant.rautils.R;
+
+
+public class BaseDialog extends Dialog {
+
+    private Context mCtx;
+    private View mRootView;
+    private BasicDialogSetupCallBack mCallBack;
+
+    public final static int BasicDialogContentGravityTop = 0;
+    public final static int BasicDialogContentGravityCenter = 1;
+    public final static int BasicDialogContentGravityBottom = 2;
+
+    public BaseDialog(@NonNull Context context, BasicDialogSetupCallBack callBack) {
+        this(context);
+
+        mCallBack = callBack;
+
+        mCtx = context;
+        init();
+    }
+
+    private BaseDialog(@NonNull Context context) {
+        this(context, R.style.RADialog);
+    }
+
+    private BaseDialog(@NonNull Context context, int themeResId) {
+        super(context, themeResId);
+    }
+
+    private void init() {
+        if (mCallBack != null) {
+            mRootView = mCallBack.createContentView(this);
+            if (mRootView != null) {
+                setContentView(mRootView);
+            }
+        }
+    }
+
+    @Override
+    public void show() {
+
+        if (mRootView == null) {
+            super.show();
+            return;
+        }
+
+        Window dialogWindow = getWindow();
+        if (dialogWindow != null) {
+
+            int gravity = BasicDialogContentGravityCenter;
+            if (mCallBack != null) {
+                gravity = mCallBack.dialogGravity(this);
+            }
+
+            switch (gravity) {
+                case BasicDialogContentGravityTop: {
+                    dialogWindow.setGravity(Gravity.TOP);
+                }
+                break;
+                case BasicDialogContentGravityCenter: {
+                    dialogWindow.setGravity(Gravity.CENTER);
+                }
+                break;
+                case BasicDialogContentGravityBottom: {
+                    dialogWindow.setGravity(Gravity.BOTTOM);
+                }
+                break;
+                default: {
+                    dialogWindow.setGravity(Gravity.CENTER);
+                }
+                break;
+            }
+
+            WindowManager.LayoutParams layoutParams = dialogWindow.getAttributes(); // 获取对话框当前的参数值
+            layoutParams.x = 0; // 新位置X坐标
+            layoutParams.y = 0; // 新位置Y坐标
+            layoutParams.width = (int) mCtx.getResources().getDisplayMetrics().widthPixels; // 宽度
+            mRootView.measure(0, 0);
+            layoutParams.height = mRootView.getMeasuredHeight();
+
+            layoutParams.alpha = 9f; // 透明度
+            dialogWindow.setAttributes(layoutParams);
+        }
+
+        super.show();
+    }
+
+    public interface BasicDialogSetupCallBack {
+
+        View createContentView(final BaseDialog dialog);
+        int dialogGravity(final BaseDialog dialog);
+
+    }
+}

+ 318 - 0
ApexDrivers/RAUtilsLibrary/src/main/java/com/usai/redant/rautils/base/BaseObject.java

@@ -0,0 +1,318 @@
+package com.usai.redant.rautils.base;
+
+import android.text.TextUtils;
+
+import org.json.JSONObject;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+/**
+ * 基础对象,方便使用json初始化对象,属性必须声明为public
+ * 如果json中元素为json对象,那么属性对应的应该为Object类型
+ * */
+public class BaseObject {
+
+    /**
+     * Utils
+     * */
+
+    private static String toUpperCaseFirstOne(String s){
+        if(Character.isUpperCase(s.charAt(0)))
+            return s;
+        else
+            return (new StringBuilder()).append(Character.toUpperCase(s.charAt(0))).append(s.substring(1)).toString();
+    }
+
+    /**
+     * Setter
+     * */
+    private boolean invokeSetter(Class cls, Class type, String key, Object value) {
+
+        String setter = "set" + toUpperCaseFirstOne(key);
+        try {
+
+            Class<?> myClassType = Class.forName(cls.getName());
+
+            Method method = myClassType.getMethod(setter,type);
+            if (method != null) {
+
+                method.invoke(this,value);
+
+                return true;
+            }
+
+        } catch (Exception e) {
+//            e.printStackTrace();
+        }
+
+        return false;
+    }
+
+    private void setValue(Class cls, Field f, Class type, String key, Object value) {
+
+        if (!invokeSetter(cls, type, key, value)) {
+            try {
+                f.set(this,value);
+            } catch (IllegalAccessException e) {
+//                e.printStackTrace();
+            }
+        }
+    }
+
+    private void setValue(Class cls, Field f, String key, Object value) {
+
+        Class type = f.getType();
+
+        if (value == null) {
+
+            boolean isInt = (type == int.class || type == long.class);
+            boolean isFloat = (type == float.class || type == double.class);
+            boolean isBool = (type == Boolean.class || type == boolean.class);
+
+            if (isInt) {
+                value = 0;
+            } else if (isFloat) {
+                value = 0.0;
+            } else if (isBool) {
+                value = false;
+            }
+
+            setValue(cls, f, type, key, value);
+
+        } else {
+
+            if (type == value.getClass()) {
+
+                setValue(cls, f, type, key, value);
+
+            } else {
+
+                boolean isInt = ((type == int.class || type == long.class) && value.getClass() == Integer.class);
+                boolean isFloat = ((type == float.class || type == double.class) && (value.getClass() == Double.class || value.getClass() == Float.class));
+                boolean isBool = ((type == Boolean.class || type == boolean.class) && (value.getClass() == boolean.class || value.getClass() == Boolean.class));
+
+                if (isInt || isFloat || isBool) {
+                    setValue(cls, f, type, key, value);
+                } else {
+
+                    if (value.getClass() == String.class) {
+
+                        String string = (String)value;
+
+                        if (type == Integer.class || type == int.class || type == long.class) {
+
+                            value = Integer.valueOf(string);
+
+
+                        } else if (type == Double.class || type == double.class || type == float.class) {
+
+                            value = Double.valueOf(string);
+
+                        } else if (type == Boolean.class || type == boolean.class) {
+
+                            value = Boolean.valueOf(string);
+                        }
+
+                        setValue(cls, f, type, key, value);
+
+                    } else {
+
+                        if (type == Object.class) {
+                            setValue(cls, f, type, key, value);
+                        }
+
+                    }
+                }
+            }
+        }
+
+    }
+
+    public void setValueForKey(String key, Object value) {
+
+        if (key == null) {
+            return;
+        }
+
+        Class cls = getClass();
+//        out:while (cls != null && cls != Class.class) {
+//
+//            Field[] fields = cls.getFields();
+//            for (Field f : fields) {
+//
+//                String name = f.getName();
+//                if (name.equals(key)) {
+//
+//                    setValue(cls, f, key, value);
+//                    break out;
+//                }
+//            }
+//
+//            cls = cls.getSuperclass();
+//        }
+
+        try {
+            Field f = cls.getField(key);
+            setValue(cls, f, key, value);
+        } catch (NoSuchFieldException e) {
+//            e.printStackTrace();
+        }
+    }
+
+    public void setValueForKeyPath(String keyPath, Object value) {
+
+        if (keyPath != null) {
+            if (keyPath.contains(".")) {
+
+                Object receiver = this;
+                String[] nodes = keyPath.split("\\."); // split 实际上是正则表达式,所以特殊字符需要转译
+                for (int i = 0; i < nodes.length; i++) {
+                    String key = nodes[i];
+                    if (i == nodes.length - 1) {
+
+                        if (receiver != null) {
+
+                            if (receiver instanceof BaseObject) {
+                                ((BaseObject) receiver).setValueForKey(key,value);
+                            } else {
+
+                                try {
+
+                                    Class cls = receiver.getClass();
+                                    Field f = cls.getField(key);
+                                    setValue(cls, f, key, value);
+                                } catch (NoSuchFieldException e) {
+//                                    e.printStackTrace();
+                                }
+                            }
+                        }
+
+                    } else {
+
+                        receiver = getValueForKey(receiver, key);
+                        if (receiver == null) {
+                            break;
+                        }
+                    }
+                }
+
+            } else {
+                setValueForKey(keyPath,value);
+            }
+        }
+    }
+
+    public void setValuesForKeysWithJSON(JSONObject json) {
+
+        if (json == null || json.length() == 0) {
+            return;
+        }
+
+
+        try {
+            Class cls = getClass();
+            while (cls != null && cls != Class.class) {
+
+                Field[] fields = cls.getFields();
+                for (Field f : fields) {
+
+                    String key = f.getName();
+
+                    Object value = json.opt(key);
+
+//                    if (value == null) {
+//                        continue;
+//                    }
+
+                    setValue(cls, f, key, value);
+                }
+                cls = cls.getSuperclass();
+            }
+        } catch (Exception e) {
+//            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Getter
+     * */
+
+    private Object invokeGetter(Class cls, String key) {
+
+        String setter = "get" + toUpperCaseFirstOne(key);
+        try {
+
+            Class<?> myClassType = Class.forName(cls.getName());
+
+            Method method = myClassType.getMethod(setter,void.class);
+            if (method != null) {
+                return method.invoke(this);
+            }
+
+        } catch (Exception e) {
+//            e.printStackTrace();
+        }
+
+        return null;
+    }
+
+    private Object getValueForKey(Object receiver, String key) {
+
+        if (receiver == null || TextUtils.isEmpty(key)) {
+            return null;
+        }
+
+        try {
+
+            Class cls = receiver.getClass();
+
+            Object obj = invokeGetter(cls, key);
+
+            if (obj == null) {
+
+                Field field = cls.getField(key);
+                if (field != null) {
+                    obj = field.get(receiver);
+                    return obj;
+                } else {
+                    return null;
+                }
+            } else {
+                return obj;
+            }
+
+        } catch (NoSuchFieldException e) {
+//            e.printStackTrace();
+        } catch (IllegalAccessException e) {
+//            e.printStackTrace();
+        }
+        return null;
+
+    }
+
+    public Object getValueForKeyPath(String keyPath) {
+
+        if (keyPath != null) {
+
+            if (keyPath.contains(".")) {
+
+                Object receiver = this;
+                String[] nodes = keyPath.split("\\."); // split 实际上是正则表达式,所以特殊字符需要转译
+                for (int i = 0; i < nodes.length; i++) {
+                    String key = nodes[i];
+                    receiver = getValueForKey(receiver, key);
+                    if (receiver == null) {
+                        break;
+                    }
+                }
+                return receiver;
+
+            } else {
+                return getValueForKey(this,keyPath);
+            }
+
+        }
+        return null;
+    }
+}

+ 176 - 0
ApexDrivers/RAUtilsLibrary/src/main/java/com/usai/redant/rautils/button/RAButton.java

@@ -0,0 +1,176 @@
+package com.usai.redant.rautils.button;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+
+import java.util.HashMap;
+
+public class RAButton extends android.support.v7.widget.AppCompatButton {
+
+    private HashMap<RAButtonState,Drawable> stateDrawableHashMap = new HashMap<>();
+    private HashMap<RAButtonState,String> stateTitleHashMap = new HashMap<>();
+    private HashMap<RAButtonState,Integer> stateTitleColorHashMap = new HashMap<>();
+
+    private RAButtonState state = RAButtonState.RAButtonStateNormal;
+    private boolean mSelected = false;
+
+    public RAButton(Context context) {
+        super(context);
+
+        init();
+    }
+
+    public RAButton(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        init();
+    }
+
+    public RAButton(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+
+        init();
+    }
+
+    private void init() {
+
+        setAllCaps(false);
+
+        String normalTitle = getText().toString();
+        Drawable normalDrawable = getBackground();
+        Integer normalTitleColor = getTextColors().getDefaultColor();
+
+        String title = stateTitleHashMap.get(RAButtonState.RAButtonStateNormal);
+        if (title == null && normalTitle != null) {
+            stateTitleHashMap.put(RAButtonState.RAButtonStateNormal,normalTitle);
+        }
+
+        Drawable background = stateDrawableHashMap.get(RAButtonState.RAButtonStateNormal);
+        if (background == null && normalDrawable != null) {
+            stateDrawableHashMap.put(RAButtonState.RAButtonStateNormal,normalDrawable);
+        }
+
+        stateTitleColorHashMap.put(RAButtonState.RAButtonStateNormal,normalTitleColor);
+
+    }
+
+    public void setBackgroundDrawableForState(RAButtonState state, Drawable drawable) {
+
+        if (state == null) {
+            return;
+        }
+
+        if (drawable != null) {
+            stateDrawableHashMap.put(state,drawable);
+        } else {
+            stateDrawableHashMap.remove(state);
+        }
+    }
+
+    public void setTitleForState(RAButtonState state, String title) {
+
+        if (state == null) {
+            return;
+        }
+        if (title == null) {
+            stateTitleHashMap.remove(state);
+        } else {
+            stateTitleHashMap.put(state,title);
+        }
+    }
+
+    public void setTitleColorForState(RAButtonState state, int color) {
+
+        if (state == null) {
+            return;
+        }
+
+        stateTitleColorHashMap.put(state,Integer.valueOf(color));
+    }
+
+    public void setText(String text) {
+        super.setText(text);
+
+        setTitleForState(state,text);
+    }
+
+    public void setTextColor(int color) {
+        super.setTextColor(color);
+
+        setTitleColorForState(state,color);
+    }
+
+    public void setBackgroundDrawable(Drawable drawable) {
+        super.setBackgroundDrawable(drawable);
+
+        setBackgroundDrawableForState(state,drawable);
+    }
+
+    private void refreshUI() {
+
+        Drawable drawable = stateDrawableHashMap.get(state);
+        if (drawable == null) {
+            drawable = stateDrawableHashMap.get(RAButtonState.RAButtonStateNormal);
+        }
+        super.setBackgroundDrawable(drawable);
+
+        String title = stateTitleHashMap.get(state);
+        if (title == null) {
+            title = stateTitleHashMap.get(RAButtonState.RAButtonStateNormal);
+        }
+        super.setText(title);
+
+        Integer colorInteger = stateTitleColorHashMap.get(state);
+        if (colorInteger != null) {
+            super.setTextColor(colorInteger.intValue());
+        }
+    }
+
+    public void setSelection(boolean selection) {
+        mSelected = selection;
+
+        if (selection) {
+            state = RAButtonState.RAButtonStateSelected;
+        } else {
+            state = RAButtonState.RAButtonStateNormal;
+        }
+
+        refreshUI();
+    }
+
+    public boolean getSelection() {
+        return mSelected;
+    }
+
+    /**
+     * 按钮触摸状态改变回调
+     * */
+    @Override
+    protected void drawableStateChanged() {
+        super.drawableStateChanged();
+
+        boolean pressed = isPressed();
+
+        if (pressed) {
+            state = RAButtonState.RAButtonStateHighlight;
+        } else {
+
+            if (mSelected) {
+                state = RAButtonState.RAButtonStateSelected;
+            } else {
+                state = RAButtonState.RAButtonStateNormal;
+            }
+
+        }
+
+        refreshUI();
+
+    }
+
+    public enum RAButtonState {
+        RAButtonStateNormal,
+        RAButtonStateHighlight,
+        RAButtonStateSelected
+    }
+}

+ 157 - 0
ApexDrivers/RAUtilsLibrary/src/main/java/com/usai/redant/rautils/camera/CameraHelper.java

@@ -0,0 +1,157 @@
+package com.usai.redant.rautils.camera;
+
+import android.Manifest;
+import android.app.Activity;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Environment;
+import android.provider.MediaStore;
+import android.support.v4.content.PermissionChecker;
+import android.widget.Toast;
+
+import com.usai.redant.rautils.R;
+import com.usai.redant.rautils.utils.RAUtil;
+
+import java.io.File;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class CameraHelper {
+
+    /**
+     * Take Picture
+     * */
+    public static File startCamera(Activity context, int requestCode) {
+
+        File photoFile = null;
+        if (context == null) {
+            return photoFile;
+        }
+
+        boolean cameraPermission = PermissionChecker.checkSelfPermission(context,Manifest.permission.CAMERA) == PermissionChecker.PERMISSION_GRANTED;
+        boolean storageReadPermission = PermissionChecker.checkSelfPermission(context,Manifest.permission.READ_EXTERNAL_STORAGE) == PermissionChecker.PERMISSION_GRANTED;
+        boolean storageWritePermission = PermissionChecker.checkSelfPermission(context,Manifest.permission.WRITE_EXTERNAL_STORAGE) == PermissionChecker.PERMISSION_GRANTED;
+
+        if (!cameraPermission || !storageReadPermission || !storageWritePermission) {
+
+            Toast.makeText(context,context.getString(R.string.ra_allow_camera_and_storage),Toast.LENGTH_LONG).show();
+
+            return photoFile;
+        }
+
+
+        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
+        // Ensure that there's a camera activity to handle the intent
+
+        if (takePictureIntent.resolveActivity(context.getPackageManager()) != null)
+        {
+
+            try
+            {
+                photoFile = createImageFile(context);
+            }
+            catch (IOException ex)
+            {
+                ex.printStackTrace();
+            }
+            // Continue only if the File was successfully created
+            if (photoFile != null)
+            {
+                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, getImageContentUri(context,photoFile));
+                context.startActivityForResult(takePictureIntent, requestCode);
+                return photoFile;
+            }
+        }
+        return photoFile;
+    }
+
+    private static File createImageFile(Context context) throws IOException {
+        // Create an image file name
+        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmSS").format(new Date());
+        String imageFileName = "JPEG_" + timeStamp + "_";
+        String appName = RAUtil.getApplicationName(context);
+
+        File storageDir = new File(Environment.getExternalStorageDirectory().getPath() + "/" + appName + "/photo/temp/");
+
+        File dir1 = new File(Environment.getExternalStorageDirectory().getPath() + "/" + appName);
+        File dir2 = new File(Environment.getExternalStorageDirectory().getPath() + "/" + appName + "/photo");
+        File dir3 = new File(Environment.getExternalStorageDirectory().getPath() + "/" + appName + "/photo/temp/");
+
+
+        if (!dir1.exists())
+        {
+            boolean b = dir1.mkdir();
+        }
+        if (!dir2.exists())
+        {
+            boolean b = dir2.mkdir();
+        }
+        if (!dir3.exists())
+        {
+            boolean b = dir3.mkdir();
+        }
+
+
+        File image = File.createTempFile(imageFileName, /* prefix */
+                ".jpg", /* suffix */
+                storageDir /* directory */
+        );
+
+        return image;
+    }
+
+    private static Uri getImageContentUri(Context context, File imageFile) {
+        String filePath = imageFile.getAbsolutePath();
+        Cursor cursor = context.getContentResolver().query(
+                MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
+                new String[] { MediaStore.Images.Media._ID },
+                MediaStore.Images.Media.DATA + "=? ",
+                new String[] { filePath }, null);
+
+        if (cursor != null && cursor.moveToFirst()) {
+            int id = cursor.getInt(cursor
+                    .getColumnIndex(MediaStore.MediaColumns._ID));
+            Uri baseUri = Uri.parse("content://media/external/images/media");
+            return Uri.withAppendedPath(baseUri, "" + id);
+        } else {
+            if (imageFile.exists()) {
+                ContentValues values = new ContentValues();
+                values.put(MediaStore.Images.Media.DATA, filePath);
+                return context.getContentResolver().insert(
+                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
+            } else {
+                return null;
+            }
+        }
+    }
+
+    /**
+     * Photo Library
+     * */
+    public static void pickImageFromAlbum(Activity activity, int requestCode) {
+        Intent intent = new Intent();
+        intent.setAction(Intent.ACTION_GET_CONTENT);
+        intent.setType("image/*");
+        activity.startActivityForResult(intent, requestCode);
+    }
+
+    public static void pickImageFromAlbum2(Activity activity, int requestCode) {
+        Intent intent = new Intent();
+        intent.setAction(Intent.ACTION_PICK);
+        intent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
+        activity.startActivityForResult(intent, requestCode);
+    }
+
+    public static Uri getImageUriFromData(Intent data) {
+        if (data == null) {
+            Uri imageUri = data.getData();
+            return imageUri;
+        }
+        return null;
+    }
+
+}

+ 292 - 0
ApexDrivers/RAUtilsLibrary/src/main/java/com/usai/redant/rautils/carousel/CarouselView.java

@@ -0,0 +1,292 @@
+package com.usai.redant.rautils.carousel;
+
+import android.app.Activity;
+import android.content.Context;
+import android.support.annotation.Nullable;
+import android.support.v4.view.PagerAdapter;
+import android.support.v4.view.ViewPager;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.RelativeLayout;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Timer;
+import java.util.TimerTask;
+
+public class CarouselView extends RelativeLayout {
+
+    private CarouselPager mPager;
+    private Context mContext;
+    private int mResourceId = -1;
+    private CarouselView self;
+    private CarouselDelegate mDelegate;
+    private CarouselAdapter mAdapter;
+    private int mCurrentItem = 1;
+    private int mItemCount;
+
+    public CarouselView(Context context) {
+        super(context);
+        init(context);
+    }
+
+    public CarouselView(Context context, @Nullable AttributeSet attrs) {
+        super(context, attrs);
+        init(context);
+    }
+
+    public CarouselView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        init(context);
+    }
+
+    private void init(Context context) {
+        mContext = context;
+        self = this;
+
+        mAdapter = new CarouselAdapter();
+
+        mPager = new CarouselPager(mContext);
+        RelativeLayout.LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);
+        addView(mPager,layoutParams);
+
+        mPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
+            @Override
+            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+
+            }
+
+            @Override
+            public void onPageSelected(int position) {
+
+//                Log.d("Selected", "onPageSelected: " + position);
+                mCurrentItem = position;
+                int display_index = mCurrentItem;
+                if (position == 0) {
+                    display_index = mItemCount;
+                } else if (position == mItemCount + 1) {
+                    display_index = 1;
+                } else {
+                    display_index = position;
+
+                    // 代理方法在此调用避免两端点的索引重复出现
+                    if (mDelegate != null) {
+                        mDelegate.carouselDidShowItem(self,display_index - 1);
+                    }
+                }
+
+
+            }
+
+            @Override
+            public void onPageScrollStateChanged(int state) {
+
+                // 解决两端切换时闪屏
+                if (state == ViewPager.SCROLL_STATE_IDLE) {
+                    if (mCurrentItem == mPager.getAdapter().getCount() - 1) {
+                        mPager.setCurrentItem(1, false);
+                    }
+                    else if (mCurrentItem == 0) {
+                        mPager.setCurrentItem(mPager.getAdapter().getCount() - 2, false);
+                    }
+                }
+            }
+        });
+        mPager.setAdapter(mAdapter);
+        reloadData();
+    }
+
+    public void registResourceId(int resourceId) {
+        mResourceId = resourceId;
+    }
+
+    public void setDelegate(CarouselDelegate delegate) {
+        mDelegate = delegate;
+    }
+
+    public void reloadData() {
+        mAdapter.notifyDataSetChanged();
+        mCurrentItem = 1;
+        mPager.setCurrentItem(mCurrentItem,false);
+        if (mAutoScroll) {
+
+            startAutoScroll();
+        }
+    }
+
+
+
+    public interface CarouselDelegate {
+
+        void carouselWillShowItem(CarouselView carousel, View cell, int index);
+        void carouselDidShowItem(CarouselView carousel, int index);
+        int  carouselNumberOfItems(CarouselView carousel);
+
+    }
+
+    public class CarouselAdapter extends PagerAdapter {
+
+        ArrayList<View> mReusePool = new ArrayList<>();
+
+        @Override
+        public int getCount() {
+            if (mDelegate == null || mResourceId == -1) {
+
+                return mItemCount = 0;
+            } else {
+                int number = mDelegate.carouselNumberOfItems(self);
+                if (number == 0) {
+                    return mItemCount = 0;
+                } else {
+                    mItemCount = number;
+                    return number + 2;
+                }
+            }
+
+        }
+
+        @Override
+        public boolean isViewFromObject(View view, Object object) {
+            return view == object;
+        }
+
+        @Override
+        public int getItemPosition(Object object) {
+//            return super.getItemPosition(object);
+            return POSITION_NONE; // 解决notifyDataChange后界面没更新
+        }
+
+        @Override
+        public void destroyItem(ViewGroup container, int position, Object object) {
+
+            View cell = (View) object;
+            container.removeView(cell);
+            mReusePool.add(cell);
+        }
+
+        @Override
+        public Object instantiateItem(ViewGroup container, int position) {
+
+            View cell = null;
+            if (mReusePool.isEmpty()) {
+
+                cell = (View) LayoutInflater.from(mContext).inflate(mResourceId,null);
+
+            } else {
+                cell = mReusePool.get(0);
+                mReusePool.remove(cell);
+            }
+
+
+            int index = position;
+            if (position == 0) {
+                index = mItemCount - 1;
+            } else if (position == mItemCount + 1) {
+                index = 0;
+            } else {
+                index = position - 1;
+            }
+
+
+            if (mDelegate!= null) {
+                mDelegate.carouselWillShowItem(self,cell,index);
+            }
+
+            container.addView(cell);
+
+            return cell;
+        }
+    }
+
+    private Timer mTimer;
+    private TimerTask mTimerTask;
+    private boolean mAutoScroll = false;
+    private int mAutoScrollFlag = 0; // Timer开始第一次执行无效
+    private int mScrollTimeInterval = 10; // 单位秒
+
+    public void setAutoScroll(boolean autoScroll) {
+        mAutoScroll = autoScroll;
+        if (mAutoScroll) {
+            startAutoScroll();
+        } else {
+            stopAutoScroll();
+        }
+    }
+
+    public boolean getAutoScroll() {
+        return mAutoScroll;
+    }
+
+    public void setScrollTimeInterval(int scrollTimeInterval) {
+        this.mScrollTimeInterval = scrollTimeInterval;
+    }
+
+    public int getScrollTimeInterval() {
+        return this.mScrollTimeInterval;
+    }
+
+    private void startAutoScroll() {
+        if (mItemCount == 0) {
+            return;
+        }
+
+        stopAutoScroll();
+
+        mTimer = new Timer();
+        mTimerTask = new TimerTask() {
+            @Override
+            public void run() {
+                ((Activity)mContext).runOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        if (mAutoScrollFlag == 0) {
+                            mAutoScrollFlag = 1;
+                        } else {
+                            mPager.setCurrentItem(mCurrentItem + 1,true);
+                        }
+                    }
+                });
+            }
+        };
+        mTimer.schedule(mTimerTask,new Date(),1000 * mScrollTimeInterval);
+    }
+
+    private void stopAutoScroll() {
+        if (mTimer != null) {
+            mTimer.cancel();
+            mTimer = null;
+            mTimerTask = null;
+            mAutoScrollFlag = 0;
+        }
+    }
+
+    private class CarouselPager extends ViewPager {
+
+        public CarouselPager(Context context) {
+            super(context);
+        }
+
+        public CarouselPager(Context context, AttributeSet attrs) {
+            super(context, attrs);
+        }
+
+        @Override
+        public boolean onTouchEvent(MotionEvent event) {
+
+            if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE) {
+                stopAutoScroll();
+            }
+
+            if (event.getAction() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_UP) {
+                if (mAutoScroll) {
+                    startAutoScroll();
+                }
+            }
+
+            return super.onTouchEvent(event);
+        }
+    }
+}

+ 57 - 0
ApexDrivers/RAUtilsLibrary/src/main/java/com/usai/redant/rautils/utils/FileManager.java

@@ -8,6 +8,7 @@ import android.os.Build;
 import android.os.Environment;
 import android.support.v4.content.FileProvider;
 import android.text.TextUtils;
+import android.util.Base64;
 import android.util.Log;
 import android.webkit.MimeTypeMap;
 
@@ -525,8 +526,64 @@ public class FileManager {
             return move;
 
         }
+    }
+
+    public static byte[] getBytesOfFile(File file) {
+        if (file == null || !file.exists()) {
+            return null;
+        }
+
+        if (!file.isFile()) {
+            return null;
+        }
+
+        byte[] bytes = null;
+        FileInputStream is = null;
+        try {
+
+            is = new FileInputStream(file);
+            bytes = new byte[(int)file.length()];
+
+            is.read(bytes);
+
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            if (is != null) {
+                try {
+                    is.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
 
+        return bytes;
+    }
 
+    public static String base64StringFromFile(String path) {
+        if (path == null) {
+            return null;
+        }
+
+        File file = new File(path);
+        if (!file.exists()) {
+            return null;
+        }
+
+        if (!file.isFile()) {
+            return null;
+        }
+
+        byte[] bytes = getBytesOfFile(file);
+
+        if (bytes != null) {
+
+            String base64Str = Base64.encodeToString(bytes,Base64.DEFAULT);
+
+            return base64Str;
+        }
+        return null;
     }
 
 }

+ 77 - 0
ApexDrivers/RAUtilsLibrary/src/main/java/com/usai/redant/rautils/utils/ImageUtil.java

@@ -16,6 +16,8 @@ import android.util.Log;
 import java.io.BufferedOutputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.net.URI;
@@ -439,4 +441,79 @@ public class ImageUtil {
         return RAImageType.RA_IMAGE_TYPE_UNKNOWN;
     }
 
+    public static File compressImageFile(Context context, File imgFile) {
+
+        if (imgFile == null || context == null) {
+            return imgFile;
+        }
+
+        String imageFileName = imgFile.getName();
+
+        File routedFile = ImageUtil.routeBitmap(context,imgFile,null);
+
+        Bitmap source = null;
+        try {
+            FileInputStream stream = new FileInputStream(routedFile);
+            source = BitmapFactory.decodeStream(stream);
+        } catch (FileNotFoundException e) {
+            return routedFile;
+        }
+
+        if (source == null) {
+            return routedFile;
+        }
+
+        int originWidth = source.getWidth();
+        int originHeight = source.getHeight();
+
+        int width = originWidth, height = originHeight;
+
+        if (originHeight > 1024 || originWidth > 1024)
+        {
+            if (originWidth > originHeight)
+            {
+                width = 1024;
+                height = originHeight * 1024 / originWidth;
+
+            }
+            else
+            {
+
+                height = 1024;
+                width = originWidth * 1024 / originHeight;
+
+            }
+        }
+
+
+        Bitmap scaled = Bitmap.createScaledBitmap(source, width, height, true);
+
+        String scalePath = FileManager.internalStorageFileDir(context) + File.separator + "Photo" + File.separator +imageFileName;
+        File scaleFile = new File(scalePath);
+        if (!scaleFile.getParentFile().exists()) {
+            scaleFile.getParentFile().mkdirs();
+        }
+
+        try {
+
+            FileOutputStream outputStream = new FileOutputStream(scaleFile);
+            scaled.compress(Bitmap.CompressFormat.JPEG, 95, outputStream);
+
+            outputStream.flush();
+            outputStream.close();
+
+            String rotedpath = routedFile.getAbsolutePath();
+            routedFile.delete();
+
+            ImageUtil.updateGallery(context,rotedpath);
+
+            return scaleFile;
+
+        } catch (IOException e) {
+            e.printStackTrace();
+            return routedFile;
+        }
+
+    }
+
 }

+ 5 - 0
ApexDrivers/RAUtilsLibrary/src/main/res/anim/dialog_in.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<translate xmlns:android="http://schemas.android.com/apk/res/android"
+           android:duration="200"
+           android:fromYDelta="100%"
+           android:toYDelta="0" />

+ 5 - 0
ApexDrivers/RAUtilsLibrary/src/main/res/anim/dialog_out.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<translate xmlns:android="http://schemas.android.com/apk/res/android"
+           android:duration="200"
+           android:fromYDelta="0"
+           android:toYDelta="100%" />

+ 13 - 0
ApexDrivers/RAUtilsLibrary/src/main/res/drawable/actionsheet_round_corner_highlight_bg.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <corners android:radius="10dp"/>
+
+    <solid android:color="#aaaaaaaa"/>
+
+    <stroke
+        android:width="1dp"
+        android:color="#aaaaaaaa"
+        />
+
+</shape>

+ 13 - 0
ApexDrivers/RAUtilsLibrary/src/main/res/drawable/actionsheet_round_corner_normal_bg.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <corners android:radius="10dp"/>
+
+    <solid android:color="#ffffff"/>
+
+    <stroke
+        android:width="1dp"
+        android:color="#ffffff"
+        />
+
+</shape>

+ 13 - 0
ApexDrivers/RAUtilsLibrary/src/main/res/drawable/actionsheet_round_corner_selected_bg.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <corners android:radius="10dp"/>
+
+    <solid android:color="#00ffff"/>
+
+    <stroke
+        android:width="1dp"
+        android:color="#ffffff"
+        />
+
+</shape>

+ 9 - 0
ApexDrivers/RAUtilsLibrary/src/main/res/layout/action_sheet.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content"
+    android:background="#00000000"
+    >
+
+</LinearLayout>

+ 2 - 0
ApexDrivers/RAUtilsLibrary/src/main/res/values-zh/strings.xml

@@ -44,4 +44,6 @@
 
     <!---->
 
+    <string name="ra_allow_camera_and_storage">请检查相机权限和存储权限是否打开</string>
+
 </resources>

+ 22 - 0
ApexDrivers/RAUtilsLibrary/src/main/res/values/actionsheet_styles.xml

@@ -0,0 +1,22 @@
+<resources>
+
+    <style name="actionSheet" parent="@android:style/Theme.Dialog">
+
+        <!-- 背景透明 -->
+        <item name="android:windowBackground">@android:color/transparent</item>
+        <item name="android:windowContentOverlay">@null</item>
+        <!-- 浮于Activity之上 -->
+        <item name="android:windowIsFloating">true</item>
+        <!-- 边框 -->
+        <item name="android:windowFrame">@null</item>
+        <!-- Dialog以外的区域模糊效果 -->
+        <item name="android:backgroundDimEnabled">true</item>
+        <!-- 无标题 -->
+        <item name="android:windowNoTitle">true</item>
+        <!-- 半透明 -->
+        <item name="android:windowIsTranslucent">true</item>
+        <!-- Dialog进入及退出动画 -->
+        <item name="android:windowAnimationStyle">@style/DialogAnimation</item>
+    </style>
+
+</resources>

+ 10 - 0
ApexDrivers/RAUtilsLibrary/src/main/res/values/animation.xml

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <!-- Dialog进出动画 -->
+    <style name="DialogAnimation" parent="@android:style/Animation.Dialog">
+        <item name="android:windowEnterAnimation">@anim/dialog_in</item>
+        <item name="android:windowExitAnimation">@anim/dialog_out</item>
+    </style>
+
+</resources>

+ 25 - 0
ApexDrivers/RAUtilsLibrary/src/main/res/values/basic_dialog_style.xml

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <!--Dialog 样式-->
+
+    <style name="RADialog" parent="@android:style/Theme.Dialog">
+
+        <!-- 背景透明 -->
+        <item name="android:windowBackground">@android:color/transparent</item>
+        <item name="android:windowContentOverlay">@null</item>
+        <!-- 浮于Activity之上 -->
+        <item name="android:windowIsFloating">true</item>
+        <!-- 边框 -->
+        <item name="android:windowFrame">@null</item>
+        <!-- Dialog以外的区域模糊效果 -->
+        <item name="android:backgroundDimEnabled">true</item>
+        <!-- 无标题 -->
+        <item name="android:windowNoTitle">true</item>
+        <!-- 半透明 -->
+        <item name="android:windowIsTranslucent">true</item>
+        <!-- Dialog进入及退出动画 -->
+        <item name="android:windowAnimationStyle">@style/DialogAnimation</item>
+    </style>
+
+</resources>

+ 2 - 0
ApexDrivers/RAUtilsLibrary/src/main/res/values/strings.xml

@@ -44,4 +44,6 @@
 
     <!---->
 
+    <string name="ra_allow_camera_and_storage">please allow app use camera and storage</string>
+
 </resources>

+ 178 - 29
ApexDrivers/apexcrm/src/main/java/com/usai/apex/apexcrm/MainActivity.java

@@ -3,6 +3,7 @@ package com.usai.apex.apexcrm;
 import android.Manifest;
 import android.content.Context;
 import android.content.Intent;
+import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
@@ -10,18 +11,26 @@ import android.support.v4.content.PermissionChecker;
 import android.support.v7.app.AppCompatActivity;
 
 import android.util.Log;
+import android.view.View;
 import android.webkit.ValueCallback;
 import android.widget.Toast;
 
+import com.usai.redant.rautils.actionSheet.ActionSheet;
+import com.usai.redant.rautils.camera.CameraHelper;
+import com.usai.redant.rautils.utils.FileManager;
+import com.usai.redant.rautils.utils.ImageUtil;
+import com.usai.redant.rautils.utils.RAUtil;
 import com.usai.redant.rautils.zxing.codescanner.CaptureActivity;
 
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
 
-import java.util.ArrayList;
+import java.io.File;
+import java.net.URI;
+import java.net.URL;
+
 
-//import android.webkit.WebView;
 public class MainActivity extends AppCompatActivity {
 
     private static final String TAG = "MainActivity";
@@ -31,6 +40,9 @@ public class MainActivity extends AppCompatActivity {
     private RAWebView mWebView;
 
     private static final int REQUEST_SCANNER_CODE = 100;
+    private static final int REQUEST_CAMERA_CODE = 101;
+    private static final int REQUEST_PHOTO_LIBRARY_CODE = 102;
+    private static final int REQUEST_SIGNATURE_CODE = 103;
 
     private static final String CurrentActionStringKey = "CurrentActionStringKey";
     private static final String ExcuteJSArrayKey = "ExcuteJSArrayKey";
@@ -120,35 +132,16 @@ public class MainActivity extends AppCompatActivity {
         Log.d(TAG, "onActivityResult: ");
         if (requestCode == REQUEST_SCANNER_CODE) {
 
-            if (resultCode == RESULT_OK) {
-
-                Bundle bundle = data.getExtras();
-                String pid = bundle.getString("pid");
-
-                Log.d(TAG, "onActivityResult: Scanner Value " + pid);
+            onScannerResult(resultCode, data);
 
-                if (mCurrentActionString != null) {
-                    try {
-                        JSONObject json = new JSONObject(mCurrentActionString);
-                        String js = mJSInterface.returnToWebPage(json, pid);
-                        if (js != null) {
+        } else if (requestCode == REQUEST_CAMERA_CODE) {
 
-                            saveExcuteJS(js);
-
-                            mWebView.evaluateJavascript(js, new ValueCallback<String>() {
-                                @Override
-                                public void onReceiveValue(String value) {
-                                    Log.d(TAG, "onReceiveValue: " + value);
-                                }
-                            });
-                        }
-
-                    } catch (JSONException e) {
-                        e.printStackTrace();
-                    }
-                }
-            }
+            onCameraResult(resultCode, data);
+        } else if (requestCode == REQUEST_PHOTO_LIBRARY_CODE) {
 
+            onPhotoLibraryResult(resultCode, data);
+        } else if (requestCode == REQUEST_SIGNATURE_CODE) {
+            onSignatureResult(resultCode, data);
         }
 
         mCurrentActionString = null;
@@ -185,6 +178,122 @@ public class MainActivity extends AppCompatActivity {
 
     }
 
+    private void checkCameraPermission() {
+
+        String[] permissions = {Manifest.permission.CAMERA,Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE};
+
+        RAUtil.checkPermissions(self,permissions);
+    }
+
+    /**
+     *
+     * Private
+     * */
+
+    private void evaluateCurrentAction(String value) {
+
+        if (mCurrentActionString != null && value != null) {
+            try {
+                JSONObject json = new JSONObject(mCurrentActionString);
+                String js = mJSInterface.returnToWebPage(json, value);
+                if (js != null) {
+
+                    saveExcuteJS(js);
+
+                    mWebView.evaluateJavascript(js, new ValueCallback<String>() {
+                        @Override
+                        public void onReceiveValue(String value) {
+                            Log.d(TAG, "onReceiveValue: " + value);
+                        }
+                    });
+                }
+
+            } catch (JSONException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    private void setImageForPath(String path) {
+        if (path != null) {
+            String imgBase64 = FileManager.base64StringFromFile(path));
+
+            if (imgBase64 != null) {
+                String base64 = String.format("data:image/jpg;base64,%s",imgBase64);
+                evaluateCurrentAction(base64);
+            }
+        }
+    }
+
+    /**
+     * Result
+     * */
+
+    private void onScannerResult(int resultCode, Intent data) {
+
+        if (resultCode == RESULT_OK) {
+
+            Bundle bundle = data.getExtras();
+            String pid = bundle.getString("pid");
+
+            Log.d(TAG, "onActivityResult: Scanner Value " + pid);
+            evaluateCurrentAction(pid);
+        }
+    }
+
+    private void onCameraResult(int resultCode, Intent data) {
+
+        if (resultCode == RESULT_OK) {
+
+            if (mCameraFile != null && mCameraFile.exists()) {
+                mCameraFile = ImageUtil.compressImageFile(self, mCameraFile);
+
+                if (mCameraFile != null) {
+                    self.setImageForPath(mCameraFile.getAbsolutePath());
+                }
+            }
+
+        }
+        mCameraFile = null;
+    }
+
+    private void onPhotoLibraryResult(int resultCode, Intent data) {
+
+        if (resultCode == RESULT_OK) {
+            Uri uri = CameraHelper.getImageUriFromData(data);
+            if (uri != null) {
+                String path = uri.getPath();
+                if (path != null) {
+                    setImageForPath(path);
+                }
+            }
+        }
+    }
+
+    private void onSignatureResult(int resultCode, Intent data) {
+
+        if (resultCode == RESULT_OK) {
+
+        }
+    }
+
+
+    /**
+     * Private Action
+     * */
+
+    private File mCameraFile;
+
+    private void openCamera(String msg) {
+        mCurrentActionString = msg;
+        mCameraFile = CameraHelper.startCamera(self,REQUEST_CAMERA_CODE);
+    }
+
+    private void openPhotoLibrary(String msg) {
+        mCurrentActionString = msg;
+        CameraHelper.pickImageFromAlbum2(self, REQUEST_PHOTO_LIBRARY_CODE);
+    }
+
     /**
      * Action
      * */
@@ -213,7 +322,23 @@ public class MainActivity extends AppCompatActivity {
 
         @Override
         public void Share(String msg) {
+            if (msg != null) {
+                try {
+                    JSONObject json = new JSONObject(msg);
+                    String urlStr = json.getString("url");
+                    URL url = new URL(urlStr);
+
+                    Intent share = new Intent();
+                    share.setAction(Intent.ACTION_SEND);
+                    share.setType("text/plain");
+                    share.putExtra(Intent.EXTRA_STREAM, url);
 
+                    self.startActivity(Intent.createChooser(share, "Share"));
+
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
         }
 
         @Override
@@ -232,13 +357,37 @@ public class MainActivity extends AppCompatActivity {
         }
 
         @Override
-        public void Photo(String msg) {
+        public void Photo(final String msg) {
+
+            ActionSheet actionSheet = new ActionSheet(self);
+            actionSheet.addAction(self.getString(R.string.wb_photo_library_action), ActionSheet.ActionType.ActionTypeDefault, new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    openPhotoLibrary(msg);
+                }
+            });
+
+            actionSheet.addAction(self.getString(R.string.wb_camera_action), ActionSheet.ActionType.ActionTypeDefault, new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    openCamera(msg);
+                }
+            });
+
+            actionSheet.addAction(self.getString(R.string.btn_cancel), ActionSheet.ActionType.ACtionTypeCancel, new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
 
+                }
+            });
+
+            actionSheet.show();
         }
 
         @Override
         public void Email(String msg) {
 
+
         }
 
         @Override

+ 6 - 1
ApexDrivers/apexcrm/src/main/res/values-zh/strings.xml

@@ -1,6 +1,11 @@
 <resources>
     <string name="app_name">Apex CRM</string>
 
-    <string name="allow_camera">请检查相机权限是否打开</string>
+    <string name="btn_cancel">取消</string>
 
+    <string name="allow_camera">请检查相机权限是否打开</string>
+    <string name="wb_photo_library_action">相册</string>
+    <string name="wb_camera_action">相机</string>
+    
+    
 </resources>

+ 4 - 0
ApexDrivers/apexcrm/src/main/res/values/strings.xml

@@ -1,6 +1,10 @@
 <resources>
     <string name="app_name">Apex CRM</string>
 
+    <string name="btn_cancel">Cancel</string>
+
     <string name="allow_camera">please allow app use camera</string>
+    <string name="wb_photo_library_action">Photo Library</string>
+    <string name="wb_camera_action">Camera</string>
 
 </resources>