提交 7b4c8354 编写于 作者: B Blankj

see 04/20 log

上级 077e24ec
......@@ -165,17 +165,6 @@
android:name=".feature.core.toast.ToastActivity"
android:launchMode="singleTop" />
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.blankj.androidutilcode.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
<!--sub-->
<activity
android:name=".feature.sub.SubUtilActivity"
......
......@@ -61,7 +61,8 @@ public class UtilsApp extends BaseApplication {
.setSingleTagSwitch(true)// 一条日志仅输出一条,默认开,为美化 AS 3.1 的 Logcat
.setConsoleFilter(LogUtils.V)// log 的控制台过滤器,和 logcat 过滤器同理,默认 Verbose
.setFileFilter(LogUtils.V)// log 文件过滤器,和 logcat 过滤器同理,默认 Verbose
.setStackDeep(1);// log 栈深度,默认为 1
.setStackDeep(1)// log 栈深度,默认为 1
.setStackOffset(0);// 设置栈偏移,比如二次封装的话就需要设置,默认为 0
LogUtils.d(config.toString());
}
......
......@@ -89,10 +89,7 @@ public class AppActivity extends BaseBackActivity {
AssertHelper.releaseInstallApk(new AssertHelper.OnReleasedListener() {
@Override
public void onReleased() {
AppUtils.installApp(
Config.TEST_APK_PATH,
"com.blankj.androidutilcode.provider"
);
AppUtils.installApp(Config.TEST_APK_PATH);
}
});
}
......
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path
name="my_external_path"
path="." />
</paths>
\ No newline at end of file
* 18/04/22 新增 LogUtils#,发布 1.13.15 版本
* 18/04/21 新增 AppUtils#relaunchApp、DeviceUtils#getABIs,发布 1.13.15 版本
* 18/04/20 新增 BarUtils#setNavBarColor、BarUtils#getNavBarColor
* 18/04/19 新增 Process#isMainProcess、Process#getCurrentProcessName,发布 1.13.14 版本
......
......@@ -341,33 +341,36 @@ clickBlankArea2HideSoftInput : 点击屏幕空白区域隐藏软键盘
* ### 日志相关 -> [LogUtils.java][log.java] -> [Demo][log.demo]
```
getConfig : 获取 log 配置
Config.setLogSwitch : 设置 log 总开关
Config.setConsoleSwitch : 设置 log 控制台开关
Config.setGlobalTag : 设置 log 全局 tag
Config.setLogHeadSwitch : 设置 log 头部信息开关
Config.setLog2FileSwitch: 设置 log 文件开关
Config.setDir : 设置 log 文件存储目录
Config.setFilePrefix : 设置 log 文件前缀
Config.setBorderSwitch : 设置 log 边框开关
Config.setConsoleFilter : 设置 log 控制台过滤器
Config.setFileFilter : 设置 log 文件过滤器
Config.setStackDeep : 设置 log 栈深度
v : tag 为类名的 Verbose 日志
vTag : 自定义 tag 的 Verbose 日志
d : tag 为类名的 Debug 日志
dTag : 自定义 tag 的 Debug 日志
i : tag 为类名的 Info 日志
iTag : 自定义 tag 的 Info 日志
w : tag 为类名的 Warn 日志
wTag : 自定义 tag 的 Warn 日志
e : tag 为类名的 Error 日志
eTag : 自定义 tag 的 Error 日志
a : tag 为类名的 Assert 日志
aTag : 自定义 tag 的 Assert 日志
file : log 到文件
json : log 字符串之 json
xml : log 字符串之 xml
getConfig : 获取 log 配置
Config.setLogSwitch : 设置 log 总开关
Config.setConsoleSwitch : 设置 log 控制台开关
Config.setGlobalTag : 设置 log 全局 tag
Config.setLogHeadSwitch : 设置 log 头部信息开关
Config.setLog2FileSwitch : 设置 log 文件开关
Config.setDir : 设置 log 文件存储目录
Config.setFilePrefix : 设置 log 文件前缀
Config.setBorderSwitch : 设置 log 边框开关
Config.setSingleTagSwitch: 设置 log 单一 tag 开关(为美化 AS 3.1 的 Logcat)
Config.setConsoleFilter : 设置 log 控制台过滤器
Config.setFileFilter : 设置 log 文件过滤器
Config.setStackDeep : 设置 log 栈深度
Config.setStackOffset : 设置 log 栈偏移
log : 自定义 tag 的 type 日志
v : tag 为类名的 Verbose 日志
vTag : 自定义 tag 的 Verbose 日志
d : tag 为类名的 Debug 日志
dTag : 自定义 tag 的 Debug 日志
i : tag 为类名的 Info 日志
iTag : 自定义 tag 的 Info 日志
w : tag 为类名的 Warn 日志
wTag : 自定义 tag 的 Warn 日志
e : tag 为类名的 Error 日志
eTag : 自定义 tag 的 Error 日志
a : tag 为类名的 Assert 日志
aTag : 自定义 tag 的 Assert 日志
file : log 到文件
json : log 字符串之 json
xml : log 字符串之 xml
```
* ### 网络相关 -> [NetworkUtils.java][network.java] -> [Demo][network.demo]
......
......@@ -350,9 +350,12 @@ Config.setLog2FileSwitch
Config.setDir
Config.setFilePrefix
Config.setBorderSwitch
Config.setSingleTagSwitch
Config.setConsoleFilter
Config.setFileFilter
Config.setStackDeep
Config.setStackOffset
log
v
vTag
d
......
......@@ -8,5 +8,15 @@
android:multiprocess="true"
android:theme="@style/ActivityTranslucent"
android:windowSoftInputMode="stateHidden|stateAlwaysHidden" />
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.utilcode.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
</application>
</manifest>
\ No newline at end of file
......@@ -33,6 +33,29 @@ public final class AppUtils {
throw new UnsupportedOperationException("u can't instantiate me...");
}
/**
* Install the app.
* <p>Target APIs greater than 25 must hold
* {@code <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />}</p>
*
* @param filePath The path of file.
*/
public static void installApp(final String filePath) {
installApp(getFileByPath(filePath));
}
/**
* Install the app.
* <p>Target APIs greater than 25 must hold
* {@code <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />}</p>
*
* @param file The file.
*/
public static void installApp(final File file) {
if (!isFileExists(file)) return;
Utils.getApp().startActivity(IntentUtils.getInstallAppIntent(file, true));
}
/**
* Install the app.
* <p>Target APIs greater than 25 must hold
......@@ -42,6 +65,7 @@ public final class AppUtils {
* @param authority Target APIs greater than 23 must hold the authority of a FileProvider
* defined in a {@code <provider>} element in your app's manifest.
*/
@Deprecated
public static void installApp(final String filePath, final String authority) {
installApp(getFileByPath(filePath), authority);
}
......@@ -55,11 +79,45 @@ public final class AppUtils {
* @param authority Target APIs greater than 23 must hold the authority of a FileProvider
* defined in a {@code <provider>} element in your app's manifest.
*/
@Deprecated
public static void installApp(final File file, final String authority) {
if (!isFileExists(file)) return;
Utils.getApp().startActivity(IntentUtils.getInstallAppIntent(file, authority, true));
}
/**
* Install the app.
* <p>Target APIs greater than 25 must hold
* {@code <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />}</p>
*
* @param activity The activity.
* @param filePath The path of file.
* @param requestCode If &gt;= 0, this code will be returned in
* onActivityResult() when the activity exits.
*/
public static void installApp(final Activity activity,
final String filePath,
final int requestCode) {
installApp(activity, getFileByPath(filePath), requestCode);
}
/**
* Install the app.
* <p>Target APIs greater than 25 must hold
* {@code <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />}</p>
*
* @param activity The activity.
* @param file The file.
* @param requestCode If &gt;= 0, this code will be returned in
* onActivityResult() when the activity exits.
*/
public static void installApp(final Activity activity,
final File file,
final int requestCode) {
if (!isFileExists(file)) return;
activity.startActivityForResult(IntentUtils.getInstallAppIntent(file), requestCode);
}
/**
* Install the app.
* <p>Target APIs greater than 25 must hold
......@@ -72,6 +130,7 @@ public final class AppUtils {
* @param requestCode If &gt;= 0, this code will be returned in
* onActivityResult() when the activity exits.
*/
@Deprecated
public static void installApp(final Activity activity,
final String filePath,
final String authority,
......@@ -91,6 +150,7 @@ public final class AppUtils {
* @param requestCode If &gt;= 0, this code will be returned in
* onActivityResult() when the activity exits.
*/
@Deprecated
public static void installApp(final Activity activity,
final File file,
final String authority,
......
......@@ -80,7 +80,7 @@ public final class CrashUtils {
final String time = FORMAT.format(new Date(System.currentTimeMillis()));
final StringBuilder sb = new StringBuilder();
final String head = "************* Log Head ****************" +
"\nThe time of Crash : " + time +
"\nTime Of Crash : " + time +
"\nDevice Manufacturer: " + Build.MANUFACTURER +
"\nDevice Model : " + Build.MODEL +
"\nAndroid Version : " + Build.VERSION.RELEASE +
......
......@@ -27,6 +27,68 @@ public final class IntentUtils {
throw new UnsupportedOperationException("u can't instantiate me...");
}
/**
* Return the intent of install app.
* <p>Target APIs greater than 25 must hold
* {@code <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />}</p>
*
* @param filePath The path of file.
* @return the intent of install app
*/
public static Intent getInstallAppIntent(final String filePath) {
return getInstallAppIntent(getFileByPath(filePath), false);
}
/**
* Return the intent of install app.
* <p>Target APIs greater than 25 must hold
* {@code <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />}</p>
*
* @param file The file.
* @return the intent of install app
*/
public static Intent getInstallAppIntent(final File file) {
return getInstallAppIntent(file, false);
}
/**
* Return the intent of install app.
* <p>Target APIs greater than 25 must hold
* {@code <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />}</p>
*
* @param filePath The path of file.
* @param isNewTask True to add flag of new task, false otherwise.
* @return the intent of install app
*/
public static Intent getInstallAppIntent(final String filePath, final boolean isNewTask) {
return getInstallAppIntent(getFileByPath(filePath), isNewTask);
}
/**
* Return the intent of install app.
* <p>Target APIs greater than 25 must hold
* {@code <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />}</p>
*
* @param file The file.
* @param isNewTask True to add flag of new task, false otherwise.
* @return the intent of install app
*/
public static Intent getInstallAppIntent(final File file, final boolean isNewTask) {
if (file == null) return null;
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri data;
String type = "application/vnd.android.package-archive";
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
data = Uri.fromFile(file);
} else {
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
String authority = Utils.getApp().getPackageName() + ".utilcode.provider";
data = FileProvider.getUriForFile(Utils.getApp(), authority, file);
}
intent.setDataAndType(data, type);
return getIntent(intent, isNewTask);
}
/**
* Return the intent of install app.
* <p>Target APIs greater than 25 must hold
......@@ -37,8 +99,9 @@ public final class IntentUtils {
* defined in a {@code <provider>} element in your app's manifest.
* @return the intent of install app
*/
@Deprecated
public static Intent getInstallAppIntent(final String filePath, final String authority) {
return getInstallAppIntent(FileUtils.getFileByPath(filePath), authority);
return getInstallAppIntent(getFileByPath(filePath), authority, false);
}
/**
......@@ -51,10 +114,29 @@ public final class IntentUtils {
* defined in a {@code <provider>} element in your app's manifest.
* @return the intent of install app
*/
@Deprecated
public static Intent getInstallAppIntent(final File file, final String authority) {
return getInstallAppIntent(file, authority, false);
}
/**
* Return the intent of install app.
* <p>Target APIs greater than 25 must hold
* {@code <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />}</p>
*
* @param filePath The path of file.
* @param authority Target APIs greater than 23 must hold the authority of a FileProvider
* defined in a {@code <provider>} element in your app's manifest.
* @param isNewTask True to add flag of new task, false otherwise.
* @return the intent of install app
*/
@Deprecated
public static Intent getInstallAppIntent(final String filePath,
final String authority,
final boolean isNewTask) {
return getInstallAppIntent(getFileByPath(filePath), authority, isNewTask);
}
/**
* Return the intent of install app.
* <p>Target APIs greater than 25 must hold
......@@ -66,6 +148,7 @@ public final class IntentUtils {
* @param isNewTask True to add flag of new task, false otherwise.
* @return the intent of install app
*/
@Deprecated
public static Intent getInstallAppIntent(final File file,
final String authority,
final boolean isNewTask) {
......@@ -451,6 +534,20 @@ public final class IntentUtils {
return isNewTask ? intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) : intent;
}
private static File getFileByPath(final String filePath) {
return isSpace(filePath) ? null : new File(filePath);
}
private static boolean isSpace(final String s) {
if (s == null) return true;
for (int i = 0, len = s.length(); i < len; ++i) {
if (!Character.isWhitespace(s.charAt(i))) {
return false;
}
}
return true;
}
// /**
// * 获取选择照片的 Intent
// *
......
......@@ -191,7 +191,7 @@ public final class LogUtils {
log(XML | type, tag, content);
}
private static void log(final int type, final String tag, final Object... contents) {
public static void log(final int type, final String tag, final Object... contents) {
if (!CONFIG.mLogSwitch || (!CONFIG.mLog2ConsoleSwitch && !CONFIG.mLog2FileSwitch)) return;
int type_low = type & 0x0f, type_high = type & 0xf0;
if (type_low < CONFIG.mConsoleFilter && type_low < CONFIG.mFileFilter) return;
......@@ -210,7 +210,17 @@ public final class LogUtils {
tag = CONFIG.mGlobalTag;
} else {
final StackTraceElement[] stackTrace = new Throwable().getStackTrace();
StackTraceElement targetElement = stackTrace[3];
final int stackIndex = 3 + CONFIG.mStackOffset;
if (stackIndex >= stackTrace.length) {
StackTraceElement targetElement = stackTrace[3];
final String fileName = getFileName(targetElement);
if (CONFIG.mTagIsSpace && isSpace(tag)) {
int index = fileName.indexOf('.');// Use proguard may not find '.'.
tag = index == -1 ? fileName : fileName.substring(0, index);
}
return new TagHead(tag, null, ": ");
}
StackTraceElement targetElement = stackTrace[stackIndex];
final String fileName = getFileName(targetElement);
if (CONFIG.mTagIsSpace && isSpace(tag)) {
int index = fileName.indexOf('.');// Use proguard may not find '.'.
......@@ -231,12 +241,15 @@ public final class LogUtils {
return new TagHead(tag, new String[]{head}, fileHead);
} else {
final String[] consoleHead =
new String[Math.min(CONFIG.mStackDeep, stackTrace.length - 3)];
new String[Math.min(
CONFIG.mStackDeep,
stackTrace.length - stackIndex
)];
consoleHead[0] = head;
int spaceLen = tName.length() + 2;
String space = new Formatter().format("%" + spaceLen + "s", "").toString();
for (int i = 1, len = consoleHead.length; i < len; ++i) {
targetElement = stackTrace[i + 3];
targetElement = stackTrace[i + stackIndex];
consoleHead[i] = new Formatter()
.format("%s%s.%s(%s:%d)",
space,
......@@ -502,7 +515,9 @@ public final class LogUtils {
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
String time = filePath.substring(filePath.length() - 9, filePath.length() - 4);
final String head = "************* Log Head ****************" +
"\nDate of Log : " + time +
"\nDevice Manufacturer: " + Build.MANUFACTURER +
"\nDevice Model : " + Build.MODEL +
"\nAndroid Version : " + Build.VERSION.RELEASE +
......@@ -578,6 +593,7 @@ public final class LogUtils {
private int mConsoleFilter = V; // The console's filter of log.
private int mFileFilter = V; // The file's filter of log.
private int mStackDeep = 1; // The stack's deep of log.
private int mStackOffset = 0; // The stack's offset of log.
private Config() {
if (mDefaultDir != null) return;
......@@ -668,6 +684,11 @@ public final class LogUtils {
return this;
}
public Config setStackOffset(@IntRange(from = 0) final int stackOffset) {
mStackOffset = stackOffset;
return this;
}
@Override
public String toString() {
return "switch: " + mLogSwitch
......@@ -681,7 +702,8 @@ public final class LogUtils {
+ LINE_SEP + "singleTag: " + mSingleTagSwitch
+ LINE_SEP + "consoleFilter: " + T[mConsoleFilter - V]
+ LINE_SEP + "fileFilter: " + T[mFileFilter - V]
+ LINE_SEP + "stackDeep: " + mStackDeep;
+ LINE_SEP + "stackDeep: " + mStackDeep
+ LINE_SEP + "mStackOffset: " + mStackOffset;
}
}
......
<?xml version="1.0" encoding="utf-8"?>
<paths>
<root-path
name="root"
path="" />
<files-path
name="files_path"
path="." />
<cache-path
name="cache_path"
path="." />
<external-path
name="external_path"
path="." />
<external-files-path
name="external_files_path"
path="." />
<external-cache-path
name="external_cache_path"
path="." />
</paths>
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册