Commit 456ba80d8333a5f9b76c2a55dcec5881ba29c919

Authored by 陶汉栋
1 parent 1496174c
Exists in master

no message

Showing 166 changed files with 15196 additions and 19 deletions   Show diff stats

Too many changes.

To preserve performance only 100 of 166 files displayed.

.idea/gradle.xml
... ... @@ -9,6 +9,7 @@
9 9 <set>
10 10 <option value="$PROJECT_DIR$" />
11 11 <option value="$PROJECT_DIR$/app" />
  12 + <option value="$PROJECT_DIR$/mvpsdk" />
12 13 </set>
13 14 </option>
14 15 <option name="resolveModulePerSourceSet" value="false" />
... ...
.idea/misc.xml
1 1 <?xml version="1.0" encoding="UTF-8"?>
2 2 <project version="4">
  3 + <component name="NullableNotNullManager">
  4 + <option name="myDefaultNullable" value="android.support.annotation.Nullable" />
  5 + <option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
  6 + <option name="myNullables">
  7 + <value>
  8 + <list size="4">
  9 + <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
  10 + <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
  11 + <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
  12 + <item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
  13 + </list>
  14 + </value>
  15 + </option>
  16 + <option name="myNotNulls">
  17 + <value>
  18 + <list size="4">
  19 + <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
  20 + <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
  21 + <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
  22 + <item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
  23 + </list>
  24 + </value>
  25 + </option>
  26 + </component>
3 27 <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
4 28 <output url="file://$PROJECT_DIR$/build/classes" />
5 29 </component>
... ...
.idea/modules.xml
... ... @@ -4,6 +4,7 @@
4 4 <modules>
5 5 <module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
6 6 <module fileurl="file://$PROJECT_DIR$/expressscanner.iml" filepath="$PROJECT_DIR$/expressscanner.iml" />
  7 + <module fileurl="file://$PROJECT_DIR$/mvpsdk/mvpsdk.iml" filepath="$PROJECT_DIR$/mvpsdk/mvpsdk.iml" />
7 8 </modules>
8 9 </component>
9 10 </project>
10 11 \ No newline at end of file
... ...
app/build.gradle
... ... @@ -19,10 +19,13 @@ android {
19 19 }
20 20  
21 21 dependencies {
22   - implementation fileTree(dir: 'libs', include: ['*.jar'])
  22 + implementation fileTree(include: ['*.jar'], dir: 'libs')
23 23 implementation 'com.android.support:appcompat-v7:26.1.0'
24 24 implementation 'com.android.support.constraint:constraint-layout:1.1.0'
  25 + implementation 'com.android.support:support-v4:26.1.0'
25 26 testImplementation 'junit:junit:4.12'
26 27 androidTestImplementation 'com.android.support.test:runner:1.0.1'
27 28 androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
  29 + implementation project(':mvpsdk')
  30 + implementation files('libs/zkcsdk.jar')
28 31 }
... ...
app/libs/zkcsdk.jar 0 → 100644
No preview for this file type
app/src/main/AndroidManifest.xml
1 1 <?xml version="1.0" encoding="utf-8"?>
2 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3   - package="com.shunzhi.expressscanner" >
  3 + package="com.shunzhi.expressscanner">
  4 +
  5 + <uses-permission android:name="android.permission.INTERNET" />
4 6  
5 7 <application
  8 + android:name=".AppContext"
6 9 android:allowBackup="true"
7 10 android:icon="@mipmap/ic_launcher"
8 11 android:label="@string/app_name"
9 12 android:roundIcon="@mipmap/ic_launcher_round"
10 13 android:supportsRtl="true"
11   - android:theme="@style/AppTheme" >
12   - <activity android:name=".MainActivity" >
  14 + android:theme="@style/AppTheme">
  15 + <activity
  16 + android:name=".MainActivity"
  17 + android:theme="@style/Theme.AppCompat.Light.NoActionBar">
13 18 <intent-filter>
14 19 <action android:name="android.intent.action.MAIN" />
15 20  
16 21 <category android:name="android.intent.category.LAUNCHER" />
17 22 </intent-filter>
18 23 </activity>
  24 + <activity
  25 + android:name=".base.BaseActivity"
  26 + android:label="@string/title_activity_base"
  27 + android:theme="@style/AppTheme.NoActionBar"></activity>
19 28 </application>
20 29  
21 30 </manifest>
22 31 \ No newline at end of file
... ...
app/src/main/java/com/shunzhi/expressscanner/AppConfig.java 0 → 100644
... ... @@ -0,0 +1,57 @@
  1 +package com.shunzhi.expressscanner;
  2 +
  3 +import android.content.Context;
  4 +import android.content.SharedPreferences;
  5 +import android.preference.PreferenceManager;
  6 +import android.text.TextUtils;
  7 +
  8 +/**
  9 + * Created by ToaHanDong on 2018/4/24.
  10 + */
  11 +
  12 +public class AppConfig {
  13 +
  14 +// public static String BASE_URL="http://ecampus.zjyzzx.net/";
  15 +
  16 + public static String BASE_URL="http://60.190.202.57:1000/";
  17 +
  18 + public static String LOGIN_NAME="15305755683";
  19 + public static String LOGIN_PWD="755683";
  20 +
  21 + public static String ACCESS_TOKEN = "access_token";
  22 + public static final String OPEN_SCAN = "open_scan";
  23 + public static String CURRENT_USERID = "current_userid";
  24 + public static String SCHOOL_ID="school_id";
  25 +
  26 + private static AppConfig appConfig = null;
  27 + public static AppConfig getAppConfig() {
  28 + if (appConfig == null) {
  29 + appConfig = new AppConfig();
  30 + }
  31 + return appConfig;
  32 + }
  33 +
  34 + //得到保存的值
  35 + public String get(String key) {
  36 + return getSharedPreferences(AppContext.getContext()).getString(key, null);
  37 + }
  38 +
  39 + private SharedPreferences getSharedPreferences(Context context) {
  40 + return PreferenceManager.getDefaultSharedPreferences(context);
  41 + }
  42 +
  43 + //保存键值对
  44 + public void set(String key, String value) {
  45 + SharedPreferences.Editor editor = getSharedPreferences(AppContext.getContext()).edit();
  46 + if (TextUtils.isEmpty(value)) {
  47 + editor.putString(key, value);
  48 + } else {
  49 + editor.putString(key, value.trim());
  50 + }
  51 + editor.commit();
  52 + }
  53 +
  54 + public boolean getBoolean(String openScan) {
  55 + return true;
  56 + }
  57 +}
... ...
app/src/main/java/com/shunzhi/expressscanner/AppContext.java 0 → 100644
... ... @@ -0,0 +1,19 @@
  1 +package com.shunzhi.expressscanner;
  2 +
  3 +import com.share.mvpsdk.global.GlobalApplication;
  4 +import com.share.mvpsdk.helper.RetrofitCreateHelper;
  5 +
  6 +/**
  7 + * Created by ToaHanDong on 2018/4/24.
  8 + */
  9 +
  10 +public class AppContext extends GlobalApplication {
  11 +
  12 + @Override
  13 + public void onCreate() {
  14 + super.onCreate();
  15 +
  16 + RetrofitCreateHelper.getInstance().setAuthorization(AppConfig.getAppConfig().get(AppConfig.ACCESS_TOKEN));
  17 +
  18 + }
  19 +}
... ...
app/src/main/java/com/shunzhi/expressscanner/MainActivity.java
1 1 package com.shunzhi.expressscanner;
2 2  
  3 +import android.annotation.SuppressLint;
  4 +import android.content.Context;
  5 +import android.media.MediaPlayer;
  6 +import android.os.Message;
  7 +import android.os.RemoteException;
  8 +import android.os.Vibrator;
  9 +import android.support.v4.app.FragmentTransaction;
3 10 import android.support.v7.app.AppCompatActivity;
4 11 import android.os.Bundle;
  12 +import android.widget.FrameLayout;
  13 +import android.widget.Toast;
5 14  
6   -public class MainActivity extends AppCompatActivity {
  15 +import com.share.mvpsdk.base.activity.BaseCompatActivity;
  16 +import com.shunzhi.expressscanner.base.BaseActivity;
  17 +import com.shunzhi.expressscanner.fragment.MainFragment;
  18 +import com.smartdevice.aidl.ICallBack;
  19 +import com.smartdevice.aidl.IZKCService;
  20 +import com.zkc.baseLibrary.MessageType;
  21 +
  22 +public class MainActivity extends BaseCompatActivity {
  23 +
  24 + FrameLayout frame;
  25 +
  26 + FragmentTransaction fragmentTransaction = null;
  27 +
  28 + MainFragment mainFragment;
  29 +
  30 + @Override
  31 + protected void initView(Bundle savedInstanceState) {
  32 +
  33 + frame = findViewById(R.id.frame);
  34 + fragmentTransaction = getSupportFragmentManager().beginTransaction();
  35 + mainFragment = new MainFragment();
  36 + fragmentTransaction.add(R.id.frame, mainFragment)
  37 + .show(mainFragment).commit();
  38 +
  39 + }
7 40  
8 41 @Override
9   - protected void onCreate(Bundle savedInstanceState) {
10   - super.onCreate(savedInstanceState);
11   - setContentView(R.layout.activity_main);
  42 + protected int getLayoutId() {
  43 + return R.layout.activity_main;
12 44 }
13 45 }
... ...
app/src/main/java/com/shunzhi/expressscanner/api/MainApi.java 0 → 100644
... ... @@ -0,0 +1,42 @@
  1 +package com.shunzhi.expressscanner.api;
  2 +
  3 +import com.google.gson.JsonObject;
  4 +
  5 +import io.reactivex.Observable;
  6 +import retrofit2.http.Field;
  7 +import retrofit2.http.FormUrlEncoded;
  8 +import retrofit2.http.GET;
  9 +import retrofit2.http.POST;
  10 +import retrofit2.http.Query;
  11 +
  12 +/**
  13 + * Created by ToaHanDong on 2018/4/24.
  14 + */
  15 +
  16 +public interface MainApi {
  17 +
  18 + @FormUrlEncoded
  19 + @POST("Token")
  20 + Observable<JsonObject> login(@Field("grant_type") String grant_type, @Field("username") String username
  21 + , @Field("password") String password);
  22 +
  23 + @GET("api/NewAssets/IsExpressReceive")
  24 + Observable<JsonObject> getExpressInfo(@Query("ExpressNumber") String expressCode,@Query("schoolid") String schoolId);
  25 +
  26 + @POST("api/Account/CurrentInfo")
  27 + Observable<JsonObject> getCurrentInfo();
  28 +
  29 + @GET("api/NewAssets/SearchExpressPhone")
  30 + Observable<JsonObject> SearchExpressPhone(@Query("moilb") String moilb);
  31 +
  32 + @GET("api/NewAssets/SearchNameByPhone")
  33 + Observable<JsonObject> SearchNameByPhone(@Query("moilb") String moilb);
  34 +
  35 + @GET("api/NewAssets/InsertExpress")
  36 + Observable<JsonObject> InsertExpress(@Query("ExpressNumber") String ExpressNumber,@Query("MoilePhone") String MoilePhone,
  37 + @Query("UserName") String UserName,@Query("schoolId") String schoolId);
  38 +
  39 + @GET("api/NewAssets/UpdateIsReceive")
  40 + Observable<JsonObject> UpdateIsReceive(@Query("ExpressNumber") String ExpressNumber,@Query("schoolId") String schoolId);
  41 +
  42 +}
... ...
app/src/main/java/com/shunzhi/expressscanner/base/BaseActivity.java 0 → 100644
... ... @@ -0,0 +1,77 @@
  1 +package com.shunzhi.expressscanner.base;
  2 +
  3 +import android.content.Context;
  4 +import android.os.Bundle;
  5 +import android.os.Handler;
  6 +import android.os.Message;
  7 +import android.support.design.widget.FloatingActionButton;
  8 +import android.support.design.widget.Snackbar;
  9 +import android.support.v7.app.AppCompatActivity;
  10 +import android.support.v7.widget.Toolbar;
  11 +import android.view.View;
  12 +import android.view.inputmethod.InputMethodManager;
  13 +
  14 +import com.share.mvpsdk.base.activity.BaseCompatActivity;
  15 +import com.shunzhi.expressscanner.R;
  16 +import com.shunzhi.expressscanner.common.MessageCenter;
  17 +import com.smartdevice.aidl.IZKCService;
  18 +import com.zkc.baseLibrary.ZkcManager;
  19 +
  20 +public abstract class BaseActivity extends BaseCompatActivity {
  21 + public static int DEVICE_MODEL = 0;
  22 + public Handler mhanlder;
  23 + public IZKCService mIzkcService = null;
  24 +
  25 + @Override
  26 + protected void onCreate(Bundle savedInstanceState) {
  27 + super.onCreate(savedInstanceState);
  28 + setContentView(getLayoutId());
  29 + MessageCenter.getInstance().addHandler(getHandler());
  30 + initView(savedInstanceState);
  31 + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
  32 + imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
  33 + //创建接口管理者对象 create the object of interface manager
  34 + ZkcManager.getInstance().onCreate(this, mhanlder);
  35 +// Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
  36 +// setSupportActionBar(toolbar);
  37 +//
  38 +// FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
  39 +// fab.setOnClickListener(new View.OnClickListener() {
  40 +// @Override
  41 +// public void onClick(View view) {
  42 +// Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
  43 +// .setAction("Action", null).show();
  44 +// }
  45 +// });
  46 + }
  47 +
  48 + protected void handleStateMessage(Message message) {
  49 + }
  50 +
  51 + /**
  52 + * handler
  53 + */
  54 + protected Handler getHandler() {
  55 + if (mhanlder == null) {
  56 + mhanlder = new Handler() {
  57 + public void handleMessage(Message msg) {
  58 + handleStateMessage(msg);
  59 + }
  60 + };
  61 + }
  62 + return mhanlder;
  63 + }
  64 +
  65 + protected void sendMessage(int what, Object obj) {
  66 + Message message = new Message();
  67 + message.what = what;
  68 + message.obj = obj;
  69 + getHandler().sendMessage(message);
  70 + }
  71 +
  72 + protected abstract void initView(Bundle savedInstanceState);
  73 +
  74 + protected abstract int getLayoutId();
  75 +
  76 +
  77 +}
... ...
app/src/main/java/com/shunzhi/expressscanner/bean/ExpressBean.java 0 → 100644
... ... @@ -0,0 +1,26 @@
  1 +package com.shunzhi.expressscanner.bean;
  2 +
  3 +/**
  4 + * Created by ToaHanDong on 2018/4/24.
  5 + */
  6 +
  7 +public class ExpressBean {
  8 +
  9 + public String expressCode;
  10 +
  11 + public String teacherName;
  12 +
  13 + public String teacherNum;
  14 +
  15 + public int state;//0:未领取 1:已领取 2:未录入
  16 +
  17 + @Override
  18 + public String toString() {
  19 + return "ExpressBean{" +
  20 + "expressCode='" + expressCode + '\'' +
  21 + ", teacherName='" + teacherName + '\'' +
  22 + ", teacherNum='" + teacherNum + '\'' +
  23 + ", state=" + state +
  24 + '}';
  25 + }
  26 +}
... ...
app/src/main/java/com/shunzhi/expressscanner/common/MessageCenter.java 0 → 100644
... ... @@ -0,0 +1,60 @@
  1 +package com.shunzhi.expressscanner.common;
  2 +
  3 +import android.os.Handler;
  4 +import android.os.Message;
  5 +
  6 +import java.util.List;
  7 +import java.util.Vector;
  8 +
  9 +public class MessageCenter {
  10 +
  11 + private List<Handler> mHandlerList = new Vector<Handler>();
  12 + private static MessageCenter CENTER = null;
  13 +
  14 + private MessageCenter() {
  15 +
  16 + }
  17 +
  18 + public static MessageCenter getInstance() {
  19 + if (CENTER == null) {
  20 + CENTER = new MessageCenter();
  21 + }
  22 + return CENTER;
  23 + }
  24 +
  25 + public synchronized void addHandler(Handler handler) {
  26 + mHandlerList.add(handler);
  27 + }
  28 +
  29 + public synchronized void removeHandler(Handler handler) {
  30 + mHandlerList.remove(handler);
  31 + }
  32 +
  33 + public synchronized void sendMessage(int what, Object obj) {
  34 + Message message = new Message();
  35 + message.obj = obj;
  36 + message.what = what;
  37 + sendMessage(message);
  38 + }
  39 +
  40 + public synchronized void sendMessageWithPre(int what, Object obj, int arg1) {
  41 + Message message = new Message();
  42 + message.obj = obj;
  43 + message.arg1 = arg1;
  44 + message.what = what;
  45 + sendMessage(message);
  46 + }
  47 +
  48 + public synchronized void sendMessage(Message message) {
  49 + for (Handler handler : mHandlerList) {
  50 + handler.sendMessage(Message.obtain(message));
  51 + }
  52 + }
  53 +
  54 + public synchronized void sendEmptyMessage(int what) {
  55 + for (Handler handler : mHandlerList) {
  56 + handler.sendEmptyMessage(what);
  57 + }
  58 + }
  59 +
  60 +}
... ...
app/src/main/java/com/shunzhi/expressscanner/contract/MainContract.java 0 → 100644
... ... @@ -0,0 +1,70 @@
  1 +package com.shunzhi.expressscanner.contract;
  2 +
  3 +import com.google.gson.JsonObject;
  4 +import com.share.mvpsdk.base.BasePresenter;
  5 +import com.share.mvpsdk.base.IBaseFragment;
  6 +import com.share.mvpsdk.base.IBaseModel;
  7 +import com.share.mvpsdk.base.IBaseView;
  8 +import com.shunzhi.expressscanner.bean.ExpressBean;
  9 +
  10 +import java.util.List;
  11 +
  12 +import io.reactivex.Observable;
  13 +
  14 +/**
  15 + * Created by ToaHanDong on 2018/4/24.
  16 + */
  17 +
  18 +public interface MainContract {
  19 +
  20 + abstract class MainPresenter extends BasePresenter<IMainModel,IMainView>{
  21 +
  22 + public abstract void login(String loginName,String loginPwd);
  23 +
  24 + public abstract void getExpressInfo(String expressCode);
  25 +
  26 + public abstract void getTeacherName(String tel);
  27 +
  28 + public abstract void upExpressInfo(ExpressBean expressBean);
  29 +
  30 + public abstract void SearchExpressPhone(String mobile);
  31 +
  32 + public abstract void UpdateIsReceive(String ExpressNumber,String schoolId);
  33 +
  34 + }
  35 +
  36 +
  37 + interface IMainModel extends IBaseModel{
  38 +
  39 + Observable<JsonObject> getTeacherName(String tel);
  40 +
  41 + Observable<JsonObject> getExpressInfo(String expressCode,String schoolId);
  42 +
  43 + Observable<JsonObject> login(String logName,String logPwd);
  44 +
  45 + Observable<JsonObject> upExpressInfo(ExpressBean expressBean);
  46 +
  47 + Observable<JsonObject> getCurrentInfo();
  48 +
  49 + Observable<JsonObject> SearchExpressPhone(String mobile);
  50 +
  51 + Observable<JsonObject> UpdateIsReceive(String ExpressNumber,String schoolId);
  52 +
  53 + }
  54 +
  55 + interface IMainView extends IBaseFragment{
  56 +
  57 +
  58 + void showTeacherName(String name);
  59 +
  60 + void showExpressInfo(ExpressBean expressBean);
  61 +
  62 + void showExpressInfoSuccess(boolean isSuccess);
  63 +
  64 + void showSearchModel(List<String> stringList);
  65 +
  66 + void showUpdateIsReceive(boolean isUpdate);
  67 + }
  68 +
  69 +
  70 +}
... ...
app/src/main/java/com/shunzhi/expressscanner/fragment/MainFragment.java 0 → 100644
... ... @@ -0,0 +1,463 @@
  1 +package com.shunzhi.expressscanner.fragment;
  2 +
  3 +import android.annotation.SuppressLint;
  4 +import android.content.Context;
  5 +import android.graphics.drawable.BitmapDrawable;
  6 +import android.media.MediaPlayer;
  7 +import android.os.Bundle;
  8 +import android.os.Handler;
  9 +import android.os.Message;
  10 +import android.os.RemoteException;
  11 +import android.os.Vibrator;
  12 +import android.support.annotation.NonNull;
  13 +import android.support.annotation.Nullable;
  14 +import android.support.v7.widget.LinearLayoutManager;
  15 +import android.support.v7.widget.RecyclerView;
  16 +import android.text.Editable;
  17 +import android.text.TextWatcher;
  18 +import android.view.LayoutInflater;
  19 +import android.view.View;
  20 +import android.view.ViewGroup;
  21 +import android.view.WindowManager;
  22 +import android.widget.Button;
  23 +import android.widget.EditText;
  24 +import android.widget.LinearLayout;
  25 +import android.widget.PopupWindow;
  26 +import android.widget.TextView;
  27 +
  28 +import com.share.mvpsdk.base.BasePresenter;
  29 +import com.share.mvpsdk.base.adapter.BaseRecyclerViewAdapter;
  30 +import com.share.mvpsdk.base.adapter.BaseRecyclerViewHolder;
  31 +import com.share.mvpsdk.base.adapter.OnItemClickListener;
  32 +import com.share.mvpsdk.base.fragment.BaseMVPCompatFragment;
  33 +import com.share.mvpsdk.utils.NetworkConnectionUtils;
  34 +import com.share.mvpsdk.utils.StringUtils;
  35 +import com.share.mvpsdk.utils.ToastUtils;
  36 +import com.shunzhi.expressscanner.AppConfig;
  37 +import com.shunzhi.expressscanner.R;
  38 +import com.shunzhi.expressscanner.bean.ExpressBean;
  39 +import com.shunzhi.expressscanner.contract.MainContract;
  40 +import com.shunzhi.expressscanner.present.MainPresenter;
  41 +import com.smartdevice.aidl.ICallBack;
  42 +import com.smartdevice.aidl.IZKCService;
  43 +import com.zkc.baseLibrary.MessageType;
  44 +import com.zkc.baseLibrary.ZkcManager;
  45 +
  46 +import java.util.List;
  47 +
  48 +/**
  49 + */
  50 +public class MainFragment extends BaseMVPCompatFragment<MainContract.MainPresenter, MainContract.IMainModel> implements MainContract.IMainView
  51 + , View.OnClickListener {
  52 +
  53 + public MainFragment newInstance() {
  54 + MainFragment mainFragment = new MainFragment();
  55 + return mainFragment;
  56 + }
  57 +
  58 + public final int INSERT_SUCCESS = 24;
  59 +
  60 + EditText etExpressCode, etTel, etName;
  61 +
  62 + Button tvCommint, tvCancle;
  63 +
  64 + TextView tvTips;
  65 +
  66 + public IZKCService mIzkcService = null;
  67 +
  68 + MediaPlayer player;
  69 +
  70 + Vibrator vibrator;
  71 +
  72 + public String text = "";
  73 +
  74 + MyPopu myPopu = null;
  75 +
  76 + LinearLayout layout_tel, layout_name, layout_express;
  77 +
  78 + @Override
  79 + public int getLayoutId() {
  80 + return R.layout.fragment_main;
  81 + }
  82 +
  83 + ICallBack.Stub mCallback = new ICallBack.Stub() {
  84 +
  85 + @SuppressLint("MissingPermission")
  86 + @Override
  87 + public void onReturnValue(byte[] buffer, int size)
  88 + throws RemoteException {
  89 + String codeStr = new String(buffer, 0, size);
  90 + text = codeStr;
  91 + player.start();
  92 +// vibrator.vibrate(100);
  93 + Message message = mhanlder.obtainMessage();
  94 + message.what = MessageType.BaiscMessage.SCAN_RESULT_GET_SUCCESS;
  95 + message.obj = text;
  96 + mhanlder.sendMessage(message);
  97 + }
  98 + };
  99 +
  100 + @Override
  101 + public void initUI(View view, @Nullable Bundle savedInstanceState) {
  102 + mPresenter.login(AppConfig.LOGIN_NAME, AppConfig.LOGIN_PWD);
  103 +
  104 + etExpressCode = view.findViewById(R.id.etExpressCode);
  105 + etTel = view.findViewById(R.id.etTel);
  106 + etName = view.findViewById(R.id.etName);
  107 + tvCommint = view.findViewById(R.id.tvCommint);
  108 + tvCancle = view.findViewById(R.id.tvCancle);
  109 + tvTips = view.findViewById(R.id.tvTips);
  110 + layout_tel = view.findViewById(R.id.layout_tel);
  111 + layout_name = view.findViewById(R.id.layout_name);
  112 + layout_express = view.findViewById(R.id.layout_express);
  113 +
  114 + tvCommint.setOnClickListener(this);
  115 + tvCancle.setOnClickListener(this);
  116 + player = MediaPlayer.create(getContext(), R.raw.scan);
  117 + vibrator = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE);
  118 + initZkc();
  119 + if (!NetworkConnectionUtils.isConnected(getContext())){
  120 + ToastUtils.showToast("请连接网络");
  121 + tvTips.setText("网络已断开,请连接网络");
  122 + }
  123 + etTel.addTextChangedListener(new TextWatcher() {
  124 + @Override
  125 + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
  126 +
  127 + }
  128 +
  129 + @Override
  130 + public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
  131 +
  132 + }
  133 +
  134 + @Override
  135 + public void afterTextChanged(Editable editable) {
  136 + if (editable.length() >= 3 && tvCommint.getText().toString().equals("确定录入"))
  137 + mPresenter.SearchExpressPhone(editable.toString());
  138 + }
  139 + });
  140 + }
  141 +
  142 + private void initZkc() {
  143 +
  144 + ZkcManager.getInstance().onCreate(getActivity(), mhanlder);
  145 +
  146 + }
  147 +
  148 + @NonNull
  149 + @Override
  150 + public BasePresenter initPresenter() {
  151 + return new MainPresenter();
  152 + }
  153 +
  154 + /**
  155 + * 扫描快递后,显示快递的状态
  156 + *
  157 + * @param expressBean
  158 + */
  159 + @Override
  160 + public void showExpressInfo(ExpressBean expressBean) {
  161 +
  162 + etExpressCode.setText(text);
  163 + switch (expressBean.state) {
  164 + case 0://未领取
  165 + noImport(expressBean);
  166 + break;
  167 + case 1://已领取
  168 + hasGetExpress(expressBean);
  169 + break;
  170 + case 2://未录入
  171 + insertExpress();
  172 + break;
  173 + }
  174 +
  175 + }
  176 +
  177 + /**
  178 + * 显示教师名字
  179 + *
  180 + * @param name
  181 + */
  182 + @Override
  183 + public void showTeacherName(String name) {
  184 + if (null != myPopu) myPopu.dismiss();
  185 + etName.setText(name);
  186 + tvCommint.setText("确定录入");
  187 + tvTips.setText("提示: 录入快递信息");
  188 + tvCancle.setVisibility(View.VISIBLE);
  189 + etExpressCode.setVisibility(View.VISIBLE);
  190 + etName.setFocusable(false);
  191 + etTel.setFocusable(false);
  192 + etExpressCode.setFocusable(false);
  193 + }
  194 +
  195 + //显示快递录入是否成功
  196 + @Override
  197 + public void showExpressInfoSuccess(boolean isSuccess) {
  198 + if (isSuccess) {
  199 + tvTips.setText("录入成功");
  200 + ToastUtils.showToast("录入成功");
  201 + mhanlder.sendEmptyMessageDelayed(INSERT_SUCCESS, 3000);
  202 + }
  203 + }
  204 +
  205 + /**
  206 + * 模糊查询的手机号
  207 + *
  208 + * @param stringList
  209 + */
  210 + @Override
  211 + public void showSearchModel(List<String> stringList) {
  212 + if (null == myPopu) myPopu = new MyPopu();
  213 + myPopu.showAsDropDown(etTel);
  214 + myPopu.showDatas(stringList);
  215 + //焦点还是要在手机号输入框
  216 + etTel.setFocusable(true);
  217 + }
  218 +
  219 + //显示快递是否领取成功
  220 + @Override
  221 + public void showUpdateIsReceive(boolean isUpdate) {
  222 + if (isUpdate) {
  223 + ToastUtils.showToast("领取成功");
  224 + mhanlder.sendEmptyMessageDelayed(INSERT_SUCCESS, 3000);
  225 + }
  226 + }
  227 +
  228 + @Override
  229 + public void onClick(View view) {
  230 + switch (view.getId()) {
  231 + case R.id.tvCommint:
  232 + String commintText = tvCommint.getText().toString();
  233 + //录入快递
  234 + if (commintText.equals("确定录入")) {
  235 +
  236 + if (!StringUtils.isPhoneNumberValid(etTel.getText().toString())) {
  237 + ToastUtils.showToast("请输入合法的手机号");
  238 + return;
  239 + }
  240 + ExpressBean expressBean = new ExpressBean();
  241 + expressBean.expressCode = etExpressCode.getText().toString();
  242 + expressBean.teacherNum = etTel.getText().toString();
  243 + expressBean.teacherName = etName.getText().toString();
  244 + mPresenter.upExpressInfo(expressBean);
  245 +
  246 + } else if (commintText.equals("确定并扫描快递")) {
  247 +
  248 + try {
  249 + mIzkcService.scan();
  250 + } catch (RemoteException e) {
  251 + e.printStackTrace();
  252 + }
  253 +
  254 + } else if (commintText.equals("领取")) {
  255 + mPresenter.UpdateIsReceive(etExpressCode.getText().toString(), AppConfig.getAppConfig().get(AppConfig.SCHOOL_ID));
  256 + } else if (commintText.equals("确定")) {
  257 + showExpress();
  258 + }
  259 + break;
  260 + case R.id.tvCancle:
  261 + showExpress();
  262 + break;
  263 + }
  264 + }
  265 +
  266 + //显示扫描界面
  267 + private void showExpress() {
  268 + layout_express.setVisibility(View.VISIBLE);
  269 + layout_name.setVisibility(View.INVISIBLE);
  270 + layout_tel.setVisibility(View.INVISIBLE);
  271 + tvCancle.setVisibility(View.GONE);
  272 + etExpressCode.setFocusable(true);
  273 + etName.setFocusable(true);
  274 + etTel.setFocusable(true);
  275 + etExpressCode.setFocusableInTouchMode(true);
  276 + etName.setFocusableInTouchMode(true);
  277 + etTel.setFocusableInTouchMode(true);
  278 + tvCommint.setText("确定并扫描快递");
  279 + etExpressCode.setText("");
  280 + etTel.setText("");
  281 + etName.setText("");
  282 + etExpressCode.setBackground(getResources().getDrawable(R.drawable.shape_edit));
  283 + tvTips.setText("点击扫描快递按钮扫描快递");
  284 + }
  285 +
  286 + /**
  287 + * 已录入
  288 + *
  289 + * @param expressBean
  290 + */
  291 + private void noImport(ExpressBean expressBean) {
  292 + showContents(expressBean);
  293 + tvCommint.setText("领取");
  294 + tvTips.setText("快递未领取,点击领取按钮可领取");
  295 + }
  296 +
  297 + /**
  298 + * 录入快递
  299 + */
  300 + private void insertExpress() {
  301 + layout_express.setVisibility(View.VISIBLE);
  302 + layout_name.setVisibility(View.VISIBLE);
  303 + layout_tel.setVisibility(View.VISIBLE);
  304 + tvCancle.setVisibility(View.VISIBLE);
  305 + etExpressCode.setBackground(getResources().getDrawable(R.drawable.shape_edit));
  306 + etName.setBackground(getResources().getDrawable(R.drawable.shape_edit));
  307 + etTel.setBackground(getResources().getDrawable(R.drawable.shape_edit));
  308 + tvCommint.setText("确定录入");
  309 + tvTips.setText("快递未录入请输入手机号");
  310 + }
  311 +
  312 + //已领取
  313 + private void hasGetExpress(ExpressBean expressBean) {
  314 + showContents(expressBean);
  315 + etExpressCode.setBackground(null);
  316 + etName.setBackground(null);
  317 + etTel.setBackground(null);
  318 + tvCommint.setText("确定");
  319 + tvTips.setText("快递已经被领取");
  320 + }
  321 +
  322 + //显示信息
  323 + private void showContents(ExpressBean expressBean) {
  324 + etExpressCode.setText(expressBean.expressCode);
  325 + etTel.setText(expressBean.teacherNum);
  326 + etName.setText(expressBean.teacherName);
  327 + layout_tel.setVisibility(View.VISIBLE);
  328 + layout_name.setVisibility(View.VISIBLE);
  329 + layout_express.setVisibility(View.VISIBLE);
  330 + etName.setFocusable(false);
  331 + etTel.setFocusable(false);
  332 + etExpressCode.setFocusable(false);
  333 + tvCancle.setVisibility(View.VISIBLE);
  334 + }
  335 +
  336 + Handler mhanlder = new Handler() {
  337 + @Override
  338 + public void handleMessage(Message message) {
  339 + super.handleMessage(message);
  340 + switch (message.what) {
  341 + //服务绑定成功 service bind success
  342 + case MessageType.BaiscMessage.SEVICE_BIND_SUCCESS:
  343 +// Toast.makeText(getContext(), getString(R.string.service_bind_success), Toast.LENGTH_SHORT).show();
  344 + mIzkcService = (IZKCService) message.obj;
  345 + registerCallbackAndInitScan();
  346 + break;
  347 + //服务绑定失败 service bind fail
  348 + case MessageType.BaiscMessage.SEVICE_BIND_FAIL:
  349 +// Toast.makeText(getContext(), getString(R.string.service_bind_fail), Toast.LENGTH_SHORT).show();
  350 + break;
  351 + case MessageType.BaiscMessage.SCAN_RESULT_GET_SUCCESS:
  352 + mPresenter.getExpressInfo(text);
  353 + break;
  354 + case INSERT_SUCCESS:
  355 + showExpress();
  356 + break;
  357 + }
  358 + }
  359 + };
  360 +
  361 + private void registerCallbackAndInitScan() {
  362 + try {
  363 + //设置扫描模块 set up scan module
  364 + mIzkcService.setModuleFlag(4);
  365 + //注册扫描数据回调接口
  366 + mIzkcService.registerCallBack("Scanner", mCallback);
  367 + //打开扫描 open scan
  368 + mIzkcService.openScan(true);
  369 +// btn_scan.setEnabled(true);
  370 + } catch (RemoteException e) {
  371 + e.printStackTrace();
  372 + }
  373 + }
  374 +
  375 + @Override
  376 + public void onDestroy() {
  377 + super.onDestroy();
  378 + try {
  379 + mIzkcService.unregisterCallBack("Scanner", mCallback);
  380 + } catch (RemoteException e) {
  381 + e.printStackTrace();
  382 + }
  383 + }
  384 +
  385 +
  386 + private class MyPopu extends PopupWindow {
  387 +
  388 + RecyclerView recyclerView;
  389 + MyAdapter myAdapter;
  390 +
  391 + public MyPopu() {
  392 +
  393 + View view = LayoutInflater.from(getContext()).inflate(R.layout.popu_mobile, null);
  394 + recyclerView = view.findViewById(R.id.recyclerView);
  395 +
  396 + setWidth(WindowManager.LayoutParams.MATCH_PARENT);
  397 + setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
  398 +
  399 + setFocusable(false);
  400 + setOutsideTouchable(true);
  401 + setBackgroundDrawable(new BitmapDrawable());
  402 +
  403 + setContentView(view);
  404 + update();
  405 + }
  406 +
  407 + public void showDatas(List<String> list) {
  408 + if (null == myAdapter) myAdapter = new MyAdapter();
  409 + if (null == recyclerView.getAdapter()) {
  410 + recyclerView.setAdapter(myAdapter);
  411 + myAdapter.setOnItemClickListener(new OnItemClickListener() {
  412 + @Override
  413 + public void onItemClickListener(Object object, int position) {
  414 + etTel.setText(object.toString());
  415 + mPresenter.getTeacherName(object.toString());
  416 + dismiss();
  417 + }
  418 + });
  419 + }
  420 + myAdapter.addAll(list);
  421 + }
  422 +
  423 + private class MyAdapter extends BaseRecyclerViewAdapter<String> {
  424 +
  425 + @Override
  426 + public void onAttachedToRecyclerView(RecyclerView recyclerView) {
  427 + super.onAttachedToRecyclerView(recyclerView);
  428 + LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
  429 + layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
  430 + recyclerView.setLayoutManager(layoutManager);
  431 + }
  432 +
  433 + @Override
  434 + public BaseRecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
  435 + View view = LayoutInflater.from(getContext()).inflate(R.layout.item_mobile, parent, false);
  436 + return new MyViewholder(view);
  437 + }
  438 +
  439 + private class MyViewholder extends BaseRecyclerViewHolder<String> {
  440 +
  441 + TextView tvName;
  442 +
  443 + public MyViewholder(View itemView) {
  444 + super(itemView);
  445 + tvName = itemView.findViewById(R.id.tvName);
  446 + }
  447 +
  448 + @Override
  449 + public void onBindViewHolder(final String object, final int position) {
  450 + tvName.setText(object);
  451 + tvName.setOnClickListener(new View.OnClickListener() {
  452 + @Override
  453 + public void onClick(View view) {
  454 + onItemClickListener.onItemClickListener(object, position);
  455 + }
  456 + });
  457 + }
  458 + }
  459 + }
  460 +
  461 + }
  462 +
  463 +}
... ...
app/src/main/java/com/shunzhi/expressscanner/model/MainModel.java 0 → 100644
... ... @@ -0,0 +1,70 @@
  1 +package com.shunzhi.expressscanner.model;
  2 +
  3 +import android.util.Log;
  4 +
  5 +import com.google.gson.JsonObject;
  6 +import com.share.mvpsdk.base.BaseModel;
  7 +import com.share.mvpsdk.helper.RetrofitCreateHelper;
  8 +import com.share.mvpsdk.helper.RxHelper;
  9 +import com.shunzhi.expressscanner.AppConfig;
  10 +import com.shunzhi.expressscanner.api.MainApi;
  11 +import com.shunzhi.expressscanner.bean.ExpressBean;
  12 +import com.shunzhi.expressscanner.contract.MainContract;
  13 +
  14 +import io.reactivex.Observable;
  15 +
  16 +/**
  17 + * Created by ToaHanDong on 2018/4/24.
  18 + */
  19 +
  20 +public class MainModel extends BaseModel implements MainContract.IMainModel {
  21 +
  22 +
  23 + public static MainModel newInstance(){
  24 + return new MainModel();
  25 + }
  26 +
  27 + @Override
  28 + public Observable<JsonObject> getTeacherName(String tel) {
  29 + return RetrofitCreateHelper.getInstance().createApi(MainApi.class,AppConfig.BASE_URL)
  30 + .SearchNameByPhone(tel).compose(RxHelper.<JsonObject>rxSchedulerHelper());
  31 + }
  32 +
  33 + @Override
  34 + public Observable<JsonObject> getExpressInfo(String expressCode,String schoolId) {
  35 + return RetrofitCreateHelper.getInstance().createApi(MainApi.class,AppConfig.BASE_URL)
  36 + .getExpressInfo(expressCode,schoolId).compose(RxHelper.<JsonObject>rxSchedulerHelper());
  37 + }
  38 +
  39 + @Override
  40 + public Observable<JsonObject> login(String logName, String logPwd) {
  41 + return RetrofitCreateHelper.getInstance().login(MainApi.class, AppConfig.BASE_URL)
  42 + .login("password",logName,logPwd).compose(RxHelper.<JsonObject>rxSchedulerHelper());
  43 + }
  44 +
  45 + @Override
  46 + public Observable<JsonObject> upExpressInfo(ExpressBean expressBean) {
  47 + String schoolId=AppConfig.getAppConfig().get(AppConfig.SCHOOL_ID);
  48 + return RetrofitCreateHelper.getInstance().createApi(MainApi.class,AppConfig.BASE_URL)
  49 + .InsertExpress(expressBean.expressCode,expressBean.teacherNum,expressBean.teacherName
  50 + ,schoolId).compose(RxHelper.<JsonObject>rxSchedulerHelper());
  51 + }
  52 +
  53 + @Override
  54 + public Observable<JsonObject> getCurrentInfo() {
  55 + return RetrofitCreateHelper.getInstance().createApi(MainApi.class,AppConfig.BASE_URL)
  56 + .getCurrentInfo().compose(RxHelper.<JsonObject>rxSchedulerHelper());
  57 + }
  58 +
  59 + @Override
  60 + public Observable<JsonObject> SearchExpressPhone(String mobile) {
  61 + return RetrofitCreateHelper.getInstance().createApi(MainApi.class,AppConfig.BASE_URL)
  62 + .SearchExpressPhone(mobile).compose(RxHelper.<JsonObject>rxSchedulerHelper());
  63 + }
  64 +
  65 + @Override
  66 + public Observable<JsonObject> UpdateIsReceive(String ExpressNumber, String schoolId) {
  67 + return RetrofitCreateHelper.getInstance().createApi(MainApi.class,AppConfig.BASE_URL)
  68 + .UpdateIsReceive(ExpressNumber,schoolId).compose(RxHelper.<JsonObject>rxSchedulerHelper());
  69 + }
  70 +}
... ...
app/src/main/java/com/shunzhi/expressscanner/present/MainPresenter.java 0 → 100644
... ... @@ -0,0 +1,217 @@
  1 +package com.shunzhi.expressscanner.present;
  2 +
  3 +import android.util.Log;
  4 +
  5 +import com.google.gson.JsonArray;
  6 +import com.google.gson.JsonObject;
  7 +import com.share.mvpsdk.RxManager;
  8 +import com.share.mvpsdk.utils.OkHttpExceptionUtil;
  9 +import com.share.mvpsdk.utils.ToastUtils;
  10 +import com.shunzhi.expressscanner.AppConfig;
  11 +import com.shunzhi.expressscanner.bean.ExpressBean;
  12 +import com.shunzhi.expressscanner.contract.MainContract;
  13 +import com.shunzhi.expressscanner.model.MainModel;
  14 +
  15 +import org.json.JSONObject;
  16 +
  17 +import java.util.ArrayList;
  18 +import java.util.List;
  19 +
  20 +import io.reactivex.functions.Consumer;
  21 +import retrofit2.HttpException;
  22 +import timber.log.Timber;
  23 +
  24 +/**
  25 + * Created by ToaHanDong on 2018/4/24.
  26 + */
  27 +
  28 +public class MainPresenter extends MainContract.MainPresenter {
  29 + @Override
  30 + public MainContract.IMainModel getModel() {
  31 + return MainModel.newInstance();
  32 + }
  33 +
  34 + @Override
  35 + public void onStart() {
  36 +
  37 + }
  38 +
  39 + @Override
  40 + public void login(String loginName, String loginPwd) {
  41 +
  42 + mRxManager.register(mIModel.login(loginName, loginPwd).subscribe(new Consumer<JsonObject>() {
  43 + @Override
  44 + public void accept(JsonObject jsonObject) throws Exception {
  45 + String access_token = jsonObject.get("access_token").getAsString();
  46 + AppConfig.getAppConfig().set(AppConfig.ACCESS_TOKEN, access_token);
  47 + getCurrentInfo();
  48 + }
  49 + }, new Consumer<Throwable>() {
  50 + @Override
  51 + public void accept(Throwable throwable) throws Exception {
  52 + try {
  53 + OkHttpExceptionUtil.handOkHttpException((HttpException) throwable);
  54 + } catch (Exception e) {
  55 + e.printStackTrace();
  56 + }
  57 + }
  58 + }));
  59 +
  60 + }
  61 +
  62 + private void getCurrentInfo() {
  63 +
  64 + mRxManager.register(mIModel.getCurrentInfo().subscribe(new Consumer<JsonObject>() {
  65 + @Override
  66 + public void accept(JsonObject jsonObject) throws Exception {
  67 + if (jsonObject.get("status").getAsInt() == 1) {
  68 + JsonObject data = jsonObject.getAsJsonObject("data");
  69 + AppConfig.getAppConfig().set(AppConfig.CURRENT_USERID, data.get("id").getAsString());
  70 + JsonArray teachClass = data.getAsJsonArray("teachClass");
  71 + if (teachClass.size() > 0) {
  72 + JsonObject jsonObject1 = teachClass.get(0).getAsJsonObject();
  73 + AppConfig.getAppConfig().set(AppConfig.SCHOOL_ID, jsonObject1.get("schoolId").getAsString());
  74 + }
  75 + }
  76 + }
  77 + }, new Consumer<Throwable>() {
  78 + @Override
  79 + public void accept(Throwable throwable) throws Exception {
  80 + Log.d("55555", "getCurrentInfo=" + throwable.toString());
  81 + }
  82 + }));
  83 +
  84 + }
  85 +
  86 + @Override
  87 + public void getExpressInfo(String expressCode) {
  88 +
  89 + String scholId = AppConfig.getAppConfig().get(AppConfig.SCHOOL_ID);
  90 + mRxManager.register(mIModel.getExpressInfo(expressCode, scholId).subscribe(new Consumer<JsonObject>() {
  91 + @Override
  92 + public void accept(JsonObject jsonObject) throws Exception {
  93 + if (jsonObject.get("status").getAsInt() == 1) {
  94 + JsonArray jsonArray = jsonObject.getAsJsonArray("data");
  95 + ExpressBean expressBean = new ExpressBean();
  96 + if (jsonArray.size() > 0) {
  97 + JsonObject exoressBeanObj = jsonArray.get(0).getAsJsonObject();
  98 + expressBean.teacherName = exoressBeanObj.get("userName").getAsString();
  99 + expressBean.teacherNum = exoressBeanObj.get("moilePhone").getAsString();
  100 + expressBean.expressCode = exoressBeanObj.get("expressNumber").getAsString();
  101 + expressBean.state = exoressBeanObj.get("state").getAsInt();
  102 + } else {//未录入快递
  103 + expressBean.state = 2;
  104 + }
  105 + mIView.showExpressInfo(expressBean);
  106 + }
  107 + Log.d("55555", "getExpressInfo=" + jsonObject.toString());
  108 + }
  109 + }, new Consumer<Throwable>() {
  110 + @Override
  111 + public void accept(Throwable throwable) throws Exception {
  112 + Log.d("55555", "getExpressInfo=" + throwable.toString());
  113 + }
  114 + }));
  115 +
  116 + }
  117 +
  118 + @Override
  119 + public void getTeacherName(String tel) {
  120 + mRxManager.register(mIModel.getTeacherName(tel).subscribe(new Consumer<JsonObject>() {
  121 + @Override
  122 + public void accept(JsonObject jsonObject) throws Exception {
  123 + try {
  124 +
  125 + if (jsonObject.get("status").getAsInt() == 1) {
  126 + JsonObject data = jsonObject.getAsJsonObject("data");
  127 + mIView.showTeacherName(data.get("userName").getAsString());
  128 + } else ToastUtils.showToast(jsonObject.get("message").getAsString());
  129 +
  130 + } catch (Exception e) {
  131 + e.printStackTrace();
  132 + }
  133 + }
  134 + }, new Consumer<Throwable>() {
  135 + @Override
  136 + public void accept(Throwable throwable) throws Exception {
  137 +
  138 + }
  139 + }));
  140 + }
  141 +
  142 + //录入快递
  143 + @Override
  144 + public void upExpressInfo(ExpressBean expressBean) {
  145 + mRxManager.register(mIModel.upExpressInfo(expressBean).subscribe(new Consumer<JsonObject>() {
  146 + @Override
  147 + public void accept(JsonObject jsonObject) throws Exception {
  148 + try {
  149 + if (jsonObject.get("status").getAsInt() == 1) {
  150 + mIView.showExpressInfoSuccess(true);
  151 + } else ToastUtils.showToast(jsonObject.get("message").getAsString());
  152 + } catch (Exception e) {
  153 + e.printStackTrace();
  154 + }
  155 + }
  156 + }, new Consumer<Throwable>() {
  157 + @Override
  158 + public void accept(Throwable throwable) throws Exception {
  159 +// Log.d("55555","upExpressInfo="+throwable.toString());
  160 + }
  161 + }));
  162 + }
  163 +
  164 + @Override
  165 + public void SearchExpressPhone(String mobile) {
  166 + mRxManager.register(mIModel.SearchExpressPhone(mobile).subscribe(new Consumer<JsonObject>() {
  167 + @Override
  168 + public void accept(JsonObject jsonObject) throws Exception {
  169 + try {
  170 + Log.d("55555","SearchExpressPhone="+jsonObject.toString());
  171 + if (jsonObject.get("status").getAsInt() == 1) {
  172 + List<String> list = new ArrayList<>();
  173 + JsonArray data = jsonObject.getAsJsonArray("data");
  174 + for (int i = 0; i < data.size(); i++) {
  175 + JsonObject jsonObject1 = data.get(i).getAsJsonObject();
  176 + list.add(jsonObject1.get("moilePhone").getAsString());
  177 + }
  178 + mIView.showSearchModel(list);
  179 + } else ToastUtils.showToast(jsonObject.get("message").getAsString());
  180 + } catch (Exception e) {
  181 + e.printStackTrace();
  182 + }
  183 + }
  184 + }, new Consumer<Throwable>() {
  185 + @Override
  186 + public void accept(Throwable throwable) throws Exception {
  187 + Log.d("55555","SearchExpressPhone="+throwable.toString());
  188 + }
  189 + }));
  190 + }
  191 +
  192 + /**
  193 + * 领取快递
  194 + * @param ExpressNumber
  195 + * @param schoolId
  196 + */
  197 + @Override
  198 + public void UpdateIsReceive(String ExpressNumber, String schoolId) {
  199 + mRxManager.register(mIModel.UpdateIsReceive(ExpressNumber,schoolId).subscribe(new Consumer<JsonObject>() {
  200 + @Override
  201 + public void accept(JsonObject jsonObject) throws Exception {
  202 + try {
  203 + if (jsonObject.get("status").getAsInt()==1){
  204 + mIView.showUpdateIsReceive(true);
  205 + }else ToastUtils.showToast(jsonObject.get("message").getAsString());
  206 + }catch (Exception e){
  207 + e.printStackTrace();
  208 + }
  209 + }
  210 + }, new Consumer<Throwable>() {
  211 + @Override
  212 + public void accept(Throwable throwable) throws Exception {
  213 + ToastUtils.showToast(throwable.toString());
  214 + }
  215 + }));
  216 + }
  217 +}
... ...
app/src/main/res/drawable/selector_btn.xml 0 → 100644
... ... @@ -0,0 +1,7 @@
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<selector xmlns:android="http://schemas.android.com/apk/res/android">
  3 +
  4 + <item android:state_pressed="true" android:drawable="@drawable/shape_gray"/>
  5 + <item android:drawable="@drawable/shape_blue"/>
  6 +
  7 +</selector>
0 8 \ No newline at end of file
... ...
app/src/main/res/drawable/shape_blue.xml 0 → 100644
... ... @@ -0,0 +1,7 @@
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<shape xmlns:android="http://schemas.android.com/apk/res/android">
  3 +
  4 + <corners android:radius="@dimen/dp_8"/>
  5 + <solid android:color="@color/md_light_blue_500"/>
  6 +
  7 +</shape>
0 8 \ No newline at end of file
... ...
app/src/main/res/drawable/shape_edit.xml 0 → 100644
... ... @@ -0,0 +1,8 @@
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<shape xmlns:android="http://schemas.android.com/apk/res/android">
  3 +
  4 + <corners android:radius="@dimen/dp_8"/>
  5 +
  6 + <stroke android:color="@color/gray" android:width="1dp"/>
  7 +
  8 +</shape>
0 9 \ No newline at end of file
... ...
app/src/main/res/drawable/shape_gray.xml 0 → 100644
... ... @@ -0,0 +1,5 @@
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<shape xmlns:android="http://schemas.android.com/apk/res/android">
  3 + <corners android:radius="@dimen/dp_8"/>
  4 + <solid android:color="@color/gray"/>
  5 +</shape>
0 6 \ No newline at end of file
... ...
app/src/main/res/layout/activity_base.xml 0 → 100644
... ... @@ -0,0 +1,33 @@
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3 + xmlns:app="http://schemas.android.com/apk/res-auto"
  4 + xmlns:tools="http://schemas.android.com/tools"
  5 + android:layout_width="match_parent"
  6 + android:layout_height="match_parent"
  7 + tools:context="com.shunzhi.expressscanner.base.BaseActivity">
  8 +
  9 + <android.support.design.widget.AppBarLayout
  10 + android:layout_width="match_parent"
  11 + android:layout_height="wrap_content"
  12 + android:theme="@style/AppTheme.AppBarOverlay">
  13 +
  14 + <android.support.v7.widget.Toolbar
  15 + android:id="@+id/toolbar"
  16 + android:layout_width="match_parent"
  17 + android:layout_height="?attr/actionBarSize"
  18 + android:background="?attr/colorPrimary"
  19 + app:popupTheme="@style/AppTheme.PopupOverlay" />
  20 +
  21 + </android.support.design.widget.AppBarLayout>
  22 +
  23 + <include layout="@layout/content_base" />
  24 +
  25 + <android.support.design.widget.FloatingActionButton
  26 + android:id="@+id/fab"
  27 + android:layout_width="wrap_content"
  28 + android:layout_height="wrap_content"
  29 + android:layout_gravity="bottom|end"
  30 + android:layout_margin="@dimen/fab_margin"
  31 + app:srcCompat="@android:drawable/ic_dialog_email" />
  32 +
  33 +</android.support.design.widget.CoordinatorLayout>
... ...
app/src/main/res/layout/activity_main.xml
1 1 <?xml version="1.0" encoding="utf-8"?>
2   -<android.support.constraint.ConstraintLayout
  2 +<FrameLayout
3 3 xmlns:android="http://schemas.android.com/apk/res/android"
4 4 xmlns:tools="http://schemas.android.com/tools"
5 5 xmlns:app="http://schemas.android.com/apk/res-auto"
6 6 android:layout_width="match_parent"
7 7 android:layout_height="match_parent"
  8 + android:id="@+id/frame"
8 9 tools:context="com.shunzhi.expressscanner.MainActivity">
9 10  
10   - <TextView
11   - android:layout_width="wrap_content"
12   - android:layout_height="wrap_content"
13   - android:text="Hello World!"
14   - app:layout_constraintBottom_toBottomOf="parent"
15   - app:layout_constraintLeft_toLeftOf="parent"
16   - app:layout_constraintRight_toRightOf="parent"
17   - app:layout_constraintTop_toTopOf="parent" />
18 11  
19   -</android.support.constraint.ConstraintLayout>
  12 +</FrameLayout>
... ...
app/src/main/res/layout/content_base.xml 0 → 100644
... ... @@ -0,0 +1,11 @@
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3 + xmlns:app="http://schemas.android.com/apk/res-auto"
  4 + xmlns:tools="http://schemas.android.com/tools"
  5 + android:layout_width="match_parent"
  6 + android:layout_height="match_parent"
  7 + app:layout_behavior="@string/appbar_scrolling_view_behavior"
  8 + tools:context="com.shunzhi.expressscanner.base.BaseActivity"
  9 + tools:showIn="@layout/activity_base">
  10 +
  11 +</android.support.constraint.ConstraintLayout>
... ...
app/src/main/res/layout/fragment_main.xml 0 → 100644
... ... @@ -0,0 +1,180 @@
  1 +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2 + xmlns:tools="http://schemas.android.com/tools"
  3 + android:layout_width="match_parent"
  4 + android:layout_height="match_parent"
  5 + android:background="@color/white"
  6 + tools:context="com.shunzhi.expressscanner.fragment.MainFragment">
  7 +
  8 +
  9 + <LinearLayout
  10 + android:layout_width="match_parent"
  11 + android:layout_height="wrap_content"
  12 + android:layout_gravity="center"
  13 + android:layout_marginBottom="@dimen/dp_60"
  14 + android:orientation="vertical">
  15 +
  16 + <LinearLayout
  17 + android:layout_width="match_parent"
  18 + android:gravity="center"
  19 + android:layout_height="wrap_content"
  20 + android:orientation="vertical"
  21 + >
  22 + <TextView
  23 + android:layout_width="wrap_content"
  24 + android:layout_height="wrap_content"
  25 + android:layout_marginBottom="@dimen/dp_10"
  26 + android:text="快递管理系统"
  27 + android:textColor="@color/text_color_dark"
  28 + android:textSize="@dimen/sp_20" />
  29 +
  30 +
  31 + <LinearLayout
  32 + android:id="@+id/layout_express"
  33 + android:layout_width="match_parent"
  34 + android:layout_height="wrap_content"
  35 + android:layout_marginLeft="10dp"
  36 + android:layout_marginRight="10dp"
  37 + android:layout_marginTop="@dimen/dp_10"
  38 + android:gravity="center">
  39 +
  40 + <TextView
  41 + android:layout_width="0dp"
  42 + android:layout_height="wrap_content"
  43 + android:layout_weight="1"
  44 + android:gravity="right"
  45 + android:text="快递号:"
  46 + android:textColor="@color/text_color_dark"
  47 + android:textSize="@dimen/sp_14" />
  48 +
  49 + <EditText
  50 + android:id="@+id/etExpressCode"
  51 + android:layout_width="0dp"
  52 + android:layout_height="@dimen/avatarSize"
  53 + android:layout_marginLeft="@dimen/dp_10"
  54 + android:layout_weight="5"
  55 + android:background="@drawable/shape_edit"
  56 + android:hint="快递单号"
  57 + android:maxLines="1"
  58 + android:paddingLeft="@dimen/dp_5"
  59 + android:singleLine="true"
  60 + android:textColor="@color/text_color_dark"
  61 + android:textColorHint="@color/gray"
  62 + android:textSize="@dimen/sp_14" />
  63 +
  64 + </LinearLayout>
  65 +
  66 + <LinearLayout
  67 + android:id="@+id/layout_tel"
  68 + android:layout_width="match_parent"
  69 + android:layout_height="wrap_content"
  70 + android:layout_marginLeft="10dp"
  71 + android:layout_marginRight="10dp"
  72 + android:layout_marginTop="@dimen/dp_10"
  73 + android:gravity="center"
  74 + android:visibility="invisible">
  75 +
  76 + <TextView
  77 + android:layout_width="0dp"
  78 + android:layout_height="wrap_content"
  79 + android:layout_weight="1"
  80 + android:gravity="right"
  81 + android:text="手机号:"
  82 + android:textColor="@color/text_color_dark"
  83 + android:textSize="@dimen/sp_14" />
  84 +
  85 + <EditText
  86 + android:id="@+id/etTel"
  87 + android:layout_width="0dp"
  88 + android:layout_height="@dimen/avatarSize"
  89 + android:layout_marginLeft="@dimen/dp_10"
  90 + android:layout_weight="5"
  91 + android:paddingLeft="@dimen/dp_5"
  92 + android:background="@drawable/shape_edit"
  93 + android:hint="请输入11位手机号"
  94 + android:maxLines="1"
  95 + android:singleLine="true"
  96 + android:textColor="@color/text_color_dark"
  97 + android:textColorHint="@color/gray"
  98 + android:textSize="@dimen/sp_14" />
  99 +
  100 + </LinearLayout>
  101 +
  102 + <LinearLayout
  103 + android:id="@+id/layout_name"
  104 + android:layout_width="match_parent"
  105 + android:layout_height="wrap_content"
  106 + android:layout_marginLeft="10dp"
  107 + android:layout_marginRight="10dp"
  108 + android:layout_marginTop="@dimen/dp_10"
  109 + android:gravity="center"
  110 + android:visibility="invisible">
  111 +
  112 + <TextView
  113 + android:layout_width="0dp"
  114 + android:layout_height="wrap_content"
  115 + android:layout_weight="1"
  116 + android:gravity="right"
  117 + android:text="姓名:"
  118 + android:textColor="@color/text_color_dark"
  119 + android:textSize="@dimen/sp_14" />
  120 +
  121 + <EditText
  122 + android:id="@+id/etName"
  123 + android:layout_width="0dp"
  124 + android:layout_height="@dimen/avatarSize"
  125 + android:layout_marginLeft="@dimen/dp_10"
  126 + android:layout_weight="5"
  127 + android:paddingLeft="@dimen/dp_5"
  128 + android:background="@drawable/shape_edit"
  129 + android:hint="无需输入,根据号码显示姓名"
  130 + android:maxLines="1"
  131 + android:singleLine="true"
  132 + android:textColor="@color/gray"
  133 + android:textColorHint="@color/gray"
  134 + android:textSize="@dimen/sp_14" />
  135 +
  136 + </LinearLayout>
  137 +
  138 + <Button
  139 + android:id="@+id/tvCommint"
  140 + android:layout_width="match_parent"
  141 + android:layout_height="wrap_content"
  142 + android:layout_marginLeft="@dimen/dp_10"
  143 + android:layout_marginRight="@dimen/dp_10"
  144 + android:layout_marginTop="@dimen/dp_30"
  145 + android:background="@drawable/selector_btn"
  146 + android:gravity="center"
  147 + android:text="确定并扫描快递"
  148 + android:textColor="@color/white"
  149 + android:textSize="@dimen/sp_16" />
  150 +
  151 + </LinearLayout>
  152 + <Button
  153 + android:id="@+id/tvCancle"
  154 + android:layout_width="match_parent"
  155 + android:layout_height="wrap_content"
  156 + android:layout_marginLeft="@dimen/dp_10"
  157 + android:layout_marginRight="@dimen/dp_10"
  158 + android:layout_marginTop="@dimen/dp_10"
  159 + android:background="@drawable/shape_gray"
  160 + android:gravity="center"
  161 + android:text="取消"
  162 + android:textColor="@color/white"
  163 + android:textSize="@dimen/sp_16"
  164 + android:visibility="gone" />
  165 +
  166 +
  167 + </LinearLayout>
  168 +
  169 + <TextView
  170 + android:id="@+id/tvTips"
  171 + android:layout_width="wrap_content"
  172 + android:layout_height="wrap_content"
  173 + android:layout_gravity="bottom|center"
  174 + android:layout_marginBottom="60dp"
  175 + android:text="提示:请扫描快递"
  176 + android:textColor="@color/md_red_500"
  177 + android:textSize="@dimen/sp_14" />
  178 +
  179 +
  180 +</FrameLayout>
... ...
app/src/main/res/layout/item_mobile.xml 0 → 100644
... ... @@ -0,0 +1,26 @@
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3 + android:layout_width="match_parent"
  4 + android:layout_height="?android:actionBarSize">
  5 +
  6 + <TextView
  7 + android:layout_width="match_parent"
  8 + android:layout_height="match_parent"
  9 + android:textColor="@color/text_color_dark"
  10 + android:textSize="@dimen/sp_14"
  11 + android:gravity="center_vertical"
  12 + android:layout_gravity="center_vertical"
  13 + android:paddingLeft="15dp"
  14 + android:id="@+id/tvName"
  15 + />
  16 +
  17 + <View
  18 + android:layout_width="match_parent"
  19 + android:layout_height="0.5dp"
  20 + android:layout_gravity="bottom"
  21 + android:background="@color/gray"
  22 + android:layout_marginLeft="@dimen/dp_10"
  23 + android:layout_marginRight="@dimen/dp_10"
  24 + />
  25 +
  26 +</FrameLayout>
0 27 \ No newline at end of file
... ...
app/src/main/res/layout/popu_mobile.xml 0 → 100644
... ... @@ -0,0 +1,14 @@
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3 + android:layout_width="match_parent"
  4 + android:layout_marginLeft="10dp"
  5 + android:layout_marginRight="10dp"
  6 + android:background="@color/white"
  7 + android:layout_height="match_parent">
  8 +
  9 + <android.support.v7.widget.RecyclerView
  10 + android:id="@+id/recyclerView"
  11 + android:layout_width="match_parent"
  12 + android:layout_height="match_parent"></android.support.v7.widget.RecyclerView>
  13 +
  14 +</LinearLayout>
0 15 \ No newline at end of file
... ...
app/src/main/res/raw/beep.ogg 0 → 100644
No preview for this file type
app/src/main/res/raw/scan.ogg 0 → 100644
No preview for this file type
app/src/main/res/values/dimens.xml 0 → 100644
... ... @@ -0,0 +1,3 @@
  1 +<resources>
  2 + <dimen name="fab_margin">16dp</dimen>
  3 +</resources>
... ...
app/src/main/res/values/strings.xml
1 1 <resources>
2 2 <string name="app_name">ExpressScanner</string>
  3 +
  4 + <!-- TODO: Remove or change this placeholder text -->
  5 + <string name="hello_blank_fragment">Hello blank fragment</string>
  6 + <string name="title_activity_base">BaseActivity</string>
  7 + <string name="service_bind_success">服务绑定成功</string>
  8 + <string name="service_bind_fail">服务绑定失败</string>
3 9 </resources>
... ...
app/src/main/res/values/styles.xml
... ... @@ -8,4 +8,13 @@
8 8 <item name="colorAccent">@color/colorAccent</item>
9 9 </style>
10 10  
  11 + <style name="AppTheme.NoActionBar">
  12 + <item name="windowActionBar">false</item>
  13 + <item name="windowNoTitle">true</item>
  14 + </style>
  15 +
  16 + <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
  17 +
  18 + <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
  19 +
11 20 </resources>
... ...
build.gradle
... ... @@ -19,9 +19,49 @@ allprojects {
19 19 repositories {
20 20 google()
21 21 jcenter()
  22 + maven { url 'https://jitpack.io' }
22 23 }
23 24 }
24 25  
25 26 task clean(type: Delete) {
26 27 delete rootProject.buildDir
27 28 }
  29 +
  30 +
  31 +ext {
  32 + // Sdk and tools
  33 + minSdkVersion = 16
  34 + targetSdkVersion = 26
  35 + compileSdkVersion = 26
  36 + buildToolsVersion = '26.0.2'
  37 +
  38 + // App dependencies
  39 + supportLibraryVersion = '26.1.0'
  40 + guavaVersion = '18.0'
  41 + junitVersion = '4.12'
  42 + mockitoVersion = '1.10.19'
  43 + powerMockito = '1.6.2'
  44 + hamcrestVersion = '1.3'
  45 + runnerVersion = '0.4.1'
  46 + rulesVersion = '0.4.1'
  47 + espressoVersion = '2.2.1'
  48 + retrofitVersion = '2.2.0'
  49 + okhttploggingVersion = '3.4.1'
  50 + okhttpVersion = '3.4.1'
  51 + rxjavaVersion = '2.0.1'
  52 + rxandroidVersion = '2.0.1'
  53 + rxbindingVersion = '2.0.0'
  54 + rxPerssionsVersion = '0.9.4@aar'
  55 + glideVersion = '3.6.1'
  56 + glideokhttpVersion = '1.3.1'
  57 + photoviewVersion = '1.2.4'
  58 + butterknifeVersion = '8.4.0'
  59 + fragmentationVersion = '1.1.6'
  60 + loggerVersion = '1.15'
  61 + circleImageviewVersion = '2.1.0'
  62 + BaseRecyclerViewAdapterHelperVersion = '2.9.34'
  63 + SwtichButtonVersion = '1.4.6'
  64 + PhotoViewVersion = '1.4.1'
  65 + BottomSheetVersion = '1.3.0@aar'
  66 + glideTransformationVersion = '2.0.1'
  67 +}
... ...
mvpsdk/.gitignore 0 → 100644
... ... @@ -0,0 +1 @@
  1 +/build
... ...
mvpsdk/build.gradle 0 → 100644
... ... @@ -0,0 +1,129 @@
  1 +apply plugin: 'com.android.library'
  2 +
  3 +android {
  4 + compileSdkVersion rootProject.ext.compileSdkVersion
  5 + buildToolsVersion rootProject.ext.buildToolsVersion
  6 +
  7 +
  8 + defaultConfig {
  9 + minSdkVersion rootProject.ext.minSdkVersion
  10 + targetSdkVersion rootProject.ext.targetSdkVersion
  11 + versionCode 1
  12 + versionName "1.0"
  13 +
  14 + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
  15 +
  16 + }
  17 +
  18 + buildTypes {
  19 + def BOOLEAN = "boolean"
  20 + def TRUE = "true"
  21 + def FALSE = "false"
  22 + def IS_SHOW_LOG = "IS_SHOW_LOG"
  23 +
  24 + release {
  25 + minifyEnabled false
  26 + buildConfigField BOOLEAN, IS_SHOW_LOG, FALSE
  27 + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
  28 + }
  29 + }
  30 + publishNonDefault true
  31 +}
  32 +//repositories {
  33 +// flatDir {
  34 +// dirs 'libs' //this way we can find the .aar file in libs folder
  35 +// }
  36 +// google()
  37 +//}
  38 +dependencies {
  39 + implementation fileTree(dir: 'libs', include: ['*.jar'])
  40 +
  41 + implementation 'com.android.support:appcompat-v7:26.1.0'
  42 + implementation 'com.android.support.constraint:constraint-layout:1.0.2'
  43 + testImplementation 'junit:junit:4.12'
  44 + androidTestImplementation 'com.android.support.test:runner:1.0.1'
  45 + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
  46 +
  47 + // Android support
  48 + compile "com.android.support:appcompat-v7:$rootProject.supportLibraryVersion"
  49 + compile "com.android.support:cardview-v7:$rootProject.supportLibraryVersion"
  50 + compile "com.android.support:design:$rootProject.supportLibraryVersion"
  51 + compile "com.android.support:recyclerview-v7:$rootProject.supportLibraryVersion"
  52 +
  53 + //delete
  54 + compile 'com.yanzhenjie:recyclerview-swipe:1.1.4'
  55 +
  56 + // Retrofit
  57 + compile "com.squareup.retrofit2:retrofit:$rootProject.retrofitVersion"
  58 + compile "com.squareup.retrofit2:converter-gson:$rootProject.retrofitVersion"
  59 + compile "com.squareup.retrofit2:adapter-rxjava2:$rootProject.retrofitVersion"
  60 + compile "com.squareup.okhttp3:logging-interceptor:$rootProject.okhttploggingVersion"
  61 + compile "com.squareup.okhttp3:okhttp:$rootProject.okhttpVersion"
  62 +
  63 + // RxJava
  64 + compile "io.reactivex.rxjava2:rxjava:$rootProject.rxjavaVersion"
  65 + compile "io.reactivex.rxjava2:rxandroid:$rootProject.rxandroidVersion"
  66 + compile "com.jakewharton.rxbinding2:rxbinding:$rootProject.rxbindingVersion"
  67 +
  68 + // Glide
  69 + compile "com.github.bumptech.glide:glide:$rootProject.glideVersion"
  70 + compile "com.github.bumptech.glide:okhttp-integration:$rootProject.glideokhttpVersion"
  71 + compile "jp.wasabeef:glide-transformations:$rootProject.glideTransformationVersion"
  72 +
  73 + //Butterknife
  74 + compile "com.jakewharton:butterknife:$rootProject.butterknifeVersion"
  75 + annotationProcessor 'com.jakewharton:butterknife-compiler:8.4.0'
  76 +
  77 + //fragmentation
  78 + compile "me.yokeyword:fragmentation:$rootProject.fragmentationVersion"
  79 +
  80 + //Logger
  81 + compile "com.orhanobut:logger:$rootProject.loggerVersion"
  82 +
  83 + //circle imageview
  84 + compile "de.hdodenhof:circleimageview:$rootProject.circleImageviewVersion"
  85 +
  86 + //BaseRecyclerViewAdapterHelper
  87 + compile "com.github.CymChad:BaseRecyclerViewAdapterHelper:$rootProject.BaseRecyclerViewAdapterHelperVersion"
  88 +
  89 + //SwitchButton
  90 + compile "com.kyleduo.switchbutton:library:$rootProject.SwtichButtonVersion"
  91 +
  92 + //PhotoView
  93 + compile "com.bm.photoview:library:$rootProject.PhotoViewVersion"
  94 +
  95 + compile "com.cocosw:bottomsheet:$rootProject.BottomSheetVersion"
  96 +
  97 + //permissions
  98 + compile "com.tbruyelle.rxpermissions2:rxpermissions:$rootProject.rxPerssionsVersion"
  99 +
  100 + //timber
  101 + compile 'com.jakewharton.timber:timber:4.5.1'
  102 +
  103 + //jiaozivideoplayer
  104 + compile 'cn.jzvd:jiaozivideoplayer:6.2.7'
  105 +// compile(name: 'jiaozivideoplayer-6.2.3', ext: 'aar')
  106 +
  107 + //轮播图XBanner
  108 + compile 'com.xhb:xbanner:1.3.1'
  109 +
  110 + //省市区联动
  111 + compile 'me.leefeng:citypicker:1.0'
  112 +
  113 + //日历控件
  114 + compile 'com.github.idic779:monthweekmaterialcalendarview:1.7'
  115 +
  116 + //标签拖动排序
  117 + compile 'com.huxq17.handygridview:handygridview:1.1.0'
  118 +
  119 + //xrecyclerview
  120 + compile 'com.jcodecraeer:xrecyclerview:1.5.9'
  121 +
  122 + //悬浮窗
  123 +// compile 'com.github.yhaolpz:FloatWindow:1.0.8'
  124 +//数据库
  125 + compile 'com.j256.ormlite:ormlite-core:4.48'
  126 + compile 'com.j256.ormlite:ormlite-android:4.48'
  127 +
  128 +
  129 +}
... ...
mvpsdk/proguard-rules.pro 0 → 100644
... ... @@ -0,0 +1,21 @@
  1 +# Add project specific ProGuard rules here.
  2 +# You can control the set of applied configuration files using the
  3 +# proguardFiles setting in build.gradle.
  4 +#
  5 +# For more details, see
  6 +# http://developer.android.com/guide/developing/tools/proguard.html
  7 +
  8 +# If your project uses WebView with JS, uncomment the following
  9 +# and specify the fully qualified class name to the JavaScript interface
  10 +# class:
  11 +#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
  12 +# public *;
  13 +#}
  14 +
  15 +# Uncomment this to preserve the line number information for
  16 +# debugging stack traces.
  17 +#-keepattributes SourceFile,LineNumberTable
  18 +
  19 +# If you keep the line number information, uncomment this to
  20 +# hide the original source file name.
  21 +#-renamesourcefileattribute SourceFile
... ...
mvpsdk/src/androidTest/java/com/share/mvpsdk/ExampleInstrumentedTest.java 0 → 100644
... ... @@ -0,0 +1,26 @@
  1 +package com.share.mvpsdk;
  2 +
  3 +import android.content.Context;
  4 +import android.support.test.InstrumentationRegistry;
  5 +import android.support.test.runner.AndroidJUnit4;
  6 +
  7 +import org.junit.Test;
  8 +import org.junit.runner.RunWith;
  9 +
  10 +import static org.junit.Assert.*;
  11 +
  12 +/**
  13 + * Instrumented test, which will execute on an Android device.
  14 + *
  15 + * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
  16 + */
  17 +@RunWith(AndroidJUnit4.class)
  18 +public class ExampleInstrumentedTest {
  19 + @Test
  20 + public void useAppContext() throws Exception {
  21 + // Context of the app under test.
  22 + Context appContext = InstrumentationRegistry.getTargetContext();
  23 +
  24 + assertEquals("com.share.mvpsdk.test", appContext.getPackageName());
  25 + }
  26 +}
... ...
mvpsdk/src/main/AndroidManifest.xml 0 → 100644
... ... @@ -0,0 +1,7 @@
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3 + package="com.share.mvpsdk">
  4 +
  5 + <application></application>
  6 +
  7 +</manifest>
0 8 \ No newline at end of file
... ...
mvpsdk/src/main/java/com/share/mvpsdk/AppManager.java 0 → 100644
... ... @@ -0,0 +1,111 @@
  1 +package com.share.mvpsdk;
  2 +
  3 +import android.annotation.SuppressLint;
  4 +import android.app.Activity;
  5 +import android.app.ActivityManager;
  6 +import android.content.Context;
  7 +
  8 +import java.util.Stack;
  9 +
  10 +/**
  11 + * Created by Horrarndoo on 2017/4/5.
  12 + * <p>
  13 + * AppManager 管理Activity栈
  14 + */
  15 +
  16 +public class AppManager {
  17 + private static Stack<Activity> activityStack;
  18 + private static AppManager instance;
  19 +
  20 + private AppManager() {
  21 + }
  22 +
  23 + /**
  24 + * 单一实例
  25 + */
  26 + public static AppManager getAppManager() {
  27 + if (instance == null) {
  28 + instance = new AppManager();
  29 + }
  30 + return instance;
  31 + }
  32 +
  33 + /**
  34 + * 添加Activity到堆栈
  35 + */
  36 + public void addActivity(Activity activity) {
  37 + if (activityStack == null) {
  38 + activityStack = new Stack<Activity>();
  39 + }
  40 + activityStack.add(activity);
  41 + }
  42 +
  43 + /**
  44 + * 获取当前Activity(堆栈中最后一个压入的)
  45 + */
  46 + public Activity currentActivity() {
  47 + Activity activity = activityStack.lastElement();
  48 + return activity;
  49 + }
  50 +
  51 + /**
  52 + * 结束当前Activity(堆栈中最后一个压入的)
  53 + */
  54 + public void finishActivity() {
  55 + Activity activity = activityStack.lastElement();
  56 + finishActivity(activity);
  57 + }
  58 +
  59 + /**
  60 + * 结束指定的Activity
  61 + */
  62 + public void finishActivity(Activity activity) {
  63 + if (activity != null) {
  64 + activityStack.remove(activity);
  65 + activity.finish();
  66 + activity = null;
  67 + }
  68 + }
  69 +
  70 + /**
  71 + * 结束指定类名的Activity
  72 + */
  73 + public void finishActivity(Class<?> cls) {
  74 + for (Activity activity : activityStack) {
  75 + if (activity.getClass().equals(cls)) {
  76 + finishActivity(activity);
  77 + }
  78 + }
  79 + }
  80 +
  81 + /**
  82 + * 结束所有Activity
  83 + */
  84 + public void finishAllActivity() {
  85 + for (int i = 0, size = activityStack.size(); i < size; i++) {
  86 + if (null != activityStack.get(i)) {
  87 + activityStack.get(i).finish();
  88 + }
  89 + }
  90 + activityStack.clear();
  91 + }
  92 +
  93 + /**
  94 + * 退出应用程序
  95 + */
  96 + @SuppressLint("MissingPermission")
  97 + public void AppExit(Context context) {
  98 + try {
  99 + finishAllActivity();
  100 + ActivityManager activityMgr =
  101 + (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
  102 + activityMgr.killBackgroundProcesses(context.getPackageName());
  103 + System.exit(0);
  104 + } catch (Exception e) {
  105 + }
  106 + }
  107 +
  108 + public boolean isAppExit() {
  109 + return activityStack == null || activityStack.isEmpty();
  110 + }
  111 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/RxManager.java 0 → 100644
... ... @@ -0,0 +1,23 @@
  1 +package com.share.mvpsdk;
  2 +
  3 +
  4 +import io.reactivex.disposables.CompositeDisposable;
  5 +import io.reactivex.disposables.Disposable;
  6 +
  7 +/**
  8 + * Created by Horrarndoo on 2017/9/12.
  9 + * <p>
  10 + * 用于管理Rxjava 注册订阅和取消订阅
  11 + */
  12 +
  13 +public class RxManager {
  14 + private CompositeDisposable mCompositeDisposable = new CompositeDisposable();// 管理订阅者者
  15 +
  16 + public void register(Disposable d) {
  17 + mCompositeDisposable.add(d);
  18 + }
  19 +
  20 + public void unSubscribe() {
  21 + mCompositeDisposable.dispose();// 取消订阅
  22 + }
  23 +}
0 24 \ No newline at end of file
... ...
mvpsdk/src/main/java/com/share/mvpsdk/adapter/FragmentAdapter.java 0 → 100644
... ... @@ -0,0 +1,42 @@
  1 +package com.share.mvpsdk.adapter;
  2 +
  3 +
  4 +import android.support.v4.app.Fragment;
  5 +import android.support.v4.app.FragmentManager;
  6 +import android.support.v4.app.FragmentStatePagerAdapter;
  7 +import android.support.v4.view.PagerAdapter;
  8 +import android.view.ViewGroup;
  9 +
  10 +import java.util.List;
  11 +
  12 +/**
  13 + * Created by Horrarndoo on 2017/9/7.
  14 + * <p>
  15 + */
  16 +public class FragmentAdapter extends FragmentStatePagerAdapter {
  17 + private List<Fragment> fragments;
  18 +
  19 + public FragmentAdapter(FragmentManager fm, List<Fragment> fragments) {
  20 + super(fm);
  21 + this.fragments = fragments;
  22 + }
  23 +
  24 + @Override
  25 + public Fragment getItem(int position) {
  26 + return fragments.get(position);
  27 + }
  28 +
  29 + @Override
  30 + public int getCount() {
  31 + return fragments == null ? 0 : fragments.size();
  32 + }
  33 +
  34 + public int getItemPosition(Object object) {
  35 + return PagerAdapter.POSITION_NONE;
  36 + }
  37 +
  38 + @Override
  39 + public void destroyItem(ViewGroup container, int position, Object object) {
  40 + // super.destroyItem(container, position, object);
  41 + }
  42 +}
0 43 \ No newline at end of file
... ...
mvpsdk/src/main/java/com/share/mvpsdk/anim/AnimManager.java 0 → 100644
... ... @@ -0,0 +1,75 @@
  1 +package com.share.mvpsdk.anim;
  2 +
  3 +import android.content.Context;
  4 +import android.os.Build;
  5 +import android.support.annotation.NonNull;
  6 +import android.view.View;
  7 +import android.view.animation.AnimationUtils;
  8 +
  9 +/**
  10 + * Created by Horrarndoo on 2017/9/11.
  11 + * <p>
  12 + */
  13 +
  14 +public class AnimManager {
  15 + /**
  16 + * Alpha and scaleX 动画
  17 + * Alpha 0->1
  18 + * ScaleX 0.8->1
  19 + *
  20 + * @param context context
  21 + * @param view view
  22 + * @param startDelay 动画开始前延时(ms)
  23 + * @param duration 动画持续时间(ms)
  24 + */
  25 + public static void animAlphaAndScaleX(Context context, @NonNull View view, int startDelay, int
  26 + duration) {
  27 + view.setAlpha(0f);
  28 + view.setScaleX(0.8f);
  29 +
  30 + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  31 + view.animate()
  32 + .alpha(1f)
  33 + .scaleX(1f)
  34 + .setStartDelay(startDelay)
  35 + .setDuration(duration)
  36 + .setInterpolator(AnimUtils.getFastOutSlowInInterpolator(context))
  37 + .start();
  38 + }else{
  39 + view.animate()
  40 + .alpha(1f)
  41 + .scaleX(1f)
  42 + .setStartDelay(startDelay)
  43 + .setDuration(duration)
  44 + .setInterpolator(AnimationUtils.loadInterpolator(context, android.R.interpolator.linear))
  45 + .start();
  46 + }
  47 + }
  48 +
  49 + /**
  50 + * Alpha and scale X Y 动画
  51 + * Alpha 0->1
  52 + * ScaleX 0->1
  53 + * ScaleY 0->1
  54 + *
  55 + * @param context context
  56 + * @param view view
  57 + * @param startDelay 动画开始前延时(ms)
  58 + * @param duration 动画持续时间(ms)
  59 + */
  60 + public static void animAlphaAndScale(Context context, @NonNull View view, int startDelay, int
  61 + duration) {
  62 + view.setAlpha(0f);
  63 + view.setScaleX(0f);
  64 + view.setScaleY(0f);
  65 +
  66 + view.animate()
  67 + .alpha(1f)
  68 + .scaleX(1f)
  69 + .scaleY(1f)
  70 + .setStartDelay(startDelay)
  71 + .setDuration(duration)
  72 + .setInterpolator(AnimationUtils.loadInterpolator(context,
  73 + android.R.interpolator.overshoot)).start();
  74 + }
  75 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/anim/AnimUtils.java 0 → 100644
... ... @@ -0,0 +1,330 @@
  1 +/*
  2 + * Copyright 2015 Google Inc.
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +
  17 +package com.share.mvpsdk.anim;
  18 +
  19 +import android.animation.Animator;
  20 +import android.animation.TimeInterpolator;
  21 +import android.content.Context;
  22 +import android.os.Build;
  23 +import android.support.annotation.RequiresApi;
  24 +import android.transition.Transition;
  25 +import android.util.ArrayMap;
  26 +import android.util.Property;
  27 +import android.view.animation.AnimationUtils;
  28 +import android.view.animation.Interpolator;
  29 +
  30 +import java.util.ArrayList;
  31 +
  32 +/**
  33 + * Utility methods for working with animations.
  34 + */
  35 +public class AnimUtils {
  36 +
  37 + private AnimUtils() { }
  38 +
  39 + private static Interpolator fastOutSlowIn;
  40 + private static Interpolator fastOutLinearIn;
  41 + private static Interpolator linearOutSlowIn;
  42 +
  43 + public static Interpolator getFastOutSlowInInterpolator(Context context) {
  44 + if (fastOutSlowIn == null) {
  45 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  46 + fastOutSlowIn = AnimationUtils.loadInterpolator(context,
  47 + android.R.interpolator.fast_out_slow_in);
  48 + }
  49 + }
  50 + return fastOutSlowIn;
  51 + }
  52 +
  53 + public static Interpolator getFastOutLinearInInterpolator(Context context) {
  54 + if (fastOutLinearIn == null) {
  55 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  56 + fastOutLinearIn = AnimationUtils.loadInterpolator(context,
  57 + android.R.interpolator.fast_out_linear_in);
  58 + }
  59 + }
  60 + return fastOutLinearIn;
  61 + }
  62 +
  63 + public static Interpolator getLinearOutSlowInInterpolator(Context context) {
  64 + if (linearOutSlowIn == null) {
  65 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  66 + linearOutSlowIn = AnimationUtils.loadInterpolator(context,
  67 + android.R.interpolator.linear_out_slow_in);
  68 + }
  69 + }
  70 + return linearOutSlowIn;
  71 + }
  72 +
  73 + /**
  74 + * Linear interpolate between a and b with parameter t.
  75 + */
  76 + public static float lerp(float a, float b, float t) {
  77 + return a + (b - a) * t;
  78 + }
  79 +
  80 +
  81 + /**
  82 + * An implementation of {@link Property} to be used specifically with fields of
  83 + * type
  84 + * <code>float</code>. This type-specific subclass enables performance benefit by allowing
  85 + * calls to a {@link #set(Object, Float) set()} function that takes the primitive
  86 + * <code>float</code> type and avoids autoboxing and other overhead associated with the
  87 + * <code>Float</code> class.
  88 + *
  89 + * @param <T> The class on which the Property is declared.
  90 + **/
  91 + public static abstract class FloatProperty<T> extends Property<T, Float> {
  92 + public FloatProperty(String name) {
  93 + super(Float.class, name);
  94 + }
  95 +
  96 + /**
  97 + * A type-specific override of the {@link #set(Object, Float)} that is faster when dealing
  98 + * with fields of type <code>float</code>.
  99 + */
  100 + public abstract void setValue(T object, float value);
  101 +
  102 + @Override
  103 + final public void set(T object, Float value) {
  104 + setValue(object, value);
  105 + }
  106 + }
  107 +
  108 + /**
  109 + * An implementation of {@link Property} to be used specifically with fields of
  110 + * type
  111 + * <code>int</code>. This type-specific subclass enables performance benefit by allowing
  112 + * calls to a {@link #set(Object, Integer) set()} function that takes the primitive
  113 + * <code>int</code> type and avoids autoboxing and other overhead associated with the
  114 + * <code>Integer</code> class.
  115 + *
  116 + * @param <T> The class on which the Property is declared.
  117 + */
  118 + public static abstract class IntProperty<T> extends Property<T, Integer> {
  119 +
  120 + public IntProperty(String name) {
  121 + super(Integer.class, name);
  122 + }
  123 +
  124 + /**
  125 + * A type-specific override of the {@link #set(Object, Integer)} that is faster when dealing
  126 + * with fields of type <code>int</code>.
  127 + */
  128 + public abstract void setValue(T object, int value);
  129 +
  130 + @Override
  131 + final public void set(T object, Integer value) {
  132 + setValue(object, value.intValue());
  133 + }
  134 +
  135 + }
  136 +
  137 + /**
  138 + * https://halfthought.wordpress.com/2014/11/07/reveal-transition/
  139 + * <p/>
  140 + * Interrupting Activity transitions can yield an OperationNotSupportedException when the
  141 + * transition tries to pause the animator. Yikes! We can fix this by wrapping the Animator:
  142 + */
  143 + @RequiresApi(api = Build.VERSION_CODES.KITKAT)
  144 + public static class NoPauseAnimator extends Animator {
  145 + private final Animator mAnimator;
  146 + private final ArrayMap<AnimatorListener, AnimatorListener> mListeners =
  147 + new ArrayMap<AnimatorListener, AnimatorListener>();
  148 +
  149 + public NoPauseAnimator(Animator animator) {
  150 + mAnimator = animator;
  151 + }
  152 +
  153 + @RequiresApi(api = Build.VERSION_CODES.KITKAT)
  154 + @Override
  155 + public void addListener(AnimatorListener listener) {
  156 + AnimatorListener wrapper = new AnimatorListenerWrapper(this, listener);
  157 + if (!mListeners.containsKey(listener)) {
  158 + mListeners.put(listener, wrapper);
  159 + mAnimator.addListener(wrapper);
  160 + }
  161 + }
  162 +
  163 + @Override
  164 + public void cancel() {
  165 + mAnimator.cancel();
  166 + }
  167 +
  168 + @Override
  169 + public void end() {
  170 + mAnimator.end();
  171 + }
  172 +
  173 + @Override
  174 + public long getDuration() {
  175 + return mAnimator.getDuration();
  176 + }
  177 +
  178 + @Override
  179 + public TimeInterpolator getInterpolator() {
  180 + return mAnimator.getInterpolator();
  181 + }
  182 +
  183 + @Override
  184 + public void setInterpolator(TimeInterpolator timeInterpolator) {
  185 + mAnimator.setInterpolator(timeInterpolator);
  186 + }
  187 +
  188 + @Override
  189 + public ArrayList<AnimatorListener> getListeners() {
  190 + return new ArrayList<AnimatorListener>(mListeners.keySet());
  191 + }
  192 +
  193 + @Override
  194 + public long getStartDelay() {
  195 + return mAnimator.getStartDelay();
  196 + }
  197 +
  198 + @Override
  199 + public void setStartDelay(long delayMS) {
  200 + mAnimator.setStartDelay(delayMS);
  201 + }
  202 +
  203 + @Override
  204 + public boolean isPaused() {
  205 + return mAnimator.isPaused();
  206 + }
  207 +
  208 + @Override
  209 + public boolean isRunning() {
  210 + return mAnimator.isRunning();
  211 + }
  212 +
  213 + @Override
  214 + public boolean isStarted() {
  215 + return mAnimator.isStarted();
  216 + }
  217 +
  218 + /* We don't want to override pause or resume methods because we don't want them
  219 + * to affect mAnimator.
  220 + public void pause();
  221 +
  222 + public void resume();
  223 +
  224 + public void addPauseListener(AnimatorPauseListener listener);
  225 +
  226 + public void removePauseListener(AnimatorPauseListener listener);
  227 + */
  228 +
  229 + @Override
  230 + public void removeAllListeners() {
  231 + mListeners.clear();
  232 + mAnimator.removeAllListeners();
  233 + }
  234 +
  235 + @Override
  236 + public void removeListener(AnimatorListener listener) {
  237 + AnimatorListener wrapper = mListeners.get(listener);
  238 + if (wrapper != null) {
  239 + mListeners.remove(listener);
  240 + mAnimator.removeListener(wrapper);
  241 + }
  242 + }
  243 +
  244 + @Override
  245 + public Animator setDuration(long durationMS) {
  246 + mAnimator.setDuration(durationMS);
  247 + return this;
  248 + }
  249 +
  250 + @Override
  251 + public void setTarget(Object target) {
  252 + mAnimator.setTarget(target);
  253 + }
  254 +
  255 + @Override
  256 + public void setupEndValues() {
  257 + mAnimator.setupEndValues();
  258 + }
  259 +
  260 + @Override
  261 + public void setupStartValues() {
  262 + mAnimator.setupStartValues();
  263 + }
  264 +
  265 + @Override
  266 + public void start() {
  267 + mAnimator.start();
  268 + }
  269 + }
  270 +
  271 + static class AnimatorListenerWrapper implements Animator.AnimatorListener {
  272 + private final Animator mAnimator;
  273 + private final Animator.AnimatorListener mListener;
  274 +
  275 + public AnimatorListenerWrapper(Animator animator, Animator.AnimatorListener listener) {
  276 + mAnimator = animator;
  277 + mListener = listener;
  278 + }
  279 +
  280 + @Override
  281 + public void onAnimationStart(Animator animator) {
  282 + mListener.onAnimationStart(mAnimator);
  283 + }
  284 +
  285 + @Override
  286 + public void onAnimationEnd(Animator animator) {
  287 + mListener.onAnimationEnd(mAnimator);
  288 + }
  289 +
  290 + @Override
  291 + public void onAnimationCancel(Animator animator) {
  292 + mListener.onAnimationCancel(mAnimator);
  293 + }
  294 +
  295 + @Override
  296 + public void onAnimationRepeat(Animator animator) {
  297 + mListener.onAnimationRepeat(mAnimator);
  298 + }
  299 + }
  300 +
  301 + @RequiresApi(api = Build.VERSION_CODES.KITKAT)
  302 + public static class TransitionListenerAdapter implements Transition.TransitionListener {
  303 +
  304 + @Override
  305 + public void onTransitionStart(Transition transition) {
  306 +
  307 + }
  308 +
  309 + @Override
  310 + public void onTransitionEnd(Transition transition) {
  311 +
  312 + }
  313 +
  314 + @Override
  315 + public void onTransitionCancel(Transition transition) {
  316 +
  317 + }
  318 +
  319 + @Override
  320 + public void onTransitionPause(Transition transition) {
  321 +
  322 + }
  323 +
  324 + @Override
  325 + public void onTransitionResume(Transition transition) {
  326 +
  327 + }
  328 + }
  329 +
  330 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/anim/ToolbarAnimManager.java 0 → 100644
... ... @@ -0,0 +1,93 @@
  1 +package com.share.mvpsdk.anim;
  2 +
  3 +import android.content.Context;
  4 +import android.support.annotation.NonNull;
  5 +import android.support.v7.widget.ActionMenuView;
  6 +import android.support.v7.widget.Toolbar;
  7 +import android.view.View;
  8 +import android.widget.ImageButton;
  9 +import android.widget.TextView;
  10 +
  11 +/**
  12 + * Created by Horrarndoo on 2017/9/11.
  13 + * <p>
  14 + * Toolbar动画Manager
  15 + */
  16 +
  17 +public class ToolbarAnimManager {
  18 + /**
  19 + * Toolbar 进场动画
  20 + * <p>
  21 + * Textview&ActionMenuView渐变动画
  22 + *
  23 + * @param context context
  24 + * @param toolbar toolbar
  25 + */
  26 + public static void animIn(Context context, @NonNull Toolbar toolbar) {
  27 + ImageButton ibIcon = null;
  28 + TextView tvTitle = null;
  29 + ActionMenuView amvTheme = null;
  30 + int childCount = toolbar.getChildCount();
  31 + for (int i = 0; i < childCount; i++) {
  32 + View child = toolbar.getChildAt(i);
  33 + if(child instanceof ImageButton) {
  34 + ibIcon = (ImageButton) child;
  35 + continue;
  36 + }
  37 +
  38 + if (child instanceof ActionMenuView) {
  39 + amvTheme = (ActionMenuView) child;
  40 + continue;
  41 + }
  42 +
  43 + if (child instanceof TextView)
  44 + tvTitle = (TextView) child;
  45 + }
  46 +
  47 + if(ibIcon != null)
  48 + animNavigationIcon(context, ibIcon);
  49 +
  50 + if(tvTitle != null)
  51 + animTitle(context, tvTitle);
  52 +
  53 + if(amvTheme != null)
  54 + animMenu(context, amvTheme);
  55 + }
  56 +
  57 + /**
  58 + * Toolbar Title动画
  59 + * <p>
  60 + * NavigationIcon渐变动画
  61 + *
  62 + * @param context context
  63 + * @param imageButton 执行动画的view
  64 + */
  65 + public static void animNavigationIcon(Context context, @NonNull ImageButton imageButton) {
  66 + AnimManager.animAlphaAndScaleX(context, imageButton, 500, 900);
  67 + }
  68 +
  69 + /**
  70 + * Toolbar Title动画
  71 + * <p>
  72 + * ActionMenuView渐变动画
  73 + *
  74 + * @param context context
  75 + * @param textView 执行动画的view
  76 + */
  77 + public static void animTitle(Context context, @NonNull TextView textView) {
  78 + AnimManager.animAlphaAndScaleX(context, textView, 500, 900);
  79 + }
  80 +
  81 + /**
  82 + * Toolbar ActionMenuView动画
  83 + * <p>
  84 + * ActionMenuView渐变动画
  85 + *
  86 + * @param context context
  87 + * @param avm 执行动画的view
  88 + */
  89 + public static void animMenu(Context context, @NonNull ActionMenuView avm) {
  90 + AnimManager.animAlphaAndScale(context, avm, 500, 200); // filter
  91 + AnimManager.animAlphaAndScale(context, avm, 700, 200); // overflow
  92 + }
  93 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/base/BaseModel.java 0 → 100644
... ... @@ -0,0 +1,11 @@
  1 +package com.share.mvpsdk.base;
  2 +
  3 +/**
  4 + * Created by Horrarndoo on 2017/4/25.
  5 + * base model类
  6 + */
  7 +
  8 +public abstract class BaseModel {
  9 + public BaseModel() {
  10 + }
  11 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/base/BasePresenter.java 0 → 100644
... ... @@ -0,0 +1,53 @@
  1 +package com.share.mvpsdk.base;
  2 +
  3 +import android.support.annotation.NonNull;
  4 +
  5 +import com.share.mvpsdk.RxManager;
  6 +
  7 +
  8 +/**
  9 + * Created by Horrarndoo on 2017/4/25.
  10 + * <p>
  11 + * base presenter
  12 + */
  13 +
  14 +public abstract class BasePresenter<M, V> {
  15 + public M mIModel;
  16 + public V mIView;
  17 + protected RxManager mRxManager = new RxManager();
  18 +
  19 + /**
  20 + * 返回presenter想持有的Model引用
  21 + *
  22 + * @return presenter持有的Model引用
  23 + */
  24 + public abstract M getModel();
  25 +
  26 + /**
  27 + * 绑定IModel和IView的引用
  28 + *
  29 + * @param m model
  30 + * @param v view
  31 + */
  32 + public void attachMV(@NonNull M m, @NonNull V v) {
  33 + this.mIModel = m;
  34 + this.mIView = v;
  35 + this.onStart();
  36 + }
  37 +
  38 + /**
  39 + * 解绑IModel和IView
  40 + */
  41 + public void detachMV() {
  42 + mRxManager.unSubscribe();
  43 + mIView = null;
  44 + mIModel = null;
  45 + }
  46 +
  47 + /**
  48 + * IView和IModel绑定完成立即执行
  49 + * <p>
  50 + * 实现类实现绑定完成后的逻辑,例如数据初始化等,界面初始化, 更新等
  51 + */
  52 + public abstract void onStart();
  53 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/base/IBaseActivity.java 0 → 100644
... ... @@ -0,0 +1,35 @@
  1 +package com.share.mvpsdk.base;
  2 +
  3 +import android.os.Bundle;
  4 +import android.support.annotation.NonNull;
  5 +
  6 +/**
  7 + * Created by Horrarndoo on 2017/9/6.
  8 + * <p>
  9 + * BaseActivity接口
  10 + */
  11 +
  12 +public interface IBaseActivity extends IBaseView {
  13 + /**
  14 + * 跳往新的Activity
  15 + *
  16 + * @param clz 要跳往的Activity
  17 + */
  18 + void startNewActivity(@NonNull Class<?> clz);
  19 +
  20 + /**
  21 + * 跳往新的Activity
  22 + *
  23 + * @param clz 要跳往的Activity
  24 + * @param bundle 携带的bundle数据
  25 + */
  26 + void startNewActivity(@NonNull Class<?> clz, Bundle bundle);
  27 +
  28 + /**
  29 + * 跳往新的Activity
  30 + * @param clz 要跳转的Activity
  31 + * @param bundle bundel数据
  32 + * @param requestCode requestCode
  33 + */
  34 + void startNewActivityForResult(@NonNull Class<?> clz, Bundle bundle, int requestCode);
  35 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/base/IBaseFragment.java 0 → 100644
... ... @@ -0,0 +1,92 @@
  1 +package com.share.mvpsdk.base;
  2 +
  3 +import android.app.Activity;
  4 +import android.os.Bundle;
  5 +import android.support.annotation.NonNull;
  6 +
  7 +import me.yokeyword.fragmentation.SupportFragment;
  8 +
  9 +/**
  10 + * Created by Horrarndoo on 2017/9/6.
  11 + * <p>
  12 + * BaseFragment接口
  13 + */
  14 +
  15 +public interface IBaseFragment extends IBaseView {
  16 + /**
  17 + * 出栈到目标fragment
  18 + *
  19 + * @param targetFragmentClass 目标fragment
  20 + * @param includeTargetFragment 是否包含该fragment
  21 + * true 目标fragment也出栈
  22 + * <p>
  23 + * false 出栈到目标fragment,目标fragment不出栈
  24 + */
  25 + void popToFragment(Class<?> targetFragmentClass, boolean includeTargetFragment);
  26 +
  27 + /**
  28 + * 跳往新的Fragment
  29 + *
  30 + * @param supportFragment 要跳往的Fragment(继承自supportFragment)
  31 + */
  32 + void startNewFragment(@NonNull SupportFragment supportFragment);
  33 +
  34 + /**
  35 + * 跳往新的Fragment,并出栈当前fragment
  36 + *
  37 + * @param supportFragment 要跳往的Fragment(继承自supportFragment)
  38 + */
  39 + void startNewFragmentWithPop(@NonNull SupportFragment supportFragment);
  40 +
  41 + /**
  42 + * 跳往新的Fragment
  43 + *
  44 + * @param supportFragment 要跳往的Fragment(继承自supportFragment)
  45 + * @param requestCode requestCode
  46 + */
  47 + void startNewFragmentForResult(@NonNull SupportFragment supportFragment, int requestCode);
  48 +
  49 + /**
  50 + * 设置Fragment返回Result
  51 + *
  52 + * @param resultCode resultCode
  53 + * @param data result data
  54 + */
  55 + void setOnFragmentResult(int resultCode, Bundle data);
  56 +
  57 + /**
  58 + * 跳往新的Activity
  59 + *
  60 + * @param clz 要跳往的Activity
  61 + */
  62 + void startNewActivity(@NonNull Class<?> clz);
  63 +
  64 + /**
  65 + * 跳往新的Activity
  66 + *
  67 + * @param clz 要跳往的Activity
  68 + * @param bundle 携带的bundle数据
  69 + */
  70 + void startNewActivity(@NonNull Class<?> clz, Bundle bundle);
  71 +
  72 + /**
  73 + * 跳往新的Activity
  74 + *
  75 + * @param clz 要跳转的Activity
  76 + * @param bundle bundel数据
  77 + * @param requestCode requestCode
  78 + */
  79 + void startNewActivityForResult(@NonNull Class<?> clz, Bundle bundle, int requestCode);
  80 +
  81 + /**
  82 + * 返回当前fragment是否可见
  83 + * @return 当前fragment是否可见
  84 + */
  85 + boolean isVisiable();
  86 +
  87 + /**
  88 + * 返回当前fragment绑定的activity
  89 + * @return activity
  90 + */
  91 + Activity getBindActivity();
  92 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/base/IBaseModel.java 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +package com.share.mvpsdk.base;
  2 +
  3 +/**
  4 + * Created by Horrarndoo on 2017/4/25.
  5 + * base model接口
  6 + */
  7 +
  8 +public interface IBaseModel {
  9 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/base/IBaseView.java 0 → 100644
... ... @@ -0,0 +1,47 @@
  1 +package com.share.mvpsdk.base;
  2 +
  3 +import android.support.annotation.NonNull;
  4 +
  5 +/**
  6 + * Created by Horrarndoo on 2017/5/2.
  7 + * fragment base view接口
  8 + */
  9 +
  10 +public interface IBaseView {
  11 + /**
  12 + * 初始化presenter
  13 + * <p>
  14 + * 此方法返回的presenter对象不可为空
  15 + */
  16 + @NonNull
  17 + BasePresenter initPresenter();
  18 +
  19 + /**
  20 + * 显示toast消息
  21 + *
  22 + * @param msg 要显示的toast消息字符串
  23 + */
  24 + void showToast(String msg);
  25 +
  26 + /**
  27 + * 显示等待dialog
  28 + *
  29 + * @param waitMsg 等待消息字符串
  30 + */
  31 + void showWaitDialog(String waitMsg);
  32 +
  33 + /**
  34 + * 隐藏等待dialog
  35 + */
  36 + void hideWaitDialog();
  37 +
  38 + /**
  39 + * 隐藏键盘
  40 + */
  41 + void hideKeybord();
  42 +
  43 + /**
  44 + * 回退
  45 + */
  46 + void back();
  47 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/base/activity/BaseCompatActivity.java 0 → 100644
... ... @@ -0,0 +1,250 @@
  1 +package com.share.mvpsdk.base.activity;
  2 +
  3 +import android.content.Context;
  4 +import android.content.Intent;
  5 +import android.content.pm.ActivityInfo;
  6 +import android.os.Bundle;
  7 +import android.support.v7.app.AppCompatDelegate;
  8 +import android.support.v7.widget.Toolbar;
  9 +import android.view.View;
  10 +import android.view.inputmethod.InputMethodManager;
  11 +
  12 +
  13 +import com.share.mvpsdk.AppManager;
  14 +import com.share.mvpsdk.R;
  15 +import com.share.mvpsdk.global.GlobalApplication;
  16 +import com.share.mvpsdk.utils.AppUtils;
  17 +import com.share.mvpsdk.utils.SpUtils;
  18 +import com.share.mvpsdk.utils.StatusBarUtils;
  19 +import com.share.mvpsdk.utils.ThemeUtils;
  20 +import com.share.mvpsdk.widgets.WaitPorgressDialog;
  21 +
  22 +import butterknife.ButterKnife;
  23 +import me.yokeyword.fragmentation.SupportActivity;
  24 +import me.yokeyword.fragmentation.anim.DefaultVerticalAnimator;
  25 +import me.yokeyword.fragmentation.anim.FragmentAnimator;
  26 +
  27 +/**
  28 + * Created by Horrarndoo on 2017/9/7.
  29 + * <p>
  30 + * BaseActivity
  31 + */
  32 +
  33 +public abstract class BaseCompatActivity extends SupportActivity {
  34 + protected GlobalApplication mApplication;
  35 + protected WaitPorgressDialog mWaitPorgressDialog;
  36 + protected Context mContext;//全局上下文对象
  37 + protected boolean isTransAnim;
  38 +
  39 + static {
  40 + //5.0以下兼容vector
  41 + AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
  42 + }
  43 +
  44 + @Override
  45 + protected void onCreate(Bundle savedInstanceState) {
  46 + super.onCreate(savedInstanceState);
  47 + init(savedInstanceState);
  48 + }
  49 +
  50 + @Override
  51 + protected void onDestroy() {
  52 + super.onDestroy();
  53 + AppManager.getAppManager().finishActivity(this);
  54 + }
  55 +
  56 + @Override
  57 + public FragmentAnimator onCreateFragmentAnimator() {
  58 + //fragment切换使用默认Vertical动画
  59 + return new DefaultVerticalAnimator();
  60 + }
  61 +
  62 + private void init(Bundle savedInstanceState) {
  63 + setTheme(ThemeUtils.themeArr[SpUtils.getThemeIndex(this)][
  64 + SpUtils.getNightModel(this) ? 1 : 0]);
  65 + setContentView(getLayoutId());
  66 + ButterKnife.bind(this);
  67 +// StatusBarUtils.setTransparent(this);
  68 + StatusBarUtils.setBarColor(this,getResources().getColor(R.color.titleColor));
  69 + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
  70 + initData();
  71 + initView(savedInstanceState);
  72 + AppManager.getAppManager().addActivity(this);
  73 + }
  74 +
  75 + public void reload() {
  76 + Intent intent = getIntent();
  77 + overridePendingTransition(0, 0);
  78 + intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
  79 + finish();
  80 + overridePendingTransition(0, 0);
  81 + startActivity(intent);
  82 + }
  83 +
  84 + /**
  85 + * 初始化数据
  86 + * <p>
  87 + * 子类可以复写此方法初始化子类数据
  88 + */
  89 + protected void initData() {
  90 + mContext = AppUtils.getContext();
  91 + mApplication = GlobalApplication.getInstance();
  92 + mWaitPorgressDialog = new WaitPorgressDialog(this);
  93 + isTransAnim = true;
  94 + }
  95 +
  96 + /**
  97 + * 初始化view
  98 + * <p>
  99 + * 子类实现 控件绑定、视图初始化等内容
  100 + *
  101 + * @param savedInstanceState savedInstanceState
  102 + */
  103 + protected abstract void initView(Bundle savedInstanceState);
  104 +
  105 + /**
  106 + * 获取当前layouty的布局ID,用于设置当前布局
  107 + * <p>
  108 + * 交由子类实现
  109 + *
  110 + * @return layout Id
  111 + */
  112 + protected abstract int getLayoutId();
  113 +
  114 + /**
  115 + * 显示提示框
  116 + *
  117 + * @param msg 提示框内容字符串
  118 + */
  119 + protected void showProgressDialog(String msg) {
  120 + mWaitPorgressDialog.setMessage(msg);
  121 + mWaitPorgressDialog.show();
  122 + }
  123 +
  124 + /**
  125 + * 隐藏提示框
  126 + */
  127 + protected void hideProgressDialog() {
  128 + if (mWaitPorgressDialog != null) {
  129 + mWaitPorgressDialog.dismiss();
  130 + }
  131 + }
  132 +
  133 + /**
  134 + * [页面跳转]
  135 + *
  136 + * @param clz 要跳转的Activity
  137 + */
  138 + public void startActivity(Class<?> clz) {
  139 + startActivity(new Intent(this, clz));
  140 + if (isTransAnim)
  141 + overridePendingTransition(R.anim.activity_start_zoom_in, R.anim
  142 + .activity_start_zoom_out);
  143 + }
  144 +
  145 + /**
  146 + * [页面跳转]
  147 + *
  148 + * @param clz 要跳转的Activity
  149 + * @param intent intent
  150 + */
  151 + public void startActivity(Class<?> clz, Intent intent) {
  152 + intent.setClass(this, clz);
  153 + startActivity(intent);
  154 + if (isTransAnim)
  155 + overridePendingTransition(R.anim.activity_start_zoom_in, R.anim
  156 + .activity_start_zoom_out);
  157 + }
  158 +
  159 + /**
  160 + * [携带数据的页面跳转]
  161 + *
  162 + * @param clz 要跳转的Activity
  163 + * @param bundle bundel数据
  164 + */
  165 + public void startActivity(Class<?> clz, Bundle bundle) {
  166 + Intent intent = new Intent();
  167 + intent.setClass(this, clz);
  168 + if (bundle != null) {
  169 + intent.putExtras(bundle);
  170 + }
  171 + startActivity(intent);
  172 + if (isTransAnim)
  173 + overridePendingTransition(R.anim.activity_start_zoom_in, R.anim
  174 + .activity_start_zoom_out);
  175 + }
  176 +
  177 + /**
  178 + * [含有Bundle通过Class打开编辑界面]
  179 + *
  180 + * @param clz 要跳转的Activity
  181 + * @param bundle bundel数据
  182 + * @param requestCode requestCode
  183 + */
  184 + public void startActivityForResult(Class<?> clz, Bundle bundle,
  185 + int requestCode) {
  186 + Intent intent = new Intent();
  187 + intent.setClass(this, clz);
  188 + if (bundle != null) {
  189 + intent.putExtras(bundle);
  190 + }
  191 + startActivityForResult(intent, requestCode);
  192 + if (isTransAnim)
  193 + overridePendingTransition(R.anim.activity_start_zoom_in, R.anim
  194 + .activity_start_zoom_out);
  195 + }
  196 +
  197 + @Override
  198 + public void finish() {
  199 + super.finish();
  200 + if (isTransAnim)
  201 + overridePendingTransition(R.anim.activity_finish_trans_in, R.anim
  202 + .activity_finish_trans_out);
  203 + }
  204 +
  205 + /**
  206 + * 隐藏键盘
  207 + *
  208 + * @return 隐藏键盘结果
  209 + * <p>
  210 + * true:隐藏成功
  211 + * <p>
  212 + * false:隐藏失败
  213 + */
  214 + protected boolean hiddenKeyboard() {
  215 + //点击空白位置 隐藏软键盘
  216 + InputMethodManager mInputMethodManager = (InputMethodManager) getSystemService
  217 + (INPUT_METHOD_SERVICE);
  218 + return mInputMethodManager.hideSoftInputFromWindow(this
  219 + .getCurrentFocus().getWindowToken(), 0);
  220 + }
  221 +
  222 + protected void initTitleBar(Toolbar toolbar, String title) {
  223 + toolbar.setTitle(title);
  224 + setSupportActionBar(toolbar);
  225 + getSupportActionBar().setDisplayHomeAsUpEnabled(true);
  226 + getSupportActionBar().setDisplayShowHomeEnabled(true);
  227 + toolbar.setNavigationIcon(R.mipmap.ic_arrow_back_white);
  228 + toolbar.setNavigationOnClickListener(new View.OnClickListener() {
  229 + @Override
  230 + public void onClick(View view) {
  231 + onBackPressedSupport();
  232 + }
  233 + });
  234 + }
  235 +
  236 + /**
  237 + * 是否使用overridePendingTransition过度动画
  238 + * @return 是否使用overridePendingTransition过度动画,默认使用
  239 + */
  240 + protected boolean isTransAnim() {
  241 + return isTransAnim;
  242 + }
  243 +
  244 + /**
  245 + * 设置是否使用overridePendingTransition过度动画
  246 + */
  247 + protected void setIsTransAnim(boolean b){
  248 + isTransAnim = b;
  249 + }
  250 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/base/activity/BaseMVPCompatActivity.java 0 → 100644
... ... @@ -0,0 +1,94 @@
  1 +package com.share.mvpsdk.base.activity;
  2 +
  3 +import android.os.Bundle;
  4 +import android.support.annotation.NonNull;
  5 +
  6 +import com.share.mvpsdk.base.BasePresenter;
  7 +import com.share.mvpsdk.base.IBaseActivity;
  8 +import com.share.mvpsdk.base.IBaseModel;
  9 +import com.share.mvpsdk.utils.ToastUtils;
  10 +
  11 +
  12 +/**
  13 + * Created by Horrarndoo on 2017/4/6.
  14 + * <p>
  15 + * Mvp Activity基类
  16 + */
  17 +public abstract class BaseMVPCompatActivity<P extends BasePresenter, M extends IBaseModel> extends
  18 + BaseCompatActivity implements IBaseActivity {
  19 + /**
  20 + * presenter 具体的presenter由子类确定
  21 + */
  22 + protected P mPresenter;
  23 +
  24 + /**
  25 + * model 具体的model由子类确定
  26 + */
  27 + private M mIMode;
  28 +
  29 + /**
  30 + * 初始化数据
  31 + * <p>
  32 + * 子类可以复写此方法初始化子类数据
  33 + */
  34 + protected void initData() {
  35 + super.initData();
  36 + mPresenter = (P) initPresenter();
  37 + if (mPresenter != null) {
  38 + mIMode = (M) mPresenter.getModel();
  39 + if (mIMode != null) {
  40 + mPresenter.attachMV(mIMode, this);
  41 + }
  42 + //Logger.d("attach M V success.");
  43 + }
  44 + }
  45 +
  46 + @Override
  47 + protected void onDestroy() {
  48 + super.onDestroy();
  49 + if (mPresenter != null) {
  50 + mPresenter.detachMV();
  51 + //Logger.d("detach M V success.");
  52 + }
  53 + }
  54 +
  55 + @Override
  56 + public void showWaitDialog(String msg) {
  57 + showProgressDialog(msg);
  58 + }
  59 +
  60 + @Override
  61 + public void hideWaitDialog() {
  62 + hideProgressDialog();
  63 + }
  64 +
  65 + @Override
  66 + public void showToast(String msg) {
  67 + ToastUtils.showToast(msg);
  68 + }
  69 +
  70 + @Override
  71 + public void startNewActivity(@NonNull Class<?> clz) {
  72 + startActivity(clz);
  73 + }
  74 +
  75 + @Override
  76 + public void startNewActivity(@NonNull Class<?> clz, Bundle bundle) {
  77 + startActivity(clz, bundle);
  78 + }
  79 +
  80 + @Override
  81 + public void startNewActivityForResult(@NonNull Class<?> clz, Bundle bundle, int requestCode) {
  82 + startActivityForResult(clz, bundle, requestCode);
  83 + }
  84 +
  85 + @Override
  86 + public void hideKeybord() {
  87 + hiddenKeyboard();
  88 + }
  89 +
  90 + @Override
  91 + public void back() {
  92 + super.onBackPressedSupport();
  93 + }
  94 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/base/adapter/BaseRecyclerViewAdapter.java 0 → 100644
... ... @@ -0,0 +1,79 @@
  1 +package com.share.mvpsdk.base.adapter;
  2 +
  3 +import android.support.v7.widget.RecyclerView;
  4 +import android.view.ViewGroup;
  5 +
  6 +
  7 +import java.util.ArrayList;
  8 +import java.util.List;
  9 +
  10 +/**
  11 + * Created by ToaHanDong on 2017/3/23.
  12 + */
  13 +
  14 +public abstract class BaseRecyclerViewAdapter<T> extends RecyclerView.Adapter<BaseRecyclerViewHolder> {
  15 +
  16 + private List<T> data = new ArrayList<>();
  17 + public OnItemClickListener onItemClickListener;
  18 + public OnItemLongClickListener onItemLongClickListener;
  19 +
  20 + @Override
  21 + public BaseRecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
  22 + return null;
  23 + }
  24 +
  25 + @Override
  26 + public void onBindViewHolder(BaseRecyclerViewHolder holder, int position) {
  27 + holder.onBindViewHolder(data.get(getPosition(position)), getPosition(position));
  28 + }
  29 +
  30 +
  31 + @Override
  32 + public int getItemCount() {
  33 + return data.size();
  34 + }
  35 +
  36 + public void addAll(List<T> data) {
  37 + removeAll();
  38 + if (data!=null)
  39 + this.data.addAll(data);
  40 + notifyDataSetChanged();
  41 + }
  42 +
  43 + public void removeAll() {
  44 + data.clear();
  45 + }
  46 +
  47 + public void remove(int position) {
  48 + data.remove(position);
  49 + }
  50 +
  51 + public void notift() {
  52 + notifyDataSetChanged();
  53 + }
  54 +
  55 + public void remove(T object) {
  56 + data.remove(object);
  57 + }
  58 +
  59 + public List<T> getData() {
  60 + return data;
  61 + }
  62 +
  63 + public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
  64 + this.onItemClickListener = onItemClickListener;
  65 + }
  66 +
  67 + public void setOnItemLongClickListener(OnItemLongClickListener onItemLongClickListener) {
  68 + this.onItemLongClickListener = onItemLongClickListener;
  69 + }
  70 +
  71 + private int getPosition(int position) {
  72 + return position;
  73 +// if (data.size() <= 9) {
  74 +// return position;
  75 +// }
  76 +// return position % (data.size());
  77 + }
  78 +
  79 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/base/adapter/BaseRecyclerViewHolder.java 0 → 100644
... ... @@ -0,0 +1,22 @@
  1 +package com.share.mvpsdk.base.adapter;
  2 +
  3 +import android.support.v7.widget.RecyclerView;
  4 +import android.view.View;
  5 +
  6 +/**
  7 + * Created by ToaHanDong on 2017/3/23.
  8 + */
  9 +
  10 +public abstract class BaseRecyclerViewHolder<T> extends RecyclerView.ViewHolder {
  11 +
  12 + public BaseRecyclerViewHolder(View itemView) {
  13 + super(itemView);
  14 + }
  15 +
  16 + public abstract void onBindViewHolder(T object, final int position);
  17 +
  18 + void OnBaseBindViewHolder(T Object,int position){
  19 + onBindViewHolder(Object,position);
  20 + }
  21 +
  22 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/base/adapter/OnItemClickListener.java 0 → 100644
... ... @@ -0,0 +1,10 @@
  1 +package com.share.mvpsdk.base.adapter;
  2 +
  3 +/**
  4 + * Created by ToaHanDong on 2017/3/23.
  5 + */
  6 +
  7 +public interface OnItemClickListener<T> {
  8 +
  9 + void onItemClickListener(T object, int position);
  10 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/base/adapter/OnItemLongClickListener.java 0 → 100644
... ... @@ -0,0 +1,10 @@
  1 +package com.share.mvpsdk.base.adapter;
  2 +
  3 +/**
  4 + * Created by ToaHanDong on 2017/3/23.
  5 + */
  6 +
  7 +public interface OnItemLongClickListener<T> {
  8 +
  9 + void onItemLongClickListener(T object, int position);
  10 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/base/entity/BaseEntity.java 0 → 100644
... ... @@ -0,0 +1,47 @@
  1 +package com.share.mvpsdk.base.entity;
  2 +
  3 +import java.io.Serializable;
  4 +
  5 +/**
  6 + * Created by ToaHanDong on 2017/4/27.
  7 + */
  8 +
  9 +public class BaseEntity<T> implements Serializable {
  10 +
  11 + private int status;
  12 + private String message;
  13 + private T data;
  14 +
  15 + public int getStatus() {
  16 + return status;
  17 + }
  18 +
  19 + public void setStatus(int status) {
  20 + this.status = status;
  21 + }
  22 +
  23 + public String getMessage() {
  24 + return message;
  25 + }
  26 +
  27 + public void setMessage(String message) {
  28 + this.message = message;
  29 + }
  30 +
  31 + public T getData() {
  32 + return data;
  33 + }
  34 +
  35 + public void setData(T data) {
  36 + this.data = data;
  37 + }
  38 +
  39 + @Override
  40 + public String toString() {
  41 + return "BaseEntity{" +
  42 + "status=" + status +
  43 + ", message='" + message + '\'' +
  44 + ", data=" + data +
  45 + '}';
  46 + }
  47 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/base/entity/BaseListEntity.java 0 → 100644
... ... @@ -0,0 +1,48 @@
  1 +package com.share.mvpsdk.base.entity;
  2 +
  3 +import java.io.Serializable;
  4 +import java.util.List;
  5 +
  6 +/**
  7 + * Created by ToaHanDong on 2017/6/6.
  8 + */
  9 +
  10 +public class BaseListEntity<T> implements Serializable {
  11 +
  12 + private int status;
  13 + private String message;
  14 + private List<T> data;
  15 +
  16 + public int getStatus() {
  17 + return status;
  18 + }
  19 +
  20 + public void setStatus(int status) {
  21 + this.status = status;
  22 + }
  23 +
  24 + public String getMessage() {
  25 + return message;
  26 + }
  27 +
  28 + public void setMessage(String message) {
  29 + this.message = message;
  30 + }
  31 +
  32 + public List<T> getData() {
  33 + return data;
  34 + }
  35 +
  36 + public void setData(List<T> data) {
  37 + this.data = data;
  38 + }
  39 +
  40 + @Override
  41 + public String toString() {
  42 + return "BaseListEntity{" +
  43 + "status=" + status +
  44 + ", message='" + message + '\'' +
  45 + ", data=" + data +
  46 + '}';
  47 + }
  48 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/base/fragment/BaseCompatFragment.java 0 → 100644
... ... @@ -0,0 +1,153 @@
  1 +package com.share.mvpsdk.base.fragment;
  2 +
  3 +import android.app.Activity;
  4 +import android.content.Context;
  5 +import android.content.pm.ActivityInfo;
  6 +import android.os.Bundle;
  7 +import android.support.annotation.LayoutRes;
  8 +import android.support.annotation.Nullable;
  9 +import android.util.Log;
  10 +import android.view.LayoutInflater;
  11 +import android.view.View;
  12 +import android.view.ViewGroup;
  13 +
  14 +
  15 +import com.share.mvpsdk.global.GlobalApplication;
  16 +import com.share.mvpsdk.utils.AppUtils;
  17 +import com.share.mvpsdk.widgets.WaitPorgressDialog;
  18 +
  19 +import butterknife.ButterKnife;
  20 +import butterknife.Unbinder;
  21 +import me.yokeyword.fragmentation.SupportFragment;
  22 +import timber.log.Timber;
  23 +
  24 +/**
  25 + * Created by Horrarndoo on 2017/9/26.
  26 + * <p>
  27 + */
  28 +
  29 +public abstract class BaseCompatFragment extends SupportFragment {
  30 +
  31 + protected String TAG;
  32 + protected Context mContext;
  33 + protected Activity mActivity;
  34 + protected GlobalApplication mApplication;
  35 + protected WaitPorgressDialog mWaitPorgressDialog;
  36 +// private Unbinder binder;
  37 +
  38 + @Override
  39 + public void onAttach(Context context) {
  40 + mActivity = (Activity) context;
  41 + mContext = context;
  42 + super.onAttach(context);
  43 + }
  44 +
  45 + @Override
  46 + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable
  47 + Bundle savedInstanceState) {
  48 + if (getLayoutView() != null) {
  49 + return getLayoutView();
  50 + } else {
  51 + // return inflater.inflate(getLayoutId(), null);
  52 + return inflater.inflate(getLayoutId(), container, false);
  53 + }
  54 + }
  55 +
  56 + @Override
  57 + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
  58 + ButterKnife.bind(this, view);
  59 + super.onViewCreated(view, savedInstanceState);
  60 + mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
  61 + TAG = getClass().getSimpleName();
  62 + getBundle(getArguments());
  63 + initData();
  64 + initUI(view, savedInstanceState);
  65 + }
  66 +
  67 +
  68 + @Override
  69 + public void onDestroyView() {
  70 + super.onDestroyView();
  71 +// if (binder != null)
  72 +// binder.unbind();
  73 + }
  74 +
  75 + @Override
  76 + public void onDetach() {
  77 + super.onDetach();
  78 + }
  79 +
  80 + @Override
  81 + public void onDestroy() {
  82 + super.onDestroy();
  83 + }
  84 +
  85 + @LayoutRes
  86 + public abstract int getLayoutId();
  87 +
  88 + public View getLayoutView() {
  89 + return null;
  90 + }
  91 +
  92 + /**
  93 + * 得到Activity传进来的值
  94 + */
  95 + public void getBundle(Bundle bundle) {
  96 + }
  97 +
  98 + /**
  99 + * 初始化UI
  100 + */
  101 + public abstract void initUI(View view, @Nullable Bundle savedInstanceState);
  102 +
  103 + /**
  104 + * 在监听器之前把数据准备好
  105 + */
  106 + public void initData() {
  107 + mWaitPorgressDialog = new WaitPorgressDialog(mActivity);
  108 + mContext = AppUtils.getContext();
  109 + mApplication = GlobalApplication.getInstance();
  110 + }
  111 +
  112 + /**
  113 + * 处理回退事件
  114 + *
  115 + * @return true 事件已消费
  116 + * <p>
  117 + * false 事件向上传递
  118 + */
  119 + @Override
  120 + public boolean onBackPressedSupport() {
  121 + if (getFragmentManager().getBackStackEntryCount() > 1) {
  122 + //如果当前存在fragment>1,当前fragment出栈
  123 + pop();
  124 + } else {
  125 + //已经退栈到root fragment,交由Activity处理回退事件
  126 + return false;
  127 + }
  128 + return true;
  129 + }
  130 +
  131 + /**
  132 + * 显示提示框
  133 + *
  134 + * @param msg 提示框内容字符串
  135 + */
  136 + protected void showProgressDialog(String msg) {
  137 + if (mWaitPorgressDialog.isShowing()) {
  138 + mWaitPorgressDialog.dismiss();
  139 + }
  140 +
  141 + mWaitPorgressDialog.setMessage(msg);
  142 + mWaitPorgressDialog.show();
  143 + }
  144 +
  145 + /**
  146 + * 隐藏提示框
  147 + */
  148 + protected void hideProgressDialog() {
  149 + if (mWaitPorgressDialog != null) {
  150 + mWaitPorgressDialog.dismiss();
  151 + }
  152 + }
  153 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/base/fragment/BaseMVPCompatFragment.java 0 → 100644
... ... @@ -0,0 +1,128 @@
  1 +package com.share.mvpsdk.base.fragment;
  2 +
  3 +import android.app.Activity;
  4 +import android.os.Bundle;
  5 +import android.support.annotation.NonNull;
  6 +import android.widget.Toast;
  7 +
  8 +
  9 +import com.share.mvpsdk.base.BasePresenter;
  10 +import com.share.mvpsdk.base.IBaseFragment;
  11 +import com.share.mvpsdk.base.IBaseModel;
  12 +import com.share.mvpsdk.base.activity.BaseCompatActivity;
  13 +import com.share.mvpsdk.utils.ToastUtils;
  14 +
  15 +import me.yokeyword.fragmentation.SupportFragment;
  16 +
  17 +/**
  18 + * Created by Horrarndoo on 2017/9/6.
  19 + * <p>
  20 + * Mvp Fragment基类
  21 + * <p>
  22 + * 实现IBaseView方法、绑定butterknife
  23 + */
  24 +
  25 +public abstract class BaseMVPCompatFragment<P extends BasePresenter, M extends IBaseModel> extends
  26 + BaseCompatFragment implements IBaseFragment {
  27 + public P mPresenter;
  28 + public M mIMode;
  29 +
  30 + /**
  31 + * 在监听器之前把数据准备好
  32 + */
  33 + public void initData() {
  34 + super.initData();
  35 +
  36 + mPresenter = (P) initPresenter();
  37 + if (mPresenter != null) {
  38 + mIMode = (M) mPresenter.getModel();
  39 + if (mIMode != null) {
  40 + mPresenter.attachMV(mIMode, this);
  41 + }
  42 + }
  43 + }
  44 +
  45 + @Override
  46 + public void onDestroy() {
  47 + super.onDestroy();
  48 + if (mPresenter != null) {
  49 + mPresenter.detachMV();
  50 + }
  51 + }
  52 +
  53 + @Override
  54 + public void showWaitDialog(String msg) {
  55 + showProgressDialog(msg);
  56 + }
  57 +
  58 + @Override
  59 + public void hideWaitDialog() {
  60 + hideProgressDialog();
  61 + }
  62 +
  63 + @Override
  64 + public void showToast(String msg) {
  65 + ToastUtils.showToast(mContext, msg, Toast.LENGTH_SHORT);
  66 + }
  67 +
  68 + @Override
  69 + public void back() {
  70 + this.onBackPressedSupport();
  71 + }
  72 +
  73 + @Override
  74 + public void startNewFragment(@NonNull SupportFragment supportFragment) {
  75 + start(supportFragment);
  76 + }
  77 +
  78 + @Override
  79 + public void startNewFragmentWithPop(@NonNull SupportFragment supportFragment) {
  80 + startWithPop(supportFragment);
  81 + }
  82 +
  83 + @Override
  84 + public void startNewFragmentForResult(@NonNull SupportFragment supportFragment, int
  85 + requestCode) {
  86 + startForResult(supportFragment, requestCode);
  87 + }
  88 +
  89 + @Override
  90 + public void popToFragment(Class<?> targetFragmentClass, boolean includeTargetFragment) {
  91 + popTo(targetFragmentClass, includeTargetFragment);
  92 + }
  93 +
  94 + @Override
  95 + public void hideKeybord() {
  96 + hideSoftInput();
  97 + }
  98 +
  99 + @Override
  100 + public void setOnFragmentResult(int ResultCode, Bundle data) {
  101 + setFragmentResult(ResultCode, data);
  102 + }
  103 +
  104 + @Override
  105 + public void startNewActivity(@NonNull Class<?> clz) {
  106 + ((BaseCompatActivity) mActivity).startActivity(clz);
  107 + }
  108 +
  109 + @Override
  110 + public void startNewActivity(@NonNull Class<?> clz, Bundle bundle) {
  111 + ((BaseCompatActivity) mActivity).startActivity(clz, bundle);
  112 + }
  113 +
  114 + @Override
  115 + public void startNewActivityForResult(@NonNull Class<?> clz, Bundle bundle, int requestCode) {
  116 + ((BaseCompatActivity) mActivity).startActivityForResult(clz, bundle, requestCode);
  117 + }
  118 +
  119 + @Override
  120 + public boolean isVisiable() {
  121 + return isSupportVisible();
  122 + }
  123 +
  124 + @Override
  125 + public Activity getBindActivity() {
  126 + return mActivity;
  127 + }
  128 +}
0 129 \ No newline at end of file
... ...
mvpsdk/src/main/java/com/share/mvpsdk/base/fragment/BaseRecycleFragment.java 0 → 100644
... ... @@ -0,0 +1,68 @@
  1 +package com.share.mvpsdk.base.fragment;
  2 +
  3 +import android.os.Bundle;
  4 +import android.support.annotation.Nullable;
  5 +import android.view.LayoutInflater;
  6 +import android.view.View;
  7 +import android.view.ViewGroup;
  8 +
  9 +import com.share.mvpsdk.R;
  10 +import com.share.mvpsdk.base.BasePresenter;
  11 +import com.share.mvpsdk.base.IBaseModel;
  12 +
  13 +
  14 +/**
  15 + * Created by Horrarndoo on 2017/10/17.
  16 + * <p>
  17 + * 带RecycleView加载状态view的fragment,主要用于显示加载中、空界面、加载失败等状态界面显示
  18 + */
  19 +
  20 +public abstract class BaseRecycleFragment<P extends BasePresenter, M extends IBaseModel> extends
  21 + BaseMVPCompatFragment<P, M> {
  22 + /**
  23 + * 网络异常View
  24 + */
  25 + protected View errorView;
  26 + /**
  27 + * loadingView
  28 + */
  29 + protected View loadingView;
  30 + /**
  31 + * 没有内容view
  32 + */
  33 + protected View emptyView;
  34 +
  35 + @Override
  36 + public void onLazyInitView(@Nullable Bundle savedInstanceState) {
  37 + super.onLazyInitView(savedInstanceState);
  38 + showLoading();
  39 + }
  40 +
  41 + @Override
  42 + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable
  43 + Bundle savedInstanceState) {
  44 + errorView = inflater.inflate(R.layout.view_network_error, container, false);
  45 + loadingView = inflater.inflate(R.layout.view_loading, container, false);
  46 + emptyView = inflater.inflate(R.layout.view_empty, container, false);
  47 + errorView.setOnClickListener(new View.OnClickListener() {
  48 + @Override
  49 + public void onClick(View v) {
  50 + showLoading();
  51 + onErrorViewClick(v);
  52 + }
  53 + });
  54 + return super.onCreateView(inflater, container, savedInstanceState);
  55 + }
  56 +
  57 + /**
  58 + * 网络异常view被点击时触发,由子类实现
  59 + *
  60 + * @param view view
  61 + */
  62 + protected abstract void onErrorViewClick(View view);
  63 +
  64 + /**
  65 + * 显示加载中view,由子类实现
  66 + */
  67 + protected abstract void showLoading();
  68 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/config/DBConfig.java 0 → 100644
... ... @@ -0,0 +1,16 @@
  1 +package com.share.mvpsdk.config;
  2 +
  3 +/**
  4 + * Created by Horrarndoo on 2017/9/13.
  5 + * <p>
  6 + * 数据库全局常量
  7 + */
  8 +
  9 +public class DBConfig {
  10 + public static final String DB_NAME = "db_name_yizhi";
  11 + public static final String TABLE_ZHIHU = "table_zhihu";
  12 + public static final String TABLE_WANGYI = "table_top_news";
  13 + public static final String TABLE_WEIXIN = "table_weixin";
  14 + public static final String TABLE_GANKIO_DAY = "table_gank_io_day";
  15 + public static final String TABLE_GANKIO_CUSTOM = "table_gank_io_custom";
  16 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/config/ItemState.java 0 → 100644
... ... @@ -0,0 +1,19 @@
  1 +package com.share.mvpsdk.config;
  2 +
  3 +/**
  4 + * Created by Horrarndoo on 2017/9/13.
  5 + * <p>
  6 + * item状态全局常量
  7 + */
  8 +
  9 +public class ItemState {
  10 + /**
  11 + * 已读状态
  12 + */
  13 + public static final int STATE_IS_READ = 1;
  14 +
  15 + /**
  16 + * 非已读状态
  17 + */
  18 + public static final int STATE_IS_NO_READ = 0;
  19 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/global/GlobalApplication.java 0 → 100644
... ... @@ -0,0 +1,72 @@
  1 +package com.share.mvpsdk.global;
  2 +
  3 +import android.app.Application;
  4 +import android.content.Context;
  5 +import android.os.Handler;
  6 +
  7 +import com.orhanobut.logger.LogLevel;
  8 +import com.orhanobut.logger.Logger;
  9 +import com.share.mvpsdk.utils.ToastUtils;
  10 +
  11 +import timber.log.BuildConfig;
  12 +import timber.log.Timber;
  13 +
  14 +
  15 +/**
  16 + * Created by Horrarndoo on 2017/9/1.
  17 + * <p>
  18 + * 全局Application
  19 + */
  20 +
  21 +public class GlobalApplication extends Application {
  22 + private static final String LOG_TAG = "YZ_LOGGER";
  23 + protected static Context context;
  24 + protected static Handler handler;
  25 + protected static int mainThreadId;
  26 + private static GlobalApplication mApp;
  27 +
  28 + public static synchronized GlobalApplication getInstance() {
  29 + return mApp;
  30 + }
  31 +
  32 + @Override
  33 + public void onCreate() {
  34 + super.onCreate();
  35 + context = getApplicationContext();
  36 + handler = new Handler();
  37 + mainThreadId = android.os.Process.myTid();
  38 + mApp=this;
  39 + if (!BuildConfig.DEBUG) {
  40 + Timber.plant(new Timber.DebugTree());
  41 + }
  42 + //LogLevel.FULL : LogLevel.NONE
  43 +// Logger.init(LOG_TAG).logLevel(LogLevel.FULL);
  44 + }
  45 +
  46 + /**
  47 + * 获取上下文对象
  48 + *
  49 + * @return context
  50 + */
  51 + public static Context getContext() {
  52 + return context;
  53 + }
  54 +
  55 + /**
  56 + * 获取全局handler
  57 + *
  58 + * @return 全局handler
  59 + */
  60 + public static Handler getHandler() {
  61 + return handler;
  62 + }
  63 +
  64 + /**
  65 + * 获取主线程id
  66 + *
  67 + * @return 主线程id
  68 + */
  69 + public static int getMainThreadId() {
  70 + return mainThreadId;
  71 + }
  72 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/helper/BottomNavigationViewHelper.java 0 → 100644
... ... @@ -0,0 +1,37 @@
  1 +package com.share.mvpsdk.helper;
  2 +
  3 +import android.support.design.internal.BottomNavigationItemView;
  4 +import android.support.design.internal.BottomNavigationMenuView;
  5 +import android.support.design.widget.BottomNavigationView;
  6 +import android.util.Log;
  7 +
  8 +import java.lang.reflect.Field;
  9 +
  10 +/**
  11 + * Created by Horrarndoo on 2017/9/22.
  12 + * <p>
  13 + * BottomNavigationView禁止3个item以上动画切换效果
  14 + */
  15 +public class BottomNavigationViewHelper {
  16 + public static void disableShiftMode(BottomNavigationView view) {
  17 + BottomNavigationMenuView menuView = (BottomNavigationMenuView) view.getChildAt(0);
  18 + try {
  19 + Field shiftingMode = menuView.getClass().getDeclaredField("mShiftingMode");
  20 + shiftingMode.setAccessible(true);
  21 + shiftingMode.setBoolean(menuView, false);
  22 + shiftingMode.setAccessible(false);
  23 + for (int i = 0; i < menuView.getChildCount(); i++) {
  24 + BottomNavigationItemView item = (BottomNavigationItemView) menuView.getChildAt(i);
  25 + //noinspection RestrictedApi
  26 + item.setShiftingMode(false);
  27 + // set once again checked value, so view will be updated
  28 + //noinspection RestrictedApi
  29 + item.setChecked(item.getItemData().isChecked());
  30 + }
  31 + } catch (NoSuchFieldException e) {
  32 + Log.e("BNVHelper", "Unable to get shift mode field", e);
  33 + } catch (IllegalAccessException e) {
  34 + Log.e("BNVHelper", "Unable to change value of shift mode", e);
  35 + }
  36 + }
  37 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/helper/RetrofitCreateHelper.java 0 → 100644
... ... @@ -0,0 +1,130 @@
  1 +package com.share.mvpsdk.helper;
  2 +
  3 +
  4 +import com.share.mvpsdk.helper.okhttp.CacheInterceptor;
  5 +import com.share.mvpsdk.utils.StringUtils;
  6 +
  7 +import java.io.IOException;
  8 +import java.util.concurrent.TimeUnit;
  9 +
  10 +import okhttp3.Interceptor;
  11 +import okhttp3.OkHttpClient;
  12 +import okhttp3.Request;
  13 +import okhttp3.Response;
  14 +import okhttp3.logging.HttpLoggingInterceptor;
  15 +import retrofit2.Retrofit;
  16 +import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
  17 +import retrofit2.converter.gson.GsonConverterFactory;
  18 +
  19 +/**
  20 + * Created by Horrarndoo on 2017/9/7.
  21 + * <p>
  22 + */
  23 +
  24 +public class RetrofitCreateHelper {
  25 + private static final int TIMEOUT_READ = 20;
  26 + private static final int TIMEOUT_CONNECTION = 10;
  27 + private static String Authorization = "", token = "";
  28 + private static RetrofitCreateHelper retrofitCreateHelper = null;
  29 + private static final HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor()
  30 + .setLevel(HttpLoggingInterceptor.Level.BODY);
  31 + private static CacheInterceptor cacheInterceptor = new CacheInterceptor();
  32 + private static OkHttpClient.Builder okhttpClientBuilder = null;
  33 +
  34 + /*private static OkHttpClient okHttpClient = new OkHttpClient.Builder()
  35 + //SSL证书
  36 + .sslSocketFactory(TrustManager.getUnsafeOkHttpClient())
  37 + .hostnameVerifier(org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
  38 + //打印日志
  39 + .addInterceptor(interceptor)
  40 + //设置Cache拦截器
  41 + .addNetworkInterceptor(cacheInterceptor)
  42 + .addInterceptor(cacheInterceptor)
  43 + .cache(HttpCache.getCache())
  44 + //time out
  45 + .connectTimeout(TIMEOUT_CONNECTION, TimeUnit.SECONDS)
  46 + .readTimeout(TIMEOUT_READ, TimeUnit.SECONDS)
  47 + .writeTimeout(TIMEOUT_READ, TimeUnit.SECONDS)
  48 + //失败重连
  49 + .retryOnConnectionFailure(true)
  50 + .build();*/
  51 + public static RetrofitCreateHelper getInstance() {
  52 + if (null == retrofitCreateHelper) {
  53 + synchronized (RetrofitCreateHelper.class) {
  54 + if (null == retrofitCreateHelper) retrofitCreateHelper = new RetrofitCreateHelper();
  55 + }
  56 + }
  57 + return retrofitCreateHelper;
  58 + }
  59 +
  60 + public RetrofitCreateHelper() {
  61 + try {
  62 + if (null == okhttpClientBuilder) {
  63 + okhttpClientBuilder = new OkHttpClient.Builder();
  64 + okhttpClientBuilder.connectTimeout(10000, TimeUnit.SECONDS);
  65 + okhttpClientBuilder.addInterceptor(new Interceptor() {
  66 + @Override
  67 + public Response intercept(Chain chain) throws IOException {
  68 + Request original = chain.request();
  69 + Request.Builder requestBuilder = original.newBuilder().header("Authorization", Authorization);
  70 + Request request = requestBuilder.build();
  71 + return chain.proceed(request);
  72 + }
  73 + });
  74 + okhttpClientBuilder.addNetworkInterceptor(cacheInterceptor);
  75 + okhttpClientBuilder.addInterceptor(interceptor);
  76 + }
  77 + } catch (Exception e) {
  78 + e.printStackTrace();
  79 + }
  80 + }
  81 +
  82 + public <T> T createApi(Class<T> clazz, String url) {
  83 + Authorization = token;
  84 + Retrofit retrofit = new Retrofit.Builder()
  85 + .baseUrl(url)
  86 + .client(okhttpClientBuilder.build())
  87 + .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
  88 + .addConverterFactory(GsonConverterFactory.create())
  89 + .build();
  90 + return retrofit.create(clazz);
  91 + }
  92 +
  93 + // public static <T> T loginApi(Class<T> clazz, String url) {
  94 +// Authorization= StringUtils.getSign();
  95 +// okHttpClient.newBuilder().addInterceptor(new Interceptor() {
  96 +// @Override
  97 +// public Response intercept(Chain chain) throws IOException {
  98 +// Request original = chain.request();
  99 +// Request.Builder requestBuilder = original.newBuilder().header("Authorization", Authorization);
  100 +// Request request = requestBuilder.build();
  101 +// return chain.proceed(request);
  102 +// }
  103 +// });
  104 +// Log.d("77777","Authorization="+Authorization);
  105 +// Retrofit retrofit = new Retrofit.Builder()
  106 +// .baseUrl(url)
  107 +// .client(okHttpClient)
  108 +// .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
  109 +// .addConverterFactory(GsonConverterFactory.create())
  110 +// .build();
  111 +// return retrofit.create(clazz);
  112 +// }
  113 + public void setAuthorization(String Authorization) {
  114 + this.token ="Bearer " + Authorization;
  115 + }
  116 +
  117 + public <T> T login(Class<T> clazz, String url) {
  118 + Authorization = StringUtils.getSign();
  119 + Retrofit retrofit = new Retrofit.Builder()
  120 + .client(okhttpClientBuilder.build())
  121 + .baseUrl(url)
  122 + .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
  123 + .addConverterFactory(GsonConverterFactory.create())
  124 + .build();
  125 + return retrofit.create(clazz);
  126 + }
  127 +
  128 +
  129 +}
  130 +
... ...
mvpsdk/src/main/java/com/share/mvpsdk/helper/RxHelper.java 0 → 100644
... ... @@ -0,0 +1,76 @@
  1 +package com.share.mvpsdk.helper;
  2 +
  3 +
  4 +import io.reactivex.BackpressureStrategy;
  5 +import io.reactivex.Flowable;
  6 +import io.reactivex.FlowableEmitter;
  7 +import io.reactivex.FlowableOnSubscribe;
  8 +import io.reactivex.Observable;
  9 +import io.reactivex.ObservableEmitter;
  10 +import io.reactivex.ObservableOnSubscribe;
  11 +import io.reactivex.ObservableSource;
  12 +import io.reactivex.ObservableTransformer;
  13 +import io.reactivex.android.schedulers.AndroidSchedulers;
  14 +import io.reactivex.schedulers.Schedulers;
  15 +
  16 +/**
  17 + * Created by Horrarndoo on 2017/9/12.
  18 + * <p>
  19 + */
  20 +public class RxHelper {
  21 + /**
  22 + * 统一线程处理
  23 + * <p>
  24 + * 发布事件io线程,接收事件主线程
  25 + */
  26 + public static <T> ObservableTransformer<T, T> rxSchedulerHelper() {//compose处理线程
  27 + return new ObservableTransformer<T, T>() {
  28 +
  29 + @Override
  30 + public ObservableSource<T> apply(Observable<T> upstream) {
  31 + return upstream.subscribeOn(Schedulers.io())
  32 + .observeOn(AndroidSchedulers.mainThread());
  33 + }
  34 + };
  35 + }
  36 +
  37 + /**
  38 + * 生成Flowable
  39 + *
  40 + * @param t
  41 + * @return Flowable
  42 + */
  43 + public static <T> Flowable<T> createFlowable(final T t) {
  44 + return Flowable.create(new FlowableOnSubscribe<T>() {
  45 + @Override
  46 + public void subscribe(FlowableEmitter<T> emitter) throws Exception {
  47 + try {
  48 + emitter.onNext(t);
  49 + emitter.onComplete();
  50 + } catch (Exception e) {
  51 + emitter.onError(e);
  52 + }
  53 + }
  54 + }, BackpressureStrategy.BUFFER);
  55 + }
  56 +
  57 + /**
  58 + * 生成Observable
  59 + *
  60 + * @param t
  61 + * @return Flowable
  62 + */
  63 + public static <T> Observable<T> createObservable(final T t) {
  64 + return Observable.create(new ObservableOnSubscribe<T>() {
  65 + @Override
  66 + public void subscribe(ObservableEmitter<T> emitter) throws Exception {
  67 + try {
  68 + emitter.onNext(t);
  69 + emitter.onComplete();
  70 + } catch (Exception e) {
  71 + emitter.onError(e);
  72 + }
  73 + }
  74 + });
  75 + }
  76 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/helper/okhttp/CacheInterceptor.java 0 → 100644
... ... @@ -0,0 +1,84 @@
  1 +package com.share.mvpsdk.helper.okhttp;
  2 +
  3 +
  4 +
  5 +import com.share.mvpsdk.utils.AppUtils;
  6 +import com.share.mvpsdk.utils.NetworkConnectionUtils;
  7 +
  8 +import java.io.IOException;
  9 +
  10 +import okhttp3.CacheControl;
  11 +import okhttp3.Interceptor;
  12 +import okhttp3.Request;
  13 +import okhttp3.Response;
  14 +
  15 +import static com.share.mvpsdk.utils.HttpUtils.getUserAgent;
  16 +
  17 +
  18 +/**
  19 + * Created by Horrarndoo on 2017/9/12.
  20 + * <p>
  21 + * CacheInterceptor
  22 + */
  23 +public class CacheInterceptor implements Interceptor {
  24 +
  25 + @Override
  26 + public Response intercept(Chain chain) throws IOException {
  27 +
  28 + Request request = chain.request();
  29 + Response response = chain.proceed(request);
  30 + if (NetworkConnectionUtils.isNetworkConnected(AppUtils.getContext())) {
  31 + // 有网络时, 缓存1小时
  32 + int maxAge = 60 * 60;
  33 + request = request.newBuilder()
  34 + .removeHeader("User-Agent")
  35 + .header("User-Agent", getUserAgent())
  36 + .build();
  37 +
  38 +// Response response = chain.proceed(request);
  39 + return response.newBuilder()
  40 + .removeHeader("Pragma")
  41 + .removeHeader("Cache-Control")
  42 + .header("Cache-Control", "public, max-age=" + maxAge)
  43 + .build();
  44 + } else {
  45 + // 无网络时,缓存为4周
  46 + int maxStale = 60 * 60 * 24 * 28;
  47 + request = request.newBuilder()
  48 + .cacheControl(CacheControl.FORCE_CACHE)
  49 + .removeHeader("User-Agent")
  50 + .header("User-Agent", getUserAgent())
  51 + .build();
  52 +
  53 + return response.newBuilder()
  54 + .removeHeader("Pragma")
  55 + .removeHeader("Cache-Control")
  56 + .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
  57 + .build();
  58 + }
  59 + // Request request = chain.request();
  60 + // if (!NetworkConnectionUtils.isConnected(AppUtils.getContext())) {
  61 + // request = request.newBuilder()
  62 + // .cacheControl(CacheControl.FORCE_CACHE)
  63 + // .build();
  64 + // }
  65 + // Response response = chain.proceed(request);
  66 + // if (NetworkConnectionUtils.isConnected(AppUtils.getContext())) {
  67 + // int maxAge = 0;
  68 + // // 有网络时, 不缓存, 最大保存时长为0
  69 + // response.newBuilder()
  70 + // .header("Cache-Control", "public, max-age=" + maxAge)
  71 + // .removeHeader("Pragma")
  72 + // .build();
  73 + // } else {
  74 + // // 无网络时,设置超时为4周
  75 + // int maxStale = 60 * 60 * 24 * 28;
  76 + // response.newBuilder()
  77 + // .header("Cache-Control", "public, only-if-cached, max-stale=" +
  78 + // maxStale)
  79 + // .removeHeader("Pragma")
  80 + // .build();
  81 + // }
  82 + // return response;
  83 + }
  84 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/helper/okhttp/HttpCache.java 0 → 100644
... ... @@ -0,0 +1,28 @@
  1 +package com.share.mvpsdk.helper.okhttp;
  2 +
  3 +
  4 +import android.os.Environment;
  5 +
  6 +import com.share.mvpsdk.utils.AppUtils;
  7 +
  8 +import java.io.File;
  9 +
  10 +import okhttp3.Cache;
  11 +
  12 +/**
  13 + * Created by Horrarndoo on 2017/9/12.
  14 + * <p>
  15 + */
  16 +public class HttpCache {
  17 +
  18 + private static final int HTTP_RESPONSE_DISK_CACHE_MAX_SIZE = 50 * 1024 * 1024;
  19 +
  20 + public static Cache getCache() {
  21 + File file=new File(Environment.getExternalStorageDirectory() + File
  22 + .separator + "data/NetCache");
  23 + if (!file.getParentFile().exists())file.getParentFile().mkdirs();
  24 + if (!file.exists())file.mkdirs();
  25 + return new Cache(file,
  26 + HTTP_RESPONSE_DISK_CACHE_MAX_SIZE);
  27 + }
  28 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/helper/okhttp/NetInterceptor.java 0 → 100644
... ... @@ -0,0 +1,49 @@
  1 +package com.share.mvpsdk.helper.okhttp;
  2 +
  3 +
  4 +import com.share.mvpsdk.utils.AppUtils;
  5 +import com.share.mvpsdk.utils.NetworkConnectionUtils;
  6 +
  7 +import java.io.IOException;
  8 +
  9 +import okhttp3.Interceptor;
  10 +import okhttp3.Request;
  11 +import okhttp3.Response;
  12 +
  13 +import static com.share.mvpsdk.utils.HttpUtils.getUserAgent;
  14 +
  15 +
  16 +/**
  17 + * Created by Horrarndoo on 2017/9/18.
  18 + * <p>
  19 + * 有网络时的缓存拦截器
  20 + */
  21 +
  22 +public class NetInterceptor implements Interceptor{
  23 + @Override
  24 + public Response intercept(Chain chain) throws IOException {
  25 + // 有网络时, 缓存1分钟, 最大保存时长为60s
  26 + int maxAge = 60;
  27 + Request request = chain.request();
  28 +
  29 + if (NetworkConnectionUtils.isNetworkConnected(AppUtils.getContext())) {
  30 + request = request.newBuilder()
  31 + .removeHeader("User-Agent")
  32 + .header("User-Agent", getUserAgent())
  33 + // .header("User-Agent", "Mozilla/5.0 (Windows NT 6.1;
  34 + // WOW64) AppleWebKit/537.36" +
  35 + // " (KHTML, like Gecko) Chrome/50.0.2661.102
  36 + // Safari/537.36")
  37 + .build();
  38 +
  39 + Response response = chain.proceed(request);
  40 + return response.newBuilder()
  41 + .removeHeader("Pragma")
  42 + .removeHeader("Cache-Control")
  43 + .header("Cache-Control", "public, max-age=" + maxAge)
  44 + .build();
  45 + }
  46 +
  47 + return chain.proceed(request);
  48 + }
  49 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/helper/okhttp/NoNetInterceptor.java 0 → 100644
... ... @@ -0,0 +1,50 @@
  1 +package com.share.mvpsdk.helper.okhttp;
  2 +
  3 +
  4 +import com.share.mvpsdk.utils.AppUtils;
  5 +import com.share.mvpsdk.utils.NetworkConnectionUtils;
  6 +
  7 +import java.io.IOException;
  8 +
  9 +import okhttp3.CacheControl;
  10 +import okhttp3.Interceptor;
  11 +import okhttp3.Request;
  12 +import okhttp3.Response;
  13 +
  14 +import static com.share.mvpsdk.utils.HttpUtils.getUserAgent;
  15 +
  16 +/**
  17 + * Created by Horrarndoo on 2017/9/18.
  18 + * <p>
  19 + * 无网络时的缓存拦截器
  20 + */
  21 +
  22 +public class NoNetInterceptor implements Interceptor {
  23 + @Override
  24 + public Response intercept(Chain chain) throws IOException {
  25 + // 无网络时,设置超时为4周
  26 + int maxStale = 60 * 60 * 24 * 28;
  27 + Request request = chain.request();
  28 +
  29 + if (!NetworkConnectionUtils.isNetworkConnected(AppUtils.getContext())) {
  30 + request = request.newBuilder()
  31 + .cacheControl(CacheControl.FORCE_CACHE)
  32 + .removeHeader("User-Agent")
  33 + .header("User-Agent", getUserAgent())
  34 + // .header("User-Agent", "Mozilla/5.0 (Windows NT 6.1;
  35 + // WOW64) AppleWebKit/537.36" +
  36 + // " (KHTML, like Gecko) Chrome/50.0.2661.102
  37 + // Safari/537.36")
  38 + .build();
  39 +
  40 + Response response = chain.proceed(request);
  41 + return response.newBuilder()
  42 + .removeHeader("Pragma")
  43 + .removeHeader("Cache-Control")
  44 + .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
  45 + .build();
  46 + }
  47 +
  48 + return chain.proceed(request);
  49 + }
  50 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/helper/okhttp/TrustManager.java 0 → 100644
... ... @@ -0,0 +1,54 @@
  1 +package com.share.mvpsdk.helper.okhttp;
  2 +
  3 +import java.security.cert.CertificateException;
  4 +import java.security.cert.X509Certificate;
  5 +
  6 +import javax.net.ssl.SSLContext;
  7 +import javax.net.ssl.SSLSocketFactory;
  8 +import javax.net.ssl.X509TrustManager;
  9 +
  10 +/**
  11 + * Created by Horrarndoo on 2017/9/12.
  12 + * <p>
  13 + */
  14 +public class TrustManager {
  15 +
  16 + public static SSLSocketFactory getUnsafeOkHttpClient() {
  17 + try {
  18 + // Create a trust manager that does not validate certificate chains
  19 + final X509TrustManager[] trustAllCerts = new X509TrustManager[]{new X509TrustManager() {
  20 + @Override
  21 + public void checkClientTrusted(
  22 + X509Certificate[] chain,
  23 + String authType) throws CertificateException {
  24 + }
  25 +
  26 + @Override
  27 + public void checkServerTrusted(
  28 + X509Certificate[] chain,
  29 + String authType) throws CertificateException {
  30 + }
  31 +
  32 + @Override
  33 + public X509Certificate[] getAcceptedIssuers() {
  34 + return new X509Certificate[0];
  35 + }
  36 + }};
  37 +
  38 + // Install the all-trusting trust manager
  39 + final SSLContext sslContext = SSLContext.getInstance("TLS");
  40 + sslContext.init(null, trustAllCerts,
  41 + new java.security.SecureRandom());
  42 + // Create an ssl socket factory with our all-trusting manager
  43 + final SSLSocketFactory sslSocketFactory = sslContext
  44 + .getSocketFactory();
  45 +
  46 +
  47 + return sslSocketFactory;
  48 + } catch (Exception e) {
  49 + throw new RuntimeException(e);
  50 + }
  51 +
  52 + }
  53 +}
  54 +
... ...
mvpsdk/src/main/java/com/share/mvpsdk/rxbus/BusData.java 0 → 100644
... ... @@ -0,0 +1,34 @@
  1 +package com.share.mvpsdk.rxbus;
  2 +
  3 +/**
  4 + * RxBus data
  5 + * Created by gorden on 2016/7/8.
  6 + */
  7 +public class BusData {
  8 + String id;
  9 + String status;
  10 +
  11 + public BusData() {
  12 + }
  13 +
  14 + public BusData(String id, String status) {
  15 + this.id = id;
  16 + this.status = status;
  17 + }
  18 +
  19 + public String getId() {
  20 + return id;
  21 + }
  22 +
  23 + public void setId(String id) {
  24 + this.id = id;
  25 + }
  26 +
  27 + public String getStatus() {
  28 + return status;
  29 + }
  30 +
  31 + public void setStatus(String status) {
  32 + this.status = status;
  33 + }
  34 +}
0 35 \ No newline at end of file
... ...
mvpsdk/src/main/java/com/share/mvpsdk/rxbus/RxBus.java 0 → 100644
... ... @@ -0,0 +1,355 @@
  1 +package com.share.mvpsdk.rxbus;
  2 +
  3 +import java.lang.reflect.Method;
  4 +import java.util.ArrayList;
  5 +import java.util.HashMap;
  6 +import java.util.Iterator;
  7 +import java.util.List;
  8 +import java.util.Map;
  9 +
  10 +import io.reactivex.BackpressureStrategy;
  11 +import io.reactivex.Flowable;
  12 +import io.reactivex.Scheduler;
  13 +import io.reactivex.android.schedulers.AndroidSchedulers;
  14 +import io.reactivex.disposables.Disposable;
  15 +import io.reactivex.functions.Consumer;
  16 +import io.reactivex.functions.Function;
  17 +import io.reactivex.functions.Predicate;
  18 +import io.reactivex.schedulers.Schedulers;
  19 +import io.reactivex.subjects.PublishSubject;
  20 +import io.reactivex.subjects.Subject;
  21 +
  22 +/**
  23 + * RxBus
  24 + * Created by gorden on 2016/5/12.
  25 + * update 2017/3/1
  26 + */
  27 +@SuppressWarnings("unused")
  28 +public class RxBus {
  29 + public static final String LOG_BUS = "RXBUS_LOG";
  30 + private static volatile RxBus defaultInstance;
  31 +
  32 + private Map<Class, List<Disposable>> subscriptionsByEventType = new HashMap<>();
  33 +
  34 + private Map<Object, List<Class>> eventTypesBySubscriber = new HashMap<>();
  35 +
  36 + private Map<Class, List<SubscriberMethod>> subscriberMethodByEventType = new HashMap<>();
  37 +
  38 + private final Subject<Object> bus;
  39 +
  40 + private RxBus() {
  41 + this.bus = PublishSubject.create().toSerialized();
  42 + }
  43 +
  44 + public static RxBus get() {
  45 + RxBus rxBus = defaultInstance;
  46 + if (defaultInstance == null) {
  47 + synchronized (RxBus.class) {
  48 + rxBus = defaultInstance;
  49 + if (defaultInstance == null) {
  50 + rxBus = new RxBus();
  51 + defaultInstance = rxBus;
  52 + }
  53 + }
  54 + }
  55 + return rxBus;
  56 + }
  57 +
  58 + /**
  59 + * 根据传递的 eventType 类型返回特定类型(eventType)的 被观察者
  60 + *
  61 + * @param eventType 事件类型
  62 + * @return return
  63 + */
  64 + private <T> Flowable<T> toObservable(Class<T> eventType) {
  65 + return bus.toFlowable(BackpressureStrategy.BUFFER).ofType(eventType);
  66 + }
  67 +
  68 + /**
  69 + * 根据传递的code和 eventType 类型返回特定类型(eventType)的 被观察者
  70 + *
  71 + * @param code 事件code
  72 + * @param eventType 事件类型
  73 + */
  74 + private <T> Flowable<T> toObservable(final int code, final Class<T> eventType) {
  75 + return bus.toFlowable(BackpressureStrategy.BUFFER).ofType(Message.class)
  76 + .filter(new Predicate<Message>() {
  77 + @Override
  78 + public boolean test(Message o) throws Exception {
  79 + return o.getCode() == code && eventType.isInstance(o.getObject());
  80 + }
  81 + }).map(new Function<Message, Object>() {
  82 + @Override
  83 + public Object apply(Message o) throws Exception {
  84 + return o.getObject();
  85 + }
  86 + }).cast(eventType);
  87 + }
  88 +
  89 + /**
  90 + * 注册
  91 + *
  92 + * @param subscriber 订阅者
  93 + */
  94 + public void register(Object subscriber) {
  95 + Class<?> subClass = subscriber.getClass();
  96 + Method[] methods = subClass.getDeclaredMethods();
  97 + for (Method method : methods) {
  98 + if (method.isAnnotationPresent(Subscribe.class)) {
  99 + //获得参数类型
  100 + Class[] parameterType = method.getParameterTypes();
  101 + //参数不为空 且参数个数为1
  102 + if (parameterType != null && parameterType.length == 1) {
  103 +
  104 + Class eventType = parameterType[0];
  105 +
  106 + addEventTypeToMap(subscriber, eventType);
  107 + Subscribe sub = method.getAnnotation(Subscribe.class);
  108 + int code = sub.code();
  109 + ThreadMode threadMode = sub.threadMode();
  110 +
  111 + SubscriberMethod subscriberMethod = new SubscriberMethod(subscriber, method, eventType, code, threadMode);
  112 + addSubscriberToMap(eventType, subscriberMethod);
  113 +
  114 + addSubscriber(subscriberMethod);
  115 + } else if (parameterType == null || parameterType.length == 0) {
  116 +
  117 + Class eventType = BusData.class;
  118 +
  119 + addEventTypeToMap(subscriber, eventType);
  120 + Subscribe sub = method.getAnnotation(Subscribe.class);
  121 + int code = sub.code();
  122 + ThreadMode threadMode = sub.threadMode();
  123 +
  124 + SubscriberMethod subscriberMethod = new SubscriberMethod(subscriber, method, eventType, code, threadMode);
  125 + addSubscriberToMap(eventType, subscriberMethod);
  126 +
  127 + addSubscriber(subscriberMethod);
  128 +
  129 + }
  130 + }
  131 + }
  132 + }
  133 +
  134 +
  135 + /**
  136 + * 将event的类型以订阅中subscriber为key保存到map里
  137 + *
  138 + * @param subscriber 订阅者
  139 + * @param eventType event类型
  140 + */
  141 + private void addEventTypeToMap(Object subscriber, Class eventType) {
  142 + List<Class> eventTypes = eventTypesBySubscriber.get(subscriber);
  143 + if (eventTypes == null) {
  144 + eventTypes = new ArrayList<>();
  145 + eventTypesBySubscriber.put(subscriber, eventTypes);
  146 + }
  147 +
  148 + if (!eventTypes.contains(eventType)) {
  149 + eventTypes.add(eventType);
  150 + }
  151 + }
  152 +
  153 + /**
  154 + * 将注解方法信息以event类型为key保存到map中
  155 + *
  156 + * @param eventType event类型
  157 + * @param subscriberMethod 注解方法信息
  158 + */
  159 + private void addSubscriberToMap(Class eventType, SubscriberMethod subscriberMethod) {
  160 + List<SubscriberMethod> subscriberMethods = subscriberMethodByEventType.get(eventType);
  161 + if (subscriberMethods == null) {
  162 + subscriberMethods = new ArrayList<>();
  163 + subscriberMethodByEventType.put(eventType, subscriberMethods);
  164 + }
  165 +
  166 + if (!subscriberMethods.contains(subscriberMethod)) {
  167 + subscriberMethods.add(subscriberMethod);
  168 + }
  169 + }
  170 +
  171 + /**
  172 + * 将订阅事件以event类型为key保存到map,用于取消订阅时用
  173 + *
  174 + * @param eventType event类型
  175 + * @param disposable 订阅事件
  176 + */
  177 + private void addSubscriptionToMap(Class eventType, Disposable disposable) {
  178 + List<Disposable> disposables = subscriptionsByEventType.get(eventType);
  179 + if (disposables == null) {
  180 + disposables = new ArrayList<>();
  181 + subscriptionsByEventType.put(eventType, disposables);
  182 + }
  183 +
  184 + if (!disposables.contains(disposable)) {
  185 + disposables.add(disposable);
  186 + }
  187 + }
  188 +
  189 + /**
  190 + * 用RxJava添加订阅者
  191 + *
  192 + * @param subscriberMethod d
  193 + */
  194 + @SuppressWarnings("unchecked")
  195 + private void addSubscriber(final SubscriberMethod subscriberMethod) {
  196 + Flowable flowable;
  197 + if (subscriberMethod.code == -1) {
  198 + flowable = toObservable(subscriberMethod.eventType);
  199 + } else {
  200 + flowable = toObservable(subscriberMethod.code, subscriberMethod.eventType);
  201 + }
  202 + Disposable subscription = postToObservable(flowable, subscriberMethod)
  203 + .subscribe(new Consumer<Object>() {
  204 + @Override
  205 + public void accept(Object o) throws Exception {
  206 + callEvent(subscriberMethod, o);
  207 + }
  208 + });
  209 +
  210 + addSubscriptionToMap(subscriberMethod.subscriber.getClass(), subscription);
  211 + }
  212 +
  213 + /**
  214 + * 用于处理订阅事件在那个线程中执行
  215 + *
  216 + * @param observable d
  217 + * @param subscriberMethod d
  218 + * @return Observable
  219 + */
  220 + private Flowable postToObservable(Flowable observable, SubscriberMethod subscriberMethod) {
  221 + Scheduler scheduler;
  222 + switch (subscriberMethod.threadMode) {
  223 + case MAIN:
  224 + scheduler = AndroidSchedulers.mainThread();
  225 + break;
  226 +
  227 + case NEW_THREAD:
  228 + scheduler = Schedulers.newThread();
  229 + break;
  230 +
  231 + case CURRENT_THREAD:
  232 + scheduler = Schedulers.trampoline();
  233 + break;
  234 + default:
  235 + throw new IllegalStateException("Unknown thread mode: " + subscriberMethod.threadMode);
  236 + }
  237 + return observable.observeOn(scheduler);
  238 + }
  239 +
  240 + /**
  241 + * 回调到订阅者的方法中
  242 + *
  243 + * @param method code
  244 + * @param object obj
  245 + */
  246 + private void callEvent(SubscriberMethod method, Object object) {
  247 + Class eventClass = object.getClass();
  248 + List<SubscriberMethod> methods = subscriberMethodByEventType.get(eventClass);
  249 + if (methods != null && methods.size() > 0) {
  250 + for (SubscriberMethod subscriberMethod : methods) {
  251 + Subscribe sub = subscriberMethod.method.getAnnotation(Subscribe.class);
  252 + int c = sub.code();
  253 + if (c == method.code && method.subscriber.equals(subscriberMethod.subscriber) && method.method.equals(subscriberMethod.method)) {
  254 + subscriberMethod.invoke(object);
  255 + }
  256 +
  257 + }
  258 + }
  259 + }
  260 +
  261 + /**
  262 + * 取消注册
  263 + *
  264 + * @param subscriber object
  265 + */
  266 + public void unRegister(Object subscriber) {
  267 + List<Class> subscribedTypes = eventTypesBySubscriber.get(subscriber);
  268 + if (subscribedTypes != null) {
  269 + for (Class<?> eventType : subscribedTypes) {
  270 + unSubscribeByEventType(subscriber.getClass());
  271 + unSubscribeMethodByEventType(subscriber, eventType);
  272 + }
  273 + eventTypesBySubscriber.remove(subscriber);
  274 + }
  275 + }
  276 +
  277 + /**
  278 + * subscriptions unsubscribe
  279 + *
  280 + * @param eventType eventType
  281 + */
  282 + private void unSubscribeByEventType(Class eventType) {
  283 + List<Disposable> disposables = subscriptionsByEventType.get(eventType);
  284 + if (disposables != null) {
  285 + Iterator<Disposable> iterator = disposables.iterator();
  286 + while (iterator.hasNext()) {
  287 + Disposable disposable = iterator.next();
  288 + if (disposable != null && !disposable.isDisposed()) {
  289 + disposable.dispose();
  290 + iterator.remove();
  291 + }
  292 + }
  293 + }
  294 + }
  295 +
  296 + /**
  297 + * 移除subscriber对应的subscriberMethods
  298 + *
  299 + * @param subscriber subscriber
  300 + * @param eventType eventType
  301 + */
  302 + private void unSubscribeMethodByEventType(Object subscriber, Class eventType) {
  303 + List<SubscriberMethod> subscriberMethods = subscriberMethodByEventType.get(eventType);
  304 + if (subscriberMethods != null) {
  305 + Iterator<SubscriberMethod> iterator = subscriberMethods.iterator();
  306 + while (iterator.hasNext()) {
  307 + SubscriberMethod subscriberMethod = iterator.next();
  308 + if (subscriberMethod.subscriber.equals(subscriber)) {
  309 + iterator.remove();
  310 + }
  311 + }
  312 + }
  313 + }
  314 +
  315 + public void send(int code, Object o) {
  316 + bus.onNext(new Message(code, o));
  317 + }
  318 +
  319 + public void send(Object o) {
  320 + bus.onNext(o);
  321 + }
  322 +
  323 + public void send(int code) {
  324 + bus.onNext(new Message(code, new BusData()));
  325 + }
  326 +
  327 + private class Message {
  328 + private int code;
  329 + private Object object;
  330 +
  331 + public Message() {
  332 + }
  333 +
  334 + private Message(int code, Object o) {
  335 + this.code = code;
  336 + this.object = o;
  337 + }
  338 +
  339 + private int getCode() {
  340 + return code;
  341 + }
  342 +
  343 + public void setCode(int code) {
  344 + this.code = code;
  345 + }
  346 +
  347 + private Object getObject() {
  348 + return object;
  349 + }
  350 +
  351 + public void setObject(Object object) {
  352 + this.object = object;
  353 + }
  354 + }
  355 +}
0 356 \ No newline at end of file
... ...
mvpsdk/src/main/java/com/share/mvpsdk/rxbus/Subscribe.java 0 → 100644
... ... @@ -0,0 +1,21 @@
  1 +package com.share.mvpsdk.rxbus;
  2 +
  3 +import java.lang.annotation.Documented;
  4 +import java.lang.annotation.ElementType;
  5 +import java.lang.annotation.Retention;
  6 +import java.lang.annotation.RetentionPolicy;
  7 +import java.lang.annotation.Target;
  8 +
  9 +
  10 +/**
  11 + * Rxbus
  12 + * Created by gorden on 2016/7/23.
  13 + */
  14 +@Documented
  15 +@Target(ElementType.METHOD)
  16 +@Retention(RetentionPolicy.RUNTIME)
  17 +public @interface Subscribe {
  18 + int code() default -1;
  19 +
  20 + ThreadMode threadMode() default ThreadMode.CURRENT_THREAD;
  21 +}
0 22 \ No newline at end of file
... ...
mvpsdk/src/main/java/com/share/mvpsdk/rxbus/SubscriberMethod.java 0 → 100644
... ... @@ -0,0 +1,44 @@
  1 +package com.share.mvpsdk.rxbus;
  2 +
  3 +import java.lang.reflect.InvocationTargetException;
  4 +import java.lang.reflect.Method;
  5 +
  6 +/**
  7 + *
  8 + * Created by gorden on 2016/7/23.
  9 + */
  10 +public class SubscriberMethod {
  11 + public Method method;
  12 + public ThreadMode threadMode;
  13 + public Class<?> eventType;
  14 + public Object subscriber;
  15 + public int code;
  16 +
  17 + public SubscriberMethod(Object subscriber, Method method, Class<?> eventType, int code,ThreadMode threadMode) {
  18 + this.method = method;
  19 + this.threadMode = threadMode;
  20 + this.eventType = eventType;
  21 + this.subscriber = subscriber;
  22 + this.code = code;
  23 + }
  24 +
  25 +
  26 + /**
  27 + * 调用方法
  28 + * @param o 参数
  29 + */
  30 + public void invoke(Object o){
  31 + try {
  32 + Class[] parameterType = method.getParameterTypes();
  33 + if(parameterType != null && parameterType.length == 1){
  34 + method.invoke(subscriber, o);
  35 + }else if(parameterType == null || parameterType.length == 0){
  36 + method.invoke(subscriber);
  37 + }
  38 + } catch (IllegalAccessException e) {
  39 + e.printStackTrace();
  40 + } catch (InvocationTargetException e) {
  41 + e.printStackTrace();
  42 + }
  43 + }
  44 +}
0 45 \ No newline at end of file
... ...
mvpsdk/src/main/java/com/share/mvpsdk/rxbus/ThreadMode.java 0 → 100644
... ... @@ -0,0 +1,23 @@
  1 +package com.share.mvpsdk.rxbus;
  2 +
  3 +/**
  4 + *
  5 + * Created by gorden on 2016/7/23.
  6 + */
  7 +public enum ThreadMode {
  8 + /**
  9 + * current thread
  10 + */
  11 + CURRENT_THREAD,
  12 +
  13 + /**
  14 + * android main thread
  15 + */
  16 + MAIN,
  17 +
  18 +
  19 + /**
  20 + * new thread
  21 + */
  22 + NEW_THREAD
  23 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/utils/AppUtils.java 0 → 100644
... ... @@ -0,0 +1,185 @@
  1 +package com.share.mvpsdk.utils;
  2 +
  3 +import android.annotation.SuppressLint;
  4 +import android.content.ClipData;
  5 +import android.content.ClipboardManager;
  6 +import android.content.Context;
  7 +import android.content.Intent;
  8 +import android.content.pm.PackageInfo;
  9 +import android.content.pm.PackageManager;
  10 +import android.net.Uri;
  11 +import android.os.Environment;
  12 +import android.os.Handler;
  13 +import android.telephony.TelephonyManager;
  14 +import android.util.Log;
  15 +import android.view.inputmethod.InputMethodManager;
  16 +import android.widget.EditText;
  17 +
  18 +
  19 +import com.share.mvpsdk.global.GlobalApplication;
  20 +
  21 +import java.io.File;
  22 +
  23 +import timber.log.Timber;
  24 +
  25 +/**
  26 + * Created by Horrarndoo on 2017/8/31.
  27 + * <p>
  28 + * App工具类
  29 + */
  30 +public class AppUtils {
  31 +
  32 + /**
  33 + * 获取上下文对象
  34 + *
  35 + * @return 上下文对象
  36 + */
  37 + public static Context getContext() {
  38 + return GlobalApplication.getContext();
  39 + }
  40 +
  41 + /**
  42 + * 获取全局handler
  43 + *
  44 + * @return 全局handler
  45 + */
  46 + public static Handler getHandler() {
  47 + return GlobalApplication.getHandler();
  48 + }
  49 +
  50 + /**
  51 + * 获取主线程id
  52 + *
  53 + * @return 主线程id
  54 + */
  55 + public static int getMainThreadId() {
  56 + return GlobalApplication.getMainThreadId();
  57 + }
  58 +
  59 + /**
  60 + * 获取版本名称
  61 + */
  62 + public static String getAppVersionName(Context context) {
  63 + String versionName = "";
  64 + try {
  65 + // ---get the package info---
  66 + PackageManager pm = context.getPackageManager();
  67 + PackageInfo pi = pm.getPackageInfo(context.getPackageName(), 0);
  68 + versionName = pi.versionName;
  69 + if (versionName == null || versionName.length() <= 0) {
  70 + return "";
  71 + }
  72 + } catch (Exception e) {
  73 + Log.e("VersionInfo", "Exception", e);
  74 + }
  75 + return versionName;
  76 + }
  77 +
  78 + /**
  79 + * 获取版本号
  80 + */
  81 + public static int getAppVersionCode(Context context) {
  82 + int versioncode = -1;
  83 + try {
  84 + // ---get the package info---
  85 + PackageManager pm = context.getPackageManager();
  86 + PackageInfo pi = pm.getPackageInfo(context.getPackageName(), 0);
  87 + versioncode = pi.versionCode;
  88 + } catch (Exception e) {
  89 + Log.e("VersionInfo", "Exception", e);
  90 + }
  91 + return versioncode;
  92 + }
  93 +
  94 + @SuppressLint("MissingPermission")
  95 + public static String getIMEI(Context context) {
  96 + TelephonyManager tm = (TelephonyManager) context.getSystemService(Context
  97 + .TELEPHONY_SERVICE);
  98 + return tm.getDeviceId();
  99 + }
  100 +
  101 + /**
  102 + * 显示软键盘
  103 + */
  104 + public static void openSoftInput(EditText et) {
  105 + InputMethodManager inputMethodManager = (InputMethodManager) et.getContext()
  106 + .getSystemService(Context.INPUT_METHOD_SERVICE);
  107 + inputMethodManager.showSoftInput(et, InputMethodManager.HIDE_NOT_ALWAYS);
  108 + }
  109 +
  110 + /**
  111 + * 隐藏软键盘
  112 + */
  113 + public static void hideSoftInput(EditText et) {
  114 + InputMethodManager inputMethodManager = (InputMethodManager) et.getContext()
  115 + .getSystemService(Context.INPUT_METHOD_SERVICE);
  116 + inputMethodManager.hideSoftInputFromWindow(et.getWindowToken(), InputMethodManager
  117 + .HIDE_NOT_ALWAYS);
  118 + }
  119 +
  120 + /**
  121 + * 获取SD卡路径
  122 + *
  123 + * @return 如果sd卡不存在则返回null
  124 + */
  125 + public static File getSDPath() {
  126 + File sdDir = null;
  127 + boolean sdCardExist = Environment.getExternalStorageState().equals(Environment
  128 + .MEDIA_MOUNTED); //判断sd卡是否存在
  129 + if (sdCardExist) {
  130 + sdDir = Environment.getExternalStorageDirectory();//获取跟目录
  131 + }
  132 + return sdDir;
  133 + }
  134 +
  135 + /**
  136 + * 安装文件
  137 + *
  138 + * @param data
  139 + */
  140 + public static void promptInstall(Context context, Uri data) {
  141 + Intent promptInstall = new Intent(Intent.ACTION_VIEW)
  142 + .setDataAndType(data, "application/vnd.android.package-archive");
  143 + // FLAG_ACTIVITY_NEW_TASK 可以保证安装成功时可以正常打开 app
  144 + promptInstall.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  145 + context.startActivity(promptInstall);
  146 + }
  147 +
  148 + public static void copy2clipboard(Context context, String text) {
  149 + ClipboardManager cm = (ClipboardManager) context.getSystemService(Context
  150 + .CLIPBOARD_SERVICE);
  151 + ClipData clip = ClipData.newPlainText("clip", text);
  152 + cm.setPrimaryClip(clip);
  153 + }
  154 +
  155 + /**
  156 + * 判断是否运行在主线程
  157 + *
  158 + * @return true:当前线程运行在主线程
  159 + * fasle:当前线程没有运行在主线程
  160 + */
  161 + public static boolean isRunOnUIThread() {
  162 + // 获取当前线程id, 如果当前线程id和主线程id相同, 那么当前就是主线程
  163 + int myTid = android.os.Process.myTid();
  164 + if (myTid == getMainThreadId()) {
  165 + return true;
  166 + }
  167 + return false;
  168 + }
  169 +
  170 + /**
  171 + * 运行在主线程
  172 + *
  173 + * @param r 运行的Runnable对象
  174 + */
  175 + public static void runOnUIThread(Runnable r) {
  176 + if (isRunOnUIThread()) {
  177 + // 已经是主线程, 直接运行
  178 + r.run();
  179 + } else {
  180 + // 如果是子线程, 借助handler让其运行在主线程
  181 + Log.d("66666","getHander="+getHandler()+"r="+r);
  182 + getHandler().post(r);
  183 + }
  184 + }
  185 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/utils/CacheUtils.java 0 → 100644
... ... @@ -0,0 +1,168 @@
  1 +package com.share.mvpsdk.utils;
  2 +
  3 +import android.content.Context;
  4 +import android.os.Environment;
  5 +
  6 +import java.io.File;
  7 +import java.math.BigDecimal;
  8 +
  9 +/**
  10 + * Created by ToaHanDong on 2018/3/15.
  11 + */
  12 +
  13 +public class CacheUtils {
  14 +
  15 + /** * 清除本应用内部缓存(/data/data/com.xxx.xxx/cache) * * @param context */
  16 + public static void cleanInternalCache(Context context) {
  17 + deleteFilesByDirectory(context.getCacheDir());
  18 + }
  19 +
  20 + /** * 清除本应用所有数据库(/data/data/com.xxx.xxx/databases) * * @param context */
  21 + public static void cleanDatabases(Context context) {
  22 + deleteFilesByDirectory(new File("/data/data/"
  23 + + context.getPackageName() + "/databases"));
  24 + }
  25 +
  26 + /**
  27 + * * 清除本应用SharedPreference(/data/data/com.xxx.xxx/shared_prefs) * * @param
  28 + * context
  29 + */
  30 + public static void cleanSharedPreference(Context context) {
  31 + deleteFilesByDirectory(new File("/data/data/"+ context.getPackageName() + "/shared_prefs"));
  32 + }
  33 +
  34 + /** * 按名字清除本应用数据库 * * @param context * @param dbName */
  35 + public static void cleanDatabaseByName(Context context, String dbName) {
  36 + context.deleteDatabase(dbName);
  37 + }
  38 +
  39 + /** * 清除/data/data/com.xxx.xxx/files下的内容 * * @param context */
  40 + public static void cleanFiles(Context context) {
  41 + deleteFilesByDirectory(context.getFilesDir());
  42 + }
  43 +
  44 + /**
  45 + * * 清除外部cache下的内容(/mnt/sdcard/android/data/com.xxx.xxx/cache) * * @param
  46 + * context
  47 + */
  48 + public static void cleanExternalCache(Context context) {
  49 + if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
  50 + deleteFilesByDirectory(context.getExternalCacheDir());
  51 + }
  52 + }
  53 +
  54 + /** * 清除自定义路径下的文件,使用需小心,请不要误删。而且只支持目录下的文件删除 * * @param filePath */
  55 + public static void cleanCustomCache(String filePath) {
  56 + deleteFilesByDirectory1(new File(filePath));
  57 + }
  58 +
  59 + /** * 清除本应用所有的数据 * * @param context * @param filepath */
  60 + public static void cleanApplicationData(Context context, String filepath) {
  61 +// cleanInternalCache(context);
  62 +// cleanExternalCache(context);
  63 +// cleanDatabases(context);
  64 + cleanSharedPreference(context);
  65 +// cleanFiles(context);
  66 +// cleanCustomCache(filepath);
  67 + }
  68 +
  69 + /** * 删除方法 这里只会删除某个文件夹下的文件,如果传入的directory是个文件,将不做处理 * * @param directory */
  70 + public static void deleteFilesByDirectory(File directory) {
  71 + if (directory != null && directory.exists() && directory.isDirectory()) {
  72 + for (File item : directory.listFiles()) {
  73 + item.delete();
  74 + }
  75 + }
  76 + }
  77 + private static void deleteFilesByDirectory1(File dir){
  78 + if (dir!=null && dir.isDirectory()) {
  79 + String[] children = dir.list();
  80 + //递归删除目录中的子目录下
  81 + for (int i = 0; i < children.length; i++) {
  82 + StorageUtils.DeleteDirAndFile(new File(dir, children[i]));
  83 + }
  84 + }
  85 + }
  86 +
  87 + /**
  88 + * 清理缓存
  89 + * @param context
  90 + * @param filepath
  91 + */
  92 + public static void cleanEboardCache(Context context, String filepath) {
  93 + cleanInternalCache(context);
  94 + cleanExternalCache(context);
  95 + cleanFiles(context);
  96 + cleanCustomCache(filepath);
  97 + }
  98 +
  99 + public static void clearCache(Context context)throws Exception{
  100 + File file=new File("/data/data/"+ context.getPackageName());
  101 + cleanCustomCache(file.toString());
  102 + }
  103 +
  104 + public static String getCacheSize(Context context) throws Exception {
  105 + File file=new File("/data/data/"+ context.getPackageName());
  106 + return getFormatSize(getFolderSize(file));
  107 + }
  108 +
  109 + // 获取文件
  110 + //Context.getExternalFilesDir() --> SDCard/Android/data/你的应用的包名/files/ 目录,一般放一些长时间保存的数据
  111 + //Context.getExternalCacheDir() --> SDCard/Android/data/你的应用包名/cache/目录,一般存放临时缓存数据
  112 + public static long getFolderSize(File file) throws Exception {
  113 + long size = 0;
  114 + try {
  115 + File[] fileList = file.listFiles();
  116 + for (int i = 0; i < fileList.length; i++) {
  117 + // 如果下面还有文件
  118 + if (fileList[i].isDirectory()) {
  119 + size = size + getFolderSize(fileList[i]);
  120 + } else {
  121 + size = size + fileList[i].length();
  122 + }
  123 + }
  124 + } catch (Exception e) {
  125 + e.printStackTrace();
  126 + }
  127 + return size;
  128 + }
  129 +
  130 +
  131 + /**
  132 + * 格式化单位
  133 + *
  134 + * @param size
  135 + * @return
  136 + */
  137 + public static String getFormatSize(double size) {
  138 + double kiloByte = size / 1024;
  139 + if (kiloByte < 1) {
  140 + return size + "Byte";
  141 + }
  142 +
  143 + double megaByte = kiloByte / 1024;
  144 + if (megaByte < 1) {
  145 + BigDecimal result1 = new BigDecimal(Double.toString(kiloByte));
  146 + return result1.setScale(2, BigDecimal.ROUND_HALF_UP)
  147 + .toPlainString() + "KB";
  148 + }
  149 +
  150 + double gigaByte = megaByte / 1024;
  151 + if (gigaByte < 1) {
  152 + BigDecimal result2 = new BigDecimal(Double.toString(megaByte));
  153 + return result2.setScale(2, BigDecimal.ROUND_HALF_UP)
  154 + .toPlainString() + "MB";
  155 + }
  156 +
  157 + double teraBytes = gigaByte / 1024;
  158 + if (teraBytes < 1) {
  159 + BigDecimal result3 = new BigDecimal(Double.toString(gigaByte));
  160 + return result3.setScale(2, BigDecimal.ROUND_HALF_UP)
  161 + .toPlainString() + "GB";
  162 + }
  163 + BigDecimal result4 = new BigDecimal(teraBytes);
  164 + return result4.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString()
  165 + + "TB";
  166 + }
  167 +
  168 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/utils/DBUtils.java 0 → 100644
... ... @@ -0,0 +1,114 @@
  1 +package com.share.mvpsdk.utils;
  2 +
  3 +import android.content.ContentValues;
  4 +import android.content.Context;
  5 +import android.content.SharedPreferences;
  6 +import android.database.Cursor;
  7 +import android.database.sqlite.SQLiteDatabase;
  8 +import android.database.sqlite.SQLiteOpenHelper;
  9 +
  10 +import com.share.mvpsdk.config.DBConfig;
  11 +
  12 +
  13 +/**
  14 + * Created by Horrarndoo on 2017/8/31.
  15 + * <p>
  16 + * 数据库工具类
  17 + */
  18 +public class DBUtils {
  19 + public static final String CREATE_TABLE_IF_NOT_EXISTS = "create table if not exists %s " +
  20 + "(id integer primary key autoincrement,title text unique,image text)";
  21 +
  22 +
  23 + private static DBUtils sDBUtis;
  24 + private SQLiteDatabase mSQLiteDatabase;
  25 +
  26 + private DBUtils(Context context) {
  27 + mSQLiteDatabase = new DBHelper(context, DBConfig.DB_NAME + ".db")
  28 + .getWritableDatabase();
  29 + }
  30 +
  31 + public static synchronized DBUtils getDB(Context context) {
  32 + if (sDBUtis == null) {
  33 + synchronized (DBUtils.class) {
  34 + if (sDBUtis == null)
  35 + sDBUtis = new DBUtils(context);
  36 + }
  37 + }
  38 + return sDBUtis;
  39 + }
  40 +
  41 + /**
  42 + * 插入一个item已读状态到数据表
  43 + *
  44 + * @param table 数据表名
  45 + * @param key key值
  46 + * @param value 数据值
  47 + * @return 插入结果
  48 + */
  49 + public boolean insertRead(final String table, String key, int value) {
  50 + Cursor cursor = mSQLiteDatabase.query(table, null, null, null, null, null, "id asc");
  51 + //最多缓存200条
  52 + if (cursor.getCount() > 200 && cursor.moveToNext()) {
  53 + mSQLiteDatabase.delete(table, "id=?", new String[]{String.valueOf(cursor.getInt
  54 + (cursor.getColumnIndex("id")))});
  55 + }
  56 + cursor.close();
  57 + final ContentValues contentValues = new ContentValues();
  58 + contentValues.put("key", key);
  59 + contentValues.put("is_read", value);
  60 + return (mSQLiteDatabase.insertWithOnConflict(table, null, contentValues, SQLiteDatabase
  61 + .CONFLICT_REPLACE) > 0);
  62 + }
  63 +
  64 + /**
  65 + * 判断item是否已经阅读过
  66 + *
  67 + * @param table 数据表名
  68 + * @param key key值
  69 + * @param value
  70 + * @return
  71 + */
  72 + public boolean isRead(String table, String key, int value) {
  73 + boolean isRead = false;
  74 + Cursor cursor = mSQLiteDatabase.query(table, null, "key=?", new String[]{key}, null,
  75 + null, null);
  76 + if (cursor.moveToNext() && (cursor.getInt(cursor.getColumnIndex("is_read")) == value)) {
  77 + isRead = true;
  78 + }
  79 + cursor.close();
  80 + return isRead;
  81 + }
  82 +
  83 + public void insert(String table,String key,String value){
  84 +
  85 + }
  86 +
  87 + public class DBHelper extends SQLiteOpenHelper {
  88 +
  89 + public DBHelper(Context context, String name) {
  90 + super(context, name, null, 1);
  91 + }
  92 +
  93 + @Override
  94 + public void onCreate(SQLiteDatabase db) {
  95 + //onCreate()方法只有数据库第一次被创建时才会调用,若数据库已存在,此方法不会被调用
  96 + }
  97 +
  98 + @Override
  99 + public void onOpen(SQLiteDatabase db) {
  100 + super.onOpen(db);
  101 + //数据库打开时就会被调用,将插入新表的操作方到onOpen中
  102 + db.execSQL(String.format(CREATE_TABLE_IF_NOT_EXISTS, DBConfig.TABLE_ZHIHU));
  103 + db.execSQL(String.format(CREATE_TABLE_IF_NOT_EXISTS, DBConfig.TABLE_WANGYI));
  104 + db.execSQL(String.format(CREATE_TABLE_IF_NOT_EXISTS, DBConfig.TABLE_WEIXIN));
  105 + db.execSQL(String.format(CREATE_TABLE_IF_NOT_EXISTS, DBConfig.TABLE_GANKIO_DAY));
  106 + db.execSQL(String.format(CREATE_TABLE_IF_NOT_EXISTS, DBConfig.TABLE_GANKIO_CUSTOM));
  107 + }
  108 +
  109 + @Override
  110 + public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  111 + //只有数据库进行版本升级时被调用
  112 + }
  113 + }
  114 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/utils/DateUtils.java 0 → 100644
... ... @@ -0,0 +1,259 @@
  1 +package com.share.mvpsdk.utils;
  2 +
  3 +import android.text.TextUtils;
  4 +import android.text.format.DateFormat;
  5 +
  6 +import java.text.ParseException;
  7 +import java.text.SimpleDateFormat;
  8 +import java.util.Calendar;
  9 +import java.util.Date;
  10 +import java.util.Locale;
  11 +
  12 +/**
  13 + * Created by Horrarndoo on 2017/8/31.
  14 + * <p>
  15 + * 日期时间工具类
  16 + */
  17 +public class DateUtils {
  18 +
  19 + public static final long ONE_SECOND_MILLIONS = 1000;
  20 + public static final long ONE_MINUTE_MILLIONS = 60 * ONE_SECOND_MILLIONS;
  21 + public static final long ONE_HOUR_MILLIONS = 60 * ONE_MINUTE_MILLIONS;
  22 + public static final long ONE_DAY_MILLIONS = 24 * ONE_HOUR_MILLIONS;
  23 + public static final int DAY_OF_YEAR = 365;
  24 +
  25 + // 日期格式为 2016-02-03 17:04:58
  26 + public static final String PATTERN_DATE = "yyyy年MM月dd日";
  27 + public static final String PATTERN_TIME = "HH:mm:ss";
  28 + public static final String PATTERN_SPLIT = " ";
  29 + public static final String PATTERN = PATTERN_DATE + PATTERN_SPLIT + PATTERN_TIME;
  30 +
  31 + public static String getShortTime(String dateStr) {
  32 + String str;
  33 +
  34 + Date date = str2date(dateStr);
  35 + Date curDate = new Date();
  36 +
  37 + long durTime = curDate.getTime() - date.getTime();
  38 + int dayDiff = calculateDayDiff(date, curDate);
  39 +
  40 + if (durTime <= 10 * ONE_MINUTE_MILLIONS) {
  41 + str = "刚刚";
  42 + } else if (durTime < ONE_HOUR_MILLIONS) {
  43 + str = durTime / ONE_MINUTE_MILLIONS + "分钟前";
  44 + } else if (dayDiff == 0) {
  45 + str = durTime / ONE_HOUR_MILLIONS + "小时前";
  46 + } else if (dayDiff == -1) {
  47 + str = "昨天" + DateFormat.format("HH:mm", date);
  48 + } else if (isSameYear(date, curDate) && dayDiff < -1) {
  49 + str = DateFormat.format("MM-dd", date).toString();
  50 + } else {
  51 + str = DateFormat.format("yyyy-MM", date).toString();
  52 + }
  53 +
  54 + return str;
  55 + }
  56 +
  57 + public static String format(long millis){
  58 + SimpleDateFormat format = new SimpleDateFormat("MM/dd", Locale.getDefault());
  59 + return format.format(millis);
  60 + }
  61 +
  62 + /**
  63 + * 获取日期 PATTERN_DATE 部分
  64 + */
  65 + public static String getDate(String date) {
  66 + if (TextUtils.isEmpty(date) || !date.contains(PATTERN_SPLIT)) {
  67 + return "";
  68 + }
  69 + return date.split(PATTERN_SPLIT)[0];
  70 + }
  71 +
  72 + public static String dateFormat(Date date,String fomart){
  73 + SimpleDateFormat simpleDateFormat=new SimpleDateFormat(fomart);
  74 + return simpleDateFormat.format(date);
  75 + }
  76 +
  77 + /**
  78 + * 原有日期上累加月
  79 + *
  80 + * @return 累加后的日期 PATTERN_DATE 部分
  81 + */
  82 + public static String addMonth(String date, int moonCount) {
  83 + //如果date为空 就用当前时间
  84 + if (TextUtils.isEmpty(date)) {
  85 + SimpleDateFormat df = new SimpleDateFormat(PATTERN_DATE + PATTERN_SPLIT + PATTERN_TIME);
  86 + date = df.format(new Date());
  87 + }
  88 + Calendar calendar = str2calendar(date);
  89 + calendar.add(Calendar.MONTH, moonCount);
  90 + return getDate(calendar2str(calendar));
  91 + }
  92 +
  93 + /**
  94 + * 计算天数差
  95 + */
  96 + public static int calculateDayDiff(Date targetTime, Date compareTime) {
  97 + boolean sameYear = isSameYear(targetTime, compareTime);
  98 + if (sameYear) {
  99 + return calculateDayDiffOfSameYear(targetTime, compareTime);
  100 + } else {
  101 + int dayDiff = 0;
  102 +
  103 + // 累计年数差的整年天数
  104 + int yearDiff = calculateYearDiff(targetTime, compareTime);
  105 + dayDiff += yearDiff * DAY_OF_YEAR;
  106 +
  107 + // 累计同一年内的天数
  108 + dayDiff += calculateDayDiffOfSameYear(targetTime, compareTime);
  109 +
  110 + return dayDiff;
  111 + }
  112 + }
  113 +
  114 + /**
  115 + * 计算同一年内的天数差
  116 + */
  117 + public static int calculateDayDiffOfSameYear(Date targetTime, Date compareTime) {
  118 + if (targetTime == null || compareTime == null) {
  119 + return 0;
  120 + }
  121 +
  122 + Calendar tarCalendar = Calendar.getInstance();
  123 + tarCalendar.setTime(targetTime);
  124 + int tarDayOfYear = tarCalendar.get(Calendar.DAY_OF_YEAR);
  125 +
  126 + Calendar compareCalendar = Calendar.getInstance();
  127 + compareCalendar.setTime(compareTime);
  128 + int comDayOfYear = compareCalendar.get(Calendar.DAY_OF_YEAR);
  129 +
  130 + return tarDayOfYear - comDayOfYear;
  131 + }
  132 +
  133 + /**
  134 + * 计算年数差
  135 + */
  136 + public static int calculateYearDiff(Date targetTime, Date compareTime) {
  137 + if (targetTime == null || compareTime == null) {
  138 + return 0;
  139 + }
  140 +
  141 + Calendar tarCalendar = Calendar.getInstance();
  142 + tarCalendar.setTime(targetTime);
  143 + int tarYear = tarCalendar.get(Calendar.YEAR);
  144 +
  145 + Calendar compareCalendar = Calendar.getInstance();
  146 + compareCalendar.setTime(compareTime);
  147 + int comYear = compareCalendar.get(Calendar.YEAR);
  148 +
  149 + return tarYear - comYear;
  150 + }
  151 +
  152 + /**
  153 + * 计算月数差
  154 + *
  155 + * @param targetTime
  156 + * @param compareTime
  157 + * @return
  158 + */
  159 + public static int calculateMonthDiff(String targetTime, String compareTime) {
  160 + return calculateMonthDiff(str2date(targetTime, PATTERN_DATE),
  161 + str2date(compareTime, PATTERN_DATE));
  162 + }
  163 +
  164 + /**
  165 + * 计算月数差
  166 + *
  167 + * @param targetTime
  168 + * @param compareTime
  169 + * @return
  170 + */
  171 + public static int calculateMonthDiff(Date targetTime, Date compareTime) {
  172 + Calendar tarCalendar = Calendar.getInstance();
  173 + tarCalendar.setTime(targetTime);
  174 + int tarYear = tarCalendar.get(Calendar.YEAR);
  175 + int tarMonth = tarCalendar.get(Calendar.MONTH);
  176 +
  177 + Calendar compareCalendar = Calendar.getInstance();
  178 + compareCalendar.setTime(compareTime);
  179 + int comYear = compareCalendar.get(Calendar.YEAR);
  180 + int comMonth = compareCalendar.get(Calendar.MONTH);
  181 + return ((tarYear - comYear) * 12 + tarMonth - comMonth);
  182 +
  183 + }
  184 +
  185 + /**
  186 + * 是否为同一年
  187 + */
  188 + public static boolean isSameYear(Date targetTime, Date compareTime) {
  189 + if (targetTime == null || compareTime == null) {
  190 + return false;
  191 + }
  192 +
  193 + Calendar tarCalendar = Calendar.getInstance();
  194 + tarCalendar.setTime(targetTime);
  195 + int tarYear = tarCalendar.get(Calendar.YEAR);
  196 +
  197 + Calendar compareCalendar = Calendar.getInstance();
  198 + compareCalendar.setTime(compareTime);
  199 + int comYear = compareCalendar.get(Calendar.YEAR);
  200 +
  201 + return tarYear == comYear;
  202 + }
  203 +
  204 + public static Date str2date(String str, String format) {
  205 + Date date = null;
  206 + try {
  207 + if (str != null) {
  208 + SimpleDateFormat sdf = new SimpleDateFormat(format);
  209 + date = sdf.parse(str);
  210 + }
  211 + } catch (ParseException e) {
  212 + e.printStackTrace();
  213 + }
  214 + return date;
  215 + }
  216 +
  217 + public static Date str2date(String str) {
  218 + return str2date(str, PATTERN);
  219 + }
  220 +
  221 + public static String date2str(Date date) {
  222 + return date2str(date, PATTERN);
  223 + }
  224 +
  225 + public static String date2str(Date date, String format) {
  226 + SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.CHINA);
  227 + return sdf.format(date);
  228 + }
  229 +
  230 + public static Calendar str2calendar(String str) {
  231 + Calendar calendar = null;
  232 + Date date = str2date(str);
  233 + if (date != null) {
  234 + calendar = Calendar.getInstance();
  235 + calendar.setTime(date);
  236 + }
  237 + return calendar;
  238 + }
  239 +
  240 +
  241 + public static Calendar str2calendar(String str, String format) {
  242 + Calendar calendar = null;
  243 + Date date = str2date(str, format);
  244 + if (date != null) {
  245 + calendar = Calendar.getInstance();
  246 + calendar.setTime(date);
  247 + }
  248 + return calendar;
  249 + }
  250 +
  251 + public static String calendar2str(Calendar calendar) {
  252 + return date2str(calendar.getTime());
  253 + }
  254 +
  255 + public static String calendar2str(Calendar calendar, String format) {
  256 + return date2str(calendar.getTime(), format);
  257 + }
  258 +
  259 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/utils/DialogUtils.java 0 → 100644
... ... @@ -0,0 +1,60 @@
  1 +package com.share.mvpsdk.utils;
  2 +
  3 +import android.app.Dialog;
  4 +import android.app.ProgressDialog;
  5 +import android.content.Context;
  6 +import android.content.DialogInterface;
  7 +import android.support.v7.app.AlertDialog;
  8 +
  9 +import com.share.mvpsdk.R;
  10 +
  11 +
  12 +/**
  13 + * Created by Horrarndoo on 2017/8/31.
  14 + * <p>
  15 + * 对话框工具类, 提供常用对话框显示, 使用support.v7包内的AlertDialog样式
  16 + */
  17 +public class DialogUtils {
  18 +
  19 + public static Dialog createProgressDialog(Context context) {
  20 + return createProgressDialog(context, true);
  21 + }
  22 +
  23 + public static Dialog createProgressDialog(Context context, boolean needCancle) {
  24 + ProgressDialog dialog = new ProgressDialog(context);
  25 + dialog.setMessage("Loading ...");
  26 + dialog.setCancelable(needCancle);
  27 + dialog.setCanceledOnTouchOutside(false);
  28 + return dialog;
  29 + }
  30 +
  31 + public static Dialog showCommonDialog(Context context, String message,
  32 + DialogInterface.OnClickListener listener) {
  33 + return showCommonDialog(context, message, context.getString(R.string.dialog_positive),
  34 + context.getString(R.string.dialog_negative), listener);
  35 + }
  36 +
  37 + public static Dialog showCommonDialog(Context context, String message, String positiveText,
  38 + String negativeText, DialogInterface.OnClickListener
  39 + listener) {
  40 + return new AlertDialog.Builder(context)
  41 + .setMessage(message)
  42 + .setPositiveButton(positiveText, listener)
  43 + .setNegativeButton(negativeText, null)
  44 + .show();
  45 + }
  46 +
  47 + public static Dialog showConfirmDialog(Context context, String message,
  48 + DialogInterface.OnClickListener listener) {
  49 + return showConfirmDialog(context, message, context.getString(R.string.dialog_positive),
  50 + listener);
  51 + }
  52 +
  53 + public static Dialog showConfirmDialog(Context context, String message, String positiveText,
  54 + DialogInterface.OnClickListener listener) {
  55 + return new AlertDialog.Builder(context)
  56 + .setMessage(message)
  57 + .setPositiveButton(positiveText, listener)
  58 + .show();
  59 + }
  60 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/utils/DisplayUtils.java 0 → 100644
... ... @@ -0,0 +1,195 @@
  1 +package com.share.mvpsdk.utils;
  2 +
  3 +import android.app.Activity;
  4 +import android.content.Context;
  5 +import android.graphics.Bitmap;
  6 +import android.graphics.Canvas;
  7 +import android.os.Build;
  8 +import android.renderscript.Allocation;
  9 +import android.renderscript.Element;
  10 +import android.renderscript.RenderScript;
  11 +import android.renderscript.ScriptIntrinsicBlur;
  12 +import android.util.DisplayMetrics;
  13 +import android.view.View;
  14 +import android.widget.ImageView;
  15 +
  16 +import com.bumptech.glide.Glide;
  17 +import com.share.mvpsdk.R;
  18 +
  19 +import java.io.File;
  20 +
  21 +import jp.wasabeef.glide.transformations.BlurTransformation;
  22 +
  23 +/**
  24 + * Created by Horrarndoo on 2017/8/31.
  25 + * <p>
  26 + * 显示相关工具类
  27 + */
  28 +public class DisplayUtils {
  29 + /**
  30 + * 将px值转换为dp值
  31 + */
  32 + public static int px2dp(float pxValue) {
  33 + final float scale = AppUtils.getContext().getResources().getDisplayMetrics().density;
  34 + return (int) (pxValue / scale + 0.5f);
  35 + }
  36 +
  37 + /**
  38 + * 将dp值转换为px值
  39 + */
  40 + public static int dp2px(float dpValue) {
  41 + final float scale = AppUtils.getContext().getResources().getDisplayMetrics().density;
  42 + return (int) (dpValue * scale + 0.5f);
  43 + }
  44 +
  45 + /**
  46 + * 将px值转换为sp值
  47 + */
  48 + public static int px2sp(float pxValue) {
  49 + final float scale = AppUtils.getContext().getResources().getDisplayMetrics().scaledDensity;
  50 + return (int) (pxValue / scale + 0.5f);
  51 + }
  52 +
  53 + /**
  54 + * 将sp值转换为px值
  55 + */
  56 + public static int sp2px(float dpValue) {
  57 + final float scale = AppUtils.getContext().getResources().getDisplayMetrics().scaledDensity;
  58 + return (int) (dpValue * scale + 0.5f);
  59 + }
  60 +
  61 + /**
  62 + * 获取屏幕宽度
  63 + */
  64 + public static int getScreenWidthPixels(Activity context) {
  65 + DisplayMetrics metric = new DisplayMetrics();
  66 + context.getWindowManager().getDefaultDisplay().getMetrics(metric);
  67 + return metric.widthPixels;
  68 + }
  69 +
  70 + /**
  71 + * 获取屏幕高度
  72 + */
  73 + public static int getScreenHeightPixels(Activity context) {
  74 + DisplayMetrics metric = new DisplayMetrics();
  75 + context.getWindowManager().getDefaultDisplay().getMetrics(metric);
  76 + return metric.heightPixels;
  77 + }
  78 +
  79 + /**
  80 + * 将一个view转换成bitmap位图
  81 + *
  82 + * @param view 要转换的View
  83 + * @return view转换的bitmap
  84 + */
  85 + public static Bitmap viewToBitmap(View view) {
  86 + Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(),
  87 + Bitmap.Config.ARGB_8888);
  88 + view.draw(new Canvas(bitmap));
  89 + return bitmap;
  90 + }
  91 +
  92 + /**
  93 + * 获取模糊虚化的bitmap
  94 + *
  95 + * @param context
  96 + * @param bitmap 要模糊的图片
  97 + * @param radius 模糊等级 >=0 && <=25
  98 + * @return
  99 + */
  100 + public static Bitmap getBlurBitmap(Context context, Bitmap bitmap, int radius) {
  101 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
  102 + return blurBitmap(context, bitmap, radius);
  103 + }
  104 + return bitmap;
  105 + }
  106 +
  107 + /**
  108 + * android系统的模糊方法
  109 + *
  110 + * @param bitmap 要模糊的图片
  111 + * @param radius 模糊等级 >=0 && <=25
  112 + */
  113 + public static Bitmap blurBitmap(Context context, Bitmap bitmap, int radius) {
  114 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
  115 + //Let's create an empty bitmap with the same size of the bitmap we want to blur
  116 + Bitmap outBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap
  117 + .Config.ARGB_8888);
  118 + //Instantiate a new Renderscript
  119 + RenderScript rs = RenderScript.create(context);
  120 + //Create an Intrinsic Blur Script using the Renderscript
  121 + ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
  122 + //Create the Allocations (in/out) with the Renderscript and the in/out bitmaps
  123 + Allocation allIn = Allocation.createFromBitmap(rs, bitmap);
  124 + Allocation allOut = Allocation.createFromBitmap(rs, outBitmap);
  125 + //Set the radius of the blur
  126 + blurScript.setRadius(radius);
  127 + //Perform the Renderscript
  128 + blurScript.setInput(allIn);
  129 + blurScript.forEach(allOut);
  130 + //Copy the final bitmap created by the out Allocation to the outBitmap
  131 + allOut.copyTo(outBitmap);
  132 + //recycle the original bitmap
  133 + bitmap.recycle();
  134 + //After finishing everything, we destroy the Renderscript.
  135 + rs.destroy();
  136 + return outBitmap;
  137 + } else {
  138 + return bitmap;
  139 + }
  140 + }
  141 +
  142 + /**
  143 + * 显示网络虚化图片
  144 + *
  145 + * @param context context
  146 + * @param imgUrl 图片url
  147 + * @param imageView 要显示的imageview
  148 + */
  149 + public static void displayBlurImg(Context context, final String imgUrl, ImageView imageView) {
  150 + // "23":模糊度;"4":图片缩放4倍后再进行模糊
  151 + Glide.with(context)
  152 + .load(imgUrl)
  153 + .error(R.drawable.stackblur_default)
  154 + .placeholder(R.drawable.stackblur_default)
  155 + .crossFade(300)
  156 + .bitmapTransform(new BlurTransformation(context, 23, 4))
  157 + .into(imageView);
  158 + }
  159 +
  160 + /**
  161 + * 显示本地虚化图片
  162 + *
  163 + * @param context context
  164 + * @param file 本地图片file
  165 + * @param imageView 要显示的imageview
  166 + */
  167 + public static void displayBlurImg(Context context, File file, ImageView imageView) {
  168 + // "23":模糊度;"4":图片缩放4倍后再进行模糊
  169 + Glide.with(context)
  170 + .load(file)
  171 + .error(R.drawable.stackblur_default)
  172 + .placeholder(R.drawable.stackblur_default)
  173 + .crossFade(300)
  174 + .bitmapTransform(new BlurTransformation(context, 23, 4))
  175 + .into(imageView);
  176 + }
  177 +
  178 + /**
  179 + * 显示资源虚化图片
  180 + *
  181 + * @param context context
  182 + * @param resourceId 图片资源id
  183 + * @param imageView 要显示的imageview
  184 + */
  185 + public static void displayBlurImg(Context context, Integer resourceId, ImageView imageView) {
  186 + // "23":模糊度;"4":图片缩放4倍后再进行模糊
  187 + Glide.with(context)
  188 + .load(resourceId)
  189 + .error(R.drawable.stackblur_default)
  190 + .placeholder(R.drawable.stackblur_default)
  191 + .crossFade(300)
  192 + .bitmapTransform(new BlurTransformation(context, 23, 4))
  193 + .into(imageView);
  194 + }
  195 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/utils/FileUtils.java 0 → 100644
... ... @@ -0,0 +1,291 @@
  1 +package com.share.mvpsdk.utils;
  2 +
  3 +import android.content.ContentResolver;
  4 +import android.content.Context;
  5 +import android.content.Intent;
  6 +import android.database.Cursor;
  7 +import android.graphics.Bitmap;
  8 +import android.net.Uri;
  9 +import android.os.Environment;
  10 +import android.provider.MediaStore;
  11 +import android.text.TextUtils;
  12 +
  13 +import java.io.BufferedInputStream;
  14 +import java.io.BufferedOutputStream;
  15 +import java.io.File;
  16 +import java.io.FileInputStream;
  17 +import java.io.FileNotFoundException;
  18 +import java.io.FileOutputStream;
  19 +import java.io.IOException;
  20 +import java.io.InputStream;
  21 +
  22 +/**
  23 + * Created by Horrarndoo on 2017/8/31.
  24 + * <p>
  25 + * 读取文件工具类
  26 + */
  27 +public class FileUtils {
  28 + private static final String TAG = "FileUtils";
  29 +
  30 + /**
  31 + * Convert byte[] to hex string.将byte转换成int,
  32 + * 然后利用Integer.toHexString(int)来转换成16进制字符串。
  33 + *
  34 + * @param src byte[] data
  35 + * @return hex string
  36 + */
  37 + public static String bytesToHexString(byte[] src) {
  38 + StringBuilder stringBuilder = new StringBuilder("");
  39 + if (src == null || src.length <= 0) {
  40 + return null;
  41 + }
  42 + for (int i = 0; i < src.length; i++) {
  43 + int v = src[i] & 0xFF;
  44 + String hv = Integer.toHexString(v);
  45 + if (hv.length() < 2) {
  46 + stringBuilder.append(0);
  47 + }
  48 + stringBuilder.append(hv);
  49 + }
  50 + return stringBuilder.toString();
  51 + }
  52 +
  53 + /**
  54 + * 根据文件名称和路径,获取sd卡中的文件,以File形式返回byte
  55 + */
  56 + public static File getFile(String fileName, String folder)
  57 + throws IOException {
  58 + String state = Environment.getExternalStorageState();
  59 + if (state.equals(Environment.MEDIA_MOUNTED)) {
  60 + File pathFile = new File(Environment.getExternalStorageDirectory()
  61 + + folder);
  62 + // && !pathFile .isDirectory()
  63 + if (!pathFile.exists()) {
  64 + pathFile.mkdirs();
  65 + }
  66 + File file = new File(pathFile, fileName);
  67 + return file;
  68 + }
  69 + return null;
  70 + }
  71 +
  72 + /**
  73 + * 根据文件名称和路径,获取sd卡中的文件,判断文件是否存在,存在返回true
  74 + */
  75 + public static Boolean checkFile(String fileName, String folder)
  76 + throws IOException {
  77 +
  78 + File targetFile = getFile(fileName, folder);
  79 +
  80 + if (!targetFile.exists()) {
  81 + return false;
  82 + } else {
  83 + return true;
  84 + }
  85 + }
  86 +
  87 + /**
  88 + * 根据Uri返回文件绝对路径
  89 + * 兼容了file:///开头的 和 content://开头的情况
  90 + */
  91 + public static String getRealFilePathFromUri(final Context context, final Uri uri) {
  92 + if (null == uri)
  93 + return null;
  94 + final String scheme = uri.getScheme();
  95 + String data = null;
  96 + if (scheme == null) {
  97 + data = uri.getPath();
  98 + } else if (ContentResolver.SCHEME_FILE.equalsIgnoreCase(scheme)) {
  99 + data = uri.getPath();
  100 + } else if (ContentResolver.SCHEME_CONTENT.equalsIgnoreCase(scheme)) {
  101 + Cursor cursor = context.getContentResolver().query(uri, new String[]{MediaStore
  102 + .Images.ImageColumns.DATA}, null, null, null);
  103 + if (null != cursor) {
  104 + if (cursor.moveToFirst()) {
  105 + int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
  106 + if (index > -1) {
  107 + data = cursor.getString(index);
  108 + }
  109 + }
  110 + cursor.close();
  111 + }
  112 + }
  113 + return data;
  114 + }
  115 +
  116 + /**
  117 + * 检查文件是否存在
  118 + */
  119 + public static String checkDirPath(String dirPath) {
  120 + if (TextUtils.isEmpty(dirPath)) {
  121 + return "";
  122 + }
  123 + File dir = new File(dirPath);
  124 + if (!dir.exists()) {
  125 + dir.mkdirs();
  126 + }
  127 + return dirPath;
  128 + }
  129 +
  130 + public static void copyFile(File sourcefile, File targetFile) {
  131 + FileInputStream input = null;
  132 + BufferedInputStream inbuff = null;
  133 + FileOutputStream out = null;
  134 + BufferedOutputStream outbuff = null;
  135 +
  136 + try {
  137 +
  138 + input = new FileInputStream(sourcefile);
  139 + inbuff = new BufferedInputStream(input);
  140 +
  141 + out = new FileOutputStream(targetFile);
  142 + outbuff = new BufferedOutputStream(out);
  143 +
  144 + byte[] b = new byte[1024 * 5];
  145 + int len = 0;
  146 + while ((len = inbuff.read(b)) != -1) {
  147 + outbuff.write(b, 0, len);
  148 + }
  149 + outbuff.flush();
  150 + } catch (Exception ex) {
  151 + } finally {
  152 + try {
  153 + if (inbuff != null)
  154 + inbuff.close();
  155 + if (outbuff != null)
  156 + outbuff.close();
  157 + if (out != null)
  158 + out.close();
  159 + if (input != null)
  160 + input.close();
  161 + } catch (Exception ex) {
  162 +
  163 + }
  164 + }
  165 + }
  166 +
  167 + /**
  168 + * 保存图片到本机
  169 + *
  170 + * @param context context
  171 + * @param fileName 文件名
  172 + * @param file file
  173 + * @param saveResultCallback 保存结果callback
  174 + */
  175 + public static void saveImage(final Context context, final String fileName, final File file,
  176 + final SaveResultCallback saveResultCallback) {
  177 + new Thread(new Runnable() {
  178 + @Override
  179 + public void run() {
  180 + File appDir = new File(Environment.getExternalStorageDirectory(), "yizhi");
  181 + if (!appDir.exists()) {
  182 + appDir.mkdir();
  183 + }
  184 + String saveFileName = "yizhi_pic";
  185 + if (fileName.contains(".png") || fileName.contains(".gif")) {
  186 + String fileFormat = fileName.substring(fileName.lastIndexOf("."));
  187 + saveFileName = MD5Utils.getMD5("yizhi_pic" + fileName) + fileFormat;
  188 + } else {
  189 + saveFileName = MD5Utils.getMD5("yizhi_pic" + fileName) + ".png";
  190 + }
  191 + saveFileName = saveFileName.substring(20);//取前20位作为SaveName
  192 + File savefile = new File(appDir, saveFileName);
  193 + try {
  194 + InputStream is = new FileInputStream(file);
  195 + FileOutputStream fos = new FileOutputStream(savefile);
  196 + byte[] buffer = new byte[1024 * 1024];//1M缓冲区
  197 + int count = 0;
  198 + while ((count = is.read(buffer)) > 0) {
  199 + fos.write(buffer, 0, count);
  200 + }
  201 + fos.close();
  202 + is.close();
  203 + saveResultCallback.onSavedSuccess();
  204 + } catch (FileNotFoundException e) {
  205 + saveResultCallback.onSavedFailed();
  206 + e.printStackTrace();
  207 + } catch (IOException e) {
  208 + saveResultCallback.onSavedFailed();
  209 + e.printStackTrace();
  210 + }
  211 + //保存图片后发送广播通知更新数据库
  212 + Uri uri = Uri.fromFile(savefile);
  213 + context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri));
  214 + }
  215 + }).start();
  216 + }
  217 +
  218 + /**
  219 + * 保存Bitmap到本机
  220 + *
  221 + * @param context context
  222 + * @param fileName bitmap文件名
  223 + * @param bmp bitmap
  224 + * @param saveResultCallback 保存结果callback
  225 + */
  226 + public static void saveBitmap(final Context context, final String fileName, final Bitmap bmp,
  227 + final SaveResultCallback
  228 + saveResultCallback) {
  229 + new Thread(new Runnable() {
  230 + @Override
  231 + public void run() {
  232 + File appDir = new File(Environment.getExternalStorageDirectory(), "yizhi");
  233 + if (!appDir.exists()) {
  234 + appDir.mkdir();
  235 + }
  236 + // SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
  237 + // 设置以当前时间格式为图片名称
  238 + String saveFileName = MD5Utils.getMD5("yizhi_pic" + fileName) + ".png";
  239 + saveFileName = saveFileName.substring(20);//取前20位作为SaveName
  240 + File file = new File(appDir, saveFileName);
  241 + try {
  242 + FileOutputStream fos = new FileOutputStream(file);
  243 + bmp.compress(Bitmap.CompressFormat.PNG, 100, fos);
  244 + fos.flush();
  245 + fos.close();
  246 + saveResultCallback.onSavedSuccess();
  247 + } catch (FileNotFoundException e) {
  248 + saveResultCallback.onSavedFailed();
  249 + e.printStackTrace();
  250 + } catch (IOException e) {
  251 + saveResultCallback.onSavedFailed();
  252 + e.printStackTrace();
  253 + }
  254 + //保存图片后发送广播通知更新数据库
  255 + Uri uri = Uri.fromFile(file);
  256 + context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri));
  257 + }
  258 + }).start();
  259 + }
  260 +
  261 + //保存webview缓存的
  262 + public static String getCache() {
  263 + String cacheFilePath=Environment.getExternalStorageDirectory()+File.separator+"Cache";
  264 + File cacheFile=new File(cacheFilePath);
  265 + if (!cacheFile.exists())cacheFile.mkdirs();
  266 + return cacheFile.toString();
  267 + }
  268 +
  269 + public static boolean webViewCacheIsExit(){
  270 + File file=new File(getCache());
  271 + FileInputStream fileInputStream=null;
  272 + try {
  273 + fileInputStream=new FileInputStream(file);
  274 + if (fileInputStream.available()>0)
  275 + return true;
  276 + } catch (FileNotFoundException e) {
  277 + e.printStackTrace();
  278 + } catch (IOException e) {
  279 + e.printStackTrace();
  280 + }
  281 + return false;
  282 + }
  283 +
  284 + public interface SaveResultCallback {
  285 + void onSavedSuccess();
  286 +
  287 + void onSavedFailed();
  288 + }
  289 +}
  290 +
  291 +
... ...
mvpsdk/src/main/java/com/share/mvpsdk/utils/HtmlUtils.java 0 → 100644
... ... @@ -0,0 +1,93 @@
  1 +package com.share.mvpsdk.utils;
  2 +
  3 +import java.util.List;
  4 +
  5 +/**
  6 + * Created by Horrarndoo on 2017/8/31.
  7 + * <p>
  8 + * Html工具类
  9 + */
  10 +public class HtmlUtils {
  11 +
  12 + //css样式,隐藏header
  13 + private static final String HIDE_HEADER_STYLE = "<style>div.headline{display:none;}</style>";
  14 +
  15 + //css style tag,需要格式化
  16 + private static final String NEEDED_FORMAT_CSS_TAG = "<link rel=\"stylesheet\" " +
  17 + "type=\"text/css\" href=\"%s\"/>";
  18 +
  19 + // js script tag,需要格式化
  20 + private static final String NEEDED_FORMAT_JS_TAG = "<script src=\"%s\"></script>";
  21 +
  22 + public static final String MIME_TYPE = "text/html; charset=utf-8";
  23 +
  24 + public static final String ENCODING = "utf-8";
  25 +
  26 + private HtmlUtils() {
  27 +
  28 + }
  29 +
  30 + /**
  31 + * 根据css链接生成Link标签
  32 + *
  33 + * @param url String
  34 + * @return String
  35 + */
  36 + public static String createCssTag(String url) {
  37 +
  38 + return String.format(NEEDED_FORMAT_CSS_TAG, url);
  39 + }
  40 +
  41 + /**
  42 + * 根据多个css链接生成Link标签
  43 + *
  44 + * @param urls List<String>
  45 + * @return String
  46 + */
  47 + public static String createCssTag(List<String> urls) {
  48 +
  49 + final StringBuilder sb = new StringBuilder();
  50 + for (String url : urls) {
  51 + sb.append(createCssTag(url));
  52 + }
  53 + return sb.toString();
  54 + }
  55 +
  56 + /**
  57 + * 根据js链接生成Script标签
  58 + *
  59 + * @param url String
  60 + * @return String
  61 + */
  62 + public static String createJsTag(String url) {
  63 +
  64 + return String.format(NEEDED_FORMAT_JS_TAG, url);
  65 + }
  66 +
  67 + /**
  68 + * 根据多个js链接生成Script标签
  69 + *
  70 + * @param urls List<String>
  71 + * @return String
  72 + */
  73 + public static String createJsTag(List<String> urls) {
  74 +
  75 + final StringBuilder sb = new StringBuilder();
  76 + for (String url : urls) {
  77 + sb.append(createJsTag(url));
  78 + }
  79 + return sb.toString();
  80 + }
  81 +
  82 + /**
  83 + * 根据样式标签,html字符串,js标签
  84 + * 生成完整的HTML文档
  85 + */
  86 +
  87 + public static String createHtmlData(String html, List<String> cssList, List<String> jsList) {
  88 + final String css = HtmlUtils.createCssTag(cssList);
  89 + final String js = HtmlUtils.createJsTag(jsList);
  90 + return css.concat(HIDE_HEADER_STYLE).concat(html).concat(js);
  91 + }
  92 +}
  93 +
... ...
mvpsdk/src/main/java/com/share/mvpsdk/utils/HttpUtils.java 0 → 100644
... ... @@ -0,0 +1,76 @@
  1 +package com.share.mvpsdk.utils;
  2 +
  3 +import android.os.Build;
  4 +import android.support.annotation.NonNull;
  5 +import android.webkit.WebSettings;
  6 +
  7 +import com.orhanobut.logger.Logger;
  8 +
  9 +import java.util.ArrayList;
  10 +import java.util.List;
  11 +import java.util.regex.Matcher;
  12 +import java.util.regex.Pattern;
  13 +
  14 +/**
  15 + * Created by Horrarndoo on 2017/9/18.
  16 + * <p>
  17 + * HttpUtils 主要用于获取UserAgent
  18 + */
  19 +
  20 +public class HttpUtils {
  21 + /**
  22 + * 获取UserAgent
  23 + *
  24 + * @return UserAgent
  25 + */
  26 + @NonNull
  27 + public static String getUserAgent() {
  28 + String userAgent = "";
  29 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
  30 + try {
  31 + userAgent = WebSettings.getDefaultUserAgent(AppUtils.getContext());
  32 + } catch (Exception e) {
  33 + userAgent = System.getProperty("http.agent");
  34 + }
  35 + } else {
  36 + userAgent = System.getProperty("http.agent");
  37 + }
  38 + StringBuffer sb = new StringBuffer();
  39 + for (int i = 0, length = userAgent.length(); i < length; i++) {
  40 + char c = userAgent.charAt(i);
  41 + if (c <= '\u001f' || c >= '\u007f') {
  42 + sb.append(String.format("\\u%04x", (int) c));
  43 + } else {
  44 + sb.append(c);
  45 + }
  46 + }
  47 + return sb.toString();
  48 + }
  49 +
  50 + public static String makeUA() {
  51 + final String ua = Build.BRAND + "/" + Build.MODEL + "/" + Build.VERSION.RELEASE;
  52 + return ua;
  53 + }
  54 +
  55 + public static String[] returnImageUrlsFromHtml(String html) {
  56 + List<String> imageSrcList = new ArrayList<String>();
  57 + Pattern p = Pattern.compile("<img\\b[^>]*\\bsrc\\b\\s*=\\s*('|\")?([^'\"\n\r\f>]+(\\" +
  58 + ".jpg|\\.bmp|\\.eps|\\.gif|\\.mif|\\.miff|\\.png|\\.tif|\\.tiff|\\.svg|\\.wmf|\\" +
  59 + ".jpe|\\.jpeg|\\.dib|\\.ico|\\.tga|\\.cut|\\.pic|\\b)\\b)[^>]*>", Pattern
  60 + .CASE_INSENSITIVE);
  61 + Matcher m = p.matcher(html);
  62 + String quote = null;
  63 + String src = null;
  64 + while (m.find()) {
  65 + quote = m.group(1);
  66 + src = (quote == null || quote.trim().length() == 0) ? m.group(2).split("//s+")[0] : m
  67 + .group(2);
  68 + imageSrcList.add(src);
  69 + }
  70 + if (imageSrcList.size() == 0) {
  71 + Logger.e("资讯中未匹配到图片链接");
  72 + return null;
  73 + }
  74 + return imageSrcList.toArray(new String[imageSrcList.size()]);
  75 + }
  76 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/utils/IOUtils.java 0 → 100644
... ... @@ -0,0 +1,25 @@
  1 +package com.share.mvpsdk.utils;
  2 +
  3 +import java.io.Closeable;
  4 +import java.io.IOException;
  5 +
  6 +/**
  7 + * Created by Horrarndoo on 2017/8/31.
  8 + * <p>
  9 + * IO流工具类
  10 + */
  11 +public class IOUtils {
  12 + /**
  13 + * 关闭流
  14 + */
  15 + public static boolean close(Closeable io) {
  16 + if (io != null) {
  17 + try {
  18 + io.close();
  19 + } catch (IOException e) {
  20 + LogUtils.e(e);
  21 + }
  22 + }
  23 + return true;
  24 + }
  25 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/utils/ImageUtils.java 0 → 100644
... ... @@ -0,0 +1,339 @@
  1 +package com.share.mvpsdk.utils;
  2 +
  3 +import android.annotation.TargetApi;
  4 +import android.app.Activity;
  5 +import android.content.ContentUris;
  6 +import android.content.ContentValues;
  7 +import android.content.Context;
  8 +import android.content.DialogInterface;
  9 +import android.content.Intent;
  10 +import android.database.Cursor;
  11 +import android.net.Uri;
  12 +import android.os.Build;
  13 +import android.os.Environment;
  14 +import android.provider.DocumentsContract;
  15 +import android.provider.MediaStore;
  16 +import android.support.v7.app.AlertDialog;
  17 +
  18 +import com.bumptech.glide.Glide;
  19 +import com.bumptech.glide.request.FutureTarget;
  20 +
  21 +import io.reactivex.Observable;
  22 +import io.reactivex.ObservableSource;
  23 +import io.reactivex.functions.Function;
  24 +
  25 +/**
  26 + * 图片工具类
  27 + */
  28 +public class ImageUtils {
  29 +
  30 + /**
  31 + * 拍照
  32 + */
  33 + public static final int REQUEST_CODE_FROM_CAMERA = 1 << 10;
  34 +
  35 + /**
  36 + * 相册
  37 + */
  38 + public static final int REQUEST_CODE_FROM_ALBUM = 1 << 12;
  39 +
  40 + /**
  41 + * 裁剪
  42 + */
  43 + public static final int REQUEST_CODE_CROP_IMAGE = 1 << 14;
  44 +
  45 + /**
  46 + * 存放拍照图片的uri地址
  47 + */
  48 + public static Uri imageUriFromCamera;
  49 +
  50 + /**
  51 + * 存放裁剪图片的uri地址
  52 + */
  53 + public static Uri cropImageUri;
  54 +
  55 + /**
  56 + * 显示获取照片不同方式对话框
  57 + */
  58 + public static void showImagePickDialog(final Activity activity) {
  59 + showImagePickDialog(activity, 0);
  60 + }
  61 +
  62 + /**
  63 + * 显示获取照片不同方式对话框
  64 + */
  65 + public static void showImagePickDialog(final Activity activity, final int addRequest) {
  66 + String title = "选择获取图片方式";
  67 + String[] items = new String[]{"拍照", "相册"};
  68 + new AlertDialog.Builder(activity)
  69 + .setTitle(title)
  70 + .setItems(items, new DialogInterface.OnClickListener() {
  71 + @Override
  72 + public void onClick(DialogInterface dialog, int which) {
  73 + dialog.dismiss();
  74 + switch (which) {
  75 + case 0:
  76 + pickImageFromCamera(activity, addRequest);
  77 + break;
  78 + case 1:
  79 + pickImageFromAlbum(activity, addRequest);
  80 + break;
  81 + default:
  82 + break;
  83 + }
  84 + }
  85 + })
  86 + .setNegativeButton("取消", null)
  87 + .show();
  88 + }
  89 +
  90 + /**
  91 + * 打开相机拍照获取图片
  92 + */
  93 + @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
  94 + public static void pickImageFromCamera(final Activity activity, int addRequest) {
  95 + // 先生成一个uri地址用于存放拍照获取的图片
  96 + imageUriFromCamera = createImageUri(activity);
  97 +
  98 + Intent intent = new Intent();
  99 + intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
  100 + intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUriFromCamera);
  101 + activity.startActivityForResult(intent, REQUEST_CODE_FROM_CAMERA + addRequest);
  102 + }
  103 +
  104 + /**
  105 + * 打开相机拍照获取图片
  106 + */
  107 + public static void pickImageFromCamera(final Activity activity) {
  108 + pickImageFromCamera(activity, 0);
  109 + }
  110 +
  111 + /**
  112 + * 打开本地相册选取图片
  113 + */
  114 + @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
  115 + public static void pickImageFromAlbum(final Activity activity, int addRequest) {
  116 + Intent intent = new Intent();
  117 + intent.setAction(Intent.ACTION_GET_CONTENT);
  118 + intent.setType("image/*");
  119 + activity.startActivityForResult(intent, REQUEST_CODE_FROM_ALBUM + addRequest);
  120 + }
  121 +
  122 + /**
  123 + * 打开本地相册选取图片
  124 + */
  125 + public static void pickImageFromAlbum(final Activity activity) {
  126 + pickImageFromAlbum(activity, 0);
  127 + }
  128 +
  129 + /**
  130 + * 压缩图片
  131 + *
  132 + * @param context context
  133 + * @param uri 图片uri
  134 + * @param reqW 上传图片需要压缩的宽度
  135 + * @param reqH 上传图片需要压缩的高度
  136 + * @return 上传成功回调
  137 + */
  138 + public static Observable<byte[]> compressImage(final Context context,
  139 + Uri uri,
  140 + final int reqW,
  141 + final int reqH) {
  142 + // 先从本地获取图片,利用Glide压缩图片后获取byte[]
  143 + return Observable.just(uri)
  144 + .flatMap(new Function<Uri, ObservableSource<byte[]>>() {
  145 + @Override
  146 + public ObservableSource<byte[]> apply(Uri uri) throws Exception {
  147 + // 在work线程中,同步压缩图片,然后Observable返回
  148 + // 即将Glide的回调封装成RxJava的Observable
  149 + FutureTarget<byte[]> future = Glide.with(context)
  150 + .load(uri)
  151 + .asBitmap()
  152 + .toBytes()
  153 + .into(reqW, reqH);
  154 +
  155 + byte[] bytes;
  156 + try {
  157 + bytes = future.get();
  158 + } catch (Exception e) {
  159 + // 获取失败时,抛出runtime异常
  160 + // 该异常会被Subscriber捕捉,进onError
  161 + throw new RuntimeException(e);
  162 + }
  163 + return Observable.just(bytes);
  164 + }
  165 + });
  166 + }
  167 +
  168 + /**
  169 + * 图片裁剪
  170 + */
  171 + public static void cropImage(Activity activity, Uri srcUri) {
  172 + cropImageUri = createImageUri(activity);
  173 +
  174 + Intent intent = new Intent("com.android.camera.action.CROP");
  175 + intent.setDataAndType(srcUri, "image/*");
  176 + intent.putExtra("crop", "true");
  177 +
  178 + ////////////////////////////////////////////////////////////////
  179 + // 1.宽高和比例都不设置时,裁剪框可以自行调整(比例和大小都可以随意调整)
  180 + ////////////////////////////////////////////////////////////////
  181 + // 2.只设置裁剪框宽高比(aspect)后,裁剪框比例固定不可调整,只能调整大小
  182 + /////////////////////////////////
  183 + // 3.裁剪后生成图片宽高(output)的设置和裁剪框无关,只决定最终生成图片大小
  184 + ////////////////////////////////////////////////////////////////
  185 + // 4.裁剪框宽高比例(aspect)可以和裁剪后生成图片比例(output)不同,此时,
  186 + // 会以裁剪框的宽为准,按照裁剪宽高比例生成一个图片,该图和框选部分可能不同,
  187 + // 不同的情况可能是截取框选的一部分,也可能超出框选部分,向下延伸补足
  188 + ////////////////////////////////////////////////////////////////
  189 +
  190 + // aspectX aspectY 是裁剪框宽高的比例
  191 + intent.putExtra("aspectX", 1);
  192 + intent.putExtra("aspectY", 1);
  193 + // outputX outputY 是裁剪后生成图片的宽高
  194 + // intent.putExtra("outputX", 300);
  195 + // intent.putExtra("outputY", 100);
  196 +
  197 + // return-data为true时,会直接返回bitmap数据,但是大图裁剪时会出现OOM,推荐下面为false时的方式
  198 + // return-data为false时,不会返回bitmap,但需要指定一个MediaStore.EXTRA_OUTPUT保存图片uri
  199 + intent.putExtra("return-data", false);
  200 + intent.putExtra(MediaStore.EXTRA_OUTPUT, cropImageUri);
  201 +
  202 + activity.startActivityForResult(intent, REQUEST_CODE_CROP_IMAGE);
  203 + }
  204 +
  205 + /**
  206 + * 创建一条图片uri,用于保存拍照后的照片
  207 + */
  208 + private static Uri createImageUri(Context context) {
  209 + String name = "boreImg" + System.currentTimeMillis();
  210 + ContentValues values = new ContentValues();
  211 + values.put(MediaStore.Images.Media.TITLE, name);
  212 + values.put(MediaStore.Images.Media.DISPLAY_NAME, name + ".jpeg");
  213 + values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
  214 + Uri uri = context.getContentResolver().insert(MediaStore.Images.Media
  215 + .EXTERNAL_CONTENT_URI, values);
  216 + return uri;
  217 + }
  218 +
  219 + /**
  220 + * 删除一条图片
  221 + */
  222 + public static void deleteImageUri(Context context, Uri uri) {
  223 + context.getContentResolver().delete(uri, null, null);
  224 + }
  225 +
  226 + /**
  227 + * 用第三方应用app打开图片
  228 + */
  229 + public static void openImageByOtherApp(Context context, Uri imageUri) {
  230 + Intent intent = new Intent();
  231 + intent.setAction(Intent.ACTION_VIEW);
  232 + intent.setDataAndType(imageUri, "image/*");
  233 + context.startActivity(intent);
  234 + }
  235 +
  236 + /**
  237 + * 根据Uri获取图片绝对路径,解决Android4.4以上版本Uri转换
  238 + */
  239 + public static String getImageAbsolutePath19(Context context, Uri imageUri) {
  240 + if (context == null || imageUri == null)
  241 + return null;
  242 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
  243 + && DocumentsContract.isDocumentUri(context, imageUri)) {
  244 + if (isExternalStorageDocument(imageUri)) {
  245 + String docId = DocumentsContract.getDocumentId(imageUri);
  246 + String[] split = docId.split(":");
  247 + String type = split[0];
  248 + if ("primary".equalsIgnoreCase(type)) {
  249 + return Environment.getExternalStorageDirectory() + "/" + split[1];
  250 + }
  251 + } else if (isDownloadsDocument(imageUri)) {
  252 + String id = DocumentsContract.getDocumentId(imageUri);
  253 + Uri contentUri = ContentUris.withAppendedId(Uri.parse
  254 + ("content://downloads/public_downloads"), Long.valueOf(id));
  255 + return getDataColumn(context, contentUri, null, null);
  256 + } else if (isMediaDocument(imageUri)) {
  257 + String docId = DocumentsContract.getDocumentId(imageUri);
  258 + String[] split = docId.split(":");
  259 + String type = split[0];
  260 + Uri contentUri = null;
  261 + if ("image".equals(type)) {
  262 + contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
  263 + } else if ("video".equals(type)) {
  264 + contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
  265 + } else if ("audio".equals(type)) {
  266 + contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
  267 + }
  268 + String selection = MediaStore.Images.Media._ID + "=?";
  269 + String[] selectionArgs = new String[]{split[1]};
  270 + return getDataColumn(context, contentUri, selection, selectionArgs);
  271 + }
  272 + }
  273 +
  274 + // MediaStore (and general)
  275 + if ("content".equalsIgnoreCase(imageUri.getScheme())) {
  276 + // Return the remote address
  277 + if (isGooglePhotosUri(imageUri))
  278 + return imageUri.getLastPathSegment();
  279 + return getDataColumn(context, imageUri, null, null);
  280 + }
  281 + // File
  282 + else if ("file".equalsIgnoreCase(imageUri.getScheme())) {
  283 + return imageUri.getPath();
  284 + }
  285 + return null;
  286 + }
  287 +
  288 + private static String getDataColumn(Context context, Uri uri, String selection, String[]
  289 + selectionArgs) {
  290 + Cursor cursor = null;
  291 + String column = MediaStore.Images.Media.DATA;
  292 + String[] projection = {column};
  293 + try {
  294 + cursor = context.getContentResolver().query(uri, projection, selection,
  295 + selectionArgs, null);
  296 + if (cursor != null && cursor.moveToFirst()) {
  297 + int index = cursor.getColumnIndexOrThrow(column);
  298 + return cursor.getString(index);
  299 + }
  300 + } finally {
  301 + if (cursor != null)
  302 + cursor.close();
  303 + }
  304 + return null;
  305 + }
  306 +
  307 + /**
  308 + * @param uri The Uri to check.
  309 + * @return Whether the Uri authority is ExternalStorageProvider.
  310 + */
  311 + private static boolean isExternalStorageDocument(Uri uri) {
  312 + return "com.android.externalstorage.documents".equals(uri.getAuthority());
  313 + }
  314 +
  315 + /**
  316 + * @param uri The Uri to check.
  317 + * @return Whether the Uri authority is DownloadsProvider.
  318 + */
  319 + private static boolean isDownloadsDocument(Uri uri) {
  320 + return "com.android.providers.downloads.documents".equals(uri.getAuthority());
  321 + }
  322 +
  323 + /**
  324 + * @param uri The Uri to check.
  325 + * @return Whether the Uri authority is MediaProvider.
  326 + */
  327 + private static boolean isMediaDocument(Uri uri) {
  328 + return "com.android.providers.media.documents".equals(uri.getAuthority());
  329 + }
  330 +
  331 + /**
  332 + * @param uri The Uri to check.
  333 + * @return Whether the Uri authority is Google Photos.
  334 + */
  335 + private static boolean isGooglePhotosUri(Uri uri) {
  336 + return "com.google.android.apps.photos.content".equals(uri.getAuthority());
  337 + }
  338 +
  339 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/utils/JsonUtils.java 0 → 100644
... ... @@ -0,0 +1,65 @@
  1 +package com.share.mvpsdk.utils;
  2 +
  3 +import com.google.gson.Gson;
  4 +import com.google.gson.JsonObject;
  5 +import com.google.gson.JsonSyntaxException;
  6 +
  7 +import java.lang.reflect.Type;
  8 +
  9 +/**
  10 + * Created by Horrarndoo on 2017/9/20.
  11 + * <p>
  12 + * Json转换工具类
  13 + */
  14 +public class JsonUtils {
  15 +
  16 + private static Gson mGson = new Gson();
  17 +
  18 + /**
  19 + * 将对象准换为json字符串
  20 + *
  21 + * @param object
  22 + * @param <T>
  23 + * @return
  24 + */
  25 + public static <T> String serialize(T object) {
  26 + return mGson.toJson(object);
  27 + }
  28 +
  29 + /**
  30 + * 将json字符串转换为对象
  31 + *
  32 + * @param json
  33 + * @param clz
  34 + * @param <T>
  35 + * @return
  36 + */
  37 + public static <T> T deserialize(String json, Class<T> clz) throws JsonSyntaxException {
  38 + return mGson.fromJson(json, clz);
  39 + }
  40 +
  41 + /**
  42 + * 将json对象转换为实体对象
  43 + *
  44 + * @param json
  45 + * @param clz
  46 + * @param <T>
  47 + * @return
  48 + * @throws JsonSyntaxException
  49 + */
  50 + public static <T> T deserialize(JsonObject json, Class<T> clz) throws JsonSyntaxException {
  51 + return mGson.fromJson(json, clz);
  52 + }
  53 +
  54 + /**
  55 + * 将json字符串转换为对象
  56 + *
  57 + * @param json
  58 + * @param type
  59 + * @param <T>
  60 + * @return
  61 + */
  62 + public static <T> T deserialize(String json, Type type) throws JsonSyntaxException {
  63 + return mGson.fromJson(json, type);
  64 + }
  65 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/utils/LogUtils.java 0 → 100644
... ... @@ -0,0 +1,168 @@
  1 +package com.share.mvpsdk.utils;
  2 +
  3 +import android.util.Log;
  4 +
  5 +
  6 +/**
  7 + * Created by Horrarndoo on 2017/4/5.
  8 + * <p>
  9 + * Log工具类
  10 + */
  11 +public class LogUtils {
  12 + /**
  13 + * 日志输出级别NONE
  14 + */
  15 + public static final int LEVEL_NONE = 0;
  16 + /**
  17 + * 日志输出级别E
  18 + */
  19 + public static final int LEVEL_ERROR = 1;
  20 + /**
  21 + * 日志输出级别W
  22 + */
  23 + public static final int LEVEL_WARN = 2;
  24 + /**
  25 + * 日志输出级别I
  26 + */
  27 + public static final int LEVEL_INFO = 3;
  28 + /**
  29 + * 日志输出级别D
  30 + */
  31 + public static final int LEVEL_DEBUG = 4;
  32 + /**
  33 + * 日志输出级别V
  34 + */
  35 + public static final int LEVEL_VERBOSE = 5;
  36 +
  37 + /**
  38 + * 日志输出时的TAG
  39 + */
  40 + private static String mTag = "LogUtils";
  41 +
  42 + /**
  43 + * 是否允许输出log
  44 + */
  45 + private static int mDebuggable = LEVEL_VERBOSE;
  46 +
  47 + /**
  48 + * 设置调试Log开关
  49 + *
  50 + * @param isEnable 是否允许log
  51 + */
  52 + public static void setDebuggable(boolean isEnable) {
  53 + mDebuggable = isEnable ? LEVEL_VERBOSE : LEVEL_NONE;
  54 + }
  55 +
  56 + /**
  57 + * 以级别为 d 的形式输出LOG
  58 + */
  59 + public static void v(String msg) {
  60 + if (mDebuggable >= LEVEL_VERBOSE) {
  61 + Log.v(mTag, msg);
  62 + }
  63 + }
  64 +
  65 + /**
  66 + * 以级别为 d 的形式输出LOG
  67 + */
  68 + public static void d(String msg) {
  69 + if (mDebuggable >= LEVEL_DEBUG) {
  70 + Log.d(mTag, msg);
  71 + }
  72 + }
  73 +
  74 + /**
  75 + * 以级别为 i 的形式输出LOG
  76 + */
  77 + public static void i(String msg) {
  78 + if (mDebuggable >= LEVEL_INFO) {
  79 + Log.i(mTag, msg);
  80 + }
  81 + }
  82 +
  83 + /**
  84 + * 以级别为 w 的形式输出LOG
  85 + */
  86 + public static void w(String msg) {
  87 + if (mDebuggable >= LEVEL_WARN) {
  88 + Log.w(mTag, msg);
  89 + }
  90 + }
  91 +
  92 + /**
  93 + * 以级别为 e 的形式输出LOG
  94 + */
  95 + public static void e(String msg) {
  96 + if (mDebuggable >= LEVEL_ERROR) {
  97 + Log.e(mTag, msg);
  98 + }
  99 + }
  100 +
  101 + /**
  102 + * 以级别为 w 的形式输出Throwable
  103 + */
  104 + public static void w(Throwable tr) {
  105 + w("", tr);
  106 + }
  107 +
  108 + /**
  109 + * 以级别为 w 的形式输出LOG信息和Throwable
  110 + */
  111 + public static void w(String msg, Throwable tr) {
  112 + Log.w(mTag, msg, tr);
  113 + }
  114 +
  115 + /**
  116 + * 以级别为 e 的形式输出Throwable
  117 + */
  118 + public static void e(Throwable tr) {
  119 + e("", tr);
  120 + }
  121 +
  122 + /**
  123 + * 以级别为 e 的形式输出LOG信息和Throwable
  124 + */
  125 + public static void e(String msg, Throwable tr) {
  126 + if (mDebuggable >= LEVEL_ERROR && null != msg) {
  127 + Log.e(mTag, msg, tr);
  128 + }
  129 + }
  130 +
  131 + private static int originStackIndex = 2;
  132 +
  133 + /**
  134 + * 获取当前方法所在的文件名
  135 + *
  136 + * @return 当前方法所在的文件名
  137 + */
  138 + public static String getFileName() {
  139 + return Thread.currentThread().getStackTrace()[originStackIndex].getFileName();
  140 + }
  141 +
  142 + /**
  143 + * 获取当前方法所在的Class名
  144 + *
  145 + * @return 当前方法所在的Class名
  146 + */
  147 + public static String getClassName() {
  148 + return Thread.currentThread().getStackTrace()[originStackIndex].getClassName();
  149 + }
  150 +
  151 + /**
  152 + * 获取当前方法名
  153 + *
  154 + * @return 当前方法名
  155 + */
  156 + public static String getMethodName() {
  157 + return Thread.currentThread().getStackTrace()[originStackIndex].getMethodName();
  158 + }
  159 +
  160 + /**
  161 + * 获取当前代码执行处行数
  162 + *
  163 + * @return 当前代码执行处行数
  164 + */
  165 + public static int getLineNumber() {
  166 + return Thread.currentThread().getStackTrace()[originStackIndex].getLineNumber();
  167 + }
  168 +}
0 169 \ No newline at end of file
... ...
mvpsdk/src/main/java/com/share/mvpsdk/utils/MD5Utils.java 0 → 100644
... ... @@ -0,0 +1,38 @@
  1 +package com.share.mvpsdk.utils;
  2 +
  3 +import java.security.MessageDigest;
  4 +
  5 +/**
  6 + * Created by Horrarndoo on 2017/4/5.
  7 + * <p>
  8 + * MD5加密工具类
  9 + */
  10 +public class MD5Utils {
  11 + /*
  12 + * MD5加密,32位
  13 + */
  14 + public static String getMD5(String str) {
  15 + MessageDigest md5 = null;
  16 + try {
  17 + md5 = MessageDigest.getInstance("MD5");
  18 + } catch (Exception e) {
  19 + e.printStackTrace();
  20 + return "";
  21 + }
  22 + char[] charArray = str.toCharArray();
  23 + byte[] byteArray = new byte[charArray.length];
  24 + for (int i = 0; i < charArray.length; i++) {
  25 + byteArray[i] = (byte) charArray[i];
  26 + }
  27 + byte[] md5Bytes = md5.digest(byteArray);
  28 + StringBuffer hexValue = new StringBuffer();
  29 + for (int i = 0; i < md5Bytes.length; i++) {
  30 + int val = ((int) md5Bytes[i]) & 0xff;
  31 + if (val < 16) {
  32 + hexValue.append("0");
  33 + }
  34 + hexValue.append(Integer.toHexString(val));
  35 + }
  36 + return hexValue.toString();
  37 + }
  38 +}
0 39 \ No newline at end of file
... ...
mvpsdk/src/main/java/com/share/mvpsdk/utils/NavigationUtils.java 0 → 100644
... ... @@ -0,0 +1,23 @@
  1 +package com.share.mvpsdk.utils;
  2 +
  3 +import android.support.design.internal.NavigationMenuView;
  4 +import android.support.design.widget.NavigationView;
  5 +
  6 +/**
  7 + * Created by Horrarndoo on 2017/12/12.
  8 + * <p>
  9 + * NavigationView utils
  10 + */
  11 +
  12 +public class NavigationUtils {
  13 +
  14 + public static void disableNavigationViewScrollbars(NavigationView navigationView) {
  15 + if (navigationView != null) {
  16 + NavigationMenuView navigationMenuView = (NavigationMenuView) navigationView
  17 + .getChildAt(0);
  18 + if (navigationMenuView != null) {
  19 + navigationMenuView.setVerticalScrollBarEnabled(false);
  20 + }
  21 + }
  22 + }
  23 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/utils/NetworkConnectionUtils.java 0 → 100644
... ... @@ -0,0 +1,236 @@
  1 +package com.share.mvpsdk.utils;
  2 +
  3 +import android.app.Activity;
  4 +import android.content.ComponentName;
  5 +import android.content.Context;
  6 +import android.content.Intent;
  7 +import android.net.ConnectivityManager;
  8 +import android.net.NetworkInfo;
  9 +import android.net.wifi.ScanResult;
  10 +import android.net.wifi.WifiConfiguration;
  11 +import android.net.wifi.WifiConfiguration.KeyMgmt;
  12 +import android.net.wifi.WifiManager;
  13 +import android.os.Build;
  14 +
  15 +import java.io.IOException;
  16 +import java.util.List;
  17 +
  18 +import static com.share.mvpsdk.utils.LogUtils.e;
  19 +
  20 +/**
  21 + * Created by Horrarndoo on 2017/8/31.
  22 + * <p>
  23 + * Wifi连接工具类
  24 + */
  25 +public class NetworkConnectionUtils {
  26 + private final static String TAG = "NetworkConnectionUtils";
  27 +
  28 + public NetworkConnectionUtils() {
  29 + }
  30 +
  31 + /**
  32 + * 连接指定
  33 + *
  34 + * @param manager
  35 + * @param wifiSSID
  36 + * @return
  37 + */
  38 + public static boolean connectToSocketWifi(WifiManager manager, String wifiSSID) {
  39 + LogUtils.i("要连接的socket wifi====>" + wifiSSID);
  40 + WifiConfiguration wifiConfiguration = new WifiConfiguration();
  41 + wifiConfiguration.SSID = "\"" + wifiSSID + "\"";
  42 + wifiConfiguration.allowedKeyManagement.set(KeyMgmt.NONE);
  43 + wifiConfiguration.wepKeys[0] = "\"" + "\""; //小米手机MIUI7/华为EMUI4.1 需要webKey
  44 +
  45 + int networkId = manager.addNetwork(wifiConfiguration);
  46 +
  47 + if (networkId != -1) {
  48 + manager.enableNetwork(networkId, true);
  49 + e("连接设备成功");
  50 + return true;
  51 + } else {
  52 + e("第一次连接失败,尝试第二次。");
  53 + WifiConfiguration wifiConfiguration2 = new WifiConfiguration();
  54 + wifiConfiguration2.SSID = "\"" + wifiSSID + "\"";
  55 + //wifiConfiguration.wepKeys[0] = "\"" + "\"";//去掉webKey //小米手机MIUI8不能有webKey
  56 + wifiConfiguration2.allowedKeyManagement.set(KeyMgmt.NONE);
  57 + networkId = manager.addNetwork(wifiConfiguration2);
  58 + if (networkId != -1) {
  59 + manager.enableNetwork(networkId, true);
  60 + e("连接设备成功");
  61 + return true;
  62 + }
  63 + e("连接设备失败");
  64 + }
  65 + return false;
  66 + }
  67 +
  68 + /**
  69 + * 获取要连接的wifi节点各个配置选项的加密类型
  70 + *
  71 + * @param ssid
  72 + * @return wifiConfiguration
  73 + */
  74 + public static WifiConfiguration getWifiConfiguration(WifiManager manager, String ssid, String
  75 + password) {
  76 + WifiConfiguration wifiConfiguration = new WifiConfiguration();
  77 + wifiConfiguration.SSID = "\"" + ssid + "\"";
  78 +
  79 + List<ScanResult> list = manager.getScanResults();
  80 + for (ScanResult scResult : list) {
  81 + if (ssid.equals(scResult.SSID)) {
  82 + String capabilities = scResult.capabilities;
  83 + LogUtils.i("capabilities=" + capabilities);
  84 + if (capabilities.contains("WEP") || capabilities.contains("wep")) {
  85 + wifiConfiguration.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
  86 + wifiConfiguration.preSharedKey = "\"" + password + "\"";
  87 + LogUtils.i("wep");
  88 + } else if (capabilities.contains("WPA") || capabilities.contains("wpa")) {
  89 + wifiConfiguration.allowedKeyManagement.set(KeyMgmt.WPA_PSK);
  90 + wifiConfiguration.preSharedKey = "\"" + password + "\"";
  91 + LogUtils.i("wpa");
  92 + } else {
  93 + wifiConfiguration.allowedKeyManagement.set(KeyMgmt.NONE);
  94 + LogUtils.i("none");
  95 + }
  96 + }
  97 + }
  98 + return wifiConfiguration;
  99 + }
  100 +
  101 + /**
  102 + * 给温控器成功发送联网命令后,连接温控器连接的wifi节点
  103 + *
  104 + * @param context 上下文对象
  105 + * @param ssid ssid
  106 + * @param password 密码
  107 + */
  108 + public static void connectWifiSSID(Context context, WifiManager manager, String ssid, String
  109 + password) {
  110 + e("reSetNetwork----------连接设备连入的路由---" + ssid);
  111 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
  112 + e("当前手机系统>=Android6.0,采取兼容模式");
  113 + new WifiAutoConnectManager(manager).connect(ssid, password, WifiAutoConnectManager
  114 + .getCipherType(context, ssid));
  115 + } else {
  116 + int networkId = manager.addNetwork(getWifiConfiguration(manager, ssid, password));
  117 + if (networkId != -1) {
  118 + manager.enableNetwork(networkId, true);
  119 + }
  120 + }
  121 + }
  122 +
  123 + /**
  124 + * 格式化RouterSSID
  125 + *
  126 + * @param strRouterSSID 要格式化的当前连接的路由ssid
  127 + * @return 去除"\"后的RouterSSID字符串
  128 + */
  129 + public static String formatRouterSSID(String strRouterSSID) {
  130 + //e("formate routerSSID before---" + strRouterSSID);
  131 + if (strRouterSSID.contains("\"")) {
  132 + strRouterSSID = strRouterSSID.replaceAll("\"", "");
  133 + //e("formate routerSSID after---" + strRouterSSID);
  134 + }
  135 + return strRouterSSID;
  136 + }
  137 +
  138 + /**
  139 + * Ping
  140 + * 用于确定手机是否已经连接上指定设备ip地址
  141 + */
  142 + public static boolean pingTest(String IPOrDomainName) {
  143 +
  144 + boolean isSuccess = false;
  145 + int status;
  146 + String result = "failed";
  147 + Process p;
  148 + try {
  149 + p = Runtime.getRuntime().exec("ping -c 1 " + IPOrDomainName);//
  150 + // m_strForNetAddress是输入的网址或者Ip地址
  151 + status = p.waitFor();// status 只能获取是否成功,无法获取更多的信息
  152 +
  153 + if (status == 0) {
  154 + result = "success";
  155 + isSuccess = true;
  156 + }
  157 +
  158 + } catch (IOException | InterruptedException e) {
  159 + e(e);
  160 + }
  161 + LogUtils.d("Ping result = " + result);
  162 + return isSuccess;
  163 + }
  164 +
  165 + /**
  166 + * 判断网络是否连接
  167 + */
  168 + public static boolean isConnected(Context context) {
  169 + ConnectivityManager cm = (ConnectivityManager)
  170 + context.getSystemService(Context.CONNECTIVITY_SERVICE);
  171 +
  172 + if (null == cm) {
  173 + return false;
  174 + }
  175 +
  176 + NetworkInfo info = cm.getActiveNetworkInfo();
  177 + if (null != info && info.isConnected()) {
  178 + if (info.getState() == NetworkInfo.State.CONNECTED) {
  179 + return true;
  180 + }
  181 + }
  182 + return false;
  183 + }
  184 +
  185 + /**
  186 + * 判断是否有网络
  187 + *
  188 + * @return 返回值
  189 + */
  190 + public static boolean isNetworkConnected(Context context) {
  191 + if (context != null) {
  192 + ConnectivityManager mConnectivityManager = (ConnectivityManager) context
  193 + .getSystemService(Context.CONNECTIVITY_SERVICE);
  194 + NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
  195 +
  196 + if (mNetworkInfo != null) {
  197 + return mNetworkInfo.isAvailable();
  198 + }
  199 + }
  200 + return false;
  201 + }
  202 +
  203 + /**
  204 + * 判断是否是wifi连接
  205 + */
  206 + public static boolean isWifi(Context context) {
  207 + ConnectivityManager cm = (ConnectivityManager)
  208 + context.getSystemService(Context.CONNECTIVITY_SERVICE);
  209 +
  210 + if (null == cm) {
  211 + return false;
  212 + }
  213 +
  214 + NetworkInfo info = cm.getActiveNetworkInfo();
  215 + if (null != info) {
  216 + if (info.getType() == ConnectivityManager.TYPE_WIFI) {
  217 + return true;
  218 + }
  219 + }
  220 + return false;
  221 +
  222 + }
  223 +
  224 +
  225 + /**
  226 + * 打开网络设置界面
  227 + */
  228 + public static void openSetting(Activity activity, int requestCode) {
  229 + Intent intent = new Intent("/");
  230 + ComponentName cm = new ComponentName("com.android.settings",
  231 + "com.android.settings.WirelessSettings");
  232 + intent.setComponent(cm);
  233 + intent.setAction(Intent.ACTION_VIEW);
  234 + activity.startActivityForResult(intent, requestCode);
  235 + }
  236 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/utils/OkHttpExceptionUtil.java 0 → 100644
... ... @@ -0,0 +1,28 @@
  1 +package com.share.mvpsdk.utils;
  2 +
  3 +import android.support.annotation.NonNull;
  4 +
  5 +import org.json.JSONObject;
  6 +
  7 +import okhttp3.ResponseBody;
  8 +import retrofit2.HttpException;
  9 +import retrofit2.Response;
  10 +
  11 +/**
  12 + * Created by 10501 on 2017/7/18.
  13 + */
  14 +
  15 +public class OkHttpExceptionUtil {
  16 + public static void handOkHttpException(@NonNull HttpException e){
  17 + Response response = e.response();
  18 + if (response==null)return;
  19 + ResponseBody responseBody = response.errorBody();
  20 + if (responseBody==null)return;
  21 + try {
  22 + JSONObject json = new JSONObject(responseBody.string());
  23 + ToastUtils.showToast(json.optString("message")+"json="+json);
  24 + } catch (Exception e1) {
  25 + e1.printStackTrace();
  26 + }
  27 + }
  28 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/utils/PermissionUtils.java 0 → 100644
... ... @@ -0,0 +1,323 @@
  1 +package com.share.mvpsdk.utils;
  2 +
  3 +import android.Manifest;
  4 +import android.app.Activity;
  5 +import android.app.AlertDialog;
  6 +import android.content.DialogInterface;
  7 +import android.content.Intent;
  8 +import android.content.pm.PackageManager;
  9 +import android.net.Uri;
  10 +import android.provider.Settings;
  11 +import android.support.annotation.NonNull;
  12 +import android.support.v4.app.ActivityCompat;
  13 +import android.util.Log;
  14 +import android.widget.Toast;
  15 +
  16 +
  17 +import com.share.mvpsdk.R;
  18 +
  19 +import java.util.ArrayList;
  20 +import java.util.HashMap;
  21 +import java.util.List;
  22 +import java.util.Map;
  23 +
  24 +/**
  25 + * Created by ToaHanDong on 2017/11/3.
  26 + */
  27 +
  28 +public class PermissionUtils {
  29 + private static final String TAG = PermissionUtils.class.getSimpleName();
  30 + public static final int CODE_RECORD_AUDIO = 0;
  31 + public static final int CODE_GET_ACCOUNTS = 1;
  32 + public static final int CODE_READ_PHONE_STATE = 2;
  33 + public static final int CODE_CALL_PHONE = 3;
  34 + public static final int CODE_CAMERA = 4;
  35 + public static final int CODE_ACCESS_FINE_LOCATION = 5;
  36 + public static final int CODE_ACCESS_COARSE_LOCATION = 6;
  37 + public static final int CODE_READ_EXTERNAL_STORAGE = 7;
  38 + public static final int CODE_WRITE_EXTERNAL_STORAGE = 8;
  39 + public static final int CODE_MULTI_PERMISSION = 100;
  40 +
  41 + //com.huawei.permission.sec.PERMISSION_MDM_SDCARD
  42 +// public static final String PERMISSION_MDM_SDCARD = "PERMISSION_MDM_SDCARD";
  43 + public static final String PERMISSION_RECORD_AUDIO = Manifest.permission.RECORD_AUDIO;
  44 + public static final String PERMISSION_GET_ACCOUNTS = Manifest.permission.GET_ACCOUNTS;
  45 + public static final String PERMISSION_READ_PHONE_STATE = Manifest.permission.READ_PHONE_STATE;
  46 + public static final String PERMISSION_CALL_PHONE = Manifest.permission.CALL_PHONE;
  47 + public static final String PERMISSION_CAMERA = Manifest.permission.CAMERA;
  48 + public static final String PERMISSION_ACCESS_FINE_LOCATION = Manifest.permission.ACCESS_FINE_LOCATION;
  49 + public static final String PERMISSION_ACCESS_COARSE_LOCATION = Manifest.permission.ACCESS_COARSE_LOCATION;
  50 + public static final String PERMISSION_READ_EXTERNAL_STORAGE = Manifest.permission.READ_EXTERNAL_STORAGE;
  51 + public static final String PERMISSION_WRITE_EXTERNAL_STORAGE = Manifest.permission.WRITE_EXTERNAL_STORAGE;
  52 +
  53 + private static final String[] requestPermissions = {
  54 + PERMISSION_RECORD_AUDIO,
  55 + PERMISSION_GET_ACCOUNTS,
  56 + PERMISSION_READ_PHONE_STATE,
  57 + PERMISSION_CALL_PHONE,
  58 + PERMISSION_CAMERA,
  59 + PERMISSION_ACCESS_FINE_LOCATION,
  60 + PERMISSION_ACCESS_COARSE_LOCATION,
  61 + PERMISSION_READ_EXTERNAL_STORAGE,
  62 + PERMISSION_WRITE_EXTERNAL_STORAGE
  63 +// PERMISSION_MDM_SDCARD
  64 + };
  65 +
  66 + public interface PermissionGrant {
  67 + void onPermissionGranted(int requestCode);
  68 + }
  69 +
  70 + /**
  71 + * Requests permission.
  72 + *
  73 + * @param activity
  74 + * @param requestCode request code, e.g. if you need request CAMERA permission,parameters is PermissionUtils.CODE_CAMERA
  75 + */
  76 + public static void requestPermission(final Activity activity, final int requestCode, PermissionGrant permissionGrant) {
  77 + if (activity == null) {
  78 + return;
  79 + }
  80 +
  81 + Log.i(TAG, "requestPermission requestCode:" + requestCode);
  82 + if (requestCode < 0 || requestCode >= requestPermissions.length) {
  83 + Log.w(TAG, "requestPermission illegal requestCode:" + requestCode);
  84 + return;
  85 + }
  86 +
  87 + final String requestPermission = requestPermissions[requestCode];
  88 +
  89 + //如果是6.0以下的手机,ActivityCompat.checkSelfPermission()会始终等于PERMISSION_GRANTED,
  90 + // 但是,如果用户关闭了你申请的权限,ActivityCompat.checkSelfPermission(),会导致程序崩溃(java.lang.RuntimeException: Unknown exception code: 1 msg null),
  91 + // 你可以使用try{}catch(){},处理异常,也可以在这个地方,低于23就什么都不做,
  92 + // 个人建议try{}catch(){}单独处理,提示用户开启权限。
  93 +// if (Build.VERSION.SDK_INT < 23) {
  94 +// return;
  95 +// }
  96 +
  97 + int checkSelfPermission;
  98 + try {
  99 + checkSelfPermission = ActivityCompat.checkSelfPermission(activity, requestPermission);
  100 + } catch (RuntimeException e) {
  101 +// Toast.makeText(activity, "please open this permission", Toast.LENGTH_SHORT)
  102 +// .show();
  103 + Log.e(TAG, "RuntimeException:" + e.getMessage());
  104 + return;
  105 + }
  106 +
  107 + if (checkSelfPermission != PackageManager.PERMISSION_GRANTED) {
  108 + Log.i(TAG, "ActivityCompat.checkSelfPermission != PackageManager.PERMISSION_GRANTED");
  109 +
  110 +
  111 + if (ActivityCompat.shouldShowRequestPermissionRationale(activity, requestPermission)) {
  112 + Log.i(TAG, "requestPermission shouldShowRequestPermissionRationale");
  113 + shouldShowRationale(activity, requestCode, requestPermission);
  114 +
  115 + } else {
  116 + Log.d(TAG, "requestCameraPermission else");
  117 + ActivityCompat.requestPermissions(activity, new String[]{requestPermission}, requestCode);
  118 + }
  119 +
  120 + } else {
  121 + Log.d(TAG, "ActivityCompat.checkSelfPermission ==== PackageManager.PERMISSION_GRANTED");
  122 +// Toast.makeText(activity, "opened:" + requestPermissions[requestCode], Toast.LENGTH_SHORT).show();
  123 + permissionGrant.onPermissionGranted(requestCode);
  124 + }
  125 + }
  126 +
  127 + private static void requestMultiResult(Activity activity, String[] permissions, int[] grantResults, PermissionGrant permissionGrant) {
  128 +
  129 + if (activity == null) {
  130 + return;
  131 + }
  132 +
  133 + //TODO
  134 + Log.d(TAG, "onRequestPermissionsResult permissions length:" + permissions.length);
  135 + Map<String, Integer> perms = new HashMap<>();
  136 +
  137 + ArrayList<String> notGranted = new ArrayList<>();
  138 + for (int i = 0; i < permissions.length; i++) {
  139 + Log.d(TAG, "permissions: [i]:" + i + ", permissions[i]" + permissions[i] + ",grantResults[i]:" + grantResults[i]);
  140 + perms.put(permissions[i], grantResults[i]);
  141 + if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
  142 + notGranted.add(permissions[i]);
  143 + }
  144 + }
  145 +
  146 + if (notGranted.size() == 0) {
  147 +// Toast.makeText(activity, "all permission success" + notGranted, Toast.LENGTH_SHORT)
  148 +// .show();
  149 + permissionGrant.onPermissionGranted(CODE_MULTI_PERMISSION);
  150 + } else {
  151 + openSettingActivity(activity, "those permission need granted!");
  152 + }
  153 +
  154 + }
  155 +
  156 +
  157 + /**
  158 + * 一次申请多个权限
  159 + */
  160 + public static void requestMultiPermissions(final Activity activity, PermissionGrant grant) {
  161 +
  162 + final List<String> permissionsList = getNoGrantedPermission(activity, false);
  163 + final List<String> shouldRationalePermissionsList = getNoGrantedPermission(activity, true);
  164 +
  165 + //TODO checkSelfPermission
  166 + if (permissionsList == null || shouldRationalePermissionsList == null) {
  167 + return;
  168 + }
  169 + Log.d(TAG, "requestMultiPermissions permissionsList:" + permissionsList.size() + ",shouldRationalePermissionsList:" + shouldRationalePermissionsList.size());
  170 +
  171 + if (permissionsList.size() > 0) {
  172 + ActivityCompat.requestPermissions(activity, permissionsList.toArray(new String[permissionsList.size()]),
  173 + CODE_MULTI_PERMISSION);
  174 + Log.d(TAG, "showMessageOKCancel requestPermissions");
  175 +
  176 + } else if (shouldRationalePermissionsList.size() > 0) {
  177 + showMessageOKCancel(activity, "should open those permission",
  178 + new DialogInterface.OnClickListener() {
  179 + @Override
  180 + public void onClick(DialogInterface dialog, int which) {
  181 + ActivityCompat.requestPermissions(activity, shouldRationalePermissionsList.toArray(new String[shouldRationalePermissionsList.size()]),
  182 + CODE_MULTI_PERMISSION);
  183 + Log.d(TAG, "showMessageOKCancel requestPermissions");
  184 + }
  185 + });
  186 + } else {
  187 + grant.onPermissionGranted(CODE_MULTI_PERMISSION);
  188 + }
  189 +
  190 + }
  191 +
  192 +
  193 + private static void shouldShowRationale(final Activity activity, final int requestCode, final String requestPermission) {
  194 + //TODO
  195 + String[] permissionsHint = activity.getResources().getStringArray(R.array.permissions);
  196 + showMessageOKCancel(activity, "Rationale: " + permissionsHint[requestCode], new DialogInterface.OnClickListener() {
  197 + @Override
  198 + public void onClick(DialogInterface dialog, int which) {
  199 + ActivityCompat.requestPermissions(activity,
  200 + new String[]{requestPermission},
  201 + requestCode);
  202 + Log.d(TAG, "showMessageOKCancel requestPermissions:" + requestPermission);
  203 + }
  204 + });
  205 + }
  206 +
  207 + private static void showMessageOKCancel(final Activity context, String message, DialogInterface.OnClickListener okListener) {
  208 + new AlertDialog.Builder(context)
  209 + .setMessage(message)
  210 + .setPositiveButton("OK", okListener)
  211 + .setNegativeButton("Cancel", null)
  212 + .create()
  213 + .show();
  214 +
  215 + }
  216 +
  217 + /**
  218 + * @param activity
  219 + * @param requestCode Need consistent with requestPermission
  220 + * @param permissions
  221 + * @param grantResults
  222 + */
  223 + public static void requestPermissionsResult(final Activity activity, final int requestCode, @NonNull String[] permissions,
  224 + @NonNull int[] grantResults, PermissionGrant permissionGrant) {
  225 +
  226 + if (activity == null) {
  227 + return;
  228 + }
  229 + Log.d(TAG, "requestPermissionsResult requestCode:" + requestCode);
  230 +
  231 + if (requestCode == CODE_MULTI_PERMISSION) {
  232 + requestMultiResult(activity, permissions, grantResults, permissionGrant);
  233 + return;
  234 + }
  235 +
  236 + if (requestCode < 0 || requestCode >= requestPermissions.length) {
  237 + Log.w(TAG, "requestPermissionsResult illegal requestCode:" + requestCode);
  238 +// Toast.makeText(activity, "illegal requestCode:" + requestCode, Toast.LENGTH_SHORT).show();
  239 + return;
  240 + }
  241 +
  242 + Log.i(TAG, "onRequestPermissionsResult requestCode:" + requestCode + ",permissions:" + permissions.toString()
  243 + + ",grantResults:" + grantResults.toString() + ",length:" + grantResults.length);
  244 +
  245 + if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
  246 + Log.i(TAG, "onRequestPermissionsResult PERMISSION_GRANTED");
  247 + //TODO success, do something, can use callback
  248 + permissionGrant.onPermissionGranted(requestCode);
  249 +
  250 + } else {
  251 + //TODO hint user this permission function
  252 + Log.i(TAG, "onRequestPermissionsResult PERMISSION NOT GRANTED");
  253 + //TODO
  254 + String[] permissionsHint = activity.getResources().getStringArray(R.array.permissions);
  255 + openSettingActivity(activity, "Result" + permissionsHint[requestCode]);
  256 + }
  257 +
  258 + }
  259 +
  260 + private static void openSettingActivity(final Activity activity, String message) {
  261 +
  262 + showMessageOKCancel(activity, message, new DialogInterface.OnClickListener() {
  263 + @Override
  264 + public void onClick(DialogInterface dialog, int which) {
  265 + Intent intent = new Intent();
  266 + intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
  267 + Log.d(TAG, "getPackageName(): " + activity.getPackageName());
  268 + Uri uri = Uri.fromParts("package", activity.getPackageName(), null);
  269 + intent.setData(uri);
  270 + activity.startActivity(intent);
  271 + }
  272 + });
  273 + }
  274 +
  275 +
  276 + /**
  277 + * @param activity
  278 + * @param isShouldRationale true: return no granted and shouldShowRequestPermissionRationale permissions, false:return no granted and !shouldShowRequestPermissionRationale
  279 + * @return
  280 + */
  281 + public static ArrayList<String> getNoGrantedPermission(Activity activity, boolean isShouldRationale) {
  282 +
  283 + ArrayList<String> permissions = new ArrayList<>();
  284 +
  285 + for (int i = 0; i < requestPermissions.length; i++) {
  286 + String requestPermission = requestPermissions[i];
  287 +
  288 +
  289 + //TODO checkSelfPermission
  290 + int checkSelfPermission = -1;
  291 + try {
  292 + checkSelfPermission = ActivityCompat.checkSelfPermission(activity, requestPermission);
  293 + } catch (RuntimeException e) {
  294 + Toast.makeText(activity, "please open those permission", Toast.LENGTH_SHORT)
  295 + .show();
  296 + Log.e(TAG, "RuntimeException:" + e.getMessage());
  297 + return null;
  298 + }
  299 +
  300 + if (checkSelfPermission != PackageManager.PERMISSION_GRANTED) {
  301 + Log.i(TAG, "getNoGrantedPermission ActivityCompat.checkSelfPermission != PackageManager.PERMISSION_GRANTED:" + requestPermission);
  302 +
  303 + if (ActivityCompat.shouldShowRequestPermissionRationale(activity, requestPermission)) {
  304 + Log.d(TAG, "shouldShowRequestPermissionRationale if");
  305 + if (isShouldRationale) {
  306 + permissions.add(requestPermission);
  307 + }
  308 +
  309 + } else {
  310 +
  311 + if (!isShouldRationale) {
  312 + permissions.add(requestPermission);
  313 + }
  314 + Log.d(TAG, "shouldShowRequestPermissionRationale else");
  315 + }
  316 +
  317 + }
  318 + }
  319 +
  320 + return permissions;
  321 + }
  322 +
  323 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/utils/ResourcesUtils.java 0 → 100644
... ... @@ -0,0 +1,83 @@
  1 +package com.share.mvpsdk.utils;
  2 +
  3 +import android.content.res.ColorStateList;
  4 +import android.graphics.drawable.Drawable;
  5 +import android.view.View;
  6 +
  7 +/**
  8 + * Created by Horrarndoo on 2017/9/1.
  9 + * <p>
  10 + * 资源工具类-加载资源文件
  11 + */
  12 +
  13 +public class ResourcesUtils {
  14 + /**
  15 + * 获取strings.xml资源文件字符串
  16 + *
  17 + * @param id 资源文件id
  18 + * @return 资源文件对应字符串
  19 + */
  20 + public static String getString(int id) {
  21 + return AppUtils.getContext().getResources().getString(id);
  22 + }
  23 +
  24 + /**
  25 + * 获取strings.xml资源文件字符串数组
  26 + *
  27 + * @param id 资源文件id
  28 + * @return 资源文件对应字符串数组
  29 + */
  30 + public static String[] getStringArray(int id) {
  31 + return AppUtils.getContext().getResources().getStringArray(id);
  32 + }
  33 +
  34 + /**
  35 + * 获取drawable资源文件图片
  36 + *
  37 + * @param id 资源文件id
  38 + * @return 资源文件对应图片
  39 + */
  40 + public static Drawable getDrawable(int id) {
  41 + return AppUtils.getContext().getResources().getDrawable(id);
  42 + }
  43 +
  44 + /**
  45 + * 获取colors.xml资源文件颜色
  46 + *
  47 + * @param id 资源文件id
  48 + * @return 资源文件对应颜色值
  49 + */
  50 + public static int getColor(int id) {
  51 + return AppUtils.getContext().getResources().getColor(id);
  52 + }
  53 +
  54 + /**
  55 + * 获取颜色的状态选择器
  56 + *
  57 + * @param id 资源文件id
  58 + * @return 资源文件对应颜色状态
  59 + */
  60 + public static ColorStateList getColorStateList(int id) {
  61 + return AppUtils.getContext().getResources().getColorStateList(id);
  62 + }
  63 +
  64 + /**
  65 + * 获取dimens资源文件中具体像素值
  66 + *
  67 + * @param id 资源文件id
  68 + * @return 资源文件对应像素值
  69 + */
  70 + public static int getDimen(int id) {
  71 + return AppUtils.getContext().getResources().getDimensionPixelSize(id);// 返回具体像素值
  72 + }
  73 +
  74 + /**
  75 + * 加载布局文件
  76 + *
  77 + * @param id 布局文件id
  78 + * @return 布局view
  79 + */
  80 + public static View inflate(int id) {
  81 + return View.inflate(AppUtils.getContext(), id, null);
  82 + }
  83 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/utils/ScreenUtils.java 0 → 100644
... ... @@ -0,0 +1,151 @@
  1 +package com.share.mvpsdk.utils;
  2 +
  3 +import android.app.Activity;
  4 +import android.app.ActivityGroup;
  5 +import android.content.Context;
  6 +import android.graphics.Bitmap;
  7 +import android.graphics.Rect;
  8 +import android.os.Build;
  9 +import android.support.v7.app.AppCompatActivity;
  10 +import android.util.Log;
  11 +import android.util.TypedValue;
  12 +import android.view.Display;
  13 +import android.view.View;
  14 +import android.view.ViewGroup;
  15 +import android.view.WindowManager;
  16 +
  17 +/**
  18 + * Created by Horrarndoo on 2017/9/7.
  19 + * <p>
  20 + * 屏幕相关工具类
  21 + */
  22 +
  23 +public class ScreenUtils {
  24 + private ScreenUtils() {
  25 + /* cannot be instantiated */
  26 + throw new UnsupportedOperationException("cannot be instantiated");
  27 + }
  28 +
  29 +
  30 + private static int mStatusHeight = -1;
  31 +
  32 + /**
  33 + * 获取屏幕的宽度
  34 + *
  35 + * @param context
  36 + * @return
  37 + */
  38 + public static int getScreenWidth(Context context) {
  39 + WindowManager manager = (WindowManager) context
  40 + .getSystemService(Context.WINDOW_SERVICE);
  41 + Display display = manager.getDefaultDisplay();
  42 + return display.getWidth();
  43 + }
  44 +
  45 + /**
  46 + * 获取屏幕的高度
  47 + *
  48 + * @param context
  49 + * @return
  50 + */
  51 + public static int getScreenHeight(Context context) {
  52 + WindowManager manager = (WindowManager) context
  53 + .getSystemService(Context.WINDOW_SERVICE);
  54 + Display display = manager.getDefaultDisplay();
  55 + return display.getHeight();
  56 + }
  57 +
  58 + /**
  59 + * 获取当前屏幕截图,不包含状态栏
  60 + *
  61 + * @param activity
  62 + * @return bp
  63 + */
  64 + public static Bitmap snapShotWithoutStatusBar(Activity activity) {
  65 + View view = activity.getWindow().getDecorView();
  66 + view.setDrawingCacheEnabled(true);
  67 + view.buildDrawingCache();
  68 + Bitmap bmp = view.getDrawingCache();
  69 + if (bmp == null) {
  70 + return null;
  71 + }
  72 + Rect frame = new Rect();
  73 + activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
  74 + int statusBarHeight = frame.top;
  75 + Bitmap bp = Bitmap.createBitmap(bmp, 0, statusBarHeight, bmp.getWidth(), bmp.getHeight()
  76 + - statusBarHeight);
  77 + view.destroyDrawingCache();
  78 + view.setDrawingCacheEnabled(false);
  79 +
  80 + return bp;
  81 + }
  82 +
  83 + /**
  84 + * 获取actionbar的像素高度,默认使用android官方兼容包做actionbar兼容
  85 + *
  86 + * @return
  87 + */
  88 + public static int getActionBarHeight(Context context) {
  89 + int actionBarHeight = 0;
  90 + if (context instanceof AppCompatActivity && ((AppCompatActivity) context)
  91 + .getSupportActionBar() != null) {
  92 + Log.d("isAppCompatActivity", "==AppCompatActivity");
  93 + actionBarHeight = ((AppCompatActivity) context).getSupportActionBar().getHeight();
  94 + } else if (context instanceof Activity && ((Activity) context).getActionBar() != null) {
  95 + Log.d("isActivity", "==Activity");
  96 + actionBarHeight = ((Activity) context).getActionBar().getHeight();
  97 + } else if (context instanceof ActivityGroup) {
  98 + Log.d("ActivityGroup", "==ActivityGroup");
  99 + if (((ActivityGroup) context).getCurrentActivity() instanceof AppCompatActivity && (
  100 + (AppCompatActivity) ((ActivityGroup) context).getCurrentActivity())
  101 + .getSupportActionBar() != null) {
  102 + actionBarHeight = ((AppCompatActivity) ((ActivityGroup) context)
  103 + .getCurrentActivity()).getSupportActionBar().getHeight();
  104 + } else if (((ActivityGroup) context).getCurrentActivity() instanceof Activity && (
  105 + (Activity) ((ActivityGroup) context).getCurrentActivity()).getActionBar() !=
  106 + null) {
  107 + actionBarHeight = ((Activity) ((ActivityGroup) context).getCurrentActivity())
  108 + .getActionBar().getHeight();
  109 + }
  110 + }
  111 + if (actionBarHeight != 0)
  112 + return actionBarHeight;
  113 + final TypedValue tv = new TypedValue();
  114 + if (context.getTheme().resolveAttribute(android.support.v7.appcompat.R.attr
  115 + .actionBarSize, tv, true)) {
  116 + if (context.getTheme().resolveAttribute(android.support.v7.appcompat.R.attr
  117 + .actionBarSize, tv, true))
  118 + actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, context
  119 + .getResources().getDisplayMetrics());
  120 + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
  121 + if (context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true))
  122 + actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, context
  123 + .getResources().getDisplayMetrics());
  124 + } else {
  125 + if (context.getTheme().resolveAttribute(android.support.v7.appcompat.R.attr
  126 + .actionBarSize, tv, true))
  127 + actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, context
  128 + .getResources().getDisplayMetrics());
  129 + }
  130 + Log.d("actionBarHeight", "====" + actionBarHeight);
  131 + return actionBarHeight;
  132 + }
  133 +
  134 +
  135 + /**
  136 + * 设置view margin
  137 + *
  138 + * @param v
  139 + * @param l
  140 + * @param t
  141 + * @param r
  142 + * @param b
  143 + */
  144 + public static void setMargins(View v, int l, int t, int r, int b) {
  145 + if (v.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
  146 + ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
  147 + p.setMargins(l, t, r, b);
  148 + v.requestLayout();
  149 + }
  150 + }
  151 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/utils/SnackbarUtils.java 0 → 100644
... ... @@ -0,0 +1,189 @@
  1 +package com.share.mvpsdk.utils;
  2 +
  3 +import android.graphics.Color;
  4 +import android.support.design.widget.Snackbar;
  5 +import android.view.Gravity;
  6 +import android.view.LayoutInflater;
  7 +import android.view.View;
  8 +import android.widget.LinearLayout;
  9 +import android.widget.TextView;
  10 +
  11 +import com.share.mvpsdk.R;
  12 +
  13 +
  14 +/**
  15 + * Created by Horrarndoo on 2017/8/31.
  16 + * <p>
  17 + * Snackbar工具类
  18 + */
  19 +public class SnackbarUtils {
  20 +
  21 + public static final int Info = 1;
  22 + public static final int Confirm = 2;
  23 + public static final int Warning = 3;
  24 + public static final int Alert = 4;
  25 +
  26 +
  27 + public static int red = 0xfff44336;
  28 + public static int green = 0xff4caf50;
  29 + public static int blue = 0xff2195f3;
  30 + public static int orange = 0xffffc107;
  31 +
  32 + /**
  33 + * 短显示Snackbar,自定义颜色
  34 + *
  35 + * @param view
  36 + * @param message
  37 + * @param messageColor
  38 + * @param backgroundColor
  39 + * @return
  40 + */
  41 + public static Snackbar getShort(View view, String message, int messageColor, int
  42 + backgroundColor) {
  43 + Snackbar snackbar = Snackbar.make(view, message, Snackbar.LENGTH_SHORT);
  44 + setSnackbarColor(snackbar, messageColor, backgroundColor);
  45 + return snackbar;
  46 + }
  47 +
  48 + /**
  49 + * 长显示Snackbar,自定义颜色
  50 + *
  51 + * @param view
  52 + * @param message
  53 + * @param messageColor
  54 + * @param backgroundColor
  55 + * @return
  56 + */
  57 + public static Snackbar getLong(View view, String message, int messageColor, int
  58 + backgroundColor) {
  59 + Snackbar snackbar = Snackbar.make(view, message, Snackbar.LENGTH_LONG);
  60 + setSnackbarColor(snackbar, messageColor, backgroundColor);
  61 + return snackbar;
  62 + }
  63 +
  64 + /**
  65 + * 自定义时常显示Snackbar,自定义颜色
  66 + *
  67 + * @param view
  68 + * @param message
  69 + * @param messageColor
  70 + * @param backgroundColor
  71 + * @return
  72 + */
  73 + public static Snackbar getIndefinite(View view, String message, int duration, int
  74 + messageColor, int backgroundColor) {
  75 + Snackbar snackbar = Snackbar.make(view, message, Snackbar.LENGTH_INDEFINITE).setDuration
  76 + (duration);
  77 + setSnackbarColor(snackbar, messageColor, backgroundColor);
  78 + return snackbar;
  79 + }
  80 +
  81 + /**
  82 + * 短显示Snackbar,可选预设类型
  83 + *
  84 + * @param view
  85 + * @param message
  86 + * @param type
  87 + * @return
  88 + */
  89 + public static Snackbar getShort(View view, String message, int type) {
  90 + Snackbar snackbar = Snackbar.make(view, message, Snackbar.LENGTH_SHORT);
  91 + switchType(snackbar, type);
  92 + return snackbar;
  93 + }
  94 +
  95 + /**
  96 + * 长显示Snackbar,可选预设类型
  97 + *
  98 + * @param view
  99 + * @param message
  100 + * @param type
  101 + * @return
  102 + */
  103 + public static Snackbar getLong(View view, String message, int type) {
  104 + Snackbar snackbar = Snackbar.make(view, message, Snackbar.LENGTH_LONG);
  105 + switchType(snackbar, type);
  106 + return snackbar;
  107 + }
  108 +
  109 + /**
  110 + * 自定义时常显示Snackbar,可选预设类型
  111 + *
  112 + * @param view
  113 + * @param message
  114 + * @param type
  115 + * @return
  116 + */
  117 + public static Snackbar getIndefinite(View view, String message, int duration, int type) {
  118 + Snackbar snackbar = Snackbar.make(view, message, Snackbar.LENGTH_INDEFINITE).setDuration
  119 + (duration);
  120 + switchType(snackbar, type);
  121 + return snackbar;
  122 + }
  123 +
  124 + //选择预设类型
  125 + private static void switchType(Snackbar snackbar, int type) {
  126 + switch (type) {
  127 + case Info:
  128 + setSnackbarColor(snackbar, blue);
  129 + break;
  130 + case Confirm:
  131 + setSnackbarColor(snackbar, green);
  132 + break;
  133 + case Warning:
  134 + setSnackbarColor(snackbar, orange);
  135 + break;
  136 + case Alert:
  137 + setSnackbarColor(snackbar, Color.YELLOW, red);
  138 + break;
  139 + }
  140 + }
  141 +
  142 + /**
  143 + * 设置Snackbar背景颜色
  144 + *
  145 + * @param snackbar
  146 + * @param backgroundColor
  147 + */
  148 + public static void setSnackbarColor(Snackbar snackbar, int backgroundColor) {
  149 + View view = snackbar.getView();
  150 + if (view != null) {
  151 + view.setBackgroundColor(backgroundColor);
  152 + }
  153 + }
  154 +
  155 + /**
  156 + * 设置Snackbar文字和背景颜色
  157 + *
  158 + * @param snackbar
  159 + * @param messageColor
  160 + * @param backgroundColor
  161 + */
  162 + public static void setSnackbarColor(Snackbar snackbar, int messageColor, int backgroundColor) {
  163 + View view = snackbar.getView();
  164 + if (view != null) {
  165 + view.setBackgroundColor(backgroundColor);
  166 + ((TextView) view.findViewById(R.id.snackbar_text)).setTextColor(messageColor);
  167 + }
  168 + }
  169 +
  170 + /**
  171 + * 向Snackbar中添加view
  172 + *
  173 + * @param snackbar
  174 + * @param layoutId
  175 + * @param index 新加布局在Snackbar中的位置
  176 + */
  177 + public static void addView(Snackbar snackbar, int layoutId, int index) {
  178 + View snackbarview = snackbar.getView();
  179 + Snackbar.SnackbarLayout snackbarLayout = (Snackbar.SnackbarLayout) snackbarview;
  180 +
  181 + View add_view = LayoutInflater.from(snackbarview.getContext()).inflate(layoutId, null);
  182 +
  183 + LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(LinearLayout.LayoutParams
  184 + .WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
  185 + p.gravity = Gravity.CENTER_VERTICAL;
  186 +
  187 + snackbarLayout.addView(add_view, index, p);
  188 + }
  189 +}
0 190 \ No newline at end of file
... ...
mvpsdk/src/main/java/com/share/mvpsdk/utils/SpUtils.java 0 → 100644
... ... @@ -0,0 +1,212 @@
  1 +package com.share.mvpsdk.utils;
  2 +
  3 +
  4 +import android.content.Context;
  5 +import android.content.SharedPreferences;
  6 +import android.preference.PreferenceManager;
  7 +
  8 +import com.google.gson.Gson;
  9 +import com.google.gson.JsonArray;
  10 +import com.google.gson.JsonElement;
  11 +import com.google.gson.JsonParser;
  12 +
  13 +import java.util.ArrayList;
  14 +import java.util.List;
  15 +
  16 +/**
  17 + * SharedPreferences工具类封装
  18 + */
  19 +public class SpUtils {
  20 + private static SharedPreferences sp;
  21 + private static String mPreferencesName = "share_preference_default";
  22 +
  23 + /**
  24 + * 设置preferencesName
  25 + *
  26 + * @param preferencesName preferencesName
  27 + */
  28 + private void setPreferencesName(String preferencesName) {
  29 + mPreferencesName = preferencesName;
  30 + }
  31 +
  32 + /**
  33 + * 写入boolean变量至sp中
  34 + *
  35 + * @param ctx 上下文环境
  36 + * @param key 存储节点名称
  37 + * @param value 存储节点的值
  38 + */
  39 + public static void putBoolean(Context ctx, String key, boolean value) {
  40 + //(存储节点文件名称,读写方式)
  41 + if (sp == null) {
  42 + sp = ctx.getSharedPreferences(mPreferencesName, Context
  43 + .MODE_PRIVATE);
  44 + }
  45 + sp.edit().putBoolean(key, value).apply();
  46 + }
  47 +
  48 + /**
  49 + * 读取boolean标示从sp中
  50 + *
  51 + * @param ctx 上下文环境
  52 + * @param key 存储节点名称
  53 + * @param defValue 没有此节点默认值
  54 + * @return 默认值或者此节点读取到的结果
  55 + */
  56 + public static boolean getBoolean(Context ctx, String key, boolean defValue) {
  57 + //(存储节点文件名称,读写方式)
  58 + if (sp == null) {
  59 + sp = ctx.getSharedPreferences(mPreferencesName, Context
  60 + .MODE_PRIVATE);
  61 + }
  62 + return sp.getBoolean(key, defValue);
  63 + }
  64 +
  65 + /**
  66 + * 写入String变量至sp中
  67 + *
  68 + * @param ctx 上下文环境
  69 + * @param key 存储节点名称
  70 + * @param value 存储节点的值
  71 + */
  72 + public static void putString(Context ctx, String key, String value) {
  73 + //(存储节点文件名称,读写方式)
  74 + if (sp == null) {
  75 + sp = ctx.getSharedPreferences(mPreferencesName, Context
  76 + .MODE_PRIVATE);
  77 + }
  78 + sp.edit().putString(key, value).apply();
  79 + }
  80 +
  81 + /**
  82 + * 读取String标示从sp中
  83 + *
  84 + * @param ctx 上下文环境
  85 + * @param key 存储节点名称
  86 + * @param defValue 没有此节点默认值
  87 + * @return 默认值或者此节点读取到的结果
  88 + */
  89 + public static String getString(Context ctx, String key, String defValue) {
  90 + //(存储节点文件名称,读写方式)
  91 + if (sp == null) {
  92 + sp = ctx.getSharedPreferences(mPreferencesName, Context
  93 + .MODE_PRIVATE);
  94 + }
  95 + return sp.getString(key, defValue);
  96 + }
  97 +
  98 +
  99 + /**
  100 + * 写入int变量至sp中
  101 + *
  102 + * @param ctx 上下文环境
  103 + * @param key 存储节点名称
  104 + * @param value 存储节点的值
  105 + */
  106 + public static void putInt(Context ctx, String key, int value) {
  107 + //(存储节点文件名称,读写方式)
  108 + if (sp == null) {
  109 + sp = ctx.getSharedPreferences(mPreferencesName, Context
  110 + .MODE_PRIVATE);
  111 + }
  112 + sp.edit().putInt(key, value).apply();
  113 + }
  114 +
  115 + /**
  116 + * 读取int标示从sp中
  117 + *
  118 + * @param ctx 上下文环境
  119 + * @param key 存储节点名称
  120 + * @param defValue 没有此节点默认值
  121 + * @return 默认值或者此节点读取到的结果
  122 + */
  123 + public static int getInt(Context ctx, String key, int defValue) {
  124 + //(存储节点文件名称,读写方式)
  125 + if (sp == null) {
  126 + sp = ctx.getSharedPreferences(mPreferencesName, Context
  127 + .MODE_PRIVATE);
  128 + }
  129 + return sp.getInt(key, defValue);
  130 + }
  131 +
  132 +
  133 + /**
  134 + * 从sp中移除指定节点
  135 + *
  136 + * @param ctx 上下文环境
  137 + * @param key 需要移除节点的名称
  138 + */
  139 + public static void remove(Context ctx, String key) {
  140 + if (sp == null) {
  141 + sp = ctx.getSharedPreferences(mPreferencesName, Context
  142 + .MODE_PRIVATE);
  143 + }
  144 + sp.edit().remove(key).apply();
  145 + }
  146 +
  147 + /**
  148 + * 保存List
  149 + *
  150 + * @param key sp key值
  151 + * @param datalist list
  152 + * @param <T> item 类型
  153 + */
  154 + public static <T> void setDataList(String key, List<T> datalist) {
  155 + if (null == datalist || datalist.size() <= 0)
  156 + return;
  157 +
  158 + Gson gson = new Gson();
  159 + //转换成json数据,再保存
  160 + String strJson = gson.toJson(datalist);
  161 + SpUtils.putString(AppUtils.getContext(), key, strJson);
  162 + }
  163 +
  164 + /**
  165 + * 获取List
  166 + *
  167 + * @param key sp key值
  168 + * @param <T> item 类型
  169 + * @return list
  170 + */
  171 + public static <T> List<T> getDataList(String key, Class<T> cls) {
  172 + List<T> datalist = new ArrayList<T>();
  173 + String strJson = SpUtils.getString(AppUtils.getContext(), key, null);
  174 +
  175 + if (null == strJson) {
  176 + return datalist;
  177 + }
  178 +
  179 + try {
  180 + Gson gson = new Gson();
  181 + // datalist = gson.fromJson(strJson, new TypeToken<List<T>>(){}.getType());
  182 + JsonArray array = new JsonParser().parse(strJson).getAsJsonArray();
  183 + for (final JsonElement elem : array) {
  184 + datalist.add(gson.fromJson(elem, cls));
  185 + }
  186 + }catch (Exception e){
  187 + e.printStackTrace();
  188 + }
  189 +
  190 + return datalist;
  191 + }
  192 +
  193 + public static int getThemeIndex(Context context) {
  194 + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
  195 + return prefs.getInt("ThemeIndex", 5);
  196 + }
  197 +
  198 + public static void setThemeIndex(Context context, int index) {
  199 + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
  200 + prefs.edit().putInt("ThemeIndex", index).apply();
  201 + }
  202 +
  203 + public static boolean getNightModel(Context context) {
  204 + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
  205 + return prefs.getBoolean("pNightMode", false);
  206 + }
  207 +
  208 + public static void setNightModel(Context context, boolean nightModel) {
  209 + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
  210 + prefs.edit().putBoolean("pNightMode", nightModel).apply();
  211 + }
  212 +}
... ...
mvpsdk/src/main/java/com/share/mvpsdk/utils/StatusBarUtils.java 0 → 100644
... ... @@ -0,0 +1,140 @@
  1 +package com.share.mvpsdk.utils;
  2 +
  3 +import android.app.Activity;
  4 +import android.content.Context;
  5 +import android.graphics.Color;
  6 +import android.os.Build;
  7 +import android.support.annotation.ColorInt;
  8 +import android.support.v7.widget.Toolbar;
  9 +import android.view.View;
  10 +import android.view.ViewGroup;
  11 +import android.view.Window;
  12 +import android.view.WindowManager;
  13 +
  14 +import java.lang.reflect.Field;
  15 +
  16 +
  17 +/**
  18 + * Created by Horrarndoo on 2017/8/31.
  19 + * <p>
  20 + * StatusBar工具类
  21 + */
  22 +public class StatusBarUtils {
  23 +
  24 + private static final int DEFAULT_STATUS_BAR_ALPHA = 0;
  25 +
  26 + /**
  27 + * 设置状态栏颜色
  28 + *
  29 + * @param activity 需要设置的 activity
  30 + * @param color 状态栏颜色值
  31 + */
  32 + public static void setColor(Activity activity, @ColorInt int color) {
  33 + setBarColor(activity, color);
  34 + }
  35 +
  36 + /**
  37 + * 设置状态栏背景色
  38 + * 4.4以下不处理
  39 + * 4.4使用默认沉浸式状态栏
  40 + *
  41 + * @param color 要为状态栏设置的颜色值
  42 + */
  43 + public static void setBarColor(Activity activity, int color) {
  44 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
  45 + Window win = activity.getWindow();
  46 + View decorView = win.getDecorView();
  47 + win.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);//沉浸式状态栏(4.4-5.0透明,5.0以上半透明)
  48 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//android5.0以上设置透明效果
  49 + win.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);//清除flag,为了android5.0以上也全透明效果
  50 + //让应用的主体内容占用系统状态栏的空间
  51 +// int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
  52 +// | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
  53 + int option = View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
  54 + decorView.setSystemUiVisibility(decorView.getSystemUiVisibility() | option);
  55 + win.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
  56 + win.setStatusBarColor(color);//设置状态栏背景色
  57 + }
  58 + }
  59 + }
  60 +
  61 + /**
  62 + * 设置状态栏全透明
  63 + *
  64 + * @param activity 需要设置的activity
  65 + */
  66 + public static void setTransparent(Activity activity) {
  67 + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
  68 + return;
  69 + }
  70 + setColor(activity, Color.TRANSPARENT);
  71 + }
  72 +
  73 + /**
  74 + * 修正 Toolbar 的位置
  75 + * 在 Android 4.4 版本下无法显示内容在 StatusBar 下,所以无需修正 Toolbar 的位置
  76 + *
  77 + * @param toolbar
  78 + */
  79 + public static void fixToolbar(Toolbar toolbar, Activity activity) {
  80 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
  81 + int statusHeight = getStatusBarHeight(activity);
  82 + ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) toolbar.getLayoutParams();
  83 + layoutParams.setMargins(0, statusHeight, 0, 0);
  84 + }
  85 + }
  86 +
  87 + /**
  88 + * 获取系统状态栏高度
  89 + *
  90 + * @param context
  91 + * @return
  92 + */
  93 + public static int getStatusBarHeight(Context context) {
  94 + Class<?> c = null;
  95 + Object obj = null;
  96 + Field field = null;
  97 + int x = 0, statusBarHeight = 0;
  98 + try {
  99 + c = Class.forName("com.android.internal.R$dimen");
  100 + obj = c.newInstance();
  101 + field = c.getField("status_bar_height");
  102 + x = Integer.parseInt(field.get(obj).toString());
  103 + statusBarHeight = context.getResources().getDimensionPixelSize(x);
  104 + } catch (Exception e1) {
  105 + e1.printStackTrace();
  106 + }
  107 + return statusBarHeight;
  108 + }
  109 +
  110 +// /**
  111 +// * 获取状态栏高度
  112 +// *
  113 +// * @param context context
  114 +// * @return 状态栏高度
  115 +// */
  116 +// private static int getStatusBarHeight(Context context) {
  117 +// // 获得状态栏高度
  118 +// int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen",
  119 +// "android");
  120 +// return context.getResources().getDimensionPixelSize(resourceId);
  121 +// }
  122 +
  123 + /**
  124 + * 计算状态栏颜色
  125 + *
  126 + * @param color color值
  127 + * @param alpha alpha值
  128 + * @return 最终的状态栏颜色
  129 + */
  130 + private static int calculateStatusColor(@ColorInt int color, int alpha) {
  131 + float a = 1 - alpha / 255f;
  132 + int red = color >> 16 & 0xff;
  133 + int green = color >> 8 & 0xff;
  134 + int blue = color & 0xff;
  135 + red = (int) (red * a + 0.5);
  136 + green = (int) (green * a + 0.5);
  137 + blue = (int) (blue * a + 0.5);
  138 + return 0xff << 24 | red << 16 | green << 8 | blue;
  139 + }
  140 +}
... ...