1.加入Crash,修改Binder方式,加入广播
authorkfl_614 <kfl_614@163.com>
Mon, 23 Mar 2020 12:45:56 +0000 (20:45 +0800)
committerkfl_614 <kfl_614@163.com>
Mon, 23 Mar 2020 12:45:56 +0000 (20:45 +0800)
app/build.gradle
app/proguard-rules.pro
app/src/main/AndroidManifest.xml
app/src/main/java/com/ic/work/BootBroadcastReceiver.java [new file with mode: 0644]
app/src/main/java/com/ic/work/WorkService.java
app/src/main/java/com/ic/work/WorkServiceApp.java
app/src/main/java/com/ic/work/process/PedProcess.java
app/src/main/java/com/ic/work/utils/CrashHandler.java [new file with mode: 0644]
app/src/main/java/com/ic/work/utils/IcLog.java
app/src/main/res/values/strings.xml
app/version_code.properties [new file with mode: 0644]

index 50ef5d6..b5fb414 100644 (file)
@@ -1,14 +1,23 @@
 apply plugin: 'com.android.application'
 
+static def getL02ApkBaseName() {
+    return "ICL02WorkService"
+}
+
+
 android {
+
+    def currentVersionCode = getVersionCode()
+    def currentVersionName = releaseTime()
+
     compileSdkVersion 29
     buildToolsVersion "29.0.2"
     defaultConfig {
         applicationId "com.ic.work"
         minSdkVersion 19
         targetSdkVersion 29
-        versionCode 1
-        versionName "1.0"
+        versionCode currentVersionCode
+        versionName "${currentVersionName}"
         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
     }
 
@@ -57,6 +66,39 @@ android {
             signingConfig signingConfigs.key
         }
     }
+
+    android.applicationVariants.all { variant ->
+        variant.outputs.all {
+            if (variant.buildType.name == "release") {
+                outputFileName = "${getL02ApkBaseName()}_V${currentVersionCode}_${currentVersionName}_release.apk"
+            } else {
+                outputFileName = "${getL02ApkBaseName()}_V${currentVersionCode}_${currentVersionName}_debug.apk"
+            }
+        }
+    }
+}
+
+def getVersionCode() {
+    def versionCodeFile = file('version_code.properties')
+    if (versionCodeFile.canRead()) {
+        Properties properties = new Properties()
+        properties.load(new FileInputStream(versionCodeFile))
+        def versionCode = properties['VERSION_CODE'].toInteger()//读取version_code.properties文件存放的版本号。
+        def runTasks = gradle.startParameter.taskNames
+        def task = ':app:assembleRelease'
+        if (task in runTasks) {
+            properties['VERSION_CODE'] = (++versionCode).toString()
+            properties.store(versionCodeFile.newWriter(), null)
+        }
+
+        return versionCode
+    } else {
+        throw new GradleException("无法读取version_code.properties文件!")
+    }
+}
+
+def releaseTime() {
+    return new Date().format("yyyyMMddHHmm", TimeZone.getTimeZone("GMT+08:00"))
 }
 
 dependencies {
index f1b4245..9ff9d79 100644 (file)
 # If you keep the line number information, uncomment this to
 # hide the original source file name.
 #-renamesourcefileattribute SourceFile
+-dontoptimize                           # 混合时不使用大小写混合,混合后的类名为小写
+-dontusemixedcaseclassnames             # 混合时不使用大小写混合,混合后的类名为小写
+-dontskipnonpubliclibraryclasses        # 不跳过library中的非public的类
+-dontskipnonpubliclibraryclassmembers   # 不跳过library中的非public的类成员
+-dontpreverify                          # 不做预校验,preverify是proguard的四个步骤之一,Android平台不需要preverify,去掉这一步能够加快混淆速度
+-verbose                                # 在处理时打印冗长的信息
+
+# 保留异常表,以便编译器知道哪些异常可能被抛出
+# 保留InnerClasses,否则外部无法引用内部类
+# 保留Signature,否则无法访问泛型
+-keepattributes Exceptions,SourceFile,LineNumberTable,EnclosingMethod,Signature,*Annotation*,InnerClasses,Deprecated
+
+################################## 需要保留的公共部分 ##################################
+# 保留四大组件,自定义的Application等等这些类不被混淆
+-keep public class * extends android.app.Activity
+-keep public class * extends android.app.Application
+-keep public class * extends android.app.Service
+-keep public class * extends android.content.BroadcastReceiver
+-keep public class * extends android.content.ContentProvider
+-keep public class * extends android.app.backup.BackupAgentHelper
+-keep public class * extends android.preference.Preference
+-keep public class * extends android.view.View
+-keep public class com.android.vending.licensing.ILicensingService
+
+-keep class android.support.** { *; }
+-keep public class * extends android.support.v4.**
+-keep public class * extends android.support.v7.**
+-keep public class * extends android.support.annotation.**
+-keep public class * extends android.app.Fragment
+-keep class com.google.** { *; }
+
+# 保留R下面的资源
+-keep class **.R$* {*;}
+-keepclassmembers class **.R$* {
+    public static <fields>;
+}
+
+# 保留本地native方法不被混淆
+-keepclasseswithmembernames class * {
+    native <methods>;
+}
+
+# 保留在Activity中的方法参数是view的方法,
+# 这样以来我们在layout中写的onClick就不会被影响
+-keepclassmembers class * extends android.app.Activity{
+    public void *(android.view.View);
+}
+
+# 保留我们自定义控件(继承自View)不被混淆
+-keep public class * extends android.view.View{
+    *** get*();
+    void set*(***);
+    public <init>(android.content.Context);
+    public <init>(android.content.Context, android.util.AttributeSet);
+    public <init>(android.content.Context, android.util.AttributeSet, int);
+}
+
+-keepclasseswithmembernames class * {
+    public <init>(android.content.Context, android.util.AttributeSet);
+}
+
+-keepclasseswithmembernames class * {
+    public <init>(android.content.Context, android.util.AttributeSet, int);
+}
+
+# 保留枚举类不被混淆
+-keepclassmembers enum * {
+    public static **[] values();
+    public static ** valueOf(java.lang.String);
+}
+
+-keep public interface com.ic.aidl.blood.IBloodAidlInterface
+-keep public abstract interface com.ic.aidl.blood.IBloodAidlInterface{
+public protected <methods>;
+}
+
+-keep public interface com.ic.aidl.blood.IBloodRemoteService
+-keep public abstract interface com.ic.aidl.blood.IBloodRemoteService{
+public protected <methods>;
+}
+
+-keep public interface com.ic.aidl.ped.IPedAidlInterface
+-keep public abstract interface com.ic.aidl.ped.IPedAidlInterface{
+public protected <methods>;
+}
+
+-keep public interface com.ic.aidl.ped.IPedRemoteService
+-keep public abstract interface com.ic.aidl.ped.IPedRemoteService{
+public protected <methods>;
+}
+
+-keep public interface com.ic.aidl.weather.IWeatherAidlInterface
+-keep public abstract interface com.ic.aidl.weather.IWeatherAidlInterface{
+public protected <methods>;
+}
+
+-keep public interface com.ic.aidl.weather.IWeatherRemoteService
+-keep public abstract interface com.ic.weather.ped.IWeatherRemoteService{
+public protected <methods>;
+}
+
+# 保留Parcelable序列化类不被混淆
+-keep class * implements android.os.Parcelable {
+  public static final android.os.Parcelable$Creator *;
+}
+
+# 保留Serializable序列化的类不被混淆
+-keepclassmembers class * implements java.io.Serializable {
+    static final long serialVersionUID;
+    private static final java.io.ObjectStreamField[] serialPersistentFields;
+    !static !transient <fields>;
+    !private <fields>;
+    !private <methods>;
+    private void writeObject(java.io.ObjectOutputStream);
+    private void readObject(java.io.ObjectInputStream);
+    java.lang.Object writeReplace();
+    java.lang.Object readResolve();
+}
+
+# 对于带有回调函数的onXXEvent、**On*Listener的,不能被混淆
+-keepclassmembers class * {
+    void *(**On*Event);
+    void *(**On*Listener);
+}
+
+
+-keep class com.sun.jna.** { *; }
+-dontwarn com.sun.jna.**
+
+-keep public class com.android.support.a
+-keep public class com.android.support.b
+-keep public class rx.internal.util
+
+#event bus
+-keepattributes *Annotation*
+-keepclassmembers class * {
+    @org.greenrobot.eventbus.Subscribe <methods>;
+}
+-keep enum org.greenrobot.eventbus.ThreadMode { *; }
+
+# And if you use AsyncExecutor:
+-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
+    <init>(java.lang.Throwable);
+}
\ No newline at end of file
index c017541..53673ad 100644 (file)
             android:name="com.amap.api.v2.apikey"
             android:value="80c129088f7bbe251a846d645ee8360a" />
 
-
         <service
             android:name=".WorkService"
-            android:process=":remote"
             android:enabled="true"
-            android:exported="true">
+            android:exported="true"
+            android:process=":remote">
             <intent-filter>
                 <action android:name="com.ic.action.WORK_SERVICE" />
             </intent-filter>
@@ -60,6 +59,7 @@
         </activity>
 
         <service android:name="com.amap.api.location.APSService" />
+
     </application>
 
 </manifest>
\ No newline at end of file
diff --git a/app/src/main/java/com/ic/work/BootBroadcastReceiver.java b/app/src/main/java/com/ic/work/BootBroadcastReceiver.java
new file mode 100644 (file)
index 0000000..ad136df
--- /dev/null
@@ -0,0 +1,16 @@
+package com.ic.work;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+import com.ic.work.utils.ServiceUtil;
+
+public class BootBroadcastReceiver extends BroadcastReceiver {
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        ServiceUtil.startServiceUtil(context.getApplicationContext(),
+                "com.ic.action.WORK_SERVICE",
+                context.getPackageName());
+    }
+}
index 1a1fdb4..dd9e582 100644 (file)
@@ -1,8 +1,12 @@
 package com.ic.work;
 
 import android.app.Service;
+import android.content.BroadcastReceiver;
+import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.os.IBinder;
+import android.text.TextUtils;
 
 import com.ic.work.event.BloodCheckResultEvent;
 import com.ic.work.event.BloodCheckTipsEvent;
@@ -27,6 +31,11 @@ public class WorkService extends Service {
 
     private static final String TAG = "WorkService";
 
+    private static final String HEART_ACTION = "com.ic.action.BLOOD_HEART";
+    private static final String PED_ACTION = "com.ic.action.PED_COUNT";
+
+    private static final String GET_PED_ACTION = "com.ic.action.GET_PED_COUNT";
+
     private WeatherProcess weatherProcess;
     private BloodProcess bloodProcess;
     private PedProcess pedProcess;
@@ -38,16 +47,15 @@ public class WorkService extends Service {
     @Override
     public IBinder onBind(Intent intent) {
         if (intent != null) {
-            int reqType = intent.getIntExtra("REQ_TYPE", -1);
-            IcLog.i(TAG,"Bind reqType"+reqType);
-            switch (reqType) {
-                case 101:
+            IcLog.i(TAG,intent.getPackage());
+            switch (intent.getPackage()) {
+                case "com.ic.weather":
                     //天气
                     return weatherProcess.getWeatherBinder();
-                case 102:
+                case "com.ic.blood":
                     //血压
                     return bloodProcess.getBloodBinder();
-                case 103:
+                case "com.ic.hardware":
                     //计步
                     return pedProcess.getPedBinder();
                 default:
@@ -76,28 +84,32 @@ public class WorkService extends Service {
 
         mWeatherHelper.startLocation(getApplicationContext());
 
+        registerBroadcast();
+
         IcLog.i(TAG, "work service is start");
     }
 
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
-        IcLog.i(TAG,"WorkService onStartCommand");
+        IcLog.i(TAG, "WorkService onStartCommand");
         return super.onStartCommand(intent, flags, startId);
     }
 
     @Override
     public void onDestroy() {
         super.onDestroy();
-        IcLog.i(TAG,"WorkService onDestroy");
+        IcLog.i(TAG, "WorkService onDestroy");
         bloodProcess = null;
 
         mApp = null;
         EventBus.getDefault().unregister(this);
+
+        unregisterReceiver(mIntentReceiver);
     }
 
     @Subscribe(threadMode = ThreadMode.MAIN)
     public void onMessageEvent(LocationResultEvent event) {
-        mWeatherHelper.queryWeatherServerInfo(mApp.getWeatherRepository(),event.getmCity());
+        mWeatherHelper.queryWeatherServerInfo(mApp.getWeatherRepository(), event.getmCity());
     }
 
     @Subscribe(threadMode = ThreadMode.MAIN)
@@ -122,19 +134,19 @@ public class WorkService extends Service {
     @Subscribe(threadMode = ThreadMode.MAIN)
     public void onMessageEvent(PedSettingEvent event) {
 
-        if(pedProcess != null){
+        if (pedProcess != null) {
             return;
         }
 
-        switch (event.getType()){
+        switch (event.getType()) {
             case 1:
                 int height = event.getValue();
-                SPUtils.setPedHeightSP(getApplicationContext(),height);
+                SPUtils.setPedHeightSP(getApplicationContext(), height);
                 pedProcess.updateHeight(height);
                 break;
             case 2:
                 int weight = event.getValue();
-                SPUtils.setPedWighttSP(getApplicationContext(),weight);
+                SPUtils.setPedWighttSP(getApplicationContext(), weight);
                 pedProcess.updateWeight(weight);
                 break;
         }
@@ -142,14 +154,14 @@ public class WorkService extends Service {
 
     @Subscribe(threadMode = ThreadMode.MAIN)
     public void onMessageEvent(PedRecordResultEvent event) {
-        if(pedProcess != null){
+        if (pedProcess != null) {
             pedProcess.sendPedRecord(event.getRecordList());
         }
     }
 
     @Subscribe(threadMode = ThreadMode.MAIN)
     public void onMessageEvent(PedCountEvent event) {
-        if(pedProcess != null){
+        if (pedProcess != null) {
             pedProcess.sendPedCount(event.getPedCount());
         }
 
@@ -159,29 +171,52 @@ public class WorkService extends Service {
 
     @Subscribe(threadMode = ThreadMode.MAIN)
     public void onMessageEvent(WeatherResultEvent event) {
-        if(weatherProcess != null){
+        if (weatherProcess != null) {
             weatherProcess.sendCurrWeather(event.getParcelable());
         }
     }
+
     @Subscribe(threadMode = ThreadMode.MAIN)
     public void onMessageEvent(WeatherAgainEvent event) {
-        if(mWeatherHelper != null){
+        if (mWeatherHelper != null) {
             mWeatherHelper.startLocation(getApplicationContext());
         }
     }
 
-    private void sendPedCountBroadcast(int count){
+    public void registerBroadcast() {
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(GET_PED_ACTION);
+        registerReceiver(mIntentReceiver, filter);
+    }
+
+    private void sendPedCountBroadcast(int count) {
         Intent pedIntent = new Intent();
-        pedIntent.setAction("com.ic.action.PED_COUNT");
-        pedIntent.putExtra("PED_COUNT",count);
+        pedIntent.setAction(PED_ACTION);
+        pedIntent.putExtra("PED_COUNT", count);
         sendBroadcast(pedIntent);
     }
 
-    private void sendHeartBroadcast(int count){
+    private void sendHeartBroadcast(int count) {
         Intent pedIntent = new Intent();
-        pedIntent.setAction("com.ic.action.BLOOD_HEART");
-        pedIntent.putExtra("BLOOD_HEART",count);
+        pedIntent.setAction(HEART_ACTION);
+        pedIntent.putExtra("BLOOD_HEART", count);
         sendBroadcast(pedIntent);
     }
 
+    private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (intent != null) {
+                String acyion = intent.getAction();
+                if (TextUtils.isEmpty(acyion)) {
+                    return;
+                }
+                switch (acyion) {
+                    case GET_PED_ACTION:
+                        pedProcess.startPedRunGetCount();
+                        break;
+                }
+            }
+        }
+    };
 }
index 2c9af47..9930cf9 100644 (file)
@@ -5,6 +5,7 @@ import android.app.Application;
 import com.ic.work.db.AppDatabase;
 import com.ic.work.db.PedInjection;
 import com.ic.work.db.WeatherInjection;
+import com.ic.work.utils.CrashHandler;
 import com.ic.work.utils.IcLog;
 import com.jakewharton.threetenabp.AndroidThreeTen;
 
@@ -16,6 +17,9 @@ public class WorkServiceApp extends Application {
         IcLog.setLogHead("IcWorkService");
 
         AndroidThreeTen.init(this);
+
+        CrashHandler crashHandler = CrashHandler.getInstance();
+        crashHandler.init(getApplicationContext());
     }
 
     public AppDatabase getDatabase() {
index 6c3f817..77738b2 100644 (file)
@@ -32,6 +32,10 @@ public class PedProcess {
         mRecordRun = new PedRecordRunnable(app.getRepository());
     }
 
+    public void startPedRunGetCount(){
+        ThreadPoolManager.getInstance().execute(mPedRun);
+    }
+
     public IBinder getPedBinder() {
         return pedBinder;
     }
@@ -53,7 +57,7 @@ public class PedProcess {
 
         @Override
         public void queryPedCount() throws RemoteException {
-            ThreadPoolManager.getInstance().execute(mPedRun);
+            startPedRunGetCount();
         }
 
         @Override
diff --git a/app/src/main/java/com/ic/work/utils/CrashHandler.java b/app/src/main/java/com/ic/work/utils/CrashHandler.java
new file mode 100644 (file)
index 0000000..8a779b6
--- /dev/null
@@ -0,0 +1,213 @@
+package com.ic.work.utils;
+
+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.work.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 = "IcWorkService-" + dateFormatDate.format(new Date()) + ".log";
+            if (Environment.getExternalStorageState().equals(
+                    Environment.MEDIA_MOUNTED)) {
+                File dir = new File(Environment.getExternalStorageDirectory().getPath(), "Android/ic/crash/IcWorkService");
+                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;
+    }
+}
index a7bb72c..ce8d0b9 100644 (file)
@@ -12,7 +12,7 @@ import com.ic.work.BuildConfig;
 public class IcLog {
 
     private static final String DOT = ".";
-    private static boolean isDebug = BuildConfig.DEBUG;
+    private static boolean isDebug = true;
     private static String tagHead = "";
 
     public static void v(String tag, String msg) {
index 95308ff..00b1727 100644 (file)
@@ -1,3 +1,5 @@
 <resources>
     <string name="app_name">IcWorkService</string>
+
+    <string name="program_abnormal">很抱歉,程序出现异常,即将退出</string>
 </resources>
diff --git a/app/version_code.properties b/app/version_code.properties
new file mode 100644 (file)
index 0000000..f9789d8
--- /dev/null
@@ -0,0 +1,2 @@
+#Mon Mar 23 18:58:17 CST 2020
+VERSION_CODE=11