From: kfl_614 Date: Sat, 9 Jan 2021 07:29:25 +0000 (+0800) Subject: add log4j to upload logs. X-Git-Url: http://git.snicker.com.cn/Users/apple/Desktop/static/gitweb.js?a=commitdiff_plain;h=076ec45817684544d33a17ca36ec782d8aeeee34;p=icworkservice.git add log4j to upload logs. --- diff --git a/app/IcL02WorkService/release/IcL02WorkService_V57_202101061638_release.apk b/app/IcL02WorkService/release/IcL02WorkService_V57_202101061638_release.apk deleted file mode 100644 index 064c7b2..0000000 Binary files a/app/IcL02WorkService/release/IcL02WorkService_V57_202101061638_release.apk and /dev/null differ diff --git a/app/IcL02WorkService/release/IcL02WorkService_V57_202101091515_release.apk b/app/IcL02WorkService/release/IcL02WorkService_V57_202101091515_release.apk new file mode 100644 index 0000000..4a571cb Binary files /dev/null and b/app/IcL02WorkService/release/IcL02WorkService_V57_202101091515_release.apk differ diff --git a/app/IcL02WorkService/release/output.json b/app/IcL02WorkService/release/output.json index eb8754e..6888c7a 100644 --- a/app/IcL02WorkService/release/output.json +++ b/app/IcL02WorkService/release/output.json @@ -1 +1 @@ -[{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"1.1","enabled":true,"outputFile":"IcL02WorkService_V57_202101061638_release.apk","fullName":"IcL02WorkServiceRelease","baseName":"IcL02WorkService-release"},"path":"IcL02WorkService_V57_202101061638_release.apk","properties":{}}] \ No newline at end of file +[{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"1.1","enabled":true,"outputFile":"IcL02WorkService_V57_202101091515_release.apk","fullName":"IcL02WorkServiceRelease","baseName":"IcL02WorkService-release"},"path":"IcL02WorkService_V57_202101091515_release.apk","properties":{}}] \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index cac408f..382d8d2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -62,9 +62,9 @@ android { } } - productFlavors{ + productFlavors { - IcA9WorkService{ + IcA9WorkService { flavorDimensions "IcA9WorkService" versionCode 1 versionName "5.0" @@ -72,14 +72,14 @@ android { } - IcAkWorkService{ + IcAkWorkService { flavorDimensions "IcAkWorkService" versionCode 1 versionName "1.0" buildConfigField "int", "productType", "1001" } - IcL02WorkService{ + IcL02WorkService { flavorDimensions "IcAkWorkService" versionCode 1 versionName "1.1" @@ -133,12 +133,15 @@ dependencies { implementation 'org.greenrobot:eventbus:3.2.0' - implementation 'com.squareup.okio:okio:2.4.3' - implementation 'com.alibaba:fastjson:1.2.61' implementation "androidx.room:room-runtime:2.2.5" annotationProcessor "androidx.room:room-compiler:2.2.5" 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') } diff --git a/app/libs/android-logging-log4j-1.0.3.jar b/app/libs/android-logging-log4j-1.0.3.jar new file mode 100644 index 0000000..7d4146f Binary files /dev/null and b/app/libs/android-logging-log4j-1.0.3.jar differ diff --git a/app/libs/ftp4j-1.7.2.jar b/app/libs/ftp4j-1.7.2.jar new file mode 100644 index 0000000..fca26ec Binary files /dev/null and b/app/libs/ftp4j-1.7.2.jar differ diff --git a/app/libs/log4j-1.2.17.jar b/app/libs/log4j-1.2.17.jar new file mode 100644 index 0000000..068867e Binary files /dev/null and b/app/libs/log4j-1.2.17.jar differ diff --git a/app/libs/okio-2.4.3.jar b/app/libs/okio-2.4.3.jar new file mode 100644 index 0000000..6289cf6 Binary files /dev/null and b/app/libs/okio-2.4.3.jar differ diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index ca4936c..ab3b35f 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -208,4 +208,24 @@ public protected ; (java.lang.Throwable); } + +-keep class com.facebook.** { *; } +-keep class com.mediatek.** { *; } +-keep class org.apache.** { *; } +-keep class okio.Okio.** { *; } +-keep class java.nio.** { *; } +-keep class com.android.** { *; } +-keep class android.** { *; } +-keep class android.ddm.** { *; } +-keep class com.alibaba.fastjson.** { *; } +-keep class com.eqc.watch.launcher.WatchApplication { *; } +#-keep class com.enqualcomm.support.EqcAlgorithmNative { *; } +-dontwarn com.facebook.** +-dontwarn com.mediatek.** +-dontwarn java.nio.** +-dontwarn com.alibaba.fastjson.** +-dontwarn android.** +-dontwarn com.android.** +-dontwarn rx.internal.** + -keep class com.mapbox.mapboxsdk.**{ *; } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index cecec34..53a38da 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -25,6 +25,7 @@ + " + taskEvent); //判断队列里是否有同样的任务,如果有的话不用发了, if (mTaskList.contains(taskEvent)) { @@ -263,7 +259,6 @@ public class SensorDataService extends Service implements TemperatureHelper.Temp } return; } - if (taskEvent.equals(currentTask)) { IcLog.d(TAG, "current task running..."); //通知正在执行 @@ -272,9 +267,7 @@ public class SensorDataService extends Service implements TemperatureHelper.Temp } return; } - - IcLog.d(TAG, "is running =-== > " + isRunning + - " queue size == > " + mTaskList.size()); + IcLog.d(TAG, "is running =-== > " + isRunning + " queue size == > " + mTaskList.size()); //判断是否繁忙 //如果没有的话则发送一下 if (!isRunning && mTaskList.size() == 0) { diff --git a/app/src/main/java/com/ic/work/utils/ICLogger.java b/app/src/main/java/com/ic/work/utils/ICLogger.java new file mode 100644 index 0000000..1bbfcce --- /dev/null +++ b/app/src/main/java/com/ic/work/utils/ICLogger.java @@ -0,0 +1,324 @@ +package com.ic.work.utils; + +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 Logger GPS = null; + private static Logger Nmea = null; + private static Logger APILog = null; + private static Logger alarmCycle = null; + private static Logger Battery = null; + private static Logger LBS = 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()); + + GPS = getLogger("GPS"); + GPS.addAppender(getRollingFileAppender("GPS", "%d %m%n ")); + GPS.info("init Logger " + GPS.getName() + " " + ((RollingFileAppender) GPS.getAppender("GPS")).getFile()); + + Nmea = getLogger("Nmea"); + Nmea.addAppender(getRollingFileAppender("Nmea", "%m%n")); + Nmea.info("init Logger " + Nmea.getName() + " " + ((RollingFileAppender) Nmea.getAppender("Nmea")).getFile()); + + APILog = getLogger("APILog"); + APILog.addAppender(getRollingFileAppender("APILog", "%d %m%n ")); + APILog.info("init Logger " + APILog.getName() + " " + ((RollingFileAppender) APILog.getAppender("APILog")).getFile()); + + alarmCycle = getLogger("alarmCycle"); + alarmCycle.addAppender(getRollingFileAppender("alarmCycle", "%d %m%n ")); + alarmCycle.info("init Logger " + alarmCycle.getName() + " " + ((RollingFileAppender) alarmCycle.getAppender("alarmCycle")).getFile()); + + Battery = getLogger("Battery"); + Battery.addAppender(getRollingFileAppender("Battery", "%d %m%n ")); + Battery.info("init Logger " + Battery.getName() + " " + ((RollingFileAppender) Battery.getAppender("Battery")).getFile()); + + + LBS = getLogger("LBS"); + LBS.addAppender(getRollingFileAppender("LBS", "%d %m%n ")); + LBS.info("init Logger " + LBS.getName() + " " + ((RollingFileAppender) LBS.getAppender("LBS")).getFile()); + isInitConfig = true; + } + } + + public static void logRAWtoFile(String filename, String msg) { + if (filename.equals("Nmea")) { + Nmea.info(msg); + } else if (filename.equals("LBS")) { + LBS.info(msg); + } else if (filename.equals("GPS")) { + GPS.info(msg); + } else if (filename.equals("APILog")) { + APILog.info(msg); + } else if (filename.equals("alarmCycle")) { + alarmCycle.info(msg); + } else if (filename.equals("Battery")) { + Battery.info(msg); + } else { + Log.info(msg); + } + } + + public static void logToFile(String filename, String msg) { + if (filename.equals("Nmea")) { + Nmea.info(msg); + } else if (filename.equals("LBS")) { + LBS.info(msg); + } else if (filename.equals("GPS")) { + GPS.info(msg); + } else if (filename.equals("APILog")) { + APILog.info(msg); + } else if (filename.equals("alarmCycle")) { + alarmCycle.info(msg); + } else if (filename.equals("Battery")) { + Battery.info(msg); + } else { + 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); + + } + } + +} + diff --git a/app/src/main/java/com/ic/work/utils/IcLog.java b/app/src/main/java/com/ic/work/utils/IcLog.java index 0c11184..23ef366 100644 --- a/app/src/main/java/com/ic/work/utils/IcLog.java +++ b/app/src/main/java/com/ic/work/utils/IcLog.java @@ -1,7 +1,5 @@ package com.ic.work.utils; -import android.util.Log; - /** * @author RyanLee * @date 2018/2/2 @@ -14,33 +12,23 @@ public class IcLog { private static String tagHead = ""; public static void v(String tag, String msg) { - if (isDebug) { - Log.v(mergeHeadTag(tag), msg); - } + ICLogger.v(tag + " : " + msg); } public static void d(String tag, String msg) { - if (isDebug) { - Log.d(mergeHeadTag(tag), msg); - } + ICLogger.d(tag + " : " + msg); } public static void i(String tag, String msg) { - if (isDebug) { - Log.i(mergeHeadTag(tag), msg); - } + ICLogger.i(tag + " : " + msg); } public static void w(String tag, String msg) { - if (isDebug) { - Log.w(mergeHeadTag(tag), msg); - } + ICLogger.w(tag + " : " + msg); } public static void e(String tag, String msg, Throwable e) { - if (isDebug) { - Log.e(mergeHeadTag(tag), msg, e); - } + ICLogger.e(tag + " : " + msg); } diff --git a/app/src/main/java/com/ic/work/utils/StorageUtils.java b/app/src/main/java/com/ic/work/utils/StorageUtils.java new file mode 100644 index 0000000..ae72a50 --- /dev/null +++ b/app/src/main/java/com/ic/work/utils/StorageUtils.java @@ -0,0 +1,166 @@ +/******************************************************************************* + * 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.work.utils; + +import android.content.Context; +import android.content.pm.PackageManager; +import android.os.Environment; +import android.os.StatFs; + +import java.io.File; +import java.io.IOException; + +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 StorageUtils() { + } + + public static String getExternalStorageLogDir() { + + if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + File dir = new File(Environment.getExternalStorageDirectory().getPath(), "Android/ic/icprotocol"); + String path = dir.getPath(); + if (!dir.exists()) { + dir.mkdirs(); + } + return path; + } + return "/storage/emulated/0/Android/ic/icprotocol"; + } + /** + * Returns application cache directory. Cache directory will be created on SD card + * ("/Android/data/[app_package_name]/cache") 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}.
+ * NOTE: 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 + * ("/Android/data/[app_package_name]/cache") (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}.
+ * NOTE: 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 ("/Android/data/[app_package_name]/cache/uil-images") 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; + } +}