Commit 0f706711 by 王宇航

模塊搭建完成,功能未完成

parent b00e953d
import org.checkerframework.checker.units.qual.A
ext.mainApp = true //设置为true,表示此module为主app module,一直以application方式编译
apply from: rootProject.file('cc-settings.gradle')
......@@ -73,11 +75,15 @@ dependencies {
// addComponent 'component_login'
// addComponent 'component_register'
implementation project(':public-base')
// implementation project(':arms')
implementation rootProject.ext.dependencies["arms"]
// test
testImplementation rootProject.ext.dependencies["junit"]
debugImplementation rootProject.ext.dependencies["canary-debug"]
releaseImplementation rootProject.ext.dependencies["canary-release"]
testImplementation rootProject.ext.dependencies["canary-release"]
implementation 'org.jetbrains:annotations:15.0'
}
......@@ -3,6 +3,7 @@
package="com.gingersoft.gsa.cloud">
<application
android:name=".application.MyApp"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
......
package com.gingersoft.gsa.cloud.main;
package com.gingersoft.gsa.cloud.application;
import android.app.Application;
import com.billy.cc.core.component.CC;
import com.joe.base.application.BaseApplication;
/**
* @author billy.qi
* @since 17/11/20 19:28
*/
public class MyApp extends Application {
public class MyApp extends BaseApplication {
@Override
public void onCreate() {
super.onCreate();
CC.enableVerboseLog(true);
CC.enableDebug(true);
CC.enableRemoteCC(true);
}
}
......@@ -127,7 +127,7 @@ public abstract class BaseActivity<P extends IPresenter> extends AppCompatActivi
return true;
}
/**
* 这个Activity是否会使用Fragment,框架会根据这个属性判断是否注册{@link androidx.core.app.FragmentManager.FragmentLifecycleCallbacks}
* 这个Activity是否会使用Fragment,框架会根据这个属性判断是否注册
* 如果返回false,那意味着这个Activity不需要绑定Fragment,那你再在这个Activity中绑定继承于 {@link com.jess.arms.base.BaseFragment} 的Fragment将不起任何作用
*
* @return
......
......@@ -51,7 +51,7 @@ public class GlideImageLoaderStrategy implements BaseImageLoaderStrategy<ImageCo
public void loadImage(Context ctx, ImageConfigImpl config) {
if (ctx == null) throw new NullPointerException("Context is required");
if (config == null) throw new NullPointerException("ImageConfigImpl is required");
// if (TextUtils.isEmpty(config.getUrl())) throw new NullPointerException("Url is required");
// if (TextUtils.isEmpty(network.config.getUrl())) throw new NullPointerException("Url is required");
if (config.getUrl() == null) throw new NullPointerException("Url is required");
if (config.getImageView() == null) throw new NullPointerException("Imageview is required");
......
......@@ -43,7 +43,7 @@ import java.io.ObjectOutputStream;
*/
public class DataHelper {
private static SharedPreferences mSharedPreferences;
public static final String SP_NAME = "config";
public static final String SP_NAME = "network.config";
private DataHelper() {
......
......@@ -45,6 +45,7 @@ ext {
//view
"autolayout" : "com.zhy:autolayout:1.4.5",
"autosize" : 'me.jessyan:autosize:1.1.2',
"butterknife" : "com.jakewharton:butterknife:${version["butterknifeSdkVersion"]}",
"butterknife-compiler" : "com.jakewharton:butterknife-compiler:${version["butterknifeSdkVersion"]}",
"pickerview" : "com.contrarywind:Android-PickerView:3.2.5",
......@@ -94,6 +95,7 @@ ext {
// "fragmentation" : "me.yokeyword:fragmentation:${version["fragmentationVersion"]}",
// "fragmentation-core" : "me.yokeyword:fragmentation-core:${version["fragmentationVersion"]}",
// "fragmentation-swipeback" : "me.yokeyword:fragmentation-swipeback:${version["fragmentationVersion"]}",
"constraintlayout" : "androidx.constraintlayout:constraintlayout:1.1.3",//constraintlayout約束佈局
//test
"junit" : "junit:junit:4.12",
......@@ -107,7 +109,10 @@ ext {
"logger" : "com.orhanobut:logger:2.1.1",
"canary-debug" : "com.squareup.leakcanary:leakcanary-android:${version["canarySdkVersion"]}",
"canary-release" : "com.squareup.leakcanary:leakcanary-android-no-op:${version["canarySdkVersion"]}",
"umeng-analytics" : "com.umeng.analytics:analytics:6.0.1"
"umeng-analytics" : "com.umeng.analytics:analytics:6.0.1",
// QMUI
"qmui" : "com.qmuiteam:qmui:1.2.0",
"arms" : "me.jessyan:arms:2.5.2"
]
}
......@@ -36,5 +36,6 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation project(':arms')
// implementation project(':arms')
implementation rootProject.ext.dependencies["arms"]
}
apply plugin: 'com.android.library'
ext.alwaysLib = true //虽然apply了cc-settings-2.gradle,但一直作为library编译,否则别的组件依赖此module时会报错
apply from: rootProject.file("cc-settings.gradle")
android {
compileSdkVersion 29
compileSdkVersion rootProject.ext.android["compileSdkVersion"]
buildToolsVersion "29.0.2"
defaultConfig {
minSdkVersion 18
targetSdkVersion 29
versionCode 1
versionName "1.0"
minSdkVersion rootProject.ext.android["minSdkVersion"]
targetSdkVersion rootProject.ext.android["targetSdkVersion"]
versionCode rootProject.ext.android["versionCode"]
versionName rootProject.ext.android["versionName"]
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles 'consumer-rules.pro'
}
compileOptions {
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_1_8
}
buildTypes {
release {
minifyEnabled false
......@@ -30,5 +34,8 @@ dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation files('libs/javabase64-1.2.jar')
implementation files('libs/sun.misc.BASE64Decoder.jar')
implementation rootProject.ext.dependencies["qmui"]
}
package com.joe.utils;
package com.joe.base;
import android.content.Context;
......@@ -22,6 +22,6 @@ public class ExampleInstrumentedTest {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
assertEquals("com.joe.utils.test", appContext.getPackageName());
assertEquals("com.joe.public_base.test", appContext.getPackageName());
}
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.joe.utils" />
package="com.joe.base" />
package com.joe.base.application;
import android.app.Application;
import android.content.Context;
import com.billy.cc.core.component.CC;
/**
* Created by Wyh on 2019/12/21.
*/
public class BaseApplication extends Application {
/**
* 系统上下文
*/
private static Context mAppContext;
@Override
public void onCreate() {
super.onCreate();
mAppContext = getApplicationContext();
CC.enableVerboseLog(true);
CC.enableDebug(true);
CC.enableRemoteCC(true);
}
/**
* 获取系统上下文:用于ToastUtil类
*/
public static Context getAppContext() {
return mAppContext;
}
}
package com.joe.base.utils.constans;
/**
* Created by Wyh on 2019/12/21.
*/
public class AppConstans {
public static final String SECRETKEY_VALUES = "2309485937845783";
public static final String APP_TYPE = "9";
}
package com.joe.base.utils.constans;
/**
* Created by Wyh on 2019/12/21.
*/
public class HttpsConstans {
public static String ROOT_SERVER_ADDRESS_FORMAL = "http://gingersoft.tpddns.cn:58201/ricepon-cloud-gsa/api/";// 正式服務器
}
package com.joe.base.utils.constans;
/**
* Created by Wyh on 2019/12/21.
*/
public class UserConstans {
public static String memberId = "member_id";
public static String token = "user_token";
//平板登录状态
public static String FLATBED_LOGIN_STATUS = "flatbed_login_status";
}
package com.joe.base.utils.encryption;
import java.math.BigInteger;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;
import Decoder.BASE64Decoder;
/**
* AES的加密和解密
*
* @author libo
*/
public class Aes {
//密钥 (需要前端和后端保持一致)
private static final String KEY = "gingersoft_20201";
//算法
private static final String ALGORITHMSTR = "AES/ECB/PKCS5Padding";
/**
* aes解密
*
* @param encrypt 内容
* @return
* @throws Exception
*/
public static String aesDecrypt(String encrypt) {
try {
return aesDecrypt(encrypt, KEY);
} catch (Exception e) {
e.printStackTrace();
return "";
}
}
/**
* aes加密
*
* @param content
* @return
* @throws Exception
*/
public static String aesEncrypt(String content) {
try {
return aesEncrypt(content, KEY);
} catch (Exception e) {
e.printStackTrace();
return "";
}
}
/**
* 将byte[]转为各种进制的字符串
*
* @param bytes byte[]
* @param radix 可以转换进制的范围,从Character.MIN_RADIX到Character.MAX_RADIX,超出范围后变为10进制
* @return 转换后的字符串
*/
public static String binary(byte[] bytes, int radix) {
return new BigInteger(1, bytes).toString(radix);// 这里的1代表正数
}
/**
* base 64 encode
*
* @param bytes 待编码的byte[]
* @return 编码后的base 64 code
*/
public static String base64Encode(byte[] bytes) {
// return Base64.encodeBase64String();
return java.util.Base64.getEncoder().encodeToString(bytes);
}
/**
* base 64 decode
*
* @param base64Code 待解码的base 64 code
* @return 解码后的byte[]
* @throws Exception
*/
public static byte[] base64Decode(String base64Code) throws Exception {
return base64Code == null ? null : new BASE64Decoder().decodeBuffer(base64Code);
}
/**
* AES加密
*
* @param content 待加密的内容
* @param encryptKey 加密密钥
* @return 加密后的byte[]
* @throws Exception
*/
public static byte[] aesEncryptToBytes(String content, String encryptKey) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);
Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(encryptKey.getBytes(), "AES"));
return cipher.doFinal(content.getBytes("utf-8"));
}
/**
* AES加密为base 64 code
*
* @param content 待加密的内容
* @param encryptKey 加密密钥
* @return 加密后的base 64 code
* @throws Exception
*/
public static String aesEncrypt(String content, String encryptKey) {
try {
return base64Encode(aesEncryptToBytes(content, encryptKey));
} catch (Exception e) {
System.out.print(encryptKey);
return null;
}
}
/**
* AES解密
*
* @param encryptBytes 待解密的byte[]
* @param decryptKey 解密密钥
* @return 解密后的String
* @throws Exception
*/
public static String aesDecryptByBytes(byte[] encryptBytes, String decryptKey) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);
Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(decryptKey.getBytes(), "AES"));
byte[] decryptBytes = cipher.doFinal(encryptBytes);
return new String(decryptBytes);
}
/**
* 将base 64 code AES解密
*
* @param encryptStr 待解密的base 64 code
* @param decryptKey 解密密钥
* @return 解密后的string
* @throws Exception
*/
public static String aesDecrypt(String encryptStr, String decryptKey) {
try {
return encryptStr == null ? null : aesDecryptByBytes(base64Decode(encryptStr), decryptKey);
} catch (Exception e) {
e.printStackTrace();
System.out.print(encryptStr);
}
return null;
}
/**
* 测试
*/
public static void main(String[] args) {
String content = "{\"passWord\":\"123456\",\"userName\":\"18384840551\"}";
System.out.println("加密前:" + content);
System.out.println("加密密钥和解密密钥:" + KEY);
String encrypt = aesEncrypt(content, KEY);
System.out.println("加密后:" + encrypt);
String decrypt = aesDecrypt(encrypt, KEY);
System.out.println("解密后:" + decrypt);
//base64编码
//String strBase64 = new String(Base64.encode(str.getBytes(), Base64.DEFAULT));
// String strBase64 = android.util.Base64.encodeToString("", android.util.Base64.DEFAULT);
//base64解码
// String str2 = new String(android.util.Base64.decode(strBase64.getBytes(), android.util.Base64.DEFAULT));
}
}
......@@ -8,7 +8,7 @@
* 修改单号: <修改单号>
* 修改内容: <修改内容>
*/
package com.joe.utils.encryption;
package com.joe.base.utils.encryption;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
......
package com.joe.utils.encryption;
package com.joe.base.utils.encryption;
import java.io.IOException;
import java.security.SecureRandom;
......
package com.joe.base.utils.encryption;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD5 {
private final static String[] strDigits = { "0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
public MD5() {
}
private static String byteToArrayString(byte bByte) {
int iRet = bByte;
// System.out.println("iRet="+iRet);
if (iRet < 0) {
iRet += 256;
}
int iD1 = iRet / 16;
int iD2 = iRet % 16;
return strDigits[iD1] + strDigits[iD2];
}
private static String byteToNum(byte bByte) {
int iRet = bByte;
System.out.println("iRet1=" + iRet);
if (iRet < 0) {
iRet += 256;
}
return String.valueOf(iRet);
}
private static String byteToString(byte[] bByte) {
StringBuffer sBuffer = new StringBuffer();
for (int i = 0; i < bByte.length; i++) {
sBuffer.append(byteToArrayString(bByte[i]));
}
return sBuffer.toString();
}
public static String GetMD5Code(String strObj) {
String resultString = null;
try {
resultString = new String(strObj);
MessageDigest md = MessageDigest.getInstance("MD5");
// md.digest()
resultString = byteToString(md.digest(strObj.getBytes()));
} catch (NoSuchAlgorithmException ex) {
ex.printStackTrace();
}
return resultString;
}
// 加密后解密
public static String JM(String inStr) {
char [] a = inStr.toCharArray();
for ( int i = 0 ; i < a.length; i++) {
a[i] = (char ) (a[i] ^ 't' );
}
String k = new String(a);
return k;
}
}
\ No newline at end of file
package com.joe.base.utils.log;
import android.util.Log;
/**
* autour: ELEGANT_BIN
* date: 2018/4/10 12:39
* update: 2018/4/10 12:39
* description: 解决json长度大于4k显示不全
*/
public class LogUtil {
//可以全局控制是否打印log日志
private static boolean isPrintLog = true;
private static int LOG_MAXLENGTH = 5000;
private final static String TAG = "LogUtil";
public static void v(String msg) {
v(TAG, msg);
}
public static void v(String tagName, String msg) {
if (isPrintLog) {
int strLength = msg.length();
int start = 0;
int end = LOG_MAXLENGTH;
for (int i = 0; i < 100; i++) {
if (strLength > end) {
Log.v(tagName + i, msg.substring(start, end));
start = end;
end = end + LOG_MAXLENGTH;
} else {
Log.v(tagName + i, msg.substring(start, strLength));
break;
}
}
}
}
public static void d(String msg) {
//因为String的length是字符数量不是字节数量所以为了防止中文字符过多,
// 把4*1024的MAX字节打印长度改为2001字符数
int max_str_length = 2001 - TAG.length();
//大于4000时
while (msg.length() > max_str_length) {
Log.d(TAG, msg.substring(0, max_str_length));
msg = msg.substring(max_str_length);
}
//剩余部分
d(TAG, msg);
}
public static void d(String tagName, String msg) {
if (isPrintLog) {
int strLength = msg.length();
int start = 0;
int end = LOG_MAXLENGTH;
for (int i = 0; i < 100; i++) {
if (strLength > end) {
Log.d(tagName + i, msg.substring(start, end));
start = end;
end = end + LOG_MAXLENGTH;
} else {
Log.d(tagName + i, msg.substring(start, strLength));
break;
}
}
}
}
public static void i(String msg) {
i(TAG, msg);
}
public static void i(String tagName, String msg) {
if (isPrintLog) {
int strLength = msg.length();
int start = 0;
int end = LOG_MAXLENGTH;
for (int i = 0; i < 100; i++) {
if (strLength > end) {
Log.i(tagName + i, msg.substring(start, end));
start = end;
end = end + LOG_MAXLENGTH;
} else {
Log.i(tagName + i, msg.substring(start, strLength));
break;
}
}
}
}
public static void w(String msg) {
w(TAG, msg);
}
public static void w(String tagName, String msg) {
if (isPrintLog) {
int strLength = msg.length();
int start = 0;
int end = LOG_MAXLENGTH;
for (int i = 0; i < 100; i++) {
if (strLength > end) {
Log.w(tagName + i, msg.substring(start, end));
start = end;
end = end + LOG_MAXLENGTH;
} else {
Log.w(tagName + i, msg.substring(start, strLength));
break;
}
}
}
}
public static void e(String msg) {
e(TAG, msg);
}
public static void e(String tagName, String msg) {
if (isPrintLog) {
int strLength = msg.length();
int start = 0;
int end = LOG_MAXLENGTH;
for (int i = 0; i < 100; i++) {
if (strLength > end) {
Log.e(tagName + i, msg.substring(start, end));
start = end;
end = end + LOG_MAXLENGTH;
} else {
Log.e(tagName + i, msg.substring(start, strLength));
break;
}
}
}
}
}
package com.joe.base.utils.mobile;
import android.content.Context;
import android.content.SharedPreferences;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import java.io.UnsupportedEncodingException;
import java.util.UUID;
/**
* 生成手机设备唯一UUID
*/
public class DeviceUuidFactory {
protected static final String PREFS_FILE = "device_id.xml";
protected static final String PREFS_DEVICE_ID = "device_id";
protected static UUID uuid;
public DeviceUuidFactory(Context context) {
if (uuid == null) {
synchronized (DeviceUuidFactory.class) {
if (uuid == null) {
final SharedPreferences prefs = context.getSharedPreferences(PREFS_FILE, 0);
final String id = prefs.getString(PREFS_DEVICE_ID, null);
if (id != null) {
// Use the ids previously computed and stored in the prefs file
uuid = UUID.fromString(id);
} else {
final String androidId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
// Use the Android ID unless it's broken, in which case fallback on deviceId,
// unless it's not available, then fallback on a random number which we store
// to a prefs file
try {
if (!"9774d56d682e549c".equals(androidId)) {
uuid = UUID.nameUUIDFromBytes(androidId.getBytes("utf8"));
} else {
final String deviceId = ((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId();
uuid = deviceId != null ? UUID.nameUUIDFromBytes(deviceId.getBytes("utf8")) : UUID.randomUUID();
}
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
// Write the value out to the prefs file
prefs.edit().putString(PREFS_DEVICE_ID, uuid.toString()).commit();
}
}
}
}
}
/**
* 返回当前Android设备的唯一UUID。与所有UUID一样,这个独特的ID“非常可靠”
* 在所有Android设备上都是独一无二的。比ANDROID_ID好多了。
* UUID是通过使用ANDROID_ID作为基本密钥(如果适用)生成的
* TelephonyManager.getDeviceID()如果ANDROID_ID已知不正确,最后回落
* 在一个随机的UUID上,如果getDeviceID()不返回,那么它会持续到SharedPreferences
* 可用价值。
* 在极少数情况下,此ID可能会改变。特别是,如果设备出厂设置了新的设备ID
* 可能会生成。另外,如果用户从Android2.2的某些错误实施中升级他们的手机
* 到更新的,非bug的版本的Android,设备ID可能会改变。或者,如果用户卸载您的应用程序
* 没有适当的Android ID和设备ID的设备,此ID可能会在重新安装时更改。
* 请注意,如果代码使用TelephonyManager.getDeviceId()返回,则生成的ID不会
* 出厂复位后更换。需要注意的事项
* 在直接使用ANDROID_ID时,适用于许多设备的Android2.2中的错误。**
*
* @http ://code.google.com/p/android/issues/detail?id=10603
* @返回一个UUID ,可用于为大多数用途唯一标识您的设备。
**/
public UUID getDeviceUuid() {
return uuid;
}
}
package com.joe.base.utils.mobile;
import android.content.Context;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.UUID;
/**
* 应用安装唯一ID
*这种方式的原理是在程序安装后第一次运行时生成一个ID,
*该方式和设备唯一标识不一样,不同的应用程序会产生不同的ID,
*同一个程序重新安装也会不同。所以这不是设备的唯一ID,
*但是可以保证每个用户的ID是不同的。
*可以说是用来标识每一份应用程序的唯一ID(即Installtion ID),
*可以用来跟踪应用的安装数量等
*/
public class Installation {
private static String sID = null;
private static final String INSTALLATION = "INSTALLATION";
public synchronized static String id(Context context) {
if (sID == null) {
File installation = new File(context.getFilesDir(), INSTALLATION);
try {
if (!installation.exists())
writeInstallationFile(installation);
sID = readInstallationFile(installation);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return sID;
}
private static String readInstallationFile(File installation) throws IOException {
RandomAccessFile f = new RandomAccessFile(installation, "r");
byte[] bytes = new byte[(int) f.length()];
f.readFully(bytes);
f.close();
return new String(bytes);
}
private static void writeInstallationFile(File installation) throws IOException {
FileOutputStream out = new FileOutputStream(installation);
String id = UUID.randomUUID().toString();
out.write(id.getBytes());
out.close();
}
}
package com.joe.base.utils.other;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.text.TextUtils;
import com.joe.base.utils.log.LogUtil;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* @ClassName: AppUtil
* @Description:TODO(App相关的辅助类)
*/
public class AppUtils {
/**
* 获取应用程序名称
*
* @param context
* @return
*/
public static String getAppName(Context context) {
try {
PackageManager packageManager = context.getPackageManager();
PackageInfo packageInfo = packageManager.getPackageInfo(
context.getPackageName(), 0);
int labelRes = packageInfo.applicationInfo.labelRes;
return context.getResources().getString(labelRes);
} catch (NameNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/**
* 获取版本号
*
* @param context
* @return
*/
public static int getVerCode(Context context) {
int verCode = -1;
try {
verCode = context.getPackageManager().getPackageInfo(
context.getPackageName(), 0).versionCode;
} catch (NameNotFoundException e) {
e.printStackTrace();
LogUtil.e(e.getMessage());
}
return verCode;
}
/**
* 获取版本名称
*
* @param context
* @return
*/
public static String getVerName(Context context) {
String verName = "";
try {
verName = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName;
} catch (NameNotFoundException e) {
LogUtil.e(e.getMessage());
}
return verName;
}
/**
* 获取手机mac地址
*
* @param context
* @return
*/
public static String getLocalMacAddress(Context context) {
WifiManager wifi = (WifiManager) context
.getSystemService(Context.WIFI_SERVICE);
WifiInfo info = wifi.getConnectionInfo();
return info.getMacAddress();
}
/**
* 启动到应用商店app详情界面
*
* @param appPkg 目标App的包名
* @param marketPkg 应用商店包名 ,如果为""则由系统弹出应用商店列表供用户选择,否则调转到目标市场的应用详情界面,某些应用商店可能会失败
*/
public static void launchAppDetail(Context mContext, String appPkg, String marketPkg) throws Exception {
if (TextUtils.isEmpty(appPkg)) return;
Uri uri = Uri.parse("market://details?id=" + appPkg);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
if (!TextUtils.isEmpty(marketPkg)) {
intent.setPackage(marketPkg);
}
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
}
/**
* 验证是否已安装应用并返回apk信息
*
* @param system//是否过滤掉系统app
* @param packageManager
* @param packageNames//需要验证的apk包名 mapsPackageName==null 返回手机所有已安装apk信息
* @return
*/
public static List<MyAppInfo> scanLocalInstallAppList(boolean system, PackageManager packageManager, ArrayList<String> packageNames) {
List<MyAppInfo> myAppInfos = new ArrayList<MyAppInfo>();
try {
List<PackageInfo> packageInfos = packageManager.getInstalledPackages(0);
for (int i = 0; i < packageInfos.size(); i++) {
PackageInfo packageInfo = packageInfos.get(i);
if (system) {
//过滤掉系统app
if ((ApplicationInfo.FLAG_SYSTEM & packageInfo.applicationInfo.flags) != 0) {
continue;
}
}
String packageName = packageInfo.packageName;
int index = i;
if (packageNames != null && packageNames.size() > 0) {
index = packageNames.indexOf(packageName);
if (index == -1) {
continue;
}
LogUtil.e("------------------------" + packageName);
}
MyAppInfo myAppInfo = new MyAppInfo();
myAppInfo.setSort(index);
myAppInfo.setPackageName(packageName);
String str_name = packageInfo.applicationInfo.loadLabel(packageManager).toString();
myAppInfo.setAppName(str_name);
if (packageInfo.applicationInfo.loadIcon(packageManager) == null) {
continue;
}
myAppInfo.setImage(packageInfo.applicationInfo.loadIcon(packageManager));
myAppInfos.add(myAppInfo);
}
} catch (Exception e) {
e.printStackTrace();
}
return myAppInfos;
}
public static class MyAppInfo implements Serializable {
private int sort;
private Drawable image;
private String appName;
private String packageName;
public MyAppInfo(int sort, Drawable image, String appName, String packageName) {
this.sort = sort;
this.image = image;
this.appName = appName;
this.packageName = packageName;
}
public MyAppInfo() {
}
public int getSort() {
return sort;
}
public void setSort(int sort) {
this.sort = sort;
}
public Drawable getImage() {
return image;
}
public void setImage(Drawable image) {
this.image = image;
}
public String getAppName() {
return appName;
}
public void setAppName(String appName) {
this.appName = appName;
}
public String getPackageName() {
return packageName;
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
}
}
package com.joe.base.utils.other;
import android.content.Context;
import android.content.SharedPreferences;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
/**
* @ClassName: SPUtils
* @Description: TODO(共享参数类)
*/
public class SPUtils {
public static final String FILE_NAME = "share_data";
public SPUtils() {
}
/**
* 保存数据的方法,需要拿到保存数据的具体类型,然后根据类型调用不同的保存方法
* 键 值
*
* @return void 返回类型
*/
public static void put(Context context, String key, Object object) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
if (object instanceof String) {
editor.putString(key, (String) object);
} else if (object instanceof Integer) {
editor.putInt(key, (Integer) object);
} else if (object instanceof Boolean) {
editor.putBoolean(key, (Boolean) object);
} else if (object instanceof Float) {
editor.putFloat(key, (Float) object);
} else if (object instanceof Long) {
editor.putLong(key, (Long) object);
} else {
editor.putString(key, object.toString());
}
SharedPreferencesCompat.apply(editor);
}
/**
* 得到保存数据的方法,根据默认值得到保存的数据的具体类型,然后调用相对于的方法获取值
*
* @param context
* @param key
* @param defaultObject
* @return
*/
public static Object get(Context context, String key, Object defaultObject) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
Context.MODE_PRIVATE);
if (defaultObject instanceof String) {
return sp.getString(key, (String) defaultObject);
} else if (defaultObject instanceof Integer) {
return sp.getInt(key, (Integer) defaultObject);
} else if (defaultObject instanceof Boolean) {
return sp.getBoolean(key, (Boolean) defaultObject);
} else if (defaultObject instanceof Float) {
return sp.getFloat(key, (Float) defaultObject);
} else if (defaultObject instanceof Long) {
return sp.getLong(key, (Long) defaultObject);
}
return null;
}
/**
* 移除某个key值已经对应的值
*
* @param context
* @param key
*/
public static void remove(Context context, String key) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.remove(key);
SharedPreferencesCompat.apply(editor);
}
/**
* 清除所有数据
*
* @param context
*/
public static void clear(Context context) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.clear();
SharedPreferencesCompat.apply(editor);
}
/**
* 查询某个key是否已经存在
*
* @param context
* @param key
* @return
*/
public static boolean contains(Context context, String key) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
Context.MODE_PRIVATE);
return sp.contains(key);
}
/**
* 返回所有的键值对
*
* @param context
* @return
*/
public static Map<String, ?> getAll(Context context) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
Context.MODE_PRIVATE);
return sp.getAll();
}
/**
* 创建一个解决SharedPreferencesCompat.apply方法的一个兼容类
*/
private static class SharedPreferencesCompat {
private static final Method sApplyMethod = findApplyMethod();
/**
* 反射查找apply的方法
*
* @return
*/
@SuppressWarnings({"unchecked", "rawtypes"})
private static Method findApplyMethod() {
try {
Class clz = SharedPreferences.Editor.class;
return clz.getMethod("apply");
} catch (NoSuchMethodException e) {
}
return null;
}
/**
* 如果找到则使用apply执行,否则使用commit
*
* @param editor
*/
public static void apply(SharedPreferences.Editor editor) {
try {
if (sApplyMethod != null) {
sApplyMethod.invoke(editor);
return;
}
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
editor.commit();
}
}
}
package com.joe.base.utils.other;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 作者:ELEGANT_BIN
* 版本:1.6.0
* 创建日期:2018/7/5
* 修订历史:2018/7/5
* 描述:
*/
public class TextUtil {
public static boolean isEmptyOrNullOrUndefined(String str) {
return str == null || str.length() == 0 ||
str.equals("null") || str.equals("undefined");
}
public static String isEmptyReturnString(String str) {
if (str == null || str.length() == 0 ||
str.equals("null") || str.equals("undefined")) {
return "";
} else {
return str;
}
}
public static int isEmptyReturnInt(Integer str) {
if (str == null) {
return 0;
} else {
return str;
}
}
/**
* 半角转换为全角
*
* @param input
* @return
*/
public static String ToDBC(String input) {
char[] c = input.toCharArray();
for (int i = 0; i < c.length; i++) {
if (c[i] == 12288) {
c[i] = (char) 32;
continue;
}
if (c[i] > 65280 && c[i] < 65375)
c[i] = (char) (c[i] - 65248);
}
return new String(c);
}
/**
* 去除特殊字符或将所有中文标号替换为英文标号
*
* @param str
* @return
*/
public static String stringFilter(String str) {
str = str.replaceAll("【", "[").replaceAll("】", "]")
.replaceAll("!", "!").replaceAll(":", ":");// 替换中文标号
String regEx = "[『』]"; // 清除掉特殊字符
Pattern p = Pattern.compile(regEx);
Matcher m = p.matcher(str);
return m.replaceAll("").trim();
}
}
package com.joe.base.utils.request;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import com.joe.base.utils.constans.UserConstans;
import com.joe.base.utils.encryption.MD5;
import com.joe.base.utils.mobile.DeviceUuidFactory;
import com.joe.base.utils.mobile.Installation;
import com.joe.base.utils.other.SPUtils;
import com.qmuiteam.qmui.util.QMUIDeviceHelper;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.UUID;
/**
* autour: ELEGANT_BIN
* date: 2018/4/9 18:56
* update: 2018/4/9 18:56
* description:
*/
public class RequestUtils {
/**
* @param dataMap
* @param times
* @return
* @Title: getSign
* @Description: TODO(获取签名)
*/
public static String getSign(Context context, Map<String, Object> dataMap, long times) {
String sign = "";
String token = getLoginToken(context);
if (!TextUtils.isEmpty(token)) {
MD5 md5 = new MD5();
Set<String> set = new TreeSet<>();
Set<String> keys = dataMap.keySet();
set.addAll(keys);
StringBuffer buffer = new StringBuffer();
for (String key : set) {
buffer.append(key);
buffer.append("=");
buffer.append(dataMap.get(key) + "");
}
buffer.append("token=" + token + "");
buffer.append("times=" + times + "");
sign = md5.GetMD5Code(buffer.toString());
Log.e("joe", "bufferStr=====> " + buffer.toString());
}
return sign;
}
//获取登陆token
public static String getLoginToken(Context context) {
return (String) SPUtils.get(context, UserConstans.token, "");
}
public static String getMobileToken(Context context) {
if (QMUIDeviceHelper.isTablet(context)) {
//平板端登錄做下設備区分(pad_用户_机器名_592A9789-43D2-43D1-B184-82235206C3FF)
boolean flatbedloginStatus = (int) SPUtils.get(context, UserConstans.FLATBED_LOGIN_STATUS, -1) != -1;
if (flatbedloginStatus) {
int userId = (int) SPUtils.get(context, UserConstans.memberId, 0);
String deviceModel = android.os.Build.MODEL;
return "pad_" + userId + "_" + deviceModel + "_" + getuUid(context);
}
}
return getuUid(context);
}
private static String getuUid(Context context) {
DeviceUuidFactory deviceUuidFactory = new DeviceUuidFactory(context);
UUID deviceUuid = deviceUuidFactory.getDeviceUuid();
if (deviceUuid != null) {
return deviceUuid.toString();
} else {
return Installation.id(context);
}
}
}
package com.joe.base.utils.toast;
import android.content.Context;
import android.os.Looper;
import android.widget.Toast;
public class ToastUtils {
private static Toast mToast;
/**
* 显示Toast
*/
private static void showToast(final Context context, final CharSequence text, final int duration) {
new android.os.Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
if (context != null) {
if (mToast == null) {
mToast = Toast.makeText(context, text, duration);
} else {
mToast.setText(text);
mToast.setDuration(duration);
}
mToast.show();
}
}
});
}
public static void show(Context context, int resId) {
show(context, context.getResources().getText(resId), Toast.LENGTH_SHORT);
}
public static void show(Context context, int resId, int duration) {
show(context, context.getResources().getText(resId), duration);
}
public static void show(Context context, CharSequence text) {
show(context, text, Toast.LENGTH_SHORT);
}
public static void show(Context context, CharSequence text, int duration) {
showToast(context, text, duration);
}
public static void show(Context context, int resId, Object... args) {
show(context, String.format(context.getResources().getString(resId), args), Toast.LENGTH_SHORT);
}
public static void show(Context context, String format, Object... args) {
show(context, String.format(format, args), Toast.LENGTH_SHORT);
}
public static void show(Context context, int resId, int duration, Object... args) {
show(context, String.format(context.getResources().getString(resId), args), duration);
}
public static void show(Context context, String format, int duration, Object... args) {
show(context, String.format(format, args), duration);
}
}
package com.joe.base.widget.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.text.InputFilter;
import android.text.InputType;
import android.text.Spanned;
import android.text.method.PasswordTransformationMethod;
import android.util.AttributeSet;
import android.view.View;
import android.widget.EditText;
import com.joe.base.R;
import com.joe.base.utils.other.TextUtil;
import com.joe.base.utils.toast.ToastUtils;
import java.util.ArrayList;
import java.util.List;
import androidx.appcompat.widget.AppCompatEditText;
/**
* Created by Wyh on 2019/12/19.
*/
public class MyEditText extends AppCompatEditText {
private Context context;
//輸入最大長度
private int maxLeght;
private String maxLengthTip;
//是否顯示輸入最大字數限制
private boolean isShowMaxLenght;
private int maxLenghtTextColor;
private int maxLenghtTextSize;
//是否允許輸入表情
private boolean isInputIcon;
//輸入表情時提示的內容,不設置內容不提示
private String inputIconTipText;
//清除按鈕的大小
private int clearIconSiZe;
//清除按鈕圖標
private Drawable clearIcon;
//清除按鈕右間距
private int clearRightMargin;
//清除按鈕點擊事件
private View.OnClickListener clearOnClickListener;
//查看密碼按鈕圖標
private Drawable lookIcon;
//"查看密碼"圖標的大小
private int lookIconSiZe;
//查看密碼按鈕右間距
private int lookRightMargin;
//查看密碼按鈕點擊事件
private OnClickListener lookOnClickListener;
//設置輸入密碼替換符
private String pwdChar;
//是否換行
private boolean singLeLine;
private int inputType;
// private EditText editText;
//顯示最大字數的textview
// private TextView maxLenghtTextView;
//
// private ImageView ivClear;
// private ImageView ivLook;
private List<InputFilter> mInputFilter = new ArrayList<>();
public MyEditText(Context context) {
this(context, null);
}
public MyEditText(Context context, AttributeSet attrs) {
this(context, attrs, -1);//R.attr.editTextStyle
}
public MyEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.context = context;
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyEditText);
maxLeght = typedArray.getInt(R.styleable.MyEditText_ed_MaxLength, 0);
maxLengthTip = typedArray.getString(R.styleable.MyEditText_ed_MaxLengthTip);
isShowMaxLenght = typedArray.getBoolean(R.styleable.MyEditText_ed_showMaxLenght, false);
maxLenghtTextColor = typedArray.getColor(R.styleable.MyEditText_ed_maxLengthTextColor, -1);
maxLenghtTextSize = typedArray.getDimensionPixelSize(R.styleable.MyEditText_ed_maxLengthTextSize, 12);
isInputIcon = typedArray.getBoolean(R.styleable.MyEditText_ed_isInputIcon, false);
inputIconTipText = typedArray.getString(R.styleable.MyEditText_ed_putIconTip);
clearIconSiZe = typedArray.getDimensionPixelSize(R.styleable.MyEditText_ed_clearIconSize, 12);
clearIcon = typedArray.getDrawable(R.styleable.MyEditText_ed_clearRes);
clearRightMargin = typedArray.getDimensionPixelSize(R.styleable.MyEditText_ed_clearMarginRight, 0);
lookIcon = typedArray.getDrawable(R.styleable.MyEditText_ed_lookIcon);
lookIconSiZe = typedArray.getDimensionPixelSize(R.styleable.MyEditText_ed_lookIconSize, 12);
lookRightMargin = typedArray.getDimensionPixelSize(R.styleable.MyEditText_ed_lookMarginRight, 0);
pwdChar = typedArray.getString(R.styleable.MyEditText_ed_pwdChar);
singLeLine = typedArray.getBoolean(R.styleable.MyEditText_ed_singLeLine, false);
inputType = typedArray.getInteger(R.styleable.MyEditText_inputType, 0);
typedArray.recycle();
initLeght();
if (!isInputIcon) {
mInputFilter.add(new EmojiInputFilter());
}
initEditText();
}
private void initEditText() {
InputFilter[] inputFilters = new InputFilter[mInputFilter.size()];
if (!TextUtil.isEmptyOrNullOrUndefined(pwdChar)) {
this.setInputType(InputType.TYPE_NUMBER_VARIATION_PASSWORD);
this.setTransformationMethod(new AsteriskPasswordTransformationMethod());
}
for (int i = 0; i < mInputFilter.size(); i++) {
inputFilters[i] = mInputFilter.get(i);
}
setFilters(inputFilters);
setSingleLine(singLeLine);
// if (clearIcon != null) {
// ivClear = new ImageView(context);
// ivClear.setImageDrawable(clearIcon);
// ivClear.setLayoutParams(getImgLayoutParams(clearIconSiZe, clearIconSiZe, clearRightMargin));
// this.addView(ivClear);
// ivClear.setOnClickListener(new OnClickListener() {
// @Override
// public void onClick(View view) {
// editText.setText("");
// if (clearOnClickListener != null) {
// clearOnClickListener.onClick(view);
// }
// }
// });
// }
//
//
// if (lookIcon != null) {
// ivLook = new ImageView(context);
// LayoutParams ivLookParams = getImgLayoutParams(lookIconSiZe, lookIconSiZe, lookRightMargin);
// if (ivClear != null) {
// ivLookParams.rightMargin = clearIconSiZe + lookRightMargin;
// }
// ivLook.setLayoutParams(ivLookParams);
// ivLook.setImageDrawable(lookIcon);
// this.addView(ivLook);
// ivLook.setOnClickListener(new OnClickListener() {
// @Override
// public void onClick(View view) {
// if (lookOnClickListener != null) {
// lookOnClickListener.onClick(view);
// }
// }
// });
// }
}
private void initLeght() {
if (maxLeght > 0) {
mInputFilter.add(new MaxTextLengthFilter(maxLeght));
}
}
/**
* 检测是否有emoji表情
*
* @param source
* @return
*/
private boolean containsEmoji(String source) {
int len = source.length();
for (int i = 0; i < len; i++) {
char codePoint = source.charAt(i);
if (!isEmojiCharacter(codePoint)) { //如果不能匹配,则该字符是Emoji表情
return true;
}
}
return false;
}
/**
* 判断是否是Emoji
*
* @param codePoint 比较的单个字符
* @return
*/
private boolean isEmojiCharacter(char codePoint) {
return codePoint == 0x0 || codePoint == 0x9 || codePoint == 0xA || codePoint == 0xD || codePoint >= 0x20 && codePoint <= 0xD7FF || codePoint >= 0xE000 && codePoint <= 0xFFFD;
}
public void setClearOnClickListener(OnClickListener clearOnClickListener) {
this.clearOnClickListener = clearOnClickListener;
}
public void setLookOnClickListener(OnClickListener lookOnClickListener) {
this.lookOnClickListener = lookOnClickListener;
}
//最大字數限制器
class MaxTextLengthFilter implements InputFilter {
private int mMaxLength;
public MaxTextLengthFilter(int max) {
mMaxLength = max;
}
public CharSequence filter(CharSequence source, int start, int end,
Spanned dest, int dstart, int dend) {
int keep = mMaxLength - (dest.length() - (dend - dstart));
if (keep < (end - start)) {
if (!TextUtil.isEmptyOrNullOrUndefined(maxLengthTip)) {
ToastUtils.show(context, maxLengthTip);
}
}
if (keep <= 0) {
return "";
} else if (keep >= end - start) {
return null;
} else {
return source.subSequence(start, start + keep);
}
}
}
class EmojiInputFilter implements InputFilter {
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
if (containsEmoji(source.toString())) {
//如果輸入了表情
if (!TextUtil.isEmptyOrNullOrUndefined(inputIconTipText)) {
//提示文字不為空,就彈出提示,並移除掉表情
ToastUtils.show(context, inputIconTipText);
return "";
}
return "";
}
return source;
}
}
//替換密碼輸入框顯示的密碼樣式
public class AsteriskPasswordTransformationMethod extends PasswordTransformationMethod {
@Override
public CharSequence getTransformation(CharSequence source, View view) {
return new PasswordCharSequence(source);
}
private class PasswordCharSequence implements CharSequence {
private CharSequence mSource;
public PasswordCharSequence(CharSequence source) {
mSource = source;
}
public char charAt(int index) {
return pwdChar.toCharArray()[0];
}
public int length() {
return mSource.length();
}
public CharSequence subSequence(int start, int end) {
return mSource.subSequence(start, end);
}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromXDelta="-100.0%p"
android:toXDelta="0.0" />
</set>
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromXDelta="0.0"
android:toXDelta="-100.0%p" />
</set>
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromXDelta="100.0%p"
android:toXDelta="0.0" />
</set>
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromXDelta="0.0"
android:toXDelta="100.0%p" />
</set>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="title_text_size">26dp</dimen>
<dimen name="edit_text_size">18dp</dimen>
</resources>
\ No newline at end of file
<resources>
<string name="app_name">public-utils</string>
<string name="app_name">public-base</string>
</resources>
ext.alwaysLib = true //虽然apply了cc-settings-2.gradle,但一直作为library编译,否则别的组件依赖此module时会报错
apply from: rootProject.file("cc-settings.gradle")
android {
......
ext.alwaysLib = true //虽然apply了cc-settings-2.gradle,但一直作为library编译,否则别的组件依赖此module时会报错
apply from: rootProject.file("cc-settings.gradle")
android {
......@@ -33,5 +34,13 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
// implementation project(':arms')
implementation rootProject.ext.dependencies["arms"]
implementation project(':public-base')
implementation rootProject.ext.dependencies["progressmanager"]
implementation rootProject.ext.dependencies["retrofit-url-manager"]
debugImplementation rootProject.ext.dependencies["canary-debug"]
releaseImplementation rootProject.ext.dependencies["canary-release"]
testImplementation rootProject.ext.dependencies["canary-release"]
}
package network.config.applyOptions;
import com.jess.arms.http.GlobalHttpHandler;
import com.joe.base.application.BaseApplication;
import com.joe.base.utils.constans.AppConstans;
import com.joe.base.utils.constans.UserConstans;
import com.joe.base.utils.encryption.Aes;
import com.joe.base.utils.log.LogUtil;
import com.joe.base.utils.other.AppUtils;
import com.joe.base.utils.request.RequestUtils;
import okhttp3.Headers;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
public class MyGlobalHttpHandler implements GlobalHttpHandler {
private final String TAG = this.getClass().getSimpleName();
@Override
public Response onHttpResultResponse(String httpResult, Interceptor.Chain chain, Response response) {
// 统一处理http响应。eg:状态码不是200时,根据状态码做相应的处理。
LogUtil.d("onHttpResultResponse: " + httpResult);
e(httpResult);
return response;
}
@Override
public Request onHttpRequestBefore(Interceptor.Chain chain, Request request) {
// 统一处理http请求。eg:给request统一添加token或者header以及参数加密等操作
String requestBody = request.toString();
e(requestBody);
LogUtil.d("onHttpRequestBefore: " + requestBody);
String token = Aes.aesDecrypt(UserConstans.memberId + "_" + System.currentTimeMillis() + "_" + UserConstans.token);
if (request.method().equals("GET") || request.method().equals("POST")) {
Headers headers = new Headers.Builder()
.set("secretKey", AppConstans.SECRETKEY_VALUES)//set表示name1是唯一的,会覆盖掉已经存在的,add不会覆盖已经存在的头,可以存在多个
.set("apptype", AppConstans.APP_TYPE)
.set("appinfo", AppUtils.getVerName(BaseApplication.getAppContext()))
.set("mobielModel", android.os.Build.MODEL)
.set("mobileVersion", android.os.Build.VERSION.RELEASE)
.set("mobileId", RequestUtils.getMobileToken(BaseApplication.getAppContext()))
.set("token", token)
// .set("encrypt", 1 + "")
// .set("uid", UserConstans.memberId + "")
// .set("appVersion", SApplication.VerCode + "")
.set("Domain-Name", "common")
.build();
return chain.request().newBuilder()
.headers(headers)
.build();
}
return chain.request().newBuilder()
.build();
}
private void e(String msg) {
if (msg == null) {
return;
}
//因为String的length是字符数量不是字节数量所以为了防止中文字符过多,
// 把4*1024的MAX字节打印长度改为2001字符数
int max_str_length = 2001 - TAG.length();
//大于4000时
while (msg.length() > max_str_length) {
LogUtil.e(TAG, msg);
msg = msg.substring(max_str_length);
}
//剩余部分
LogUtil.e(TAG, msg);
}
}
package network.config.applyOptions;
import android.content.Context;
import com.google.gson.GsonBuilder;
import com.jess.arms.di.module.AppModule;
/**
* @创建者 CSDN_LQR
* @描述 Gson配置
*/
public class MyGsonConfiguration implements AppModule.GsonConfiguration {
@Override
public void configGson(Context context, GsonBuilder builder) {
builder
.serializeNulls()//支持序列化null的参数
.enableComplexMapKeySerialization();//支持将序列化key为object的map,默认只能序列化key为string的map
}
}
package network.config.applyOptions;
import android.content.Context;
import com.jess.arms.di.module.ClientModule;
import java.util.concurrent.TimeUnit;
import me.jessyan.progressmanager.ProgressManager;
import me.jessyan.retrofiturlmanager.RetrofitUrlManager;
import okhttp3.OkHttpClient;
/**
* autour: 宁斌
* date: 2018/4/3 14:47
* update: 2018/4/3 14:47
* description:
*/
public class MyOkhttpConfiguration implements ClientModule.OkhttpConfiguration{
@Override
public void configOkhttp(Context context, OkHttpClient.Builder builder) {
// builder.sslSocketFactory(); //支持 Https,详情请百度
builder.writeTimeout(15, TimeUnit.SECONDS);
//使用一行代码监听 Retrofit/Okhttp 上传下载进度监听,以及 Glide 加载进度监听 详细使用方法查看 https://github.com/JessYanCoding/ProgressManager
ProgressManager.getInstance().with(builder);
//让 Retrofit 同时支持多个 BaseUrl 以及动态改变 BaseUrl. 详细使用请方法查看 https://github.com/JessYanCoding/RetrofitUrlManager
RetrofitUrlManager.getInstance().with(builder);
}
}
package network.config.applyOptions;
import android.content.Context;
import android.net.ParseException;
import com.gingersoft.gsa.cloud.network.R;
import com.google.gson.JsonIOException;
import com.google.gson.JsonParseException;
import com.jess.arms.utils.ArmsUtils;
import com.joe.base.utils.log.LogUtil;
import com.joe.base.utils.toast.ToastUtils;
import org.json.JSONException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import me.jessyan.rxerrorhandler.handler.listener.ResponseErrorListener;
import retrofit2.HttpException;
import timber.log.Timber;
public class MyResponseErrorListener implements ResponseErrorListener {
@Override
public void handleResponseError(Context context, Throwable t) {
/* 用来提供处理所有错误的监听
rxjava必要要使用ErrorHandleSubscriber(默认实现Subscriber的onError方法),此监听才生效 */
Timber.tag("Catch-Error").w(t.getMessage());
//这里不光是只能打印错误,还可以根据不同的错误作出不同的逻辑处理
String msg = ArmsUtils.getString(context, R.string.response_error_unknown_error);
if (t instanceof UnknownHostException) {
msg = ArmsUtils.getString(context, R.string.response_error_network_unavailable);
} else if (t instanceof SocketTimeoutException) {
msg = ArmsUtils.getString(context, R.string.response_error_request_timeout);
} else if (t instanceof HttpException) {
HttpException httpException = (HttpException) t;
msg = convertStatusCode(context, httpException);
} else if (t instanceof JsonParseException || t instanceof ParseException || t instanceof JSONException || t instanceof JsonIOException) {
msg = ArmsUtils.getString(context, R.string.response_error_data_parsing_error);
}
// ArmsUtils.snackbarText(msg);
LogUtil.d("handleResponseError: " + t.getMessage());
ToastUtils.show(context, msg);
}
private String convertStatusCode(Context context, HttpException httpException) {
String msg;
if (httpException.code() == 500) {
msg = ArmsUtils.getString(context, R.string.response_error_server_error);
} else if (httpException.code() == 404) {
msg = ArmsUtils.getString(context, R.string.response_error_address_does_not_exist);
} else if (httpException.code() == 403) {
msg = ArmsUtils.getString(context, R.string.response_error_request_rejected_by_server);
} else if (httpException.code() == 307) {
msg = ArmsUtils.getString(context, R.string.response_error_request_was_redirected_to_another_page);
} else {
msg = httpException.message();
}
return msg;
}
}
package network.config.applyOptions;
import android.content.Context;
import com.jess.arms.di.module.ClientModule;
import network.config.applyOptions.intercept.LoggingInterceptor;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
public class MyRetrofitConfiguration implements ClientModule.RetrofitConfiguration {
@Override
public void configRetrofit(Context context, Retrofit.Builder builder) {
// 配置多BaseUrl支持
OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
// if (BuildConfig.DEBUG) {
clientBuilder.addInterceptor(new LoggingInterceptor());//使用自定义的Log拦截器
// }
// clientBuilder.addInterceptor(new UserAgentInterceptor());//使用自定义User-Agent
// builder.client(RetrofitUrlManager.getInstance().with(clientBuilder).build());
}
}
package network.config.applyOptions;
import android.content.Context;
import com.jess.arms.di.module.ClientModule;
import io.rx_cache2.internal.RxCache;
public class MyRxCacheConfiguration implements ClientModule.RxCacheConfiguration {
@Override
public RxCache configRxCache(Context context, RxCache.Builder builder) {
// 当数据无法加载时,使用过期数据
builder.useExpiredDataIfLoaderNotAvailable(true);
// 想自定义 RxCache 的缓存文件夹或者解析方式, 如改成 fastjson, 请 return rxCacheBuilder.persistence(cacheDirectory, new FastJsonSpeaker());
// 否则请 return null;
return null;
}
}
package network.config.applyOptions.intercept;
import android.util.Log;
import com.joe.base.utils.log.LogUtil;
import java.io.IOException;
import okhttp3.FormBody;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
public class LoggingInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
//这个chain里面包含了request和response,所以你要什么都可以从这里拿
Request request = chain.request();
long t1 = System.nanoTime();//请求发起的时间
String method = request.method();
Log.e("aaa", "intercept");
if ("POST".equals(method)) {
StringBuilder sb = new StringBuilder();
if (request.body() instanceof FormBody) {
FormBody body = (FormBody) request.body();
for (int i = 0; i < body.size(); i++) {
sb.append(body.encodedName(i) + "=" + body.encodedValue(i) + ",");
}
sb.delete(sb.length() - 1, sb.length());
LogUtil.d("CSDN_LQR", String.format("發送請求 %s on %s %n%s %nRequestParams:{%s}",
request.url(), chain.connection(), request.headers(), sb.toString()));
}
} else {
LogUtil.d("CSDN_LQR", String.format("發送請求 %s on %s%n%s",
request.url(), chain.connection(), request.headers()));
}
Response response = chain.proceed(request);
long t2 = System.nanoTime();//收到响应的时间
//这里不能直接使用response.body().string()的方式输出日志
//因为response.body().string()之后,response中的流会被关闭,程序会报错,我们需要创建出一
//个新的response给应用层处理
ResponseBody responseBody = response.peekBody(1024 * 1024);
LogUtil.d("CSDN_LQR",
String.format("接收響應: [%s] %n返回json:【%s】 %.1fms %n%s",
response.request().url(),
responseBody.string(),
(t2 - t1) / 1e6d,
response.headers()
));
return response;
}
}
\ No newline at end of file
package network.config.applyOptions.intercept;
import java.io.IOException;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
/**
* 添加UA拦截器,B站请求API需要加上UA才能正常使用
*/
public class UserAgentInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
Request requestWithUserAgent = originalRequest.newBuilder()
// .removeHeader("User-Agent")
// .addHeader("User-Agent", Api.COMMON_UA_STR)
.build();
return chain.proceed(requestWithUserAgent);
}
}
\ No newline at end of file
package network.config.lifecyclesOptioins;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Application;
import android.os.Bundle;
@SuppressLint("NewApi")
public class MyActivityLifecycle implements Application.ActivityLifecycleCallbacks {
@Override
public void onActivityCreated(Activity activity, Bundle bundle) {
// EventBus.getDefault().register(activity);
if (!activity.getIntent().getBooleanExtra("isInitToolbar", false)) {
//由于加强框架的兼容性,故将 setContentView 放到 onActivityCreated 之后,onActivityStarted 之前执行
//而 findViewById 必须在 Activity setContentView() 后才有效,所以将以下代码从之前的 onActivityCreated 中移动到 onActivityStarted 中执行
activity.getIntent().putExtra("isInitToolbar", true);
//这里全局给Activity设置toolbar和title,你想象力有多丰富,这里就有多强大,以前放到BaseActivity的操作都可以放到这里
// new ToolbarUtil(activity).setToolbar();
}
}
@Override
public void onActivityStarted(Activity activity) {
}
@Override
public void onActivityResumed(Activity activity) {
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
}
@Override
public void onActivityDestroyed(Activity activity) {
// EventBus.getDefault().unregister(activity);
//横竖屏切换或配置改变时, Activity 会被重新创建实例, 但 Bundle 中的基础数据会被保存下来,移除该数据是为了保证重新创建的实例可以正常工作
activity.getIntent().removeExtra("isInitToolbar");
}
}
package network.config.lifecyclesOptioins;
import android.app.Application;
import android.content.Context;
import com.jess.arms.base.delegate.AppLifecycles;
import com.squareup.leakcanary.RefWatcher;
//import com.alibaba.android.arouter.launcher.ARouter;
public class MyAppLifecycles implements AppLifecycles {
// LeakCanary观察器
private RefWatcher mRefWatcher;
@Override
public void onCreate(Application application) {
// initTimber();
// initLeakCanary(application);
// initFragmentation();
// initARouter(application);
}
@Override
public void attachBaseContext(Context base) {
}
@Override
public void onTerminate(Application application) {
mRefWatcher = null;
}
private void initARouter(Application application) {
// if (BuildConfig.LOG_DEBUG) {
// ARouter.openDebug();
// ARouter.openLog();
// ARouter.printStackTrace(); // 打印日志的时候打印线程堆栈
// }
// ARouter.init(application);
}
// private void initFragmentation() {
// Fragmentation.builder()
// // 设置 栈视图 模式为 悬浮球模式 SHAKE: 摇一摇唤出 默认NONE:隐藏, 仅在Debug环境生效
// .stackViewMode(Fragmentation.BUBBLE)
// // 开发环境:true时,遇到异常:"Can not perform this action after onSaveInstanceState!"时,抛出,并Crash;
// // 生产环境:false时,不抛出,不会Crash,会捕获,可以在handleException()里监听到
// .debug(BuildConfig.DEBUG)
// // 生产环境时,捕获上述异常(避免crash),会捕获
// // 建议在回调处上传下面异常到崩溃监控服务器
// .handleException(new ExceptionHandler() {
// @Override
// public void onException(Exception e) {
// // 以Bugtags为例子: 把捕获到的 Exception 传到 Bugtags 后台。
// // Bugtags.sendException(e);
// }
// })
// .install();
// }
private void initLeakCanary(Application application) {
//leakCanary内存泄露检查
// mRefWatcher = BuildConfig.USE_CANARY ? LeakCanary.install(application) : RefWatcher.DISABLED;
}
private void initTimber() {
// if (BuildConfig.LOG_DEBUG) {
// Timber日志打印
// Timber.plant(new Timber.DebugTree());
// }
}
public RefWatcher getRefWatcher() {
return mRefWatcher;
}
public void setRefWatcher(RefWatcher refWatcher) {
mRefWatcher = refWatcher;
}
}
<resources>
<string name="app_name">component-order-list</string>
<!-- HttpError -->
<string name="response_error_unknown_error">未知錯誤</string>
<string name="response_error_network_unavailable">網絡不可用</string>
<string name="response_error_request_timeout">請求網絡超時</string>
<string name="response_error_data_parsing_error">數據解析錯誤</string>
<string name="response_error_server_error">服務器發生錯誤</string>
<string name="response_error_address_does_not_exist">請求地址不存在</string>
<string name="response_error_request_rejected_by_server">請求被服務器拒絕</string>
<string name="response_error_request_was_redirected_to_another_page">請求被重定向到其他頁面</string>
</resources>
include ':app', ':public-utils',
include ':app', ':public-base',
':cc-register', ':cc',
':android_internal',
':arms',
......
......@@ -36,7 +36,15 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation project(':arms')
implementation project(path: ':public-utils')
// implementation project(':arms')
implementation rootProject.ext.dependencies["arms"]
implementation project(path: ':public-base')
implementation rootProject.ext.dependencies["constraintlayout"]
implementation rootProject.ext.dependencies["retrofit-url-manager"]
// annotationProcessor rootProject.ext.dependencies["butterknife-compiler"] //Butterknife 插件, 很多人因为没加这个而报错, 切记!!!
annotationProcessor rootProject.ext.dependencies["dagger2-compiler"]//依赖插件
implementation rootProject.ext.dependencies["autosize"]
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.gsa.cloud.login">
package="com.gingersoft.gsa.cloud.user.login">
<application>
<!-- <provider-->
<!-- android:name=".remote.RemoteProvider"-->
<!-- android:authorities="${applicationId}.com.billy.cc.core.remote"-->
<!-- android:exported="true" />-->
<activity
android:name="com.gsa.cloud.user.login.LoginActivity"
android:excludeFromRecents="true"
android:exported="true"
android:taskAffinity="com.billy.cc.connection"
android:theme="@android:style/Theme.Translucent.NoTitleBar">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<action android:name="action.com.billy.cc.connection" />
</intent-filter>
</activity>
<activity android:name=".mvp.ui.activity.LoginActivity" />
<meta-data
android:name="network.config.GlobalConfiguration"
android:value="ConfigModule" />
<meta-data
android:name="design_width_in_dp"
android:value="400" />
<meta-data
android:name="design_height_in_dp"
android:value="705" />
</application>
</manifest>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.gingersoft.gsa.cloud.user.login">
......@@ -8,8 +7,16 @@
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/user_login_AppTheme">
<activity android:name=".mvp.ui.activity.LoginActivity"></activity>
android:theme="@style/AppTheme.Base">
<activity android:name=".mvp.ui.activity.LoginActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
\ No newline at end of file
</manifest>
......@@ -2,21 +2,20 @@ package com.gingersoft.gsa.cloud.user.login.di.component;
import dagger.BindsInstance;
import dagger.Component;
import com.jess.arms.di.component.AppComponent;
import com.gingersoft.gsa.cloud.user.login.di.module.LoginAModule;
import com.gingersoft.gsa.cloud.user.login.mvp.contract.LoginAContract;
import com.gingersoft.gsa.cloud.user.login.di.module.LoginModule;
import com.gingersoft.gsa.cloud.user.login.mvp.contract.LoginContract;
import com.jess.arms.di.scope.ActivityScope;
import com.gingersoft.gsa.cloud.user.login.mvp.ui.activity.LoginActivity;
import com.gingersoft.gsa.cloud.user.login.mvp.ui.activity.LoginActivity;
/**
* ================================================
* Description:
* <p>
* Created by MVPArmsTemplate on 12/20/2019 18:41
* Created by MVPArmsTemplate on 12/21/2019 16:23
* <a href="mailto:jess.yan.effort@gmail.com">Contact me</a>
* <a href="https://github.com/JessYanCoding">Follow me</a>
* <a href="https://github.com/JessYanCoding/MVPArms">Star me</a>
......@@ -25,17 +24,14 @@ import com.gingersoft.gsa.cloud.user.login.mvp.ui.activity.LoginActivity;
* ================================================
*/
@ActivityScope
@Component(modules = LoginAModule.class, dependencies = AppComponent.class)
public interface LoginAComponent {
@Component(modules = LoginModule.class, dependencies = AppComponent.class)
public interface LoginComponent {
void inject(LoginActivity activity);
@Component.Builder
interface Builder {
@BindsInstance
LoginAComponent.Builder view(LoginAContract.View view);
LoginAComponent.Builder appComponent(AppComponent appComponent);
LoginAComponent build();
LoginComponent.Builder view(LoginContract.View view);
LoginComponent.Builder appComponent(AppComponent appComponent);
LoginComponent build();
}
}
\ No newline at end of file
package com.gingersoft.gsa.cloud.user.login.di.module;
import com.jess.arms.di.scope.ActivityScope;
import com.gingersoft.gsa.cloud.user.login.mvp.contract.LoginContract;
import com.gingersoft.gsa.cloud.user.login.mvp.model.LoginModel;
import dagger.Binds;
import dagger.Module;
import dagger.Provides;
import com.gingersoft.gsa.cloud.user.login.mvp.contract.LoginAContract;
import com.gingersoft.gsa.cloud.user.login.mvp.model.LoginAModel;
/**
* ================================================
* Description:
* <p>
* Created by MVPArmsTemplate on 12/20/2019 18:41
* Created by MVPArmsTemplate on 12/21/2019 16:23
* <a href="mailto:jess.yan.effort@gmail.com">Contact me</a>
* <a href="https://github.com/JessYanCoding">Follow me</a>
* <a href="https://github.com/JessYanCoding/MVPArms">Star me</a>
......@@ -23,8 +20,8 @@ import com.gingersoft.gsa.cloud.user.login.mvp.model.LoginAModel;
* ================================================
*/
@Module
public abstract class LoginAModule {
public abstract class LoginModule {
@Binds
abstract LoginAContract.Model bindLoginAModel(LoginAModel model);
abstract LoginContract.Model bindLoginModel(LoginModel model);
}
\ No newline at end of file
......@@ -13,7 +13,7 @@ import io.reactivex.Observable;
* ================================================
* Description:
* <p>
* Created by MVPArmsTemplate on 12/20/2019 18:41
* Created by MVPArmsTemplate on 12/21/2019 16:23
* <a href="mailto:jess.yan.effort@gmail.com">Contact me</a>
* <a href="https://github.com/JessYanCoding">Follow me</a>
* <a href="https://github.com/JessYanCoding/MVPArms">Star me</a>
......@@ -21,15 +21,16 @@ import io.reactivex.Observable;
* <a href="https://github.com/JessYanCoding/MVPArmsTemplate">模版请保持更新</a>
* ================================================
*/
public interface LoginAContract {
public interface LoginContract {
//对于经常使用的关于UI的方法可以定义到IView中,如显示隐藏进度条,和显示文字消息
interface View extends IView {
void loginSuccess(TestLoginBean info);
void loginOut();
}
//Model层定义接口,外部只需关心Model返回的数据,无需关心内部细节,即是否使用缓存
interface Model extends IModel{
interface Model extends IModel {
Observable<TestLoginBean> login(HashMap<String, Object> params);
Observable<TestLoginBean> loginOut(HashMap<String, Object> params);
......
......@@ -9,22 +9,23 @@ import com.jess.arms.integration.IRepositoryManager;
import com.jess.arms.mvp.BaseModel;
import com.jess.arms.di.scope.ActivityScope;
import javax.inject.Inject;
import com.gingersoft.gsa.cloud.user.login.mvp.contract.LoginAContract;
import com.joe.utils.encryption.DESUtil;
import com.gingersoft.gsa.cloud.user.login.mvp.contract.LoginContract;
import com.joe.base.utils.encryption.DESUtil;
import com.joe.base.utils.request.RequestUtils;
import java.util.HashMap;
import io.reactivex.Observable;
import me.jessyan.retrofiturlmanager.RetrofitUrlManager;
/**
* ================================================
* Description:
* <p>
* Created by MVPArmsTemplate on 12/20/2019 18:41
* Created by MVPArmsTemplate on 12/21/2019 16:23
* <a href="mailto:jess.yan.effort@gmail.com">Contact me</a>
* <a href="https://github.com/JessYanCoding">Follow me</a>
* <a href="https://github.com/JessYanCoding/MVPArms">Star me</a>
......@@ -33,14 +34,14 @@ import io.reactivex.Observable;
* ================================================
*/
@ActivityScope
public class LoginAModel extends BaseModel implements LoginAContract.Model {
public class LoginModel extends BaseModel implements LoginContract.Model{
@Inject
Gson mGson;
@Inject
Application mApplication;
@Inject
public LoginAModel(IRepositoryManager repositoryManager) {
public LoginModel(IRepositoryManager repositoryManager) {
super(repositoryManager);
}
......@@ -51,23 +52,19 @@ public class LoginAModel extends BaseModel implements LoginAContract.Model {
this.mApplication = null;
}
@Override
public Observable<TestLoginBean> login(HashMap<String, Object> params) {
long times = System.currentTimeMillis();
// RetrofitUrlManager.getInstance().putDomain("common", "http://gingersoft.tpddns.cn:58201/");
return mRepositoryManager.obtainRetrofitService(LoginService.class)
.login(DESUtil.encrypt(mGson.toJson(params)),
times + "",
RequestUtils.getSign(params, times));
.login(DESUtil.encrypt(mGson.toJson(params)));
}
@Override
public Observable<TestLoginBean> loginOut(HashMap<String, Object> params) {
long times = System.currentTimeMillis();
RetrofitUrlManager.getInstance().putDomain("common", "http://gingersoft.tpddns.cn:58201/");
// RetrofitUrlManager.getInstance().putDomain("common", "http://gingersoft.tpddns.cn:58201/");
return mRepositoryManager.obtainRetrofitService(LoginService.class)
.loginOut(DESUtil.encrypt(mGson.toJson(params)),
times + "",
RequestUtils.getSign(params, times));
.loginOut(DESUtil.encrypt(mGson.toJson(params)));
}
}
\ No newline at end of file
......@@ -17,7 +17,7 @@ import me.jessyan.rxerrorhandler.handler.ErrorHandleSubscriber;
import javax.inject.Inject;
import com.gingersoft.gsa.cloud.user.login.mvp.contract.LoginAContract;
import com.gingersoft.gsa.cloud.user.login.mvp.contract.LoginContract;
import com.jess.arms.utils.RxLifecycleUtils;
import java.util.HashMap;
......@@ -27,7 +27,7 @@ import java.util.HashMap;
* ================================================
* Description:
* <p>
* Created by MVPArmsTemplate on 12/20/2019 18:41
* Created by MVPArmsTemplate on 12/21/2019 16:23
* <a href="mailto:jess.yan.effort@gmail.com">Contact me</a>
* <a href="https://github.com/JessYanCoding">Follow me</a>
* <a href="https://github.com/JessYanCoding/MVPArms">Star me</a>
......@@ -36,7 +36,7 @@ import java.util.HashMap;
* ================================================
*/
@ActivityScope
public class LoginAPresenter extends BasePresenter<LoginAContract.Model, LoginAContract.View> {
public class LoginPresenter extends BasePresenter<LoginContract.Model, LoginContract.View> {
@Inject
RxErrorHandler mErrorHandler;
@Inject
......@@ -47,7 +47,7 @@ public class LoginAPresenter extends BasePresenter<LoginAContract.Model, LoginAC
AppManager mAppManager;
@Inject
public LoginAPresenter(LoginAContract.Model model, LoginAContract.View rootView) {
public LoginPresenter (LoginContract.Model model, LoginContract.View rootView) {
super(model, rootView);
}
......@@ -59,6 +59,8 @@ public class LoginAPresenter extends BasePresenter<LoginAContract.Model, LoginAC
this.mImageLoader = null;
this.mApplication = null;
}
public void login(String account, String pwd) {
HashMap<String, Object> params = new HashMap<>();
params.put("userName", account.trim() + "");
......@@ -100,7 +102,4 @@ public class LoginAPresenter extends BasePresenter<LoginAContract.Model, LoginAC
});
}
}
package com.gingersoft.gsa.cloud.user.login.mvp.server;
import android.database.Observable;
import com.gingersoft.gsa.cloud.user.login.mvp.bean.TestLoginBean;
import io.reactivex.Observable;
import me.jessyan.retrofiturlmanager.RetrofitUrlManager;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.POST;
......@@ -15,10 +15,10 @@ import retrofit2.http.POST;
public interface LoginService {
@FormUrlEncoded
@POST("ricepon-cloud-gsa/api/gsa/login")
Observable<TestLoginBean> login(@Field("args") String args, @Field("time") String time, @Field("sign") String sign);
@POST("gsa/login" + RetrofitUrlManager.IDENTIFICATION_PATH_SIZE + 2)
Observable<TestLoginBean> login(@Field("args") String args);
@FormUrlEncoded
@POST("ricepon-cloud-gsa/api/gsa/logout")
Observable<TestLoginBean> loginOut(@Field("args") String args, @Field("time") String time, @Field("sign") String sign);
@POST("gsa/logout" + RetrofitUrlManager.IDENTIFICATION_PATH_SIZE + 2)
Observable<TestLoginBean> loginOut(@Field("args") String args);
}
......@@ -2,21 +2,20 @@ package com.gingersoft.gsa.cloud.user.login.mvp.ui.activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.EditText;
import android.widget.TextView;
import com.gingersoft.gsa.cloud.user.login.R;
import com.gingersoft.gsa.cloud.user.login.di.component.DaggerLoginComponent;
import com.gingersoft.gsa.cloud.user.login.mvp.bean.TestLoginBean;
import com.gingersoft.gsa.cloud.user.login.mvp.contract.LoginAContract;
import com.gingersoft.gsa.cloud.user.login.mvp.presenter.LoginAPresenter;
import com.jess.arms.base.BaseActivity;
import com.jess.arms.di.component.AppComponent;
import com.jess.arms.utils.ArmsUtils;
import com.gingersoft.gsa.cloud.user.login.mvp.contract.LoginContract;
import com.gingersoft.gsa.cloud.user.login.mvp.presenter.LoginPresenter;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import butterknife.BindView;
import butterknife.ButterKnife;
import static com.jess.arms.utils.Preconditions.checkNotNull;
......@@ -25,7 +24,7 @@ import static com.jess.arms.utils.Preconditions.checkNotNull;
* ================================================
* Description:
* <p>
* Created by MVPArmsTemplate on 12/20/2019 18:41
* Created by MVPArmsTemplate on 12/21/2019 16:23
* <a href="mailto:jess.yan.effort@gmail.com">Contact me</a>
* <a href="https://github.com/JessYanCoding">Follow me</a>
* <a href="https://github.com/JessYanCoding/MVPArms">Star me</a>
......@@ -33,19 +32,11 @@ import static com.jess.arms.utils.Preconditions.checkNotNull;
* <a href="https://github.com/JessYanCoding/MVPArmsTemplate">模版请保持更新</a>
* ================================================
*/
public class LoginActivity extends BaseActivity<LoginAPresenter> implements LoginAContract.View {
@BindView(R.id.ed_gsa_user_account)
EditText account;
@BindView(R.id.ed_gsa_user_login_pwd)
EditText pwd;
@BindView(R.id.tv_gsa_user_login)
TextView login;
public class LoginActivity extends BaseActivity<LoginPresenter> implements LoginContract.View {
@Override
public void setupActivityComponent(@NonNull AppComponent appComponent) {
DaggerLoginAComponent //如找不到该类,请编译一下项目
DaggerLoginComponent //如找不到该类,请编译一下项目
.builder()
.appComponent(appComponent)
.view(this)
......@@ -55,49 +46,11 @@ public class LoginActivity extends BaseActivity<LoginAPresenter> implements Logi
@Override
public int initView(@Nullable Bundle savedInstanceState) {
return R.layout.activity_login; //如果你不需要框架帮你设置 setContentView(id) 需要自行设置,请返回 0
return R.layout.user_login_activity_login; //如果你不需要框架帮你设置 setContentView(id) 需要自行设置,请返回 0
}
@Override
public void initData(@Nullable Bundle savedInstanceState) {
ButterKnife.bind(this);
login.setOnClickListener(v -> {
if ((login.getText().equals("登陸"))) {
mPresenter.login(account.getText().toString(), pwd.getText().toString());
} else {
//退出登錄
mPresenter.loginOut();
}
});
}
@Override
public void initIntent() {
}
@Override
public void initTopBar() {
}
@Override
public void initLanguage() {
}
@Override
public void initLayoutParams() {
}
@Override
public void initLayoutVisible() {
}
@Override
public void showLoading(String message) {
}
......
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:orientation="vertical">
<TextView
android:id="@+id/login_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="50dp"
android:text="歡迎登陸商戶端"
android:textColor="#333"
android:textSize="26dp" />
android:layout_marginTop="80dp"
android:text="@string/user_login_welcome_login"
android:textColor="@color/user_login_title_color"
android:textSize="@dimen/title_text_size"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/ed_gsa_user_account"
android:layout_width="match_parent"
android:layout_height="50dp"
<ImageView
android:id="@+id/login_icon"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginLeft="10dp"
android:background="@color/theme_color"
android:padding="8dp"
android:layout_marginTop="100dp"
android:background="#00000000"
android:src="@mipmap/ic_user"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/login_title"/>
<EditText
android:id="@+id/ed_login_user_account"
android:layout_width="0dp"
android:layout_height="0dp"
android:hint="請輸入賬戶"
android:padding="10dp"
android:textColor="#333" />
android:textColorHint="@color/user_login_edit_color"
app:layout_constraintTop_toTopOf="@id/login_icon"
app:layout_constraintBottom_toBottomOf="@id/login_icon"
android:textSize="@dimen/edit_text_size"
app:layout_constraintLeft_toRightOf="@id/login_icon"
app:layout_constraintRight_toRightOf="parent" />
<EditText
android:id="@+id/ed_gsa_user_login_pwd"
android:id="@+id/ed_login_user_pwd"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#00000000"
android:hint="請輸入密碼"
android:padding="10dp"
android:textColor="#333" />
android:textColor="#333"
android:textColorHint="@color/user_login_edit_color"
android:textSize="@dimen/edit_text_size"
app:layout_constraintTop_toBottomOf="@id/ed_login_user_account" />
<TextView
android:id="@+id/tv_gsa_user_login"
......@@ -44,6 +70,7 @@
android:padding="10dp"
android:text="登陸"
android:textColor="#fff"
android:textSize="16dp" />
android:textSize="16dp"
app:layout_constraintTop_toBottomOf="@id/ed_login_user_pwd" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="user_login_title_color">@color/title_color</color>
<color name="user_login_edit_color">@color/edit_hint_color</color>
</resources>
<resources>
<string name="user_login_name">component-user-login</string>
<string name="user_login_name" translatable="false">component-user-login</string>
<string name="user_login_welcome_login">歡迎登陸商戶端</string>
</resources>
......@@ -36,5 +36,6 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation project(':arms')
// implementation project(':arms')
implementation rootProject.ext.dependencies["arms"]
}
package com.gingersoft.gsa.cloud.user.register;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.Gravity;
import android.view.View;
import android.widget.TextView;
import com.billy.cc.core.component.CC;
import com.billy.cc.core.component.CCResult;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
public class RegisterActivity extends AppCompatActivity {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment