first commit.

This commit is contained in:
DXL
2019-09-24 18:39:43 +08:00
parent e18a916d52
commit 3c73f2c869
9740 changed files with 3269600 additions and 0 deletions
+31
View File
@@ -0,0 +1,31 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cn.dxl.common">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.VIBRATE" />
<application>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
<!--APP重启服务-->
<service
android:name="cn.dxl.common.services.RestartService"
android:enabled="true"
android:process=":restart" />
<activity android:name="cn.dxl.common.activities.CrashActivity" />
</application>
</manifest>
@@ -0,0 +1,49 @@
package cn.dxl.common.activities;
import android.app.Activity;
import android.os.Bundle;
import android.os.Process;
import androidx.annotation.Nullable;
import android.widget.TextView;
import android.widget.Toast;
import cn.dxl.common.R;
/**
* show throwable!
*/
public class CrashActivity extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_crash_main);
TextView txtShowMsg = findViewById(R.id.txtView_showMsg);
//接收意图中序列化过来的Throwable对象
Throwable t = (Throwable) getIntent().getSerializableExtra("crash");
if (t == null) {
Toast.makeText(this, "接收到的异常对象为空!", Toast.LENGTH_SHORT).show();
} else {
StringBuilder msg = new StringBuilder();
msg.append(t.getLocalizedMessage()).append('\n');
for (StackTraceElement st : t.getStackTrace()) {
msg.append('\n');
msg.append("at: ");
msg.append(st.toString());
}
txtShowMsg.setText(msg);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
//终止虚拟机的执行
finish();
Process.killProcess(Process.myPid());
System.exit(0);
}
}
@@ -0,0 +1,38 @@
package cn.dxl.common.application;
import android.app.Application;
import android.content.Context;
import cn.dxl.common.util.AppUtil;
import cn.dxl.common.util.CrashUtil;
public class App extends Application {
public interface ApplicationCallback {
Context onAttachBaseContext(Context context);
}
public ApplicationCallback getCallback() {
return callback;
}
public void setCallback(ApplicationCallback callback) {
this.callback = callback;
}
private ApplicationCallback callback;
@Override
public void onCreate() {
super.onCreate();
//异常处理
CrashUtil.register(this);
//全局contextapp环境缓存!
AppUtil.register(this);
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(callback != null ? callback.onAttachBaseContext(base) : base);
}
}
@@ -0,0 +1,20 @@
package cn.dxl.common.implement;
import android.view.animation.Animation;
public class AnimationListenerImpl implements Animation.AnimationListener {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
}
@Override
public void onAnimationRepeat(Animation animation) {
}
}
@@ -0,0 +1,10 @@
package cn.dxl.common.implement;
import android.content.DialogInterface;
public class DialogOnclickListenerImpl implements DialogInterface.OnClickListener {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
}
}
@@ -0,0 +1,17 @@
package cn.dxl.common.implement;
import android.view.View;
import android.widget.AdapterView;
public class ItemSelectedListenerImpl
implements AdapterView.OnItemSelectedListener {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
}
@@ -0,0 +1,20 @@
package cn.dxl.common.implement;
import androidx.viewpager.widget.ViewPager;
public class OnPageChangeListenerImpl implements ViewPager.OnPageChangeListener {
@Override
public void onPageScrolled(int i, float v, int i1) {
}
@Override
public void onPageSelected(int i) {
}
@Override
public void onPageScrollStateChanged(int i) {
}
}
@@ -0,0 +1,30 @@
package cn.dxl.common.implement;
import cn.dxl.common.util.PermissionUtil;
public class PermissionCallback implements PermissionUtil.Callback {
@Override
public void onStartChecks(PermissionUtil util) {
}
@Override
public void onPermissionLose(PermissionUtil util) {
}
@Override
public void onPermissionNormal(PermissionUtil util) {
}
@Override
public void whatPermissionLose(String per, PermissionUtil util) {
}
@Override
public void onEndChecks() {
}
}
@@ -0,0 +1,10 @@
package cn.dxl.common.interfaces;
import android.view.MotionEvent;
/*
* 在触发时的回调!
* */
public interface OnTouchListener {
boolean onTouch(MotionEvent event);
}
@@ -0,0 +1,7 @@
package cn.dxl.common.interfaces;
public interface RegexCommon {
//邮箱匹配规则!
String email = "[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[\\w](?:[\\w-]*[\\w])?";
}
@@ -0,0 +1,46 @@
package cn.dxl.common.posixio;
import java.io.Closeable;
import java.io.IOException;
import java.io.Serializable;
/*
* author DXL
* 通信接口,实现了必要的元素传递以及通信实现规定
*/
public interface Communication extends Serializable, Closeable {
/**
* @param sendMsg data buffer, transfer data from here.
* @param offset the data from buffer valid offset.
* @param length the data length from buffer,buffer may be 1024bytes, but valid data length is 512bytes.
* @param timeout if write need timeout, use me.
* @return the length of write finished.
* @throws IOException throw a IOException if have some problem.
*/
int write(byte[] sendMsg, int offset, int length, int timeout) throws IOException;
/**
* @param recvMsg data buffer, read data to here.
* @param offset read data to buffer from offset started.
* @param length the length of data need read.
* @param timeout if read need timeout at data length no enough, use me.
* @return the length of read finished.
* @throws IOException throw a IOException if have some problem.
*/
int read(byte[] recvMsg, int offset, int length, int timeout) throws IOException;
/**
* flush outputstream.
*
* @throws IOException throw a IOException if have some problem.
*/
void flush() throws IOException;
/**
* close io stream
*
* @throws IOException throw a IOException if have some problem.
*/
void close() throws IOException;
}
@@ -0,0 +1,42 @@
package cn.dxl.common.services;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import androidx.annotation.Nullable;
public class RestartService extends Service {
private static final String LOG_TAG = RestartService.class.getSimpleName();
private Handler handler;
private String PackageName;
public RestartService() {
handler = new Handler();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
/*
* 关闭应用后多久重新启动
*/
long stopDelayed = intent.getLongExtra("Delayed", 2000);
PackageName = intent.getStringExtra("PackageName");
handler.postDelayed(new Runnable() {
@Override
public void run() {
Intent LaunchIntent = RestartService.this.getPackageManager().getLaunchIntentForPackage(PackageName);
RestartService.this.startActivity(LaunchIntent);
RestartService.this.stopSelf();
}
}, stopDelayed);
return super.onStartCommand(intent, flags, startId);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
@@ -0,0 +1,84 @@
package cn.dxl.common.util;
import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;
/**
* AES 加密方法,是对称的密码算法(加密与解密的密钥一致),这里使用最大的 256 位的密钥
*/
public class AesUtils {
private static final int size = 128;
/**
* 获得一个 密钥长度为 256 位的 AES 密钥,
*
* @return 返回经 BASE64 处理之后的密钥字符串
*/
public static byte[] getStrKeyAES() throws NoSuchAlgorithmException, UnsupportedEncodingException {
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
SecureRandom secureRandom = new SecureRandom(String.valueOf(System.currentTimeMillis()).getBytes(Charset.forName("UTF-8")));
keyGen.init(size, secureRandom); // 这里可以是 128、192、256、越大越安全
SecretKey secretKey = keyGen.generateKey();
return secretKey.getEncoded();
}
/**
* 将使用 原生的类型byte的数组 secretKey 转为 SecretKey
*
* @param keyBytes raw key byte.
* @return SecretKey
*/
public static SecretKey strKey2SecretKey(byte[] keyBytes) {
return new SecretKeySpec(keyBytes, "AES");
}
/**
* 将使用 byte 类型的 secretKey 转为 SecretKey
*
* @param bytesKey
* @return SecretKey
*/
public static SecretKey bytesKey2SecretKey(byte[] bytesKey) {
return new SecretKeySpec(bytesKey, "AES");
}
/**
* 加密
*
* @param content 待加密内容
* @param secretKey 加密使用的 AES 密钥
* @return 加密后的密文 byte[]
*/
public static byte[] encryptAES(byte[] content, SecretKey secretKey)
throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
return cipher.doFinal(content);
}
/**
* 解密
*
* @param content 待解密内容
* @param secretKey 解密使用的 AES 密钥
* @return 解密后的明文 byte[]
*/
public static byte[] decryptAES(byte[] content, SecretKey secretKey)
throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
return cipher.doFinal(content);
}
}
@@ -0,0 +1,35 @@
package cn.dxl.common.util;
import android.app.Activity;
import android.app.Application;
import cn.dxl.common.application.App;
public class AppUtil {
private static AppUtil thiz = null;
private static App app;
private AppUtil() {
}
public static AppUtil getInstance() {
if (thiz == null) {
thiz = new AppUtil();
}
return thiz;
}
public static void register(App app) {
AppUtil.app = app;
}
public App getApp() {
return app;
}
public void finishAll() {
for (Activity activity : CrashUtil.activities) {
activity.finish();
}
}
}
@@ -0,0 +1,99 @@
package cn.dxl.common.util;
import android.content.Context;
import android.content.res.AssetManager;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
/*
* 针对Assets进行操作的类!
* */
public class AssetsUtil {
private Context context;
public AssetsUtil(Context context) {
this.context = context;
}
//判断assets文件是否存在!
public boolean isFileExists(String fileName) {
InputStream is = null;
boolean ret = false;
try {
is = context.getResources().getAssets().open(fileName);
ret = true;
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (is != null)
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return ret;
}
//得到assets指定目录下的所有文件!
public String[] getFiles(String root) {
String[] files = new String[0];
try {
files = context.getAssets().list(root);
} catch (IOException e) {
e.printStackTrace();
}
if (files == null || files.length == 0) return null;
return files;
}
//移动assets中的文件到指定目录
public boolean moveFile(String asFile, String targetPath) {
File file = new File(targetPath);
if (!file.exists() || !file.isFile()) {
try {
if (!file.createNewFile()) {
return false;
}
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
boolean ret = false;
//移动默认key文件
AssetManager am = context.getResources().getAssets();
InputStream is = null;
FileOutputStream fos = null;
try {
is = am.open(asFile);
fos = new FileOutputStream(file);
int len = is.available();
for (int i = 0; i < len; ++i) {
fos.write((byte) is.read());
}
ret = true;
} catch (IOException e) {
e.printStackTrace();
try {
if (is != null) is.close();
if (fos != null) fos.close();
ret = false;
} catch (IOException e1) {
e1.printStackTrace();
}
} finally {
try {
if (is != null) is.close();
if (fos != null) fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return ret;
}
}
@@ -0,0 +1,66 @@
package cn.dxl.common.util;
/**
* crc16多项式算法
*
* @author eguid
*/
public class CRC16 {
/**
* CRC16-XMODEM算法(四字节)
*
* @param bytes
* @return
*/
public static int crc16_ccitt_xmodem(byte[] bytes) {
return crc16_ccitt_xmodem(bytes, 0, bytes.length);
}
/**
* CRC16-XMODEM算法(四字节)
*
* @param bytes
* @param offset
* @param count
* @return
*/
public static int crc16_ccitt_xmodem(byte[] bytes, int offset, int count) {
int crc = 0x0000; // initial value
int polynomial = 0x1021; // poly value
for (int index = offset; index < count; index++) {
byte b = bytes[index];
for (int i = 0; i < 8; i++) {
boolean bit = ((b >> (7 - i) & 1) == 1);
boolean c15 = ((crc >> 15 & 1) == 1);
crc <<= 1;
if (c15 ^ bit)
crc ^= polynomial;
}
}
crc &= 0xffff;
return crc;
}
/**
* CRC16-XMODEM算法(两字节)
*
* @param bytes
* @param offset
* @param count
* @return
*/
public static short crc16_ccitt_xmodem_short(byte[] bytes, int offset, int count) {
return (short) crc16_ccitt_xmodem(bytes, offset, count);
}
/**
* CRC16-XMODEM算法(两字节)
*
* @param bytes
*/
public static short crc16_ccitt_xmodem_short(byte[] bytes) {
return crc16_ccitt_xmodem_short(bytes, 0, bytes.length);
}
}
@@ -0,0 +1,20 @@
package cn.dxl.common.util;
public class Checksum {
/**
* Calculates the checksum of the passed byte buffer.
*
* @param buffer
* @param byteCount
* @return byte checksum value
*/
public static byte calcChecksum(byte[] buffer, int byteCount) {
byte checksum = 0;
int bufPos = 0;
while (byteCount-- != 0) {
checksum += buffer[bufPos++];
}
return checksum;
}
}
@@ -0,0 +1,43 @@
package cn.dxl.common.util;
import android.app.Activity;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Build;
public class ContextUtil {
private Context context;
public ContextUtil(Context context) {
this.context = context;
}
//根据colorId得到颜色
public int getColor(int colorId) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return context.getColor(colorId);
}
return context.getResources().getColor(colorId);
}
//根据drawableId得到drawable对象
public Drawable getDrawable(int drawableId) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return context.getDrawable(drawableId);
}
return context.getResources().getDrawable(drawableId);
}
//复制文本到剪贴板
public void copyStr2Clipborad(String label, String content) {
ClipboardManager clipboardManager = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
if (clipboardManager == null) return;
//创建ClipData对象
ClipData clipData = ClipData.newPlainText(label, content);
//添加ClipData对象到剪切板中
clipboardManager.setPrimaryClip(clipData);
}
}
@@ -0,0 +1,77 @@
package cn.dxl.common.util;
import java.util.Timer;
import java.util.TimerTask;
/*
* 倒计时任务!
* */
public class CountDownTask extends TimerTask {
private int timeDelay = 1000;
private transient int countdynamic = 0;
private Progress mProgress;
private Timer timer;
public CountDownTask(Progress progress) {
timer = new Timer();
mProgress = progress;
}
//倒计时回调接口
public interface Progress {
boolean onProgress(int countdynamic);
}
//设置回调!
public void setProgress(Progress progress) {
mProgress = progress;
}
//设置每次的延迟
public CountDownTask setTimeDelay(int ms) {
timeDelay = ms;
return this;
}
//设置需要延迟多少次!
public CountDownTask setCountDown(int count) {
countdynamic = count;
return this;
}
//开始倒计时!
public CountDownTask startCountDown() {
if (countdynamic == 0) return this;
timer.schedule(this, 0, timeDelay);
return this;
}
//取消倒计时
public CountDownTask cancelCountDown() {
cancel();
countdynamic = 0;
return this;
}
//是否处于倒计时状态!
public boolean isRunning() {
return this.countdynamic != 0;
}
@Override
public void run() {
//判断为零,立刻回调结束
if (countdynamic == 0) {
mProgress.onProgress(0);
cancelCountDown();
} else {
//回调且判断需不需要继续下次回调!
if (!mProgress.onProgress(countdynamic)) {
cancelCountDown();
return;
}
--countdynamic;
}
}
}
@@ -0,0 +1,84 @@
package cn.dxl.common.util;
import android.app.Activity;
import android.app.Application;
import android.content.Intent;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import cn.dxl.common.activities.CrashActivity;
public class CrashUtil {
private static final Thread.UncaughtExceptionHandler DEFAULT_UNCAUGHT = Thread.getDefaultUncaughtExceptionHandler();
public static final List<Activity> activities = new ArrayList<>();
/*
* callback for activity!
* */
private static final
Application.ActivityLifecycleCallbacks callbacks4Act = new Application.ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle bundle) {
//must add activity to list!
activities.add(activity);
}
@Override
public void onActivityStarted(@NonNull Activity activity) {
}
@Override
public void onActivityResumed(@NonNull Activity activity) {
}
@Override
public void onActivityPaused(@NonNull Activity activity) {
}
@Override
public void onActivityStopped(@NonNull Activity activity) {
}
@Override
public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle bundle) {
}
@Override
public void onActivityDestroyed(@NonNull Activity activity) {
//must remove activity from list!
activities.remove(activity);
}
};
public static void register(final Application application) {
//register callback!
application.registerActivityLifecycleCallbacks(callbacks4Act);
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(@NonNull Thread t, @NonNull Throwable e) {
//跳转到奔溃信息处理界面
Intent intent = new Intent(application, CrashActivity.class);
intent.putExtra("crash", e);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//destroy all activity
for (Activity act : activities) {
act.finish();
}
application.startActivity(intent);
//调用默认的异常处理
if (DEFAULT_UNCAUGHT != null) {
DEFAULT_UNCAUGHT.uncaughtException(t, e);
}
}
});
}
}

Some files were not shown because too many files have changed in this diff Show More