implementation 'com.google.android.material:material:1.2.0-alpha05'
implementation 'com.jakewharton.threetenabp:threetenabp:1.2.2'
-
-
- implementation files('libs/android-logging-log4j-1.0.3.jar',
- 'libs/ftp4j-1.7.2.jar',
- 'libs/log4j-1.2.17.jar',
- 'libs/okio-2.4.3.jar')
+ implementation files('libs/ICLoger-release.aar')
}
import android.app.Application;
-import com.ic.blood.util.CrashHandler;
import com.ic.blood.util.IcLog;
+import com.ic.iclooger.CrashHandler;
+import com.ic.iclooger.ICLogger;
public class BloodApp extends Application {
IcLog.setLogHead("IcBlood");
CrashHandler crashHandler = CrashHandler.getInstance();
- crashHandler.init(getApplicationContext());
+ crashHandler.init(getApplicationContext(), getString(R.string.program_abnormal));
+ ICLogger.init(getApplicationContext(), "IcBlood");
}
}
+++ /dev/null
-package com.ic.blood.util;
-
-import android.content.Context;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.os.Build;
-import android.os.Environment;
-import android.os.Looper;
-import android.util.Log;
-import android.widget.Toast;
-
-
-import com.ic.blood.R;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.lang.reflect.Field;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-
-/**
- * Created by Administrator on 2017/5/18.
- */
-
-public class CrashHandler implements Thread.UncaughtExceptionHandler {
- public static final String TAG = CrashHandler.class.getName();
-
- // 系统默认的UncaughtException处理类
- private Thread.UncaughtExceptionHandler mDefaultHandler;
- // CrashHandler实例
- private static CrashHandler INSTANCE = new CrashHandler();
- // 程序的Context对象
- private Context mContext;
- // 用来存储设备信息和异常信息
- private Map<String, String> infos = new HashMap<String, String>();
- // 用于格式化日期,作为日志文件名的一部分
- private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS", Locale.getDefault());
- private DateFormat dateFormatDate = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
-
- /**
- * 保证只有一个CrashHandler实例
- */
- private CrashHandler() {
- }
-
- /**
- * 获取CrashHandler实例 ,单例模式
- */
- public static CrashHandler getInstance() {
- return INSTANCE;
- }
-
- /**
- * 初始化
- *
- * @param context
- */
- public void init(Context context) {
- mContext = context;
- // 获取系统默认的UncaughtException处理器
- mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
- // 设置该CrashHandler为程序的默认处理器
- Thread.setDefaultUncaughtExceptionHandler(this);
- }
-
- /**
- * 当UncaughtException发生时会转入该函数来处理
- */
- @Override
- public void uncaughtException(Thread thread, Throwable ex) {
- if (!handleException(ex) && mDefaultHandler != null) {
- // 如果用户没有处理则让系统默认的异常处理器来处理
- mDefaultHandler.uncaughtException(thread, ex);
- } else {
- try {
- Thread.sleep(3000);
- } catch (InterruptedException e) {
-// Log.e(TAG, "error : " + e);
- e.printStackTrace();
- }
- }
-
- // 退出程序
- ex.printStackTrace();
- android.os.Process.killProcess(android.os.Process.myPid());
- System.exit(1);
- }
-
- /**
- * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.
- *
- * @param ex
- * @return true:如果处理了该异常信息;否则返回false.
- */
- private boolean handleException(Throwable ex) {
- if (ex == null) {
- return false;
- }
- // 使用Toast来显示异常信息
- new Thread() {
- @Override
- public void run() {
- Looper.prepare();
- if (mContext != null) {
- Toast.makeText(mContext, R.string.program_abnormal, Toast.LENGTH_LONG)
- .show();
- Looper.loop();
- }
- }
- }.start();
- // 收集设备参数信息
- collectDeviceInfo(mContext);
- // 保存日志文件
- saveCrashInfo2File(ex);
- return true;
- }
-
- /**
- * 收集设备参数信息
- *
- * @param ctx
- */
- public void collectDeviceInfo(Context ctx) {
- infos.clear();
- infos.put("===", " PackageInfo ===");
- try {
- PackageManager pm = ctx.getPackageManager();
- PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), PackageManager.GET_ACTIVITIES);
-
- if (pi != null) {
- String versionName = pi.versionName;
- String versionCode = pi.versionCode + "";
- infos.put("versionName", versionName);
- infos.put("versionCode", versionCode);
- }
- } catch (PackageManager.NameNotFoundException e) {
- Log.e(TAG, "an error occured when collect package info " + e);
- }
-
- infos.put("===", " Build ===");
- Field[] fields = Build.class.getDeclaredFields();
- for (Field field : fields) {
- try {
- field.setAccessible(true);
- infos.put(field.getName(), field.get(null).toString());
- Log.d(TAG, field.getName() + ":" + field.get(null));
- } catch (Exception e) {
- Log.e(TAG, "an error occured when collect crash info," + e);
- }
- }
- }
-
- /**
- * 保存错误信息到文件中
- *
- * @param ex
- * @return 返回文件名称, 便于将文件传送到服务器
- */
- private String saveCrashInfo2File(Throwable ex) {
-
- String time = formatter.format(new Date());
- StringBuilder sb = new StringBuilder();
- sb.append("=== ").append(time).append(" ===\n");
-
- Writer writer = new StringWriter();
- PrintWriter printWriter = new PrintWriter(writer);
- ex.printStackTrace(printWriter);
-// ex.printStackTrace();
- Throwable cause = ex.getCause();
- while (cause != null) {
- cause.printStackTrace(printWriter);
- cause = cause.getCause();
-// cause.printStackTrace();
- }
- printWriter.close();
- String result = writer.toString();
- sb.append(result);
- sb.append("\n");
-
- sb.append("--- DEVICE INFO ---\n");
- for (Map.Entry<String, String> entry : infos.entrySet()) {
- String key = entry.getKey();
- String value = entry.getValue();
- sb.append(key).append("=").append(value).append("\n");
- }
- sb.append("\n\n");
-
- try {
- String fileName = "IcBlood-" + dateFormatDate.format(new Date()) + ".log";
- if (Environment.getExternalStorageState().equals(
- Environment.MEDIA_MOUNTED)) {
- File dir = new File(Environment.getExternalStorageDirectory().getPath(), "Android/ic/crash/IcBlood");
- String path = dir.getPath();
- if (!dir.exists()) {
- dir.mkdirs();
- }
- FileOutputStream fos = new FileOutputStream(new File(path, fileName), true);
- fos.write(sb.toString().getBytes());
- fos.close();
- }
- return fileName;
- } catch (Exception e) {
- Log.e(TAG, "an error occured while writing file...," + e);
- }
- return null;
- }
-}
+++ /dev/null
-package com.ic.blood.util;
-
-import android.content.Context;
-
-import org.apache.log4j.Level;
-import org.apache.log4j.Logger;
-import org.apache.log4j.PatternLayout;
-import org.apache.log4j.RollingFileAppender;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.PrintStream;
-
-import de.mindpipe.android.logging.log4j.LogConfigurator;
-
-import static org.apache.log4j.Logger.getLogger;
-
-
-public class ICLogger {
-
- private static boolean isInitConfig = false;
- private static Context mContext = null;
-
- private static Logger Log = null;
- // private static java.util.logging.Logger originLog= getLogger(ICLogger.class.getSimpleName());
- private static final boolean DEBUG = true; //BuildConfig.DEBUG;
-
- public static void setContext(Context context) {
- mContext = context;
- }
-
- private static String getFunctionName() {
- StackTraceElement[] currentStack = Thread.currentThread().getStackTrace();
- if (currentStack == null) {
- return null;
- } else {
- int stackLen = currentStack.length;
-
- for (int i = 0; i < stackLen; ++i) {
- StackTraceElement stackElement = currentStack[i];
- if (!stackElement.isNativeMethod() &&
- !stackElement.getClassName().equals(Thread.class.getName()) &&
- !stackElement.getClassName().equals(ICLogger.class.getName())) {
- StringBuilder sb = new StringBuilder();
- sb.append("[ ");
- sb.append(Thread.currentThread().getName());
- sb.append(": ");
- sb.append(stackElement.getFileName());
- sb.append(":");
- sb.append(stackElement.getLineNumber());
- sb.append(" ");
- sb.append(stackElement.getMethodName());
- sb.append(" ]");
- return sb.toString();
- }
- }
-
- return null;
- }
- }
-
- /**
- * 初始化与配置Logger Log4j
- * 日志信息格式中符号所代表的含义
- * (1)-X号: X信息输出时左对齐。
- * (2)%p: 输出日志信息优先级,即DEBUG,INFO,WARN,ERROR,FATAL。
- * (3)%d: 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921。
- * (4)%r: 输出自应用启动到输出该log信息耗费的毫秒数。
- * (5)%c: 输出日志信息所属的类目,通常就是所在类的全名。
- * (6)%t: 输出产生该日志事件的线程名。
- * (7)%l: 输出日志事件的发生位置,相当于%C.%M(%F:%L)的组合,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java:10)。
- * (8)%x: 输出和当前线程相关联的NDC(嵌套诊断环境),尤其用到像java servlets这样的多客户多线程的应用中。
- * (9)%%: 输出一个"%"字符。
- * (10)%F: 输出日志消息产生时所在的文件名称。
- * (11)%L: 输出代码中的行号。
- * (12)%m: 输出代码中指定的消息,产生的日志具体信息。
- * (13)%n: 输出一个回车换行符,Windows平台为"\r\n",Unix平台为"\n"输出日志信息换行。
- * 可以在%与模式字符之间加上修饰符来控制其最小宽度、最大宽度、和文本的对齐方式。如:
- * (1)%20c:指定输出category的名称,最小的宽度是20,如果category的名称小于20的话,默认的情况下右对齐。
- * (2)%-20c:指定输出category的名称,最小的宽度是20,如果category的名称小于20的话,"-"号指定左对齐。
- * (3)%.30c:指定输出category的名称,最大的宽度是30,如果category的名称大于30的话,就会将左边多出的字符截掉,但小于30的话也不会有空格。
- * (4)%20.30c:如果category的名称小于20就补空格,并且右对齐,如果其名称长于30字符,就从左边交远销出的字符截掉。
- */
- private static void initConfig() {
- if (!isInitConfig) {
-
- LogConfigurator logConfigurator = new LogConfigurator();
-
- String filename = StorageUtils.getExternalStorageLogDir() + File.separator + "log.txt";
- logConfigurator.setFileName(filename); // 日志存储路径,如果该路径没有会自动创建文件
- logConfigurator.setRootLevel(Level.ALL);
-
- logConfigurator.setLevel("log", Level.ALL);
-// logConfigurator.setFilePattern("%d %-5p [%c{2}]-[%L] %m%n");// 设置文件输出模式
- logConfigurator.setFilePattern("%d %m%n ");// 设置文件输出模式
-// 02-29 16:28:38.195 4629-4658/com.enqualcomm.support E/com.enqualcomm.support.utils.ICLogger:
- logConfigurator.setMaxBackupSize(2); // 设置最大备份数量
- logConfigurator.setMaxFileSize(1024 * 1024 * 20);// 设置最大文件大小 20MB
- logConfigurator.setImmediateFlush(true);// 设置是否立即刷新
- logConfigurator.setUseFileAppender(true); // 设置用户文件输出器
- logConfigurator.setInternalDebugging(false); //控制console是否输出
- logConfigurator.setUseLogCatAppender(true);
- logConfigurator.setLogCatPattern("%m%n");
- logConfigurator.configure();// 设置提交
-
-
-// String logfilelist[]={"Log","GPS","Nmea","APILog","alarmCycle","Battery","LBS"};
-
- //Log 和log目前是同一个配置
- Log = getLogger("log");
- Log.info("init Logger " + Log.getName());
-// Log.addAppender( getRollingFileAppender("log","%d %m%n "));
-// Log.info("init Logger "+Log.getName()+" "+((RollingFileAppender)Log.getAppender("log")).getFile());
-
- isInitConfig = true;
- }
- }
-
- public static void logRAWtoFile(String filename, String msg) {
- Log.info(msg);
- }
-
- public static void logToFile(String filename, String msg) {
- Log.info(msg);
- }
-
- private static RollingFileAppender getRollingFileAppender(String name, String layoutpattern) {
- PatternLayout fileLayout = new PatternLayout(layoutpattern);
- String filename = StorageUtils.getExternalStorageLogDir() + File.separator + name + ".txt";
- RollingFileAppender rollingFileAppender = null;
- try {
- rollingFileAppender = new RollingFileAppender(fileLayout, filename);
- } catch (IOException e) {
- e.printStackTrace();
- ICLogger.e(e.getMessage(), e);
- return null;
- }
- rollingFileAppender.setName(name);
- rollingFileAppender.setMaxBackupIndex(2); //最多3个备份文件
- rollingFileAppender.setMaximumFileSize(10 * 1024 * 1024); //10M 大小
- rollingFileAppender.setImmediateFlush(true);
-
- return rollingFileAppender;
- }
-
- public static void v(String msg) {
- initConfig();
- if (Log != null)
- Log.debug(buildMessage(msg));
- }
-
- public static void v(String msg, Throwable thr) {
- initConfig();
- if (Log != null)
- Log.debug(buildMessage(msg), thr);
- }
-
- public static void d(String msg) {
- initConfig();
- if (Log != null)
- Log.debug(buildMessage(msg));
- }
-
- public static void d(String msg, Throwable thr) {
- initConfig();
- if (Log != null)
- Log.debug(buildMessage(msg), thr);
- }
-
- public static void i(String msg) {
- initConfig();
- if (Log != null)
- Log.info(buildMessage(msg));
- }
-
- public static void i(String msg, Throwable thr) {
- initConfig();
- if (Log != null)
- Log.info(buildMessage(msg), thr);
- }
-
- public static void w(String msg) {
- initConfig();
- if (Log != null)
- Log.warn(buildMessage(msg));
- }
-
- public static void w(String msg, Throwable thr) {
- initConfig();
- if (Log != null)
- Log.warn(buildMessage(msg), thr);
- }
-
- public static void w(Throwable thr) {
- initConfig();
- if (Log != null)
- Log.warn(buildMessage(""), thr);
- }
-
- public static void e(String msg) {
- initConfig();
- if (Log != null)
- Log.error(buildMessage(msg));
- }
-
- public static void e(String msg, Throwable thr) {
- initConfig();
- if (Log != null)
- Log.error(buildMessage(msg), thr);
- }
-
- public static void PrintExceptionStackTrace(Exception e) {
-
- StringBuffer sb = new StringBuffer();
- sb.append(e.getMessage()).append("\n");
- e.printStackTrace(new PrintStream(new OutputStream() {
- @Override
- public void write(int b) throws IOException {
- sb.append((char) b);
- }
- }));
- i(sb.toString());
- }
-
- /**
- * 生成消息
- *
- * @param msg
- * @return
- */
- protected static String buildMessage(String msg) {
- initConfig();
- if (DEBUG && msg != null) {
- String var1 = getFunctionName();
- if (var1 != null) {
- StringBuilder sb = new StringBuilder();
- sb.append(var1);
- sb.append(" - ");
- sb.append(msg);
- return sb.toString();
- } else {
- return "functionName is null";
- }
- } else {
- return "msg is null";
- }
- }
-
- public static void log(String TAG, String msg) {
- if (DEBUG) {
- if (Log != null) Log.debug(TAG + " " + msg);
-
- }
- }
-
- public static void log(String TAG, String funcName, String msg) {
- if (DEBUG) {
- if (Log != null)
- Log.debug(TAG + " [" + funcName + "]" + msg);
-
- }
- }
-
-}
-
+++ /dev/null
-/*******************************************************************************
- * Copyright 2011-2013 Sergey Tarasevich
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *******************************************************************************/
-package com.ic.blood.util;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.os.Build;
-import android.os.Environment;
-import android.os.StatFs;
-import android.util.Log;
-
-import java.io.File;
-import java.io.IOException;
-
-import static android.os.Environment.DIRECTORY_DOCUMENTS;
-import static android.os.Environment.MEDIA_MOUNTED;
-
-/**
- * Provides application storage paths
- *
- * @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
- * @since 1.0.0
- */
-public final class StorageUtils {
-
- private static final String EXTERNAL_STORAGE_PERMISSION = "android.permission.WRITE_EXTERNAL_STORAGE";
- private static final String INDIVIDUAL_DIR_NAME = "uil-images";
- private static final String TAG = "StorageUtils";
-
- private StorageUtils() {
- }
-
- public static String getExternalStorageLogDir() {
- //判断版本,如果是4.4的版本则使用旧的API
- //如果是8.1的版本,使用publish的API
- if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
- File dir;
- Log.d(TAG, "current system version is == > " + Build.VERSION.SDK_INT);
- if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {
- dir = new File(Environment.getExternalStoragePublicDirectory(DIRECTORY_DOCUMENTS), "Android/ic/ICBlood");
- } else {
- dir = new File(Environment.getExternalStorageDirectory().getPath(), "Android/ic/ICBlood");
- }
- String path = dir.getPath();
- if (!dir.exists()) {
- dir.mkdirs();
- }
- return path;
- }
- return "/storage/emulated/0/Android/ic/ICBlood";
- }
-
- /**
- * Returns application cache directory. Cache directory will be created on SD card
- * <i>("/Android/data/[app_package_name]/cache")</i> if card is mounted and app has appropriate permission. Else -
- * Android defines cache directory on device's file system.
- *
- * @param context Application context
- * @return Cache {@link File directory}.<br />
- * <b>NOTE:</b> Can be null in some unpredictable cases (if SD card is unmounted and
- * {@link Context#getCacheDir() Context.getCacheDir()} returns null).
- */
- public static File getCacheDirectory(Context context) {
- return getCacheDirectory(context, true);
- }
-
- /**
- * Returns application cache directory. Cache directory will be created on SD card
- * <i>("/Android/data/[app_package_name]/cache")</i> (if card is mounted and app has appropriate permission) or
- * on device's file system depending incoming parameters.
- *
- * @param context Application context
- * @param preferExternal Whether prefer external location for cache
- * @return Cache {@link File directory}.<br />
- * <b>NOTE:</b> Can be null in some unpredictable cases (if SD card is unmounted and
- * {@link Context#getCacheDir() Context.getCacheDir()} returns null).
- */
- public static File getCacheDirectory(Context context, boolean preferExternal) {
- File appCacheDir = null;
- if (preferExternal && MEDIA_MOUNTED
- .equals(Environment.getExternalStorageState()) && hasExternalStoragePermission(context) && haveFreeSpace()) {
- appCacheDir = getExternalCacheDir(context);
- }
- if (appCacheDir == null) {
- appCacheDir = context.getCacheDir();
- }
- if (appCacheDir == null) {
- String cacheDirPath = "/data/data/" + context.getPackageName() + "/cache/";
- appCacheDir = new File(cacheDirPath);
- }
- return appCacheDir;
- }
-
- /**
- * Returns individual application cache directory (for only image caching from ImageLoader). Cache directory will be
- * created on SD card <i>("/Android/data/[app_package_name]/cache/uil-images")</i> if card is mounted and app has
- * appropriate permission. Else - Android defines cache directory on device's file system.
- *
- * @param context Application context
- * @return Cache {@link File directory}
- */
- public static File getIndividualCacheDirectory(Context context) {
- File cacheDir = getCacheDirectory(context);
- File individualCacheDir = new File(cacheDir, INDIVIDUAL_DIR_NAME);
- if (!individualCacheDir.exists()) {
- if (!individualCacheDir.mkdir()) {
- individualCacheDir = cacheDir;
- }
- }
- return individualCacheDir;
- }
-
- /**
- * Returns specified application cache directory. Cache directory will be created on SD card by defined path if card
- * is mounted and app has appropriate permission. Else - Android defines cache directory on device's file system.
- *
- * @param context Application context
- * @param cacheDir Cache directory path (e.g.: "AppCacheDir", "AppDir/cache/images")
- * @return Cache {@link File directory}
- */
- public static File getOwnCacheDirectory(Context context, String cacheDir) {
- File appCacheDir = null;
- if (MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) && hasExternalStoragePermission(context)) {
- appCacheDir = new File(Environment.getExternalStorageDirectory(), cacheDir);
- }
- if (appCacheDir == null || (!appCacheDir.exists() && !appCacheDir.mkdirs())) {
- appCacheDir = context.getCacheDir();
- }
- return appCacheDir;
- }
-
- private static File getExternalCacheDir(Context context) {
- File dataDir = new File(new File(Environment.getExternalStorageDirectory(), "Android"), "data");
- File appCacheDir = new File(new File(dataDir, context.getPackageName()), "cache");
- if (!appCacheDir.exists()) {
- if (!appCacheDir.mkdirs()) {
- return null;
- }
- try {
- new File(appCacheDir, ".nomedia").createNewFile();
- } catch (IOException e) {
- }
- }
- return appCacheDir;
- }
-
- private static boolean hasExternalStoragePermission(Context context) {
- int perm = context.checkCallingOrSelfPermission(EXTERNAL_STORAGE_PERMISSION);
- return perm == PackageManager.PERMISSION_GRANTED;
- }
-
- private static boolean haveFreeSpace() {
- if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
- StatFs st = new StatFs(Environment.getExternalStorageDirectory().getPath());
- int blockSize = st.getBlockSize();
- long available = st.getAvailableBlocks();
- long availableSize = (blockSize * available);
- if (availableSize < 1024 * 1024 * 10) {// //sd卡空间如果小于10M,就认为sd卡空间不足
- return false;
- }
- return true;
- }
- return false;
- }
-}