下面列出了android.util.Log#DEBUG 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* 打印MAp,debug级别日志
*/
public static void m(String tag, Map map) {
if (LOG_LEVEL <= Log.DEBUG) {
Set set = map.entrySet();
if (set.size() < 1) {
d(tag, "[]");
return;
}
int i = 0;
String[] s = new String[set.size()];
for (Object aSet : set) {
Map.Entry entry = (Map.Entry) aSet;
s[i] = entry.getKey() + " = " + entry.getValue() + ",\n";
i++;
}
println(Log.DEBUG, tag, Arrays.toString(s));
}
}
private static char convertLogLevelToChar(int logLevel) {
switch (logLevel) {
case Log.DEBUG:
return 'D';
case Log.ERROR:
return 'E';
case Log.INFO:
return 'I';
case Log.VERBOSE:
return 'V';
case Log.WARN:
return 'W';
case LogLineAdapterUtil.LOG_WTF:
return 'F';
}
return ' ';
}
@Override
protected void log(int priority, @Nullable String tag, @NotNull String message, @Nullable Throwable t) {
// Workaround for devices that doesn't show lower priority logs
if(Build.MANUFACTURER == null) {
return;
}
if (Build.MANUFACTURER.equals("HUAWEI") || Build.MANUFACTURER.equals("samsung")) {
if (priority == Log.VERBOSE || priority == Log.DEBUG || priority == Log.INFO)
priority = Log.ERROR;
}
if (priority >= Log.WARN) {
if(message.length() < MAX_LOG_LENGTH) {
super.log(priority, tag, message, t);
return;
}
splitLogMessage(priority, tag, message, t);
} else {
if(message.length() < MAX_LOG_LENGTH) {
super.log(priority, tag, message, t);
return;
}
splitLogMessage(priority, tag, message, t);
}
}
/**
* log Send a logLevel log message and log the exception, then collect the log entry.
*
* @param aLogLevel Used to identify log level
* @param aTag Used to identify the source of a log message. It usually identifies the class or activity
* where the log call occurs.
* @param aMessage The message you would like logged.
* @param aThrowable An exception to log
*/
public static void log(int aLogLevel, String aTag, String aMessage, Throwable aThrowable) {
if (isLoggable(aLogLevel)) {
switch (aLogLevel) {
case Log.VERBOSE:
Log.v(TAG, aTag + ": " + aMessage, aThrowable);
break;
case Log.DEBUG:
Log.d(TAG, aTag + ": " + aMessage, aThrowable);
break;
case Log.INFO:
Log.i(TAG, aTag + ": " + aMessage, aThrowable);
break;
case Log.WARN:
Log.w(TAG, aTag + ": " + aMessage, aThrowable);
break;
case Log.ERROR:
Log.e(TAG, aTag + ": " + aMessage, aThrowable);
break;
default:
Log.e(TAG, aTag + ": " + aMessage, aThrowable);
}
}
}
/**
* 打印JSON,debug级别日志
*/
public static void j(String tag, String jsonStr) {
if (LOG_LEVEL <= Log.DEBUG) {
String message;
try {
if (jsonStr.startsWith("{")) {
JSONObject jsonObject = new JSONObject(jsonStr);
message = jsonObject.toString(4); //这个是核心方法
} else if (jsonStr.startsWith("[")) {
JSONArray jsonArray = new JSONArray(jsonStr);
message = jsonArray.toString(4);
} else {
message = jsonStr;
}
} catch (JSONException e) {
message = jsonStr;
}
println(Log.DEBUG, tag, message);
}
}
/**
* 判断日志级别是否允许输出
* @param logLevel 日志级别
* @param logType 日志类型
* @return {@code true} yes, {@code false} no
*/
private boolean checkLogLevel(final LogLevel logLevel, final int logType) {
switch (logLevel) {
case INFO: // 正常级别 i
if (logType != Log.VERBOSE && logType != Log.DEBUG) {
return true;
}
break;
case WARN: // 警告级别 w
if (logType != Log.VERBOSE && logType != Log.DEBUG && logType != Log.INFO) {
return true;
}
break;
case ERROR: // 异常级别 e, wtf
if (logType == Log.ERROR || logType == Log.ASSERT) {
return true;
}
break;
default:
break;
}
return false;
}
@Override
protected void log(int priority, String tag, String message, Throwable t) {
if (priority == Log.VERBOSE || priority == Log.DEBUG || priority == Log.INFO) {
return;
}
Crashlytics.setInt(CRASHLYTICS_KEY_PRIORITY, priority);
Crashlytics.setString(CRASHLYTICS_KEY_TAG, tag);
Crashlytics.setString(CRASHLYTICS_KEY_MESSAGE, message);
if (t == null) {
Crashlytics.logException(new Exception(message));
} else {
Crashlytics.logException(t);
}
}
private static int convertCharToLogLevel(char logLevelChar) {
switch (logLevelChar) {
case 'D':
return Log.DEBUG;
case 'E':
return Log.ERROR;
case 'I':
return Log.INFO;
case 'V':
return Log.VERBOSE;
case 'W':
return Log.WARN;
case 'F':
return LogLineAdapterUtil.LOG_WTF; // 'F' actually stands for 'WTF', which is a real Android log level in 2.2
}
return -1;
}
@Override
protected void log(int type, String tag, String message) {
switch (type) {
case Log.VERBOSE:
Log.v(tag, message);
break;
case Log.INFO:
Log.i(tag, message);
break;
case Log.DEBUG:
Log.d(tag, message);
break;
case Log.WARN:
Log.w(tag, message);
break;
case Log.ERROR:
Log.e(tag, message);
break;
case Log.ASSERT:
Log.wtf(tag, message);
break;
default:
break;
}
}
public static String logPriorityToString(int priority) {
switch (priority) {
case Log.ASSERT:
return LOG_PRIORITY_NAME_ASSERT;
case Log.DEBUG:
return LOG_PRIORITY_NAME_DEBUG;
case Log.ERROR:
return LOG_PRIORITY_NAME_ERROR;
case Log.INFO:
return LOG_PRIORITY_NAME_INFO;
case Log.VERBOSE:
return LOG_PRIORITY_NAME_VERBOSE;
case Log.WARN:
return LOG_PRIORITY_NAME_WARN;
default:
return LOG_PRIORITY_NAME_UNKNOWN;
}
}
@Override
protected void log(int priority, String tag, String message, Throwable throwable) {
if (priority == Log.VERBOSE || priority == Log.DEBUG) {
return;
}
FakeCrashLibrary.log(priority, tag, message);
if (throwable != null) {
if (priority == Log.ERROR) {
FakeCrashLibrary.logError(throwable);
} else if (priority == Log.WARN) {
FakeCrashLibrary.logWarning(throwable);
}
}
}
@Override
protected void log(int priority, String tag, String message, Throwable t) {
if (priority == Log.VERBOSE || priority == Log.DEBUG) {
return;
}
//TODO Log to crash reporting
if (t != null) {
if (priority == Log.ERROR) {
//TODO Log throwable as error to crash reporting
} else if (priority == Log.WARN) {
//TODO Log throwable as warning to crash reporting
}
}
}
@Override
protected void log(int priority, @Nullable String tag, @NotNull String message, @Nullable Throwable throwable) {
if (priority >= Log.DEBUG) {
FirebaseCrashlytics.getInstance().log(message);
if (throwable != null) {
FirebaseCrashlytics.getInstance().recordException(throwable);
}
} else {
return;
}
}
public LogInfoItem(String log) {
orginalLog = log;
if (log.contains("V/")) {
level = Log.VERBOSE;
} else if (log.contains("D/")) {
level = Log.DEBUG;
} else if (log.contains("I/")) {
level = Log.INFO;
} else if (log.contains("W/")) {
level = Log.WARN;
} else if (log.contains("E/")) {
level = Log.ERROR;
} else if (log.contains("A/")) {
level = Log.ASSERT;
}
int beginIndex = log.indexOf(": ");
if (beginIndex == -1) {
meseage = log;
} else {
meseage = log.substring(beginIndex + 2);
}
beginIndex = log.indexOf("/");
int endIndex = log.indexOf("/", beginIndex + 1);
if (beginIndex != -1 && endIndex != -1) {
packagePriority = log.substring(beginIndex + 1, endIndex - 3);
}
endIndex = log.indexOf(" ");
if (endIndex != -1) {
date = log.substring(0, endIndex);
}
beginIndex = endIndex;
endIndex = log.indexOf(" ", beginIndex + 1);
if (endIndex != -1 && beginIndex != -1) {
time = log.substring(beginIndex, endIndex);
}
}
/**
* 记录D级别日志 在记录D级别日志时调用, 如果日志配置为不记录日志或日志级别高于D, 不记录日志
*
* @param msg 日志信息, 支持动态传参可以是一个或多个(避免日志信息的+操作过早的执行)
* @author kjxu
*/
public static void d(String... msg) {
if (ADB && LOG_DEGREE <= Log.DEBUG) {
getMethodNames(new Throwable().getStackTrace());
String msgStr = createLog(msg);
Log.d(className, msgStr);
writeLogToFile(Log.DEBUG, className, msgStr, null);
}
}
private static void log(int priority, String message, Object... args) {
if (priority < sLogLevel)
return;
message = String.format(message, args);
if (args.length > 0 && args[args.length - 1] instanceof Throwable) {
Throwable throwable = (Throwable) args[args.length - 1];
String stacktraceStr = Log.getStackTraceString(throwable);
message += '\n' + stacktraceStr;
}
// Write to the default log tag
Log.println(priority, LOG_TAG, message);
// Duplicate to the Xposed log if enabled
if (LOG_TO_XPOSED) {
if (priority <= Log.DEBUG) { // DEBUG level 不会在Xposed日志中生成,所以调整等级
priority = Log.INFO;
}
Log.println(priority, "Xposed", LOG_TAG + ": " + message);
}
if (LOG_TO_EDXPOSED) {
Log.println(priority, "EdXposed-Bridge", LOG_TAG + ": " + message);
}
}
@Override
protected void log(int priority, String tag, String message, Throwable t) {
// Workaround for devices that doesn't show lower priority logs
if (Build.MANUFACTURER.equals("HUAWEI") || Build.MANUFACTURER.equals("samsung")) {
if (priority == Log.VERBOSE || priority == Log.DEBUG || priority == Log.INFO)
priority = Log.ERROR;
}
super.log(priority, tag, message, t);
}
/**
*
* @param tag
* log的tag
* @param content
* log的内容
* @param logType
* log的类型,如Log.INFO,Log.DEBUG等
* @param methodDepth
*
* @param showCaller 是否显示调用者的方法名和行号等
*/
private static void LOG(String tag, String content, int logType,int methodDepth,boolean showCaller) {
if (DEBUG) {
if (SHOW_LINE_NUMBER_IN_LOG) {
Throwable throwable = new Throwable();
methodDepth++;
if (throwable.getStackTrace().length-1> methodDepth){
StackTraceElement element = throwable.getStackTrace()[methodDepth];
StringBuffer stringBuffer=new StringBuffer();
if (showCaller&& throwable.getStackTrace().length-1> methodDepth+1){
StackTraceElement elementCaller = throwable.getStackTrace()[methodDepth+1];
stringBuffer.append("[")
.append(elementCaller.getFileName())
.append(":")
.append(elementCaller.getMethodName())
.append("():")
.append(elementCaller.getLineNumber())
.append("]");
stringBuffer.append("->");
stringBuffer.append("[")
.append(element.getFileName())
.append(":")
.append(element.getMethodName())
.append("():")
.append(element.getLineNumber())
.append("]");
stringBuffer.append(""+content);
stringBuffer.append(" (")
.append(element.getFileName())
.append(":")
.append(element.getLineNumber())
.append(") ");
}else{
stringBuffer.append("[")
.append(element.getFileName())
.append(":")
.append(element.getMethodName())
.append("():")
.append(element.getLineNumber())
.append("]")
.append(content);
stringBuffer.append(" (")
.append(element.getFileName())
.append(":")
.append(element.getLineNumber())
.append(")");
}
content = stringBuffer.toString();
}
}
switch (logType) {
case Log.INFO:
Log.i(tag, content);
break;
case Log.DEBUG:
Log.d(tag, content);
break;
case Log.ERROR:
Log.e(tag, content);
break;
default:
break;
}
}
}
private static void log(final int pType, final Throwable t, final Object s1, final Object... args) {
if (pType == Log.ERROR || BuildConfig.DEBUG) {
final StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[4];
final String fullClassName = stackTraceElement.getClassName();
final String className = fullClassName.substring(fullClassName.lastIndexOf(".") + 1);
final int lineNumber = stackTraceElement.getLineNumber();
final String method = stackTraceElement.getMethodName();
final String tag = className + ":" + lineNumber;
final StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(method);
stringBuilder.append("(): ");
if (s1 != null) {
final String message = (args == null) ? s1.toString() : String.format((String) s1, args);
stringBuilder.append(message);
}
switch (pType) {
case Log.VERBOSE:
if (t != null) {
Log.v(tag, stringBuilder.toString(), t);
} else {
Log.v(tag, stringBuilder.toString());
}
break;
case Log.DEBUG:
if (t != null) {
Log.d(tag, stringBuilder.toString(), t);
} else {
Log.d(tag, stringBuilder.toString());
}
break;
case Log.INFO:
if (t != null) {
Log.i(tag, stringBuilder.toString(), t);
} else {
Log.i(tag, stringBuilder.toString());
}
break;
case Log.WARN:
if (t != null) {
Log.w(tag, stringBuilder.toString(), t);
} else {
Log.w(tag, stringBuilder.toString());
}
break;
case Log.ERROR:
if (t != null) {
Log.e(tag, stringBuilder.toString(), t);
} else {
Log.e(tag, stringBuilder.toString());
}
break;
}
}
}
@Override
public void handleEvent(AccessibilityEvent event) {
// Avoid processing events when screen is locked
if (_keyguardManager != null) {
boolean locked = _keyguardManager.inKeyguardRestrictedInputMode();
if (locked) {
Log.i(TAG, "Screen locked, skipping overlay check!");
return;
}
}
Log.d(TAG, String.format("New event %s", event.toString()));
_eventCounter.newEvent();
_notifyService.updateNotificationCount(_eventCounter.getLastMinuteEventCount());
if (_resultReceiver != null) {
Bundle bundle = new Bundle();
bundle.putLong("eventCount", _eventCounter.getLastMinuteEventCount());
_resultReceiver.send(ServiceCommunication.MSG_EVENT_COUNT_UPDATE, bundle);
}
// When overlay is detected avoid performing useless computation
if (_overlayState.isHasOverlay() || _overlayState.isPendingUninstall())
return;
if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
if (event.getPackageName() == null)
return;
String eventPackage = event.getPackageName().toString();
ComponentName componentName = new ComponentName(
eventPackage,
event.getClassName().toString()
);
ActivityInfo activityInfo = tryGetActivity(componentName);
boolean isActivity = activityInfo != null;
if (isActivity) {
LogPrinter logPrinter = new LogPrinter(Log.DEBUG, TAG);
activityInfo.dump(logPrinter, "");
}
String className = event.getClassName().toString();
// Perform detection
boolean parentAvailable = event.getSource() != null ? event.getSource().getParent() != null : false;
Log.d(TAG, String.format("Collected info isActivity %s, parentAvailable: %s", String.valueOf(isActivity), String.valueOf(parentAvailable)));
if (_overlayState.getIgnoreOncePackage().equals(eventPackage)) {
Log.d(TAG, String.format("Package %s ignored once", eventPackage));
} else if (eventPackage.equals(previousEventPackage)) {
Log.d(TAG, String.format("Last two event have the same package %s, skipping check!", eventPackage));
} else if (_layoutClasses.contains(className) && !isActivity && !parentAvailable) {
Log.d(TAG, String.format("Detected suspicious class %s without activity and parent for process %s, checking whitelist", className, eventPackage));
if (!checkWhitelistHit(eventPackage)) {
Log.d(TAG, "No whitelist entry found");
if (checkSuspectedApps(eventPackage)) {
Log.d(TAG, String.format("******* VIEW OVERLAY DETECTED!!!"));
_overlayState.setOffender(eventPackage);
_overlayState.setProcess(_currentProcess);
_notifyService.processOverlayState(_overlayState);
}
} else {
Log.d(TAG, "Whitelist hit skipping!");
}
} else if (isActivity && activityInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE && !parentAvailable) {
Log.d(TAG, String.format("Detected suspicious activity %s with single instance flag, checking whitelist", activityInfo.packageName));
if (!checkWhitelistHit(eventPackage)) {
Log.d(TAG, "No whitelist entry found");
if (checkSuspectedApps(eventPackage)) {
Log.d(TAG, String.format("******* ACTIVITY OVERLAY DETECTED!!!"));
_overlayState.setOffender(eventPackage);
_overlayState.setProcess(_currentProcess);
_notifyService.processOverlayState(_overlayState);
}
} else {
Log.d(TAG, "Whitelist hit skipping!");
}
}
previousEventPackage = eventPackage;
}
}