Commit 3dbab070 by gao.chao

工具类

时间-
尺寸转换-
log-
下载图片-
文件-
本地参数存储-
算术运算(加减乘除)-
二维码生成与解码-
toast-
下载安装APK
验证(手机号,中文,邮箱)-
图片--

第三方集成
加载网络图片(picasso)-
统一web内核 X5Webview-
网络访问(okhttp)-
Logger-
bugly-
fastgson,recyclerview-
parent 3bc7daa0
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
package="com.mayi.demo"> package="com.mayi.demo">
<application <application
android:name=".MyApplication"
android:allowBackup="true" android:allowBackup="true"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:label="@string/app_name" android:label="@string/app_name"
...@@ -17,7 +18,13 @@ ...@@ -17,7 +18,13 @@
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".TsetActviity"/> <activity android:name=".TsetActviity" />
<activity android:name=".QRActivity" />
</application> </application>
<!-- 配置APP ID -->
<meta-data
android:name="BUGLY_APPID"
android:value="cb8018da1b" />
</manifest> </manifest>
\ No newline at end of file
...@@ -10,6 +10,8 @@ import android.view.ViewGroup; ...@@ -10,6 +10,8 @@ import android.view.ViewGroup;
import android.widget.Button; import android.widget.Button;
import com.mayi.fastdevelop.base.BaseActivity; import com.mayi.fastdevelop.base.BaseActivity;
import com.mayi.fastdevelop.util.LogUtils;
import com.mayi.fastdevelop.util.SpUtil;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
...@@ -26,7 +28,17 @@ public class MainActivity extends BaseActivity { ...@@ -26,7 +28,17 @@ public class MainActivity extends BaseActivity {
list.add(new ItemBean("BaseActivity", new View.OnClickListener() { list.add(new ItemBean("BaseActivity", new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
gotoActivity(TsetActviity.class); LogUtils.postCatchedException(new Exception("11"));
SpUtil.set("ss",System.currentTimeMillis());
LogUtils.i("ss="+ SpUtil.get("ss",-1L));
// gotoActivity(TsetActviity.class);
}
}));
list.add(new ItemBean("二维码", new View.OnClickListener() {
@Override
public void onClick(View v) {
gotoActivity(QRActivity.class);
} }
})); }));
listView.setAdapter(new RecyclerView.Adapter<MyViewHolder>() { listView.setAdapter(new RecyclerView.Adapter<MyViewHolder>() {
......
package com.mayi.demo;
import android.app.Application;
import com.mayi.fastdevelop.base.BaseApplication;
public class MyApplication extends BaseApplication{
@Override
public void onCreate() {
super.onCreate();
initBugly("cb8018da1b",true);
}
@Override
public Application getChildApplication() {
return this;
}
@Override
public boolean isShowLog() {
return BuildConfig.DEBUG;
}
}
package com.mayi.demo;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import com.mayi.fastdevelop.base.BaseActivity;
import com.mayi.fastdevelop.util.BitmapUtil;
import com.mayi.fastdevelop.util.QrUtil;
public class QRActivity extends BaseActivity {
private ImageView img1, img2, img0;
private Button bt, bt0;
private EditText et, et0;
private TextView tv;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.qr_layout);
bt0 = findViewById(R.id.bt0);
et0 = findViewById(R.id.et0);
tv = findViewById(R.id.tv);
img0 = findViewById(R.id.img0);
img1 = findViewById(R.id.img1);
img2 = findViewById(R.id.img2);
bt = findViewById(R.id.bt);
et = findViewById(R.id.et);
bt0.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
img0.setImageBitmap(QrUtil.createBitmap(et0.getText().toString()));
}
});
bt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
img1.setImageBitmap(QrUtil.createBitmap(QRActivity.this, et.getText().toString(), R.mipmap.ic_launcher));
}
});
img2.setBackgroundResource(R.mipmap.qr_icon);
tv.setText("图片中二维码文字:"+QrUtil.recogQRcode(BitmapUtil.getBitmap(this,R.mipmap.qr_icon)));
}
}
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="@+id/et0"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/bt0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="文字转二维码" />
<ImageView
android:id="@+id/img0"
android:layout_width="200dp"
android:layout_height="200dp" />
<EditText
android:id="@+id/et"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/bt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="文字转二维码并且中间添加图片" />
<ImageView
android:id="@+id/img1"
android:layout_width="200dp"
android:layout_height="200dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="二维码转文字" />
<ImageView
android:id="@+id/img2"
android:layout_width="200dp"
android:layout_height="200dp" />
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</ScrollView>
\ No newline at end of file
...@@ -3,16 +3,16 @@ apply plugin: 'com.android.library' ...@@ -3,16 +3,16 @@ apply plugin: 'com.android.library'
android { android {
compileSdkVersion 28 compileSdkVersion 28
defaultConfig { defaultConfig {
minSdkVersion 19 minSdkVersion 19
targetSdkVersion 28 targetSdkVersion 28
versionCode 1 versionCode 1
versionName "1.0" versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
ndk {
// 设置支持的SO库架构
abiFilters 'armeabi', 'x86', 'armeabi-v7a', 'x86_64', 'arm64-v8a'
}
} }
buildTypes { buildTypes {
...@@ -25,10 +25,20 @@ android { ...@@ -25,10 +25,20 @@ android {
} }
dependencies { dependencies {
api fileTree(dir: 'libs', include: ['*.jar']) api fileTree(include: ['*.jar'], dir: 'libs')
api "com.tencent.bugly:crashreport_upgrade:1.3.4"
api 'com.tencent.bugly:nativecrashreport:3.6.0.1'
api 'com.squareup.okhttp3:okhttp:3.10.0'
api 'com.squareup.picasso:picasso:2.5.2'
api 'com.tencent.bugly:crashreport_upgrade:1.3.4'
api 'com.tencent.bugly:nativecrashreport:3.6.0.1'
api 'com.orhanobut:logger:2.2.0'
api 'com.alibaba:fastjson:1.2.12'
api 'com.android.support:recyclerview-v7:28.0.0' api 'com.android.support:recyclerview-v7:28.0.0'
api 'com.android.support:appcompat-v7:28.0.0' api 'com.android.support:appcompat-v7:28.0.0'
testImplementation 'junit:junit:4.12' testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
api files('libs/zixing-core-3.2.0.jar')
implementation files('libs/tbs_sdk_thirdapp_v3.6.0.1371_43624_sharewithdownload_withoutGame_obfs_20181106_121046.jar')
} }
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mayi.fastdevelop" /> xmlns:tools="http://schemas.android.com/tools"
package="com.mayi.fastdevelop">
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission
android:name="android.permission.READ_LOGS"
tools:ignore="ProtectedPermissions" />
</manifest>
package com.mayi.fastdevelop.base; package com.mayi.fastdevelop.base;
import android.app.Application; import android.app.Application;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import com.mayi.fastdevelop.util.DateUtil;
import com.mayi.fastdevelop.util.FileUtil;
import com.mayi.fastdevelop.util.LogUtils;
import com.mayi.fastdevelop.util.WriteHandler;
import com.orhanobut.logger.AndroidLogAdapter;
import com.orhanobut.logger.CsvFormatStrategy;
import com.orhanobut.logger.DiskLogAdapter;
import com.orhanobut.logger.DiskLogStrategy;
import com.orhanobut.logger.Logger;
import com.tencent.bugly.crashreport.CrashReport;
import com.tencent.smtt.sdk.CookieManager;
import com.tencent.smtt.sdk.CookieSyncManager;
import com.tencent.smtt.sdk.QbSdk;
import com.tencent.smtt.sdk.WebStorage;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
public abstract class BaseApplication extends Application { public abstract class BaseApplication extends Application {
private static BaseApplication mInstance; private static BaseApplication mInstance;
private int logSize = 5 * 1024 * 1024;//默认记录Log文件大小--5M
@Override @Override
public void onCreate() { public void onCreate() {
mInstance = this; mInstance = this;
super.onCreate(); super.onCreate();
initLog();
initX5Webview();
}
public void initBugly(String key,boolean isDebug){
CrashReport.initCrashReport(getApplicationContext(), key, isDebug);
}
private void initX5Webview() {
//清空所有Cookie
CookieSyncManager.createInstance(getApplicationContext());
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.removeSessionCookies(null);
cookieManager.removeAllCookie();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
cookieManager.flush();
} else {
CookieSyncManager.getInstance().sync();
}
WebStorage.getInstance().deleteAllData();
//搜集本地tbs内核信息并上报服务器,服务器返回结果决定使用哪个内核。
QbSdk.PreInitCallback cb = new QbSdk.PreInitCallback() {
@Override
public void onViewInitFinished(boolean arg0) {
//x5內核初始化完成的回调,为true表示x5内核加载成功,否则表示x5内核加载失败,会自动切换到系统内核。
LogUtils.i("X5内核加载完成:" + arg0);
} }
@Override
public void onCoreInitFinished() {
}
};
//x5内核初始化接口
QbSdk.initX5Environment(getApplicationContext(), cb);
}
/**
* 设置日志文件大小
*
* @param logSize
*/
public void setLogSize(int logSize) {
this.logSize = logSize;
}
private void initLog() {
LogUtils.TAG=getPackageName();
if (isWriteLog()) {
String diskPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + getPackageName() + "/logger/";
String folder = diskPath + DateUtil.getCurrentDate();
HandlerThread ht = new HandlerThread("AndroidFileLogger." + folder);
ht.start();
Handler handler = new WriteHandler(ht.getLooper(), folder, logSize);
DiskLogStrategy logStrategy = new DiskLogStrategy(handler);
Logger.addLogAdapter(new DiskLogAdapter(CsvFormatStrategy.newBuilder().tag(getPackageName()).logStrategy(logStrategy).build()));
//删除3天前的日志文件
int logSaveDay = getLogSaveDay();
if (logSaveDay < 1) {
logSaveDay = 3;
}
for (int i = 0; i < 10; i++) {
Date date = new Date(System.currentTimeMillis() - (logSaveDay + i) * 24 * 60 * 60 * 1000);
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
String time = format.format(date);
FileUtil.deleteFile(diskPath + time);
}
}
Logger.addLogAdapter(new AndroidLogAdapter() {
@Override
public boolean isLoggable(int priority, String tag) {
return isShowLog();
}
});
}
//flie:要删除的文件夹的所在位置
// private void deleteFile(File file) {
// if (file.isDirectory()) {
// File[] files = file.listFiles();
// for (int i = 0; i < files.length; i++) {
// File f = files[i];
// deleteFile(f);
// }
// file.delete();//如要保留文件夹,只删除文件,请注释这行
// }
// }
public static BaseApplication getInstance() { public static BaseApplication getInstance() {
return mInstance; return mInstance;
} }
...@@ -21,4 +133,28 @@ public abstract class BaseApplication extends Application { ...@@ -21,4 +133,28 @@ public abstract class BaseApplication extends Application {
*/ */
public abstract Application getChildApplication(); public abstract Application getChildApplication();
/**
* 是否显示log
*
* @return
*/
public abstract boolean isShowLog();
/**
* 是否需要记录日志到本地,默认开启
*
* @return
*/
public boolean isWriteLog() {
return true;
}
/**
* 获取日志保留时间不能小于1,默认保留3天
*
* @return
*/
public int getLogSaveDay() {
return 3;
}
} }
package com.mayi.fastdevelop.base; package com.mayi.fastdevelop.base;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
public abstract class BaseFragment extends Fragment{ public abstract class BaseFragment extends Fragment{
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActivity().finish();
}
} }
package com.mayi.fastdevelop.util;
import java.math.BigDecimal;
public class ArithUtil {
/**
* 提供精确的加法运算。
*
* @param v1 被加数
* @param v2 加数
* @return 两个参数的和
*/
public static double add(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.add(b2).doubleValue();
}
public static double addScale(double v1, double v2, int scale) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.add(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
}
/**
* 提供精确的减法运算。
*
* @param v1 被减数
* @param v2 减数
* @return 两个参数的差
*/
public static double sub(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.subtract(b2).doubleValue();
}
/**
* 提供精确的乘法运算。
*
* @param v1 被乘数
* @param v2 乘数
* @return 两个参数的积
*/
public static double mul(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.multiply(b2).doubleValue();
}
/**
* 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 小数点以后10位,以后的数字四舍五入。
*
* @param v1 被除数
* @param v2 除数
* @return 两个参数的商
*/
public static double div(double v1, double v2) {
return div(v1, v2, 0);
}
/**
* 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入。
*
* @param v1 被除数
* @param v2 除数
* @param scale 表示表示需要精确到小数点以后几位。
* @return 两个参数的商
*/
public static double div(double v1, double v2, int scale) {
if (scale < 0) {
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
}
/**
* 提供精确的小数位四舍五入处理。
*
* @param v 需要四舍五入的数字
* @param scale 小数点后保留几位
* @return 四舍五入后的结果
*/
public static double round(double v, int scale) {
if (scale < 0) {
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b = new BigDecimal(Double.toString(v));
BigDecimal one = new BigDecimal("1");
return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
}
}
package com.mayi.fastdevelop.util;
import android.content.Context;
/**
* @Description dp、sp转化为px的工具类
*/
public class DisplayUtil {
/**
* 将px值转换为dip或dp值,保证尺寸大小不变
*
* @param pxValue
* @return
*/
public static int px2dip(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f);
}
/**
* 将dip或dp值转换为px值,保证尺寸大小不变
*
* @param dipValue
* @return
*/
public static int dip2px(Context context, float dipValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dipValue * scale + 0.5f);
}
/**
* 将px值转换为sp值,保证文字大小不变
*
* @param pxValue
* @return
*/
public static int px2sp(Context context, float pxValue) {
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (pxValue / fontScale + 0.5f);
}
/**
* 将sp值转换为px值,保证文字大小不变
*
* @param spValue
* @return
*/
public static int sp2px(Context context, float spValue) {
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (spValue * fontScale + 0.5f);
}
}
package com.mayi.fastdevelop.util;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Environment;
import android.text.TextUtils;
import android.view.View;
import com.mayi.fastdevelop.R;
import com.squareup.picasso.Picasso;
import com.squareup.picasso.Target;
import java.io.File;
import java.io.FileOutputStream;
import java.lang.ref.WeakReference;
public class ImageUtil {
/**
* 保存网络图片
*
* @param context
* @param url
*/
public static void saveBitmap(Context context, String url) {
final WeakReference<Context> weakReference = new WeakReference<>(context);
if (TextUtils.isEmpty(url)) {
ToastUtil.show(context, context.getString(R.string.save_img_failed_2));
return;
}
Target target = new Target() {
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
Context c = weakReference.get();
if (c != null) {
saveBitmap(bitmap, Environment.getExternalStorageDirectory().toString() + "/" + c.getPackageName() + "/picture/" + System.currentTimeMillis() + ".jpg");
//刷新相册
c.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
Uri.fromFile(new File(Environment.getExternalStorageDirectory().toString() + "/" + c.getPackageName()))));
ToastUtil.show(c, c.getString(R.string.save_img_success));
}
}
@Override
public void onBitmapFailed(Drawable errorDrawable) {
Context c = weakReference.get();
if (c != null) {
ToastUtil.show(c, c.getString(R.string.save_img_failed));
}
}
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
};
Picasso.with(context).load(url).into(target);
}
/**
* 保存图片
*
* @param mBitmap 目标图片
* @param fileName 目标文件
*/
public static void saveBitmap(Bitmap mBitmap, String fileName) {
try {
File file = new File(fileName);
FileOutputStream out = new FileOutputStream(file);
mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取某个view的截图
*
* @param view 目标view
*/
public static Bitmap getViewImage(View view) {
Bitmap image = null;
try {
view.setDrawingCacheEnabled(true); //获取view缓存
view.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
// 拷贝图片,否则在setDrawingCacheEnabled(false)以后该图片会被释放掉
Bitmap cacheBitmap = view.getDrawingCache();
//方案1 (图片显示模糊)
// image = Bitmap.createBitmap(cacheBitmap);
//方案2 (图片显示模糊)
// float scale = 320f / cacheBitmap.getWidth();
// int height = (int) (cacheBitmap.getHeight() * scale);
// image = Bitmap.createScaledBitmap(cacheBitmap, 320, height, true);
//方案3
// image = scaleImageCavans(cacheBitmap, DensityUtil.dip2px(view.getContext(), 320), DensityUtil.dip2px(view.getContext(), 240));
// image = scaleImageCavans(cacheBitmap, 320, 240);
//方案4
// Matrix类进行图片处理(缩放)
Matrix matrix = new Matrix();
// 缩小
matrix.setScale(320f / cacheBitmap.getWidth(), 320f / cacheBitmap.getWidth());
// 生成新的图片
image = Bitmap.createBitmap(cacheBitmap, 0, 0, cacheBitmap.getWidth(), cacheBitmap.getHeight(), matrix, true);
} catch (Exception e) {
e.printStackTrace();
} finally {
view.setDrawingCacheEnabled(false);//释放缓存
}
return image;
}
private static PaintFlagsDrawFilter pfd = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
public static Bitmap scaleImageCavans(Bitmap bm, int newWidth, int newHeight) {
//应用图标缩放
if (bm == null) {
return null;
}
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
Bitmap newbm = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), Bitmap.Config.ARGB_8888);
Canvas mCanvas = new Canvas(newbm);
Paint mPaint = new Paint();
mPaint.setXfermode(null);
mPaint.setAntiAlias(true);
mCanvas.save();
mCanvas.scale(scaleWidth, scaleHeight);
//保证图标不失真
mCanvas.setDrawFilter(pfd);
mCanvas.drawBitmap(bm, 0, 0, null);
mCanvas.restore();
if (!bm.isRecycled()) {
bm.recycle();
}
return newbm;
}
}
package com.mayi.fastdevelop.util;
import android.text.TextUtils;
import com.alibaba.fastjson.JSON;
import com.orhanobut.logger.Logger;
import com.tencent.bugly.crashreport.CrashReport;
/**
* 日志记录工具类
*/
public class LogUtils {
public static String TAG;
/**
* 错误信息上传bugly,已自定义错误的方式
*
* @param e
*/
public static void postCatchedException(Exception e) {
StringBuffer msg = new StringBuffer();
if (!TextUtils.isEmpty(TAG)){
msg.append(TAG);
msg.append("--");
}
msg.append(e.toString());
Throwable throwable = new Throwable(msg.toString());
throwable.setStackTrace(e.getStackTrace());
CrashReport.postCatchedException(throwable);
}
/**
* Logger为第三方jar,不要直接使用,防止以后需要替换
*
* @param msg
*/
public static void i(String msg) {
Logger.i(msg);
}
public static void d(String msg) {
Logger.d(msg);
}
public static void v(String msg) {
Logger.v(msg);
}
public static void w(String msg) {
Logger.w(msg);
}
public static void e(String msg) {
Logger.e(msg);
}
/**
* 网络请求记录日志-网络请求成功,接口返回成功就算网络请求成功
*
* @param tag 发起请求的位置,要求定位到方法
* @param url
* @param parameter
* @param result
*/
public static void netWorkSuccess(String tag, String url, Object parameter, Object result) {
Logger.i(tag + " netWork Success url=" + url + " parameter=" +
JSON.toJSONString(parameter) + " result=" + JSON.toJSONString(result));
}
/**
* 网络请求记录日志-网络请求失败,并上传bugly
*
* @param tag 发起请求的位置,要求定位到方法
* @param url
* @param parameter
* @param e
*/
public static void netWorkFail(String tag, String url, Object parameter, Exception e) {
postCatchedException(e);
Logger.i(tag + " netWork Fail url=" + url + " parameter=" +
JSON.toJSONString(parameter) + " Exception=" + e.toString());
}
}
package com.mayi.fastdevelop.util;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.ChecksumException;
import com.google.zxing.EncodeHintType;
import com.google.zxing.FormatException;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.NotFoundException;
import com.google.zxing.RGBLuminanceSource;
import com.google.zxing.Result;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.QRCodeReader;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import java.util.Hashtable;
/**
* 二维码工具
*/
public class QrUtil {
private static int width = 400; // 二维码图片显示宽度
private static final int IMAGE_HALFWIDTH = 45; // 二维码中间图片显示宽度
private static int FOREGROUND_COLOR = 0xff000000; // 前景色
private static int BACKGROUND_COLOR = 0xffffffff; // 背景色
/**
* 生成二维码
*
* @param str 内容
* @return Bitmap
*/
public static Bitmap createBitmap(String str) {
Bitmap bitmap = null;
try {
Hashtable<EncodeHintType, Object> hints = new Hashtable<>();
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
hints.put(EncodeHintType.MARGIN, 1); // 二维码边界空白大小 ,如:1、2、3、4 默认好像是4
// 生成二维矩阵,编码时指定大小,不要生成了图片以后再进行缩放,这样会模糊导致识别失败
MultiFormatWriter mutiWriter = new MultiFormatWriter();
BitMatrix matrix = mutiWriter.encode(str, BarcodeFormat.QR_CODE, width, width, hints);
int width = matrix.getWidth();
int height = matrix.getHeight();
// 二维矩阵转为一维像素数组,也就是一直横着排了
int halfW = width / 2;
int halfH = height / 2;
int[] pixels = new int[width * height];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
if (matrix.get(x, y)) {
pixels[y * width + x] = FOREGROUND_COLOR;
} else { // 无信息设置像素点为白色
pixels[y * width + x] = BACKGROUND_COLOR;
}
}
}
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);// 通过像素数组生成bitmap
} catch (Throwable ex) {
ex.printStackTrace();
}
return bitmap;
}
/**
* 生成二维码 中间插入小图片
*
* @param str 内容
* @return Bitmap
*/
public static Bitmap createBitmap(Context context, String str, int centerBmpResId) {
Bitmap iconBigger = null;
Bitmap iconSmaller = null;
Bitmap bitmap = null;
try {
iconBigger = BitmapFactory.decodeResource(context.getResources(), centerBmpResId);
iconSmaller = zoomBitmap(iconBigger, IMAGE_HALFWIDTH);// 缩放一个50*50的图片
Hashtable<EncodeHintType, Object> hints = new Hashtable<>();
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
hints.put(EncodeHintType.MARGIN, 1); // 二维码边界空白大小 ,如:1、2、3、4 默认好像是4
// 生成二维矩阵,编码时指定大小,不要生成了图片以后再进行缩放,这样会模糊导致识别失败
MultiFormatWriter mutiWriter = new MultiFormatWriter();
BitMatrix matrix = mutiWriter.encode(str, BarcodeFormat.QR_CODE, width, width, hints);
int width = matrix.getWidth();
int height = matrix.getHeight();
// 二维矩阵转为一维像素数组,也就是一直横着排了
int halfW = width / 2;
int halfH = height / 2;
int[] pixels = new int[width * height];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
if (x + 10 > halfW - IMAGE_HALFWIDTH && x - 10 < halfW + IMAGE_HALFWIDTH && y + 10 > halfH - IMAGE_HALFWIDTH && y - 10 < halfH
+ IMAGE_HALFWIDTH) {
if (x > halfW - IMAGE_HALFWIDTH && x < halfW + IMAGE_HALFWIDTH && y > halfH - IMAGE_HALFWIDTH && y < halfH +
IMAGE_HALFWIDTH) {
pixels[y * width + x] = iconSmaller.getPixel(x - halfW + IMAGE_HALFWIDTH, y - halfH + IMAGE_HALFWIDTH);
} else {
pixels[y * width + x] = BACKGROUND_COLOR;
}
} else {
if (matrix.get(x, y)) {
pixels[y * width + x] = FOREGROUND_COLOR;
} else { // 无信息设置像素点为白色
pixels[y * width + x] = BACKGROUND_COLOR;
}
}
}
}
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);// 通过像素数组生成bitmap
} catch (Throwable ex) {
ex.printStackTrace();
} finally {
recycle(iconBigger);
recycle(iconSmaller);
}
return bitmap;
}
public static Bitmap recycle(Bitmap bmp) {
if (bmp != null && !bmp.isRecycled()) {
bmp.recycle();
bmp = null;
}
return bmp;
}
/**
* 缩放图片
*
* @param icon 源图片
* @param h 高度
* @return
*/
public static Bitmap zoomBitmap(Bitmap icon, int h) {
// 缩放图片
Matrix m = new Matrix();
float sx = (float) 2 * h / icon.getWidth();
float sy = (float) 2 * h / icon.getHeight();
m.setScale(sx, sy);
// 重新构造一个2h*2h的图片
return Bitmap.createBitmap(icon, 0, 0, icon.getWidth(), icon.getHeight(), m, false);
}
//识别二维码的函数
public static String recogQRcode(Bitmap QRbmp) {
int width = QRbmp.getWidth();
int height = QRbmp.getHeight();
int[] data = new int[width * height];
QRbmp.getPixels(data, 0, width, 0, 0, width, height); //得到像素
int bitmapPixels[];
bitmapPixels = new int[QRbmp.getWidth() * QRbmp.getHeight()];
QRbmp.getPixels(data, 0, QRbmp.getWidth(), 0, 0, QRbmp.getWidth(), QRbmp.getHeight());
// 将int数组转换为byte数组,也就是取像素值中蓝色值部分作为辨析内容
for (int i = 0; i < data.length; i++) {
bitmapPixels[i] = (byte) data[i];
}
RGBLuminanceSource source = new RGBLuminanceSource(QRbmp.getWidth(), QRbmp.getHeight(), bitmapPixels); //RGBLuminanceSource对象
BinaryBitmap bitmap1 = new BinaryBitmap(new HybridBinarizer(source));
QRCodeReader reader = new QRCodeReader();
Result re = null;
try {
//得到结果
re = reader.decode(bitmap1);
} catch (NotFoundException e) {
e.printStackTrace();
} catch (ChecksumException e) {
e.printStackTrace();
} catch (FormatException e) {
e.printStackTrace();
}
//Toast出内容
return re.getText();
}
}
package com.mayi.fastdevelop.util;
import android.text.TextUtils;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegUtil {
/**
* 验证密码 6-20位 必须数字字母组合
*/
public static boolean isPwd(String pwd) {
if (TextUtils.isEmpty(pwd))
return false;
Pattern p = Pattern.compile("^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$");
Matcher m = p.matcher(pwd);
return m.matches();
}
/**
* 验证邮箱
*/
public static boolean isEmail(String strEmail) {
if (TextUtils.isEmpty(strEmail))
return false;
Pattern p = Pattern.compile("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$");
Matcher m = p.matcher(strEmail);
return m.matches();
}
/**
* 验证手机格式
*
* @param mobiles
* @return
*/
public static boolean isPhone(String mobiles) {
if (TextUtils.isEmpty(mobiles)) {
return false;
}
return mobiles.matches("[1]\\d{10}");
}
/**
* 判断是否中文
*
* @param str
* @return
*/
public static boolean isChinese(String str) {
boolean temp = false;
Pattern p = Pattern.compile("[\u4e00-\u9fa5]");
Matcher m = p.matcher(str);
if (m.find()) {
temp = true;
}
return temp;
}
}
package com.mayi.fastdevelop.util;
import android.content.Context;
import android.content.SharedPreferences;
import com.mayi.fastdevelop.base.BaseApplication;
/**
* 本地存储操作类
*/
public class SpUtil {
private static SharedPreferences sp;
public static synchronized SharedPreferences getSp() {
if (sp == null) {
Context context = BaseApplication.getInstance().getChildApplication();
sp = context.getSharedPreferences(context.getPackageName(), Context.MODE_PRIVATE);
}
return sp;
}
/**
* 清空所有数据
*/
public static void clear() {
getSp().edit().clear().apply();
}
/**
* 写入.
*
* @param key 键.
* @param value 值(boolean).
*/
public static void set(String key, boolean value) {
getSp().edit().putBoolean(key, value).apply();
}
/**
* 写入.
*
* @param key 键.
* @param value 值(float).
*/
public static void set(String key, float value) {
getSp().edit().putFloat(key, value).apply();
}
/**
* 写入.
*
* @param key 键.
* @param value 值(int).
*/
public static void set(String key, int value) {
getSp().edit().putInt(key, value).apply();
}
/**
* 写入.
*
* @param key 键.
* @param value 值(long).
*/
public static void set(String key, long value) {
getSp().edit().putLong(key, value).apply();
}
/**
* 写入.
*
* @param key 键.
* @param value 值(String).
*/
public static void set(String key, String value) {
getSp().edit().putString(key, value).apply();
}
/**
* 移除指定键的值.
*
* @param key 键.
*/
public static void remove(String key) {
getSp().edit().remove(key).apply();
}
/**
* 读取.
*
* @param key 键.
* @param defValue 默认值(boolean).
* @return 获取相应键的值, 若不存在此键则返回默认值.
*/
public static boolean get(String key, boolean defValue) {
return getSp().getBoolean(key, defValue);
}
/**
* 读取.
*
* @param key 键.
* @param defValue 默认值(float).
* @return 获取相应键的值, 若不存在此键则返回默认值.
*/
public static float get(String key, float defValue) {
return getSp().getFloat(key, defValue);
}
/**
* 读取.
*
* @param key 键.
* @param defValue 默认值(int).
* @return 获取相应键的值, 若不存在此键则返回默认值.
*/
public static int get(String key, int defValue) {
return getSp().getInt(key, defValue);
}
/**
* 读取.
*
* @param key 键.
* @param defValue 默认值(long).
* @return 获取相应键的值, 若不存在此键则返回默认值.
*/
public static long get(String key, long defValue) {
return getSp().getLong(key, defValue);
}
/**
* 读取.
*
* @param key 键.
* @param defValue 默认值(String).
* @return 获取相应键的值, 若不存在此键则返回默认值.
*/
public static String get(String key, String defValue) {
return getSp().getString(key, defValue);
}
}
\ No newline at end of file
package com.mayi.fastdevelop.util;
import android.content.Context;
import android.text.TextUtils;
import android.widget.Toast;
/**
* 公共的Toast
*/
public class ToastUtil {
private static Toast sToast = null;
public static Toast show(Context context, String msg) {
return show(context, msg, Toast.LENGTH_SHORT);
}
public static Toast show(Context context, String msg, int duration) {
if (TextUtils.isEmpty(msg) || context == null) {
return null;
}
if (duration < Toast.LENGTH_SHORT) {
duration = Toast.LENGTH_SHORT;
}
if (sToast == null) {
sToast = Toast.makeText(context, msg, duration);
} else {
sToast.setDuration(duration);
sToast.setText(msg);
}
sToast.show();
return sToast;
}
}
\ No newline at end of file
package com.mayi.fastdevelop.util;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
//记录log
public class WriteHandler extends Handler {
private final String folder;
private final int maxFileSize;
public WriteHandler(Looper looper, String folder, int maxFileSize) {
super(looper);
this.folder = folder;
this.maxFileSize = maxFileSize;
}
@SuppressWarnings("checkstyle:emptyblock")
@Override
public void handleMessage(Message msg) {
String content = (String) msg.obj;
FileWriter fileWriter = null;
File logFile = getLogFile(folder, "logs");
try {
fileWriter = new FileWriter(logFile, true);
writeLog(fileWriter, content);
fileWriter.flush();
fileWriter.close();
} catch (IOException e) {
if (fileWriter != null) {
try {
fileWriter.flush();
fileWriter.close();
} catch (IOException e1) { /* fail silently */ }
}
}
}
private void writeLog(FileWriter fileWriter, String content) throws IOException {
fileWriter.append(content);
}
private File getLogFile(String folderName, String fileName) {
File folder = new File(folderName);
if (!folder.exists()) {
folder.mkdirs();
}
int newFileCount = 0;
File newFile;
File existingFile = null;
newFile = new File(folder, String.format("%s_%s.txt", fileName, newFileCount));
while (newFile.exists()) {
existingFile = newFile;
newFileCount++;
newFile = new File(folder, String.format("%s_%s.txt", fileName, newFileCount));
}
if (existingFile != null) {
if (existingFile.length() >= maxFileSize) {
return newFile;
}
return existingFile;
}
return newFile;
}
}
\ No newline at end of file
package com.mayi.fastdevelop.view;
import android.view.View;
public abstract class OnMultiClickListener implements View.OnClickListener {
// 两次点击按钮之间的点击间隔不能少于500毫秒
private static final int MIN_CLICK_DELAY_TIME = 500;
private static long lastClickTime;
public abstract void onMultiClick(View v);
@Override
public void onClick(View v) {
long curClickTime = System.currentTimeMillis();
if ((curClickTime - lastClickTime) >= MIN_CLICK_DELAY_TIME) {
// 超过点击间隔后再将lastClickTime重置为当前点击时间
lastClickTime = curClickTime;
onMultiClick(v);
}
}
}
<resources> <resources>
<string name="app_name">fastDevelop</string> <string name="app_name">fastDevelop</string>
<string name="save_img_failed_2">图片地址异常,保存图片失败!</string>
<string name="save_img_success">保存图片成功!</string>
<string name="save_img_failed">保存图片失败!</string>
</resources> </resources>
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