diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..39fb081 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures +.externalNativeBuild diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..97626ba --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..359054d --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,19 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..93713f5 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + 1.8 + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..4310679 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/QYlogger/build.gradle b/QYlogger/build.gradle new file mode 100644 index 0000000..4179efc --- /dev/null +++ b/QYlogger/build.gradle @@ -0,0 +1,40 @@ +apply plugin: 'com.android.library' +apply plugin: 'com.novoda.bintray-release' +android { + compileSdkVersion 27 + buildToolsVersion "27.0.3" + + defaultConfig { + minSdkVersion 21 + } + + lintOptions { + textReport true + textOutput 'stdout' + } + + testOptions { + unitTests.returnDefaultValues = true + } +} + +dependencies { + implementation "com.android.support:support-annotations:27.1.0" + + testImplementation 'junit:junit:4.12' + testImplementation 'com.google.truth:truth:0.28' + testImplementation 'org.robolectric:robolectric:3.3' + testImplementation 'org.mockito:mockito-core:2.8.9' + testImplementation "org.json:json:20160810" +} + + +publish { + repoName = 'JunGenius' //bintray仓库名 + userOrg ='jungenius0108' //bintray注册的用户名 + groupId = 'com.qj.logger' //compile引用时的第1部分groupId + artifactId = 'QYLogger' //compile引用时的第2部分项目名 + publishVersion = '1.1.0' //compile引用时的第3部分版本号 + desc = 'Logger for Android' + website = 'https://github.com/JunGenius/JYWebServiceImpl' +} diff --git a/QYlogger/build/generated/mockable-android-27.default-values.v3.jar b/QYlogger/build/generated/mockable-android-27.default-values.v3.jar new file mode 100644 index 0000000..a702211 Binary files /dev/null and b/QYlogger/build/generated/mockable-android-27.default-values.v3.jar differ diff --git a/QYlogger/build/generated/source/buildConfig/androidTest/debug/com/orhanobut/logger/test/BuildConfig.java b/QYlogger/build/generated/source/buildConfig/androidTest/debug/com/orhanobut/logger/test/BuildConfig.java new file mode 100644 index 0000000..464fb81 --- /dev/null +++ b/QYlogger/build/generated/source/buildConfig/androidTest/debug/com/orhanobut/logger/test/BuildConfig.java @@ -0,0 +1,13 @@ +/** + * Automatically generated file. DO NOT MODIFY + */ +package com.orhanobut.logger.test; + +public final class BuildConfig { + public static final boolean DEBUG = Boolean.parseBoolean("true"); + public static final String APPLICATION_ID = "com.orhanobut.logger.test"; + public static final String BUILD_TYPE = "debug"; + public static final String FLAVOR = ""; + public static final int VERSION_CODE = -1; + public static final String VERSION_NAME = ""; +} diff --git a/QYlogger/build/generated/source/buildConfig/debug/com/orhanobut/logger/BuildConfig.java b/QYlogger/build/generated/source/buildConfig/debug/com/orhanobut/logger/BuildConfig.java new file mode 100644 index 0000000..1fe5463 --- /dev/null +++ b/QYlogger/build/generated/source/buildConfig/debug/com/orhanobut/logger/BuildConfig.java @@ -0,0 +1,13 @@ +/** + * Automatically generated file. DO NOT MODIFY + */ +package com.orhanobut.logger; + +public final class BuildConfig { + public static final boolean DEBUG = Boolean.parseBoolean("true"); + public static final String APPLICATION_ID = "com.orhanobut.logger"; + public static final String BUILD_TYPE = "debug"; + public static final String FLAVOR = ""; + public static final int VERSION_CODE = -1; + public static final String VERSION_NAME = ""; +} diff --git a/QYlogger/build/generated/source/r/androidTest/debug/com/orhanobut/logger/R.java b/QYlogger/build/generated/source/r/androidTest/debug/com/orhanobut/logger/R.java new file mode 100644 index 0000000..17ac99f --- /dev/null +++ b/QYlogger/build/generated/source/r/androidTest/debug/com/orhanobut/logger/R.java @@ -0,0 +1,10 @@ +/* AUTO-GENERATED FILE. DO NOT MODIFY. + * + * This class was automatically generated by the + * gradle plugin from the resource data it found. It + * should not be modified by hand. + */ +package com.orhanobut.logger; + +public final class R { +} diff --git a/QYlogger/build/generated/source/r/androidTest/debug/com/orhanobut/logger/test/R.java b/QYlogger/build/generated/source/r/androidTest/debug/com/orhanobut/logger/test/R.java new file mode 100644 index 0000000..9330f42 --- /dev/null +++ b/QYlogger/build/generated/source/r/androidTest/debug/com/orhanobut/logger/test/R.java @@ -0,0 +1,11 @@ +/* AUTO-GENERATED FILE. DO NOT MODIFY. + * + * This class was automatically generated by the + * aapt tool from the resource data it found. It + * should not be modified by hand. + */ + +package com.orhanobut.logger.test; + +public final class R { +} \ No newline at end of file diff --git a/QYlogger/build/generated/source/r/debug/com/orhanobut/logger/R.java b/QYlogger/build/generated/source/r/debug/com/orhanobut/logger/R.java new file mode 100644 index 0000000..17ac99f --- /dev/null +++ b/QYlogger/build/generated/source/r/debug/com/orhanobut/logger/R.java @@ -0,0 +1,10 @@ +/* AUTO-GENERATED FILE. DO NOT MODIFY. + * + * This class was automatically generated by the + * gradle plugin from the resource data it found. It + * should not be modified by hand. + */ +package com.orhanobut.logger; + +public final class R { +} diff --git a/QYlogger/build/intermediates/attr/R.txt b/QYlogger/build/intermediates/attr/R.txt new file mode 100644 index 0000000..2c543dd --- /dev/null +++ b/QYlogger/build/intermediates/attr/R.txt @@ -0,0 +1,1353 @@ +int attr absListViewStyle 0x0101006a +int attr accessibilityEventTypes 0x01010380 +int attr accessibilityFeedbackType 0x01010382 +int attr accessibilityFlags 0x01010384 +int attr accessibilityLiveRegion 0x010103ee +int attr accessibilityTraversalAfter 0x010104d2 +int attr accessibilityTraversalBefore 0x010104d1 +int attr accountPreferences 0x0101029f +int attr accountType 0x0101028f +int attr action 0x0101002d +int attr actionBarDivider 0x0101039b +int attr actionBarItemBackground 0x0101039c +int attr actionBarPopupTheme 0x0101048d +int attr actionBarSize 0x010102eb +int attr actionBarSplitStyle 0x01010388 +int attr actionBarStyle 0x010102ce +int attr actionBarTabBarStyle 0x010102f4 +int attr actionBarTabStyle 0x010102f3 +int attr actionBarTabTextStyle 0x010102f5 +int attr actionBarTheme 0x01010431 +int attr actionBarWidgetTheme 0x01010397 +int attr actionButtonStyle 0x010102d8 +int attr actionDropDownStyle 0x010102d7 +int attr actionLayout 0x010102fb +int attr actionMenuTextAppearance 0x01010360 +int attr actionMenuTextColor 0x01010361 +int attr actionModeBackground 0x010102db +int attr actionModeCloseButtonStyle 0x010102f7 +int attr actionModeCloseDrawable 0x010102dc +int attr actionModeCopyDrawable 0x01010312 +int attr actionModeCutDrawable 0x01010311 +int attr actionModeFindDrawable 0x0101047a +int attr actionModePasteDrawable 0x01010313 +int attr actionModeSelectAllDrawable 0x0101037e +int attr actionModeShareDrawable 0x01010479 +int attr actionModeSplitBackground 0x0101039d +int attr actionModeStyle 0x01010394 +int attr actionModeWebSearchDrawable 0x0101047b +int attr actionOverflowButtonStyle 0x010102f6 +int attr actionOverflowMenuStyle 0x01010444 +int attr actionProviderClass 0x01010389 +int attr actionViewClass 0x010102fc +int attr activatedBackgroundIndicator 0x010102fd +int attr activityCloseEnterAnimation 0x010100ba +int attr activityCloseExitAnimation 0x010100bb +int attr activityOpenEnterAnimation 0x010100b8 +int attr activityOpenExitAnimation 0x010100b9 +int attr addPrintersActivity 0x010103e6 +int attr addStatesFromChildren 0x010100f0 +int attr adjustViewBounds 0x0101011e +int attr advancedPrintOptionsActivity 0x010103f1 +int attr alertDialogIcon 0x01010355 +int attr alertDialogStyle 0x0101005d +int attr alertDialogTheme 0x01010309 +int attr alignmentMode 0x0101037a +int attr allContactsName 0x010102cc +int attr allowBackup 0x01010280 +int attr allowClearUserData 0x01010005 +int attr allowEmbedded 0x010103f5 +int attr allowParallelSyncs 0x01010332 +int attr allowSingleTap 0x01010259 +int attr allowTaskReparenting 0x01010204 +int attr allowUndo 0x010104df +int attr alpha 0x0101031f +int attr alphabeticModifiers 0x0101054e +int attr alphabeticShortcut 0x010101e3 +int attr alwaysDrawnWithCache 0x010100ef +int attr alwaysRetainTaskState 0x01010203 +int attr amPmBackgroundColor 0x010104a5 +int attr amPmTextColor 0x010104a4 +int attr ambientShadowAlpha 0x010104be +int attr angle 0x010101a0 +int attr animateFirstView 0x010102d5 +int attr animateLayoutChanges 0x010102f2 +int attr animateOnClick 0x0101025c +int attr animation 0x010101cd +int attr animationCache 0x010100ed +int attr animationDuration 0x01010112 +int attr animationOrder 0x010101ce +int attr animationResolution 0x0101031a +int attr antialias 0x0101011a +int attr anyDensity 0x0101026c +int attr apduServiceBanner 0x010103ed +int attr apiKey 0x01010211 +int attr appCategory 0x01010545 +int attr author 0x010102b4 +int attr authorities 0x01010018 +int attr autoAdvanceViewId 0x0101030f +int attr autoCompleteTextViewStyle 0x0101006b +int attr autoLink 0x010100b0 +int attr autoMirrored 0x010103ea +int attr autoRemoveFromRecents 0x01010447 +int attr autoSizeMaxTextSize 0x01010546 +int attr autoSizeMinTextSize 0x01010538 +int attr autoSizePresetSizes 0x01010537 +int attr autoSizeStepGranularity 0x01010536 +int attr autoSizeTextType 0x01010535 +int attr autoStart 0x010102b5 +int attr autoText 0x0101016a +int attr autoUrlDetect 0x0101028c +int attr autoVerify 0x010104ee +int attr autofillHints 0x01010556 +int attr autofilledHighlight 0x01010568 +int attr background 0x010100d4 +int attr backgroundDimAmount 0x01010032 +int attr backgroundDimEnabled 0x0101021f +int attr backgroundSplit 0x0101038b +int attr backgroundStacked 0x0101038a +int attr backgroundTint 0x0101046b +int attr backgroundTintMode 0x0101046c +int attr backupAgent 0x0101027f +int attr backupInForeground 0x0101051a +int attr banner 0x010103f2 +int attr baseline 0x0101031c +int attr baselineAlignBottom 0x01010122 +int attr baselineAligned 0x01010126 +int attr baselineAlignedChildIndex 0x01010127 +int attr bitmap 0x01010516 +int attr borderlessButtonStyle 0x0101032b +int attr bottom 0x010101b0 +int attr bottomBright 0x010100cd +int attr bottomDark 0x010100c9 +int attr bottomLeftRadius 0x010101ab +int attr bottomMedium 0x010100ce +int attr bottomOffset 0x01010257 +int attr bottomRightRadius 0x010101ac +int attr breadCrumbShortTitle 0x01010304 +int attr breadCrumbTitle 0x01010303 +int attr breakStrategy 0x010104dd +int attr bufferType 0x0101014e +int attr button 0x01010107 +int attr buttonBarButtonStyle 0x0101032f +int attr buttonBarNegativeButtonStyle 0x0101048b +int attr buttonBarNeutralButtonStyle 0x0101048a +int attr buttonBarPositiveButtonStyle 0x01010489 +int attr buttonBarStyle 0x0101032e +int attr buttonGravity 0x010104fe +int attr buttonStyle 0x01010048 +int attr buttonStyleInset 0x0101004a +int attr buttonStyleSmall 0x01010049 +int attr buttonStyleToggle 0x0101004b +int attr buttonTint 0x0101046f +int attr buttonTintMode 0x01010470 +int attr cacheColorHint 0x01010101 +int attr calendarTextColor 0x0101049b +int attr calendarViewShown 0x0101034c +int attr calendarViewStyle 0x0101035d +int attr canControlMagnification 0x01010507 +int attr canPerformGestures 0x0101050d +int attr canRecord 0x0101051c +int attr canRequestEnhancedWebAccessibility 0x010103d8 +int attr canRequestFilterKeyEvents 0x010103d9 +int attr canRequestFingerprintGestures 0x0101054d +int attr canRequestTouchExplorationMode 0x010103d7 +int attr canRetrieveWindowContent 0x01010385 +int attr candidatesTextStyleSpans 0x01010230 +int attr capitalize 0x01010169 +int attr category 0x010103e8 +int attr centerBright 0x010100cc +int attr centerColor 0x0101020b +int attr centerDark 0x010100c8 +int attr centerMedium 0x010100cf +int attr centerX 0x010101a2 +int attr centerY 0x010101a3 +int attr certDigest 0x01010548 +int attr checkBoxPreferenceStyle 0x0101008f +int attr checkMark 0x01010108 +int attr checkMarkTint 0x010104a7 +int attr checkMarkTintMode 0x010104a8 +int attr checkable 0x010101e5 +int attr checkableBehavior 0x010101e0 +int attr checkboxStyle 0x0101006c +int attr checked 0x01010106 +int attr checkedButton 0x01010148 +int attr checkedTextViewStyle 0x010103c8 +int attr childDivider 0x01010111 +int attr childIndicator 0x0101010c +int attr childIndicatorEnd 0x010103d4 +int attr childIndicatorLeft 0x0101010f +int attr childIndicatorRight 0x01010110 +int attr childIndicatorStart 0x010103d3 +int attr choiceMode 0x0101012b +int attr classLoader 0x0101056b +int attr clearTaskOnLaunch 0x01010015 +int attr clickable 0x010100e5 +int attr clipChildren 0x010100ea +int attr clipOrientation 0x0101020a +int attr clipToPadding 0x010100eb +int attr closeIcon 0x01010481 +int attr codes 0x01010242 +int attr collapseColumns 0x0101014b +int attr collapseContentDescription 0x010104d0 +int attr collapseIcon 0x010104ff +int attr color 0x010101a5 +int attr colorAccent 0x01010435 +int attr colorActivatedHighlight 0x01010390 +int attr colorBackground 0x01010031 +int attr colorBackgroundCacheHint 0x010102ab +int attr colorBackgroundFloating 0x010104e2 +int attr colorButtonNormal 0x0101042b +int attr colorControlActivated 0x0101042a +int attr colorControlHighlight 0x0101042c +int attr colorControlNormal 0x01010429 +int attr colorEdgeEffect 0x010104ce +int attr colorError 0x01010543 +int attr colorFocusedHighlight 0x0101038f +int attr colorForeground 0x01010030 +int attr colorForegroundInverse 0x01010206 +int attr colorLongPressedHighlight 0x0101038e +int attr colorMode 0x0101054a +int attr colorMultiSelectHighlight 0x01010391 +int attr colorPressedHighlight 0x0101038d +int attr colorPrimary 0x01010433 +int attr colorPrimaryDark 0x01010434 +int attr colorSecondary 0x01010530 +int attr columnCount 0x01010377 +int attr columnDelay 0x010101cf +int attr columnOrderPreserved 0x01010378 +int attr columnWidth 0x01010117 +int attr commitIcon 0x01010485 +int attr compatibleWidthLimitDp 0x01010365 +int attr completionHint 0x01010172 +int attr completionHintView 0x01010173 +int attr completionThreshold 0x01010174 +int attr configChanges 0x0101001f +int attr configure 0x0101025d +int attr constantSize 0x01010196 +int attr content 0x0101025b +int attr contentAgeHint 0x010104b9 +int attr contentAuthority 0x01010290 +int attr contentDescription 0x01010273 +int attr contentInsetEnd 0x01010454 +int attr contentInsetEndWithActions 0x01010523 +int attr contentInsetLeft 0x01010455 +int attr contentInsetRight 0x01010456 +int attr contentInsetStart 0x01010453 +int attr contentInsetStartWithNavigation 0x01010522 +int attr contextClickable 0x010104e7 +int attr contextDescription 0x0101052e +int attr contextPopupMenuStyle 0x01010501 +int attr contextUri 0x0101052d +int attr controlX1 0x010103fc +int attr controlX2 0x010103fe +int attr controlY1 0x010103fd +int attr controlY2 0x010103ff +int attr countDown 0x0101051b +int attr country 0x010104ba +int attr cropToPadding 0x01010123 +int attr cursorVisible 0x01010152 +int attr customNavigationLayout 0x010102d2 +int attr customTokens 0x0101033b +int attr cycles 0x010101d4 +int attr dashGap 0x010101a7 +int attr dashWidth 0x010101a6 +int attr data 0x0101002e +int attr datePickerDialogTheme 0x010104ac +int attr datePickerMode 0x010104b3 +int attr datePickerStyle 0x0101035c +int attr dateTextAppearance 0x01010349 +int attr dayOfWeekBackground 0x01010494 +int attr dayOfWeekTextAppearance 0x01010495 +int attr debuggable 0x0101000f +int attr defaultFocusHighlightEnabled 0x01010562 +int attr defaultHeight 0x010104f5 +int attr defaultToDeviceProtectedStorage 0x01010504 +int attr defaultValue 0x010101ed +int attr defaultWidth 0x010104f4 +int attr delay 0x010101cc +int attr dependency 0x010101ec +int attr descendantFocusability 0x010100f1 +int attr description 0x01010020 +int attr detachWallpaper 0x010102a6 +int attr detailColumn 0x010102a3 +int attr detailSocialSummary 0x010102a4 +int attr detailsElementBackground 0x0101034e +int attr dial 0x01010102 +int attr dialogIcon 0x010101f4 +int attr dialogLayout 0x010101f7 +int attr dialogMessage 0x010101f3 +int attr dialogPreferenceStyle 0x01010091 +int attr dialogPreferredPadding 0x010104d3 +int attr dialogTheme 0x01010308 +int attr dialogTitle 0x010101f2 +int attr digits 0x01010166 +int attr directBootAware 0x01010505 +int attr direction 0x010101d1 +int attr directionDescriptions 0x010103a1 +int attr directionPriority 0x010101d2 +int attr disableDependentsState 0x010101f1 +int attr disabledAlpha 0x01010033 +int attr displayOptions 0x010102d0 +int attr dither 0x0101011c +int attr divider 0x01010129 +int attr dividerHeight 0x0101012a +int attr dividerHorizontal 0x0101032c +int attr dividerPadding 0x0101032a +int attr dividerVertical 0x0101030a +int attr documentLaunchMode 0x01010445 +int attr drawSelectorOnTop 0x010100fc +int attr drawable 0x01010199 +int attr drawableBottom 0x0101016e +int attr drawableEnd 0x01010393 +int attr drawableLeft 0x0101016f +int attr drawablePadding 0x01010171 +int attr drawableRight 0x01010170 +int attr drawableStart 0x01010392 +int attr drawableTint 0x010104d6 +int attr drawableTintMode 0x010104d7 +int attr drawableTop 0x0101016d +int attr drawingCacheQuality 0x010100e8 +int attr dropDownAnchor 0x01010263 +int attr dropDownHeight 0x01010283 +int attr dropDownHintAppearance 0x01010088 +int attr dropDownHorizontalOffset 0x010102ac +int attr dropDownItemStyle 0x01010086 +int attr dropDownListViewStyle 0x0101006d +int attr dropDownSelector 0x01010175 +int attr dropDownSpinnerStyle 0x010102d6 +int attr dropDownVerticalOffset 0x010102ad +int attr dropDownWidth 0x01010262 +int attr duplicateParentState 0x010100e9 +int attr duration 0x01010198 +int attr editTextBackground 0x01010352 +int attr editTextColor 0x01010351 +int attr editTextPreferenceStyle 0x01010092 +int attr editTextStyle 0x0101006e +int attr editable 0x0101016b +int attr editorExtras 0x01010224 +int attr elegantTextHeight 0x0101045d +int attr elevation 0x01010440 +int attr ellipsize 0x010100ab +int attr ems 0x01010158 +int attr enableVrMode 0x01010525 +int attr enabled 0x0101000e +int attr end 0x010104dc +int attr endColor 0x0101019e +int attr endX 0x01010512 +int attr endY 0x01010513 +int attr endYear 0x0101017d +int attr enterFadeDuration 0x0101030c +int attr entries 0x010100b2 +int attr entryValues 0x010101f8 +int attr eventsInterceptionEnabled 0x0101027d +int attr excludeClass 0x01010442 +int attr excludeFromRecents 0x01010017 +int attr excludeId 0x01010441 +int attr excludeName 0x0101044e +int attr exitFadeDuration 0x0101030d +int attr expandableListPreferredChildIndicatorLeft 0x01010052 +int attr expandableListPreferredChildIndicatorRight 0x01010053 +int attr expandableListPreferredChildPaddingLeft 0x0101004f +int attr expandableListPreferredItemIndicatorLeft 0x01010050 +int attr expandableListPreferredItemIndicatorRight 0x01010051 +int attr expandableListPreferredItemPaddingLeft 0x0101004e +int attr expandableListViewStyle 0x0101006f +int attr expandableListViewWhiteStyle 0x010102b6 +int attr exported 0x01010010 +int attr externalService 0x0101050e +int attr extraTension 0x0101026b +int attr extractNativeLibs 0x010104ea +int attr factor 0x010101d3 +int attr fadeDuration 0x01010278 +int attr fadeEnabled 0x0101027e +int attr fadeOffset 0x01010277 +int attr fadeScrollbars 0x010102aa +int attr fadingEdge 0x010100df +int attr fadingEdgeLength 0x010100e0 +int attr fadingMode 0x010103e1 +int attr fastScrollAlwaysVisible 0x01010335 +int attr fastScrollEnabled 0x01010226 +int attr fastScrollOverlayPosition 0x0101033a +int attr fastScrollPreviewBackgroundLeft 0x01010337 +int attr fastScrollPreviewBackgroundRight 0x01010338 +int attr fastScrollStyle 0x010103f7 +int attr fastScrollTextColor 0x01010359 +int attr fastScrollThumbDrawable 0x01010336 +int attr fastScrollTrackDrawable 0x01010339 +int attr fillAfter 0x010101bd +int attr fillAlpha 0x010104cc +int attr fillBefore 0x010101bc +int attr fillColor 0x01010404 +int attr fillEnabled 0x0101024f +int attr fillType 0x0101051e +int attr fillViewport 0x0101017a +int attr filter 0x0101011b +int attr filterTouchesWhenObscured 0x010102c4 +int attr fingerprintAuthDrawable 0x010104e8 +int attr finishOnCloseSystemDialogs 0x010102a7 +int attr finishOnTaskLaunch 0x01010014 +int attr firstDayOfWeek 0x0101033d +int attr fitsSystemWindows 0x010100dd +int attr flipInterval 0x01010179 +int attr focusable 0x010100da +int attr focusableInTouchMode 0x010100db +int attr focusedByDefault 0x01010544 +int attr focusedMonthDateColor 0x01010343 +int attr font 0x01010532 +int attr fontFamily 0x010103ac +int attr fontFeatureSettings 0x010104b7 +int attr fontProviderAuthority 0x01010550 +int attr fontProviderCerts 0x0101055d +int attr fontProviderPackage 0x01010557 +int attr fontProviderQuery 0x01010551 +int attr fontStyle 0x0101053f +int attr fontWeight 0x01010533 +int attr footerDividersEnabled 0x0101022f +int attr forceHasOverlappingRendering 0x01010521 +int attr foreground 0x01010109 +int attr foregroundGravity 0x01010200 +int attr foregroundTint 0x0101046d +int attr foregroundTintMode 0x0101046e +int attr format 0x01010105 +int attr format12Hour 0x010103ca +int attr format24Hour 0x010103cb +int attr fraction 0x010104d8 +int attr fragment 0x010102e3 +int attr fragmentAllowEnterTransitionOverlap 0x010104c8 +int attr fragmentAllowReturnTransitionOverlap 0x010104c9 +int attr fragmentCloseEnterAnimation 0x010102e7 +int attr fragmentCloseExitAnimation 0x010102e8 +int attr fragmentEnterTransition 0x010104c3 +int attr fragmentExitTransition 0x010104c2 +int attr fragmentFadeEnterAnimation 0x010102e9 +int attr fragmentFadeExitAnimation 0x010102ea +int attr fragmentOpenEnterAnimation 0x010102e5 +int attr fragmentOpenExitAnimation 0x010102e6 +int attr fragmentReenterTransition 0x010104c7 +int attr fragmentReturnTransition 0x010104c5 +int attr fragmentSharedElementEnterTransition 0x010104c4 +int attr fragmentSharedElementReturnTransition 0x010104c6 +int attr freezesText 0x0101016c +int attr fromAlpha 0x010101ca +int attr fromDegrees 0x010101b3 +int attr fromId 0x0101044a +int attr fromScene 0x010103dd +int attr fromXDelta 0x010101c6 +int attr fromXScale 0x010101c2 +int attr fromYDelta 0x010101c8 +int attr fromYScale 0x010101c4 +int attr fullBackupContent 0x010104eb +int attr fullBackupOnly 0x01010473 +int attr fullBright 0x010100ca +int attr fullDark 0x010100c6 +int attr functionalTest 0x01010023 +int attr galleryItemBackground 0x0101004c +int attr galleryStyle 0x01010070 +int attr gestureColor 0x01010275 +int attr gestureStrokeAngleThreshold 0x0101027c +int attr gestureStrokeLengthThreshold 0x0101027a +int attr gestureStrokeSquarenessThreshold 0x0101027b +int attr gestureStrokeType 0x01010279 +int attr gestureStrokeWidth 0x01010274 +int attr glEsVersion 0x01010281 +int attr goIcon 0x01010482 +int attr gradientRadius 0x010101a4 +int attr grantUriPermissions 0x0101001b +int attr gravity 0x010100af +int attr gridViewStyle 0x01010071 +int attr groupIndicator 0x0101010b +int attr hand_hour 0x01010103 +int attr hand_minute 0x01010104 +int attr handle 0x0101025a +int attr handleProfiling 0x01010022 +int attr hapticFeedbackEnabled 0x0101025e +int attr hardwareAccelerated 0x010102d3 +int attr hasCode 0x0101000c +int attr headerAmPmTextAppearance 0x010104a0 +int attr headerBackground 0x0101012f +int attr headerDayOfMonthTextAppearance 0x01010497 +int attr headerDividersEnabled 0x0101022e +int attr headerMonthTextAppearance 0x01010496 +int attr headerTimeTextAppearance 0x0101049f +int attr headerYearTextAppearance 0x01010498 +int attr height 0x01010155 +int attr hideOnContentScroll 0x01010443 +int attr hint 0x01010150 +int attr homeAsUpIndicator 0x0101030b +int attr homeLayout 0x0101031d +int attr horizontalDivider 0x0101012d +int attr horizontalGap 0x0101023f +int attr horizontalScrollViewStyle 0x01010353 +int attr horizontalSpacing 0x01010114 +int attr host 0x01010028 +int attr hotSpotX 0x01010517 +int attr hotSpotY 0x01010518 +int attr hyphenationFrequency 0x010104de +int attr icon 0x01010002 +int attr iconPreview 0x01010249 +int attr iconSpaceReserved 0x01010561 +int attr iconTint 0x0101055e +int attr iconTintMode 0x0101055f +int attr iconifiedByDefault 0x010102fa +int attr id 0x010100d0 +int attr ignoreGravity 0x010101ff +int attr imageButtonStyle 0x01010072 +int attr imageWellStyle 0x01010073 +int attr imeActionId 0x01010266 +int attr imeActionLabel 0x01010265 +int attr imeExtractEnterAnimation 0x01010268 +int attr imeExtractExitAnimation 0x01010269 +int attr imeFullscreenBackground 0x0101022c +int attr imeOptions 0x01010264 +int attr imeSubtypeExtraValue 0x010102ee +int attr imeSubtypeLocale 0x010102ec +int attr imeSubtypeMode 0x010102ed +int attr immersive 0x010102c0 +int attr importantForAccessibility 0x010103aa +int attr importantForAutofill 0x01010558 +int attr inAnimation 0x01010177 +int attr includeFontPadding 0x0101015f +int attr includeInGlobalSearch 0x0101026e +int attr indeterminate 0x01010139 +int attr indeterminateBehavior 0x0101013e +int attr indeterminateDrawable 0x0101013b +int attr indeterminateDuration 0x0101013d +int attr indeterminateOnly 0x0101013a +int attr indeterminateProgressStyle 0x01010318 +int attr indeterminateTint 0x01010469 +int attr indeterminateTintMode 0x0101046a +int attr indicatorEnd 0x010103d2 +int attr indicatorLeft 0x0101010d +int attr indicatorRight 0x0101010e +int attr indicatorStart 0x010103d1 +int attr inflatedId 0x010100f3 +int attr initOrder 0x0101001a +int attr initialKeyguardLayout 0x010103c2 +int attr initialLayout 0x01010251 +int attr innerRadius 0x0101025f +int attr innerRadiusRatio 0x0101019b +int attr inputMethod 0x01010168 +int attr inputType 0x01010220 +int attr inset 0x010104b5 +int attr insetBottom 0x010101ba +int attr insetLeft 0x010101b7 +int attr insetRight 0x010101b8 +int attr insetTop 0x010101b9 +int attr installLocation 0x010102b7 +int attr interpolator 0x01010141 +int attr isAlwaysSyncable 0x01010333 +int attr isAsciiCapable 0x010103e9 +int attr isAuxiliary 0x0101037f +int attr isDefault 0x01010221 +int attr isFeatureSplit 0x0101055b +int attr isGame 0x010103f4 +int attr isIndicator 0x01010147 +int attr isModifier 0x01010246 +int attr isRepeatable 0x01010248 +int attr isScrollContainer 0x0101024e +int attr isStatic 0x0101055a +int attr isSticky 0x01010247 +int attr isolatedProcess 0x010103a9 +int attr isolatedSplits 0x0101054b +int attr itemBackground 0x01010130 +int attr itemIconDisabledAlpha 0x01010131 +int attr itemPadding 0x0101032d +int attr itemTextAppearance 0x0101012c +int attr justificationMode 0x01010567 +int attr keepScreenOn 0x01010216 +int attr key 0x010101e8 +int attr keyBackground 0x01010233 +int attr keyEdgeFlags 0x01010245 +int attr keyHeight 0x0101023e +int attr keyIcon 0x0101024c +int attr keyLabel 0x0101024b +int attr keyOutputText 0x0101024a +int attr keyPreviewHeight 0x01010239 +int attr keyPreviewLayout 0x01010237 +int attr keyPreviewOffset 0x01010238 +int attr keySet 0x010103db +int attr keyTextColor 0x01010236 +int attr keyTextSize 0x01010234 +int attr keyWidth 0x0101023d +int attr keyboardLayout 0x010103ab +int attr keyboardMode 0x0101024d +int attr keyboardNavigationCluster 0x01010540 +int attr keycode 0x010100c5 +int attr killAfterRestore 0x0101029c +int attr label 0x01010001 +int attr labelFor 0x010103c6 +int attr labelTextSize 0x01010235 +int attr languageTag 0x01010508 +int attr largeHeap 0x0101035a +int attr largeScreens 0x01010286 +int attr largestWidthLimitDp 0x01010366 +int attr launchMode 0x0101001d +int attr launchTaskBehindSourceAnimation 0x01010492 +int attr launchTaskBehindTargetAnimation 0x01010491 +int attr layerType 0x01010354 +int attr layout 0x010100f2 +int attr layoutAnimation 0x010100ec +int attr layoutDirection 0x010103b2 +int attr layoutMode 0x010103da +int attr layout_above 0x01010184 +int attr layout_alignBaseline 0x01010186 +int attr layout_alignBottom 0x0101018a +int attr layout_alignEnd 0x010103ba +int attr layout_alignLeft 0x01010187 +int attr layout_alignParentBottom 0x0101018e +int attr layout_alignParentEnd 0x010103bc +int attr layout_alignParentLeft 0x0101018b +int attr layout_alignParentRight 0x0101018d +int attr layout_alignParentStart 0x010103bb +int attr layout_alignParentTop 0x0101018c +int attr layout_alignRight 0x01010189 +int attr layout_alignStart 0x010103b9 +int attr layout_alignTop 0x01010188 +int attr layout_alignWithParentIfMissing 0x01010192 +int attr layout_below 0x01010185 +int attr layout_centerHorizontal 0x01010190 +int attr layout_centerInParent 0x0101018f +int attr layout_centerVertical 0x01010191 +int attr layout_column 0x0101014c +int attr layout_columnSpan 0x0101037d +int attr layout_columnWeight 0x01010459 +int attr layout_gravity 0x010100b3 +int attr layout_height 0x010100f5 +int attr layout_margin 0x010100f6 +int attr layout_marginBottom 0x010100fa +int attr layout_marginEnd 0x010103b6 +int attr layout_marginHorizontal 0x0101053b +int attr layout_marginLeft 0x010100f7 +int attr layout_marginRight 0x010100f9 +int attr layout_marginStart 0x010103b5 +int attr layout_marginTop 0x010100f8 +int attr layout_marginVertical 0x0101053c +int attr layout_row 0x0101037b +int attr layout_rowSpan 0x0101037c +int attr layout_rowWeight 0x01010458 +int attr layout_scale 0x01010193 +int attr layout_span 0x0101014d +int attr layout_toEndOf 0x010103b8 +int attr layout_toLeftOf 0x01010182 +int attr layout_toRightOf 0x01010183 +int attr layout_toStartOf 0x010103b7 +int attr layout_weight 0x01010181 +int attr layout_width 0x010100f4 +int attr layout_x 0x0101017f +int attr layout_y 0x01010180 +int attr left 0x010101ad +int attr letterSpacing 0x010104b6 +int attr level 0x01010500 +int attr lineSpacingExtra 0x01010217 +int attr lineSpacingMultiplier 0x01010218 +int attr lines 0x01010154 +int attr linksClickable 0x010100b1 +int attr listChoiceBackgroundIndicator 0x010102f0 +int attr listChoiceIndicatorMultiple 0x0101021a +int attr listChoiceIndicatorSingle 0x01010219 +int attr listDivider 0x01010214 +int attr listDividerAlertDialog 0x01010305 +int attr listMenuViewStyle 0x010104f2 +int attr listPopupWindowStyle 0x010102ff +int attr listPreferredItemHeight 0x0101004d +int attr listPreferredItemHeightLarge 0x01010386 +int attr listPreferredItemHeightSmall 0x01010387 +int attr listPreferredItemPaddingEnd 0x010103be +int attr listPreferredItemPaddingLeft 0x010103a3 +int attr listPreferredItemPaddingRight 0x010103a4 +int attr listPreferredItemPaddingStart 0x010103bd +int attr listSelector 0x010100fb +int attr listSeparatorTextViewStyle 0x01010208 +int attr listViewStyle 0x01010074 +int attr listViewWhiteStyle 0x01010075 +int attr lockTaskMode 0x010104ed +int attr logo 0x010102be +int attr logoDescription 0x010104e9 +int attr longClickable 0x010100e6 +int attr loopViews 0x01010307 +int attr manageSpaceActivity 0x01010004 +int attr mapViewStyle 0x0101008a +int attr marqueeRepeatLimit 0x0101021d +int attr matchOrder 0x0101044f +int attr max 0x01010136 +int attr maxAspectRatio 0x01010560 +int attr maxButtonHeight 0x010104fd +int attr maxDate 0x01010340 +int attr maxEms 0x01010157 +int attr maxHeight 0x01010120 +int attr maxItemsPerRow 0x01010134 +int attr maxLength 0x01010160 +int attr maxLevel 0x010101b2 +int attr maxLines 0x01010153 +int attr maxRecents 0x01010446 +int attr maxRows 0x01010133 +int attr maxSdkVersion 0x01010271 +int attr maxWidth 0x0101011f +int attr maximumAngle 0x0101047f +int attr measureAllChildren 0x0101010a +int attr measureWithLargestChild 0x010102d4 +int attr mediaRouteButtonStyle 0x010103ad +int attr mediaRouteTypes 0x010103ae +int attr menuCategory 0x010101de +int attr mimeType 0x01010026 +int attr min 0x01010539 +int attr minDate 0x0101033f +int attr minEms 0x0101015a +int attr minHeight 0x01010140 +int attr minLevel 0x010101b1 +int attr minLines 0x01010156 +int attr minResizeHeight 0x01010396 +int attr minResizeWidth 0x01010395 +int attr minSdkVersion 0x0101020c +int attr minWidth 0x0101013f +int attr minimumHorizontalAngle 0x0101047d +int attr minimumVerticalAngle 0x0101047e +int attr mipMap 0x010103cd +int attr mirrorForRtl 0x010103ce +int attr mode 0x0101017e +int attr moreIcon 0x01010135 +int attr multiArch 0x0101048e +int attr multiprocess 0x01010013 +int attr name 0x01010003 +int attr navigationBarColor 0x01010452 +int attr navigationBarDividerColor 0x0101056d +int attr navigationContentDescription 0x010104c1 +int attr navigationIcon 0x010104c0 +int attr navigationMode 0x010102cf +int attr negativeButtonText 0x010101f6 +int attr nestedScrollingEnabled 0x01010436 +int attr networkSecurityConfig 0x01010527 +int attr nextClusterForward 0x01010542 +int attr nextFocusDown 0x010100e4 +int attr nextFocusForward 0x0101033c +int attr nextFocusLeft 0x010100e1 +int attr nextFocusRight 0x010100e2 +int attr nextFocusUp 0x010100e3 +int attr noHistory 0x0101022d +int attr normalScreens 0x01010285 +int attr notificationTimeout 0x01010383 +int attr numColumns 0x01010118 +int attr numStars 0x01010144 +int attr numberPickerStyle 0x01010524 +int attr numbersBackgroundColor 0x010104a2 +int attr numbersInnerTextColor 0x010104e1 +int attr numbersSelectorColor 0x010104a3 +int attr numbersTextColor 0x010104a1 +int attr numeric 0x01010165 +int attr numericModifiers 0x0101054f +int attr numericShortcut 0x010101e4 +int attr offset 0x01010514 +int attr onClick 0x0101026f +int attr oneshot 0x01010197 +int attr opacity 0x0101031e +int attr order 0x010101ea +int attr orderInCategory 0x010101df +int attr ordering 0x010102e2 +int attr orderingFromXml 0x010101e7 +int attr orientation 0x010100c4 +int attr outAnimation 0x01010178 +int attr outlineProvider 0x010104b8 +int attr overScrollFooter 0x010102c3 +int attr overScrollHeader 0x010102c2 +int attr overScrollMode 0x010102c1 +int attr overlapAnchor 0x01010462 +int attr overridesImplicitlyEnabledSubtype 0x010103a2 +int attr packageNames 0x01010381 +int attr padding 0x010100d5 +int attr paddingBottom 0x010100d9 +int attr paddingEnd 0x010103b4 +int attr paddingHorizontal 0x0101053d +int attr paddingLeft 0x010100d6 +int attr paddingMode 0x01010457 +int attr paddingRight 0x010100d8 +int attr paddingStart 0x010103b3 +int attr paddingTop 0x010100d7 +int attr paddingVertical 0x0101053e +int attr panelBackground 0x0101005e +int attr panelColorBackground 0x01010061 +int attr panelColorForeground 0x01010060 +int attr panelFullBackground 0x0101005f +int attr panelTextAppearance 0x01010062 +int attr parentActivityName 0x010103a7 +int attr password 0x0101015c +int attr path 0x0101002a +int attr pathData 0x01010405 +int attr pathPattern 0x0101002c +int attr pathPrefix 0x0101002b +int attr patternPathData 0x010104ca +int attr permission 0x01010006 +int attr permissionFlags 0x010103c7 +int attr permissionGroup 0x0101000a +int attr permissionGroupFlags 0x010103c5 +int attr persistableMode 0x0101042d +int attr persistent 0x0101000d +int attr persistentDrawingCache 0x010100ee +int attr persistentWhenFeatureAvailable 0x01010563 +int attr phoneNumber 0x01010167 +int attr pivotX 0x010101b5 +int attr pivotY 0x010101b6 +int attr pointerIcon 0x01010509 +int attr popupAnimationStyle 0x010102c9 +int attr popupBackground 0x01010176 +int attr popupCharacters 0x01010244 +int attr popupElevation 0x0101048c +int attr popupEnterTransition 0x0101051f +int attr popupExitTransition 0x01010520 +int attr popupKeyboard 0x01010243 +int attr popupLayout 0x0101023b +int attr popupMenuStyle 0x01010300 +int attr popupTheme 0x010104a9 +int attr popupWindowStyle 0x01010076 +int attr port 0x01010029 +int attr positiveButtonText 0x010101f5 +int attr preferenceCategoryStyle 0x0101008c +int attr preferenceFragmentStyle 0x01010506 +int attr preferenceInformationStyle 0x0101008d +int attr preferenceLayoutChild 0x01010094 +int attr preferenceScreenStyle 0x0101008b +int attr preferenceStyle 0x0101008e +int attr presentationTheme 0x010103c0 +int attr previewImage 0x010102da +int attr primaryContentAlpha 0x01010552 +int attr priority 0x0101001c +int attr privateImeOptions 0x01010223 +int attr process 0x01010011 +int attr progress 0x01010137 +int attr progressBackgroundTint 0x01010465 +int attr progressBackgroundTintMode 0x01010466 +int attr progressBarPadding 0x01010319 +int attr progressBarStyle 0x01010077 +int attr progressBarStyleHorizontal 0x01010078 +int attr progressBarStyleInverse 0x01010287 +int attr progressBarStyleLarge 0x0101007a +int attr progressBarStyleLargeInverse 0x01010289 +int attr progressBarStyleSmall 0x01010079 +int attr progressBarStyleSmallInverse 0x01010288 +int attr progressBarStyleSmallTitle 0x0101020f +int attr progressDrawable 0x0101013c +int attr progressTint 0x01010463 +int attr progressTintMode 0x01010464 +int attr prompt 0x0101017b +int attr propertyName 0x010102e1 +int attr propertyXName 0x01010474 +int attr propertyYName 0x01010475 +int attr protectionLevel 0x01010009 +int attr publicKey 0x010103a6 +int attr queryActionMsg 0x010101db +int attr queryAfterZeroResults 0x01010282 +int attr queryBackground 0x01010487 +int attr queryHint 0x01010358 +int attr quickContactBadgeStyleSmallWindowLarge 0x010102b3 +int attr quickContactBadgeStyleSmallWindowMedium 0x010102b2 +int attr quickContactBadgeStyleSmallWindowSmall 0x010102b1 +int attr quickContactBadgeStyleWindowLarge 0x010102b0 +int attr quickContactBadgeStyleWindowMedium 0x010102af +int attr quickContactBadgeStyleWindowSmall 0x010102ae +int attr radioButtonStyle 0x0101007e +int attr radius 0x010101a8 +int attr rating 0x01010145 +int attr ratingBarStyle 0x0101007c +int attr ratingBarStyleIndicator 0x01010210 +int attr ratingBarStyleSmall 0x0101007d +int attr readPermission 0x01010007 +int attr recognitionService 0x0101049c +int attr recreateOnConfigChanges 0x01010547 +int attr recycleEnabled 0x01010559 +int attr relinquishTaskIdentity 0x01010476 +int attr reparent 0x010104bc +int attr reparentWithOverlay 0x010104bd +int attr repeatCount 0x010101bf +int attr repeatMode 0x010101c0 +int attr reqFiveWayNav 0x01010232 +int attr reqHardKeyboard 0x01010229 +int attr reqKeyboardType 0x01010228 +int attr reqNavigation 0x0101022a +int attr reqTouchScreen 0x01010227 +int attr requireDeviceUnlock 0x010103ec +int attr required 0x0101028e +int attr requiredAccountType 0x010103d6 +int attr requiredFeature 0x01010554 +int attr requiredForAllUsers 0x010103d0 +int attr requiredNotFeature 0x01010555 +int attr requiresFadingEdge 0x010103a5 +int attr requiresSmallestWidthDp 0x01010364 +int attr resizeClip 0x010104cf +int attr resizeMode 0x01010363 +int attr resizeable 0x0101028d +int attr resizeableActivity 0x010104f6 +int attr resource 0x01010025 +int attr restoreAnyVersion 0x010102ba +int attr restoreNeedsApplication 0x0101029d +int attr restrictedAccountType 0x010103d5 +int attr restrictionType 0x01010493 +int attr resumeWhilePausing 0x010104b2 +int attr reversible 0x0101044b +int attr revisionCode 0x010104d5 +int attr right 0x010101af +int attr ringtonePreferenceStyle 0x01010093 +int attr ringtoneType 0x010101f9 +int attr rotation 0x01010326 +int attr rotationAnimation 0x0101053a +int attr rotationX 0x01010327 +int attr rotationY 0x01010328 +int attr roundIcon 0x0101052c +int attr rowCount 0x01010375 +int attr rowDelay 0x010101d0 +int attr rowEdgeFlags 0x01010241 +int attr rowHeight 0x01010132 +int attr rowOrderPreserved 0x01010376 +int attr saveEnabled 0x010100e7 +int attr scaleGravity 0x010101fe +int attr scaleHeight 0x010101fd +int attr scaleType 0x0101011d +int attr scaleWidth 0x010101fc +int attr scaleX 0x01010324 +int attr scaleY 0x01010325 +int attr scheme 0x01010027 +int attr screenDensity 0x010102cb +int attr screenOrientation 0x0101001e +int attr screenSize 0x010102ca +int attr scrollHorizontally 0x0101015b +int attr scrollIndicators 0x010104e6 +int attr scrollViewStyle 0x01010080 +int attr scrollX 0x010100d2 +int attr scrollY 0x010100d3 +int attr scrollbarAlwaysDrawHorizontalTrack 0x01010068 +int attr scrollbarAlwaysDrawVerticalTrack 0x01010069 +int attr scrollbarDefaultDelayBeforeFade 0x010102a9 +int attr scrollbarFadeDuration 0x010102a8 +int attr scrollbarSize 0x01010063 +int attr scrollbarStyle 0x0101007f +int attr scrollbarThumbHorizontal 0x01010064 +int attr scrollbarThumbVertical 0x01010065 +int attr scrollbarTrackHorizontal 0x01010066 +int attr scrollbarTrackVertical 0x01010067 +int attr scrollbars 0x010100de +int attr scrollingCache 0x010100fe +int attr searchButtonText 0x01010205 +int attr searchHintIcon 0x010104d4 +int attr searchIcon 0x01010483 +int attr searchMode 0x010101d5 +int attr searchSettingsDescription 0x0101028a +int attr searchSuggestAuthority 0x010101d6 +int attr searchSuggestIntentAction 0x010101d9 +int attr searchSuggestIntentData 0x010101da +int attr searchSuggestPath 0x010101d7 +int attr searchSuggestSelection 0x010101d8 +int attr searchSuggestThreshold 0x0101026d +int attr searchViewStyle 0x01010480 +int attr secondaryContentAlpha 0x01010553 +int attr secondaryProgress 0x01010138 +int attr secondaryProgressTint 0x01010467 +int attr secondaryProgressTintMode 0x01010468 +int attr seekBarStyle 0x0101007b +int attr segmentedButtonStyle 0x01010330 +int attr selectAllOnFocus 0x0101015e +int attr selectable 0x010101e6 +int attr selectableItemBackground 0x0101030e +int attr selectableItemBackgroundBorderless 0x0101045c +int attr selectedDateVerticalBar 0x01010347 +int attr selectedWeekBackgroundColor 0x01010342 +int attr sessionService 0x0101043d +int attr settingsActivity 0x01010225 +int attr setupActivity 0x010103f6 +int attr shadowColor 0x01010161 +int attr shadowDx 0x01010162 +int attr shadowDy 0x01010163 +int attr shadowRadius 0x01010164 +int attr shape 0x0101019a +int attr shareInterpolator 0x010101bb +int attr sharedUserId 0x0101000b +int attr sharedUserLabel 0x01010261 +int attr shortcutDisabledMessage 0x0101052b +int attr shortcutId 0x01010528 +int attr shortcutLongLabel 0x0101052a +int attr shortcutShortLabel 0x01010529 +int attr shouldDisableView 0x010101ee +int attr showAsAction 0x010102d9 +int attr showDefault 0x010101fa +int attr showDividers 0x01010329 +int attr showForAllUsers 0x010104ef +int attr showMetadataInPreview 0x0101052f +int attr showOnLockScreen 0x010103c9 +int attr showSilent 0x010101fb +int attr showText 0x010104ad +int attr showWeekNumber 0x0101033e +int attr showWhenLocked 0x01010569 +int attr shownWeekCount 0x01010341 +int attr shrinkColumns 0x0101014a +int attr singleLine 0x0101015d +int attr singleLineTitle 0x0101055c +int attr singleUser 0x010103bf +int attr slideEdge 0x01010430 +int attr smallIcon 0x0101029e +int attr smallScreens 0x01010284 +int attr smoothScrollbar 0x01010231 +int attr soundEffectsEnabled 0x01010215 +int attr spacing 0x01010113 +int attr spinnerDropDownItemStyle 0x01010087 +int attr spinnerItemStyle 0x01010089 +int attr spinnerMode 0x010102f1 +int attr spinnerStyle 0x01010081 +int attr spinnersShown 0x0101034b +int attr splitMotionEvents 0x010102ef +int attr splitName 0x01010549 +int attr splitTrack 0x0101044c +int attr spotShadowAlpha 0x010104bf +int attr src 0x01010119 +int attr ssp 0x010103e3 +int attr sspPattern 0x010103e5 +int attr sspPrefix 0x010103e4 +int attr stackFromBottom 0x010100fd +int attr stackViewStyle 0x0101043e +int attr starStyle 0x01010082 +int attr start 0x010104db +int attr startColor 0x0101019d +int attr startDelay 0x010103e2 +int attr startOffset 0x010101be +int attr startX 0x01010510 +int attr startY 0x01010511 +int attr startYear 0x0101017c +int attr stateListAnimator 0x01010448 +int attr stateNotNeeded 0x01010016 +int attr state_above_anchor 0x010100aa +int attr state_accelerated 0x0101031b +int attr state_activated 0x010102fe +int attr state_active 0x010100a2 +int attr state_checkable 0x0101009f +int attr state_checked 0x010100a0 +int attr state_drag_can_accept 0x01010368 +int attr state_drag_hovered 0x01010369 +int attr state_empty 0x010100a9 +int attr state_enabled 0x0101009e +int attr state_expanded 0x010100a8 +int attr state_first 0x010100a4 +int attr state_focused 0x0101009c +int attr state_hovered 0x01010367 +int attr state_last 0x010100a6 +int attr state_long_pressable 0x0101023c +int attr state_middle 0x010100a5 +int attr state_multiline 0x0101034d +int attr state_pressed 0x010100a7 +int attr state_selected 0x010100a1 +int attr state_single 0x010100a3 +int attr state_window_focused 0x0101009d +int attr staticWallpaperPreview 0x01010331 +int attr statusBarColor 0x01010451 +int attr stepSize 0x01010146 +int attr stopWithTask 0x0101036a +int attr streamType 0x01010209 +int attr stretchColumns 0x01010149 +int attr stretchMode 0x01010116 +int attr strokeAlpha 0x010104cb +int attr strokeColor 0x01010406 +int attr strokeLineCap 0x0101040b +int attr strokeLineJoin 0x0101040c +int attr strokeMiterLimit 0x0101040d +int attr strokeWidth 0x01010407 +int attr subMenuArrow 0x010104f3 +int attr submitBackground 0x01010488 +int attr subtitle 0x010102d1 +int attr subtitleTextAppearance 0x0101042f +int attr subtitleTextColor 0x010104e4 +int attr subtitleTextStyle 0x010102f9 +int attr subtypeExtraValue 0x0101039a +int attr subtypeId 0x010103c1 +int attr subtypeLocale 0x01010399 +int attr suggestActionMsg 0x010101dc +int attr suggestActionMsgColumn 0x010101dd +int attr suggestionRowLayout 0x01010486 +int attr summary 0x010101e9 +int attr summaryColumn 0x010102a2 +int attr summaryOff 0x010101f0 +int attr summaryOn 0x010101ef +int attr supportsAssist 0x010104f0 +int attr supportsLaunchVoiceAssistFromKeyguard 0x010104f1 +int attr supportsLocalInteraction 0x0101050f +int attr supportsPictureInPicture 0x010104f7 +int attr supportsRtl 0x010103af +int attr supportsSwitchingToNextInputMethod 0x010103eb +int attr supportsUploading 0x0101029b +int attr switchMinWidth 0x01010370 +int attr switchPadding 0x01010371 +int attr switchPreferenceStyle 0x0101036d +int attr switchStyle 0x0101043f +int attr switchTextAppearance 0x0101036e +int attr switchTextOff 0x0101036c +int attr switchTextOn 0x0101036b +int attr syncable 0x01010019 +int attr tabStripEnabled 0x010102bd +int attr tabStripLeft 0x010102bb +int attr tabStripRight 0x010102bc +int attr tabWidgetStyle 0x01010083 +int attr tag 0x010100d1 +int attr targetActivity 0x01010202 +int attr targetClass 0x0101002f +int attr targetDescriptions 0x010103a0 +int attr targetId 0x010103dc +int attr targetName 0x0101044d +int attr targetPackage 0x01010021 +int attr targetProcesses 0x01010541 +int attr targetSandboxVersion 0x0101054c +int attr targetSdkVersion 0x01010270 +int attr taskAffinity 0x01010012 +int attr taskCloseEnterAnimation 0x010100be +int attr taskCloseExitAnimation 0x010100bf +int attr taskOpenEnterAnimation 0x010100bc +int attr taskOpenExitAnimation 0x010100bd +int attr taskToBackEnterAnimation 0x010100c2 +int attr taskToBackExitAnimation 0x010100c3 +int attr taskToFrontEnterAnimation 0x010100c0 +int attr taskToFrontExitAnimation 0x010100c1 +int attr tension 0x0101026a +int attr testOnly 0x01010272 +int attr text 0x0101014f +int attr textAlignment 0x010103b1 +int attr textAllCaps 0x0101038c +int attr textAppearance 0x01010034 +int attr textAppearanceButton 0x01010207 +int attr textAppearanceInverse 0x01010035 +int attr textAppearanceLarge 0x01010040 +int attr textAppearanceLargeInverse 0x01010043 +int attr textAppearanceLargePopupMenu 0x01010301 +int attr textAppearanceListItem 0x0101039e +int attr textAppearanceListItemSecondary 0x01010432 +int attr textAppearanceListItemSmall 0x0101039f +int attr textAppearanceMedium 0x01010041 +int attr textAppearanceMediumInverse 0x01010044 +int attr textAppearancePopupMenuHeader 0x01010502 +int attr textAppearanceSearchResultSubtitle 0x010102a0 +int attr textAppearanceSearchResultTitle 0x010102a1 +int attr textAppearanceSmall 0x01010042 +int attr textAppearanceSmallInverse 0x01010045 +int attr textAppearanceSmallPopupMenu 0x01010302 +int attr textCheckMark 0x01010046 +int attr textCheckMarkInverse 0x01010047 +int attr textColor 0x01010098 +int attr textColorAlertDialogListItem 0x01010306 +int attr textColorHighlight 0x01010099 +int attr textColorHighlightInverse 0x0101034f +int attr textColorHint 0x0101009a +int attr textColorHintInverse 0x0101003f +int attr textColorLink 0x0101009b +int attr textColorLinkInverse 0x01010350 +int attr textColorPrimary 0x01010036 +int attr textColorPrimaryDisableOnly 0x01010037 +int attr textColorPrimaryInverse 0x01010039 +int attr textColorPrimaryInverseDisableOnly 0x0101028b +int attr textColorPrimaryInverseNoDisable 0x0101003d +int attr textColorPrimaryNoDisable 0x0101003b +int attr textColorSecondary 0x01010038 +int attr textColorSecondaryInverse 0x0101003a +int attr textColorSecondaryInverseNoDisable 0x0101003e +int attr textColorSecondaryNoDisable 0x0101003c +int attr textColorTertiary 0x01010212 +int attr textColorTertiaryInverse 0x01010213 +int attr textCursorDrawable 0x01010362 +int attr textDirection 0x010103b0 +int attr textEditNoPasteWindowLayout 0x01010315 +int attr textEditPasteWindowLayout 0x01010314 +int attr textEditSideNoPasteWindowLayout 0x0101035f +int attr textEditSidePasteWindowLayout 0x0101035e +int attr textEditSuggestionItemLayout 0x01010374 +int attr textFilterEnabled 0x010100ff +int attr textIsSelectable 0x01010316 +int attr textOff 0x01010125 +int attr textOn 0x01010124 +int attr textScaleX 0x01010151 +int attr textSelectHandle 0x010102c7 +int attr textSelectHandleLeft 0x010102c5 +int attr textSelectHandleRight 0x010102c6 +int attr textSelectHandleWindowStyle 0x010102c8 +int attr textSize 0x01010095 +int attr textStyle 0x01010097 +int attr textSuggestionsWindowStyle 0x01010373 +int attr textViewStyle 0x01010084 +int attr theme 0x01010000 +int attr thickness 0x01010260 +int attr thicknessRatio 0x0101019c +int attr thumb 0x01010142 +int attr thumbOffset 0x01010143 +int attr thumbPosition 0x010104e5 +int attr thumbTextPadding 0x01010372 +int attr thumbTint 0x01010471 +int attr thumbTintMode 0x01010472 +int attr thumbnail 0x010102a5 +int attr tickMark 0x0101050a +int attr tickMarkTint 0x0101050b +int attr tickMarkTintMode 0x0101050c +int attr tileMode 0x01010201 +int attr tileModeX 0x01010477 +int attr tileModeY 0x01010478 +int attr timePickerDialogTheme 0x0101049e +int attr timePickerMode 0x010104b4 +int attr timePickerStyle 0x0101049d +int attr timeZone 0x010103cc +int attr tint 0x01010121 +int attr tintMode 0x010103fb +int attr title 0x010101e1 +int attr titleCondensed 0x010101e2 +int attr titleMargin 0x010104f8 +int attr titleMarginBottom 0x010104fc +int attr titleMarginEnd 0x010104fa +int attr titleMarginStart 0x010104f9 +int attr titleMarginTop 0x010104fb +int attr titleTextAppearance 0x0101042e +int attr titleTextColor 0x010104e3 +int attr titleTextStyle 0x010102f8 +int attr toAlpha 0x010101cb +int attr toDegrees 0x010101b4 +int attr toId 0x01010449 +int attr toScene 0x010103de +int attr toXDelta 0x010101c7 +int attr toXScale 0x010101c3 +int attr toYDelta 0x010101c9 +int attr toYScale 0x010101c5 +int attr toolbarStyle 0x010104aa +int attr tooltipText 0x01010534 +int attr top 0x010101ae +int attr topBright 0x010100cb +int attr topDark 0x010100c7 +int attr topLeftRadius 0x010101a9 +int attr topOffset 0x01010258 +int attr topRightRadius 0x010101aa +int attr touchscreenBlocksFocus 0x0101048f +int attr track 0x0101036f +int attr trackTint 0x010104d9 +int attr trackTintMode 0x010104da +int attr transcriptMode 0x01010100 +int attr transformPivotX 0x01010320 +int attr transformPivotY 0x01010321 +int attr transition 0x010103df +int attr transitionGroup 0x01010401 +int attr transitionName 0x01010400 +int attr transitionOrdering 0x010103e0 +int attr transitionVisibilityMode 0x0101047c +int attr translateX 0x0101045a +int attr translateY 0x0101045b +int attr translationX 0x01010322 +int attr translationY 0x01010323 +int attr translationZ 0x010103fa +int attr trimPathEnd 0x01010409 +int attr trimPathOffset 0x0101040a +int attr trimPathStart 0x01010408 +int attr tunerCount 0x0101051d +int attr turnScreenOn 0x0101056a +int attr type 0x010101a1 +int attr typeface 0x01010096 +int attr uiOptions 0x01010398 +int attr uncertainGestureColor 0x01010276 +int attr unfocusedMonthDateColor 0x01010344 +int attr unselectedAlpha 0x0101020e +int attr updatePeriodMillis 0x01010250 +int attr use32bitAbi 0x01010515 +int attr useDefaultMargins 0x01010379 +int attr useIntrinsicSizeAsMinimum 0x01010310 +int attr useLevel 0x0101019f +int attr userVisible 0x01010291 +int attr usesCleartextTraffic 0x010104ec +int attr value 0x01010024 +int attr valueFrom 0x010102de +int attr valueTo 0x010102df +int attr valueType 0x010102e0 +int attr variablePadding 0x01010195 +int attr vendor 0x010103e7 +int attr version 0x01010519 +int attr versionCode 0x0101021b +int attr versionName 0x0101021c +int attr verticalCorrection 0x0101023a +int attr verticalDivider 0x0101012e +int attr verticalGap 0x01010240 +int attr verticalScrollbarPosition 0x01010334 +int attr verticalSpacing 0x01010115 +int attr viewportHeight 0x01010403 +int attr viewportWidth 0x01010402 +int attr visibility 0x010100dc +int attr visible 0x01010194 +int attr visibleToInstantApps 0x01010531 +int attr vmSafeMode 0x010102b8 +int attr voiceIcon 0x01010484 +int attr voiceLanguage 0x01010255 +int attr voiceLanguageModel 0x01010253 +int attr voiceMaxResults 0x01010256 +int attr voicePromptText 0x01010254 +int attr voiceSearchMode 0x01010252 +int attr wallpaperCloseEnterAnimation 0x01010295 +int attr wallpaperCloseExitAnimation 0x01010296 +int attr wallpaperIntraCloseEnterAnimation 0x01010299 +int attr wallpaperIntraCloseExitAnimation 0x0101029a +int attr wallpaperIntraOpenEnterAnimation 0x01010297 +int attr wallpaperIntraOpenExitAnimation 0x01010298 +int attr wallpaperOpenEnterAnimation 0x01010293 +int attr wallpaperOpenExitAnimation 0x01010294 +int attr webTextViewStyle 0x010102b9 +int attr webViewStyle 0x01010085 +int attr weekDayTextAppearance 0x01010348 +int attr weekNumberColor 0x01010345 +int attr weekSeparatorLineColor 0x01010346 +int attr weightSum 0x01010128 +int attr widgetCategory 0x010103c4 +int attr widgetLayout 0x010101eb +int attr width 0x01010159 +int attr windowActionBar 0x010102cd +int attr windowActionBarOverlay 0x010102e4 +int attr windowActionModeOverlay 0x010102dd +int attr windowActivityTransitions 0x010104cd +int attr windowAllowEnterTransitionOverlap 0x0101043c +int attr windowAllowReturnTransitionOverlap 0x0101043b +int attr windowAnimationStyle 0x010100ae +int attr windowBackground 0x01010054 +int attr windowBackgroundFallback 0x01010503 +int attr windowClipToOutline 0x010104ab +int attr windowCloseOnTouchOutside 0x0101035b +int attr windowContentOverlay 0x01010059 +int attr windowContentTransitionManager 0x010103f9 +int attr windowContentTransitions 0x010103f8 +int attr windowDisablePreview 0x01010222 +int attr windowDrawsSystemBarBackgrounds 0x01010450 +int attr windowElevation 0x01010490 +int attr windowEnableSplitTouch 0x01010317 +int attr windowEnterAnimation 0x010100b4 +int attr windowEnterTransition 0x01010437 +int attr windowExitAnimation 0x010100b5 +int attr windowExitTransition 0x01010438 +int attr windowFrame 0x01010055 +int attr windowFullscreen 0x0101020d +int attr windowHideAnimation 0x010100b7 +int attr windowIsFloating 0x01010057 +int attr windowIsTranslucent 0x01010058 +int attr windowLayoutInDisplayCutoutMode 0x01010586 +int attr windowLightNavigationBar 0x0101056c +int attr windowLightStatusBar 0x010104e0 +int attr windowMinWidthMajor 0x01010356 +int attr windowMinWidthMinor 0x01010357 +int attr windowNoDisplay 0x0101021e +int attr windowNoTitle 0x01010056 +int attr windowOverscan 0x010103cf +int attr windowReenterTransition 0x010104af +int attr windowReturnTransition 0x010104ae +int attr windowSharedElementEnterTransition 0x01010439 +int attr windowSharedElementExitTransition 0x0101043a +int attr windowSharedElementReenterTransition 0x010104b1 +int attr windowSharedElementReturnTransition 0x010104b0 +int attr windowSharedElementsUseOverlay 0x010104bb +int attr windowShowAnimation 0x010100b6 +int attr windowShowWallpaper 0x01010292 +int attr windowSoftInputMode 0x0101022b +int attr windowSplashscreenContent 0x01010564 +int attr windowSwipeToDismiss 0x010103f3 +int attr windowTitleBackgroundStyle 0x0101005c +int attr windowTitleSize 0x0101005a +int attr windowTitleStyle 0x0101005b +int attr windowTransitionBackgroundFadeDuration 0x01010461 +int attr windowTranslucentNavigation 0x010103f0 +int attr windowTranslucentStatus 0x010103ef +int attr writePermission 0x01010008 +int attr x 0x010100ac +int attr xlargeScreens 0x010102bf +int attr y 0x010100ad +int attr yearListItemTextAppearance 0x01010499 +int attr yearListSelectorColor 0x0101049a +int attr yesNoPreferenceStyle 0x01010090 +int attr zAdjustment 0x010101c1 diff --git a/QYlogger/build/intermediates/bundles/debug/R.txt b/QYlogger/build/intermediates/bundles/debug/R.txt new file mode 100644 index 0000000..e69de29 diff --git a/QYlogger/build/intermediates/incremental/compileDebugAidl/dependency.store b/QYlogger/build/intermediates/incremental/compileDebugAidl/dependency.store new file mode 100644 index 0000000..8b8400d Binary files /dev/null and b/QYlogger/build/intermediates/incremental/compileDebugAidl/dependency.store differ diff --git a/QYlogger/build/intermediates/incremental/compileDebugAndroidTestAidl/dependency.store b/QYlogger/build/intermediates/incremental/compileDebugAndroidTestAidl/dependency.store new file mode 100644 index 0000000..8b8400d Binary files /dev/null and b/QYlogger/build/intermediates/incremental/compileDebugAndroidTestAidl/dependency.store differ diff --git a/QYlogger/build/intermediates/incremental/mergeDebugAndroidTestResources/compile-file-map.properties b/QYlogger/build/intermediates/incremental/mergeDebugAndroidTestResources/compile-file-map.properties new file mode 100644 index 0000000..b2c1c03 --- /dev/null +++ b/QYlogger/build/intermediates/incremental/mergeDebugAndroidTestResources/compile-file-map.properties @@ -0,0 +1 @@ +#Thu Jan 31 13:21:54 CST 2019 diff --git a/QYlogger/build/intermediates/incremental/mergeDebugAndroidTestResources/merger.xml b/QYlogger/build/intermediates/incremental/mergeDebugAndroidTestResources/merger.xml new file mode 100644 index 0000000..75596c0 --- /dev/null +++ b/QYlogger/build/intermediates/incremental/mergeDebugAndroidTestResources/merger.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/QYlogger/build/intermediates/incremental/packageDebugResources/compile-file-map.properties b/QYlogger/build/intermediates/incremental/packageDebugResources/compile-file-map.properties new file mode 100644 index 0000000..d550e09 --- /dev/null +++ b/QYlogger/build/intermediates/incremental/packageDebugResources/compile-file-map.properties @@ -0,0 +1 @@ +#Thu Jan 31 13:21:53 CST 2019 diff --git a/QYlogger/build/intermediates/incremental/packageDebugResources/merger.xml b/QYlogger/build/intermediates/incremental/packageDebugResources/merger.xml new file mode 100644 index 0000000..49487d3 --- /dev/null +++ b/QYlogger/build/intermediates/incremental/packageDebugResources/merger.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/QYlogger/build/intermediates/manifest/androidTest/debug/AndroidManifest.xml b/QYlogger/build/intermediates/manifest/androidTest/debug/AndroidManifest.xml new file mode 100644 index 0000000..4fff909 --- /dev/null +++ b/QYlogger/build/intermediates/manifest/androidTest/debug/AndroidManifest.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/QYlogger/build/intermediates/manifest/androidTest/debug/output.json b/QYlogger/build/intermediates/manifest/androidTest/debug/output.json new file mode 100644 index 0000000..ad41ed4 --- /dev/null +++ b/QYlogger/build/intermediates/manifest/androidTest/debug/output.json @@ -0,0 +1 @@ +[{"outputType":{"type":"MERGED_MANIFESTS"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":-1},"path":"AndroidManifest.xml","properties":{}}] \ No newline at end of file diff --git a/QYlogger/build/intermediates/manifests/aapt/debug/AndroidManifest.xml b/QYlogger/build/intermediates/manifests/aapt/debug/AndroidManifest.xml new file mode 100644 index 0000000..29965f7 --- /dev/null +++ b/QYlogger/build/intermediates/manifests/aapt/debug/AndroidManifest.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/QYlogger/build/intermediates/manifests/aapt/debug/output.json b/QYlogger/build/intermediates/manifests/aapt/debug/output.json new file mode 100644 index 0000000..4c7ab3f --- /dev/null +++ b/QYlogger/build/intermediates/manifests/aapt/debug/output.json @@ -0,0 +1 @@ +[{"outputType":{"type":"AAPT_FRIENDLY_MERGED_MANIFESTS"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":-1},"path":"AndroidManifest.xml","properties":{"packageId":"com.orhanobut.logger","split":""}}] \ No newline at end of file diff --git a/QYlogger/build/intermediates/manifests/full/debug/AndroidManifest.xml b/QYlogger/build/intermediates/manifests/full/debug/AndroidManifest.xml new file mode 100644 index 0000000..29965f7 --- /dev/null +++ b/QYlogger/build/intermediates/manifests/full/debug/AndroidManifest.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/QYlogger/build/intermediates/manifests/full/debug/output.json b/QYlogger/build/intermediates/manifests/full/debug/output.json new file mode 100644 index 0000000..4dee18b --- /dev/null +++ b/QYlogger/build/intermediates/manifests/full/debug/output.json @@ -0,0 +1 @@ +[{"outputType":{"type":"MERGED_MANIFESTS"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":-1},"path":"AndroidManifest.xml","properties":{"packageId":"com.orhanobut.logger","split":""}}] \ No newline at end of file diff --git a/QYlogger/build/intermediates/res/androidTest/debug/output.json b/QYlogger/build/intermediates/res/androidTest/debug/output.json new file mode 100644 index 0000000..66aa9e6 --- /dev/null +++ b/QYlogger/build/intermediates/res/androidTest/debug/output.json @@ -0,0 +1 @@ +[{"outputType":{"type":"PROCESSED_RES"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":-1},"path":"resources-debugAndroidTest.ap_","properties":{}}] \ No newline at end of file diff --git a/QYlogger/build/intermediates/res/androidTest/debug/resources-debugAndroidTest.ap_ b/QYlogger/build/intermediates/res/androidTest/debug/resources-debugAndroidTest.ap_ new file mode 100644 index 0000000..43e6796 Binary files /dev/null and b/QYlogger/build/intermediates/res/androidTest/debug/resources-debugAndroidTest.ap_ differ diff --git a/QYlogger/build/intermediates/res/debug/output.json b/QYlogger/build/intermediates/res/debug/output.json new file mode 100644 index 0000000..9406258 --- /dev/null +++ b/QYlogger/build/intermediates/res/debug/output.json @@ -0,0 +1 @@ +[{"outputType":{"type":"PROCESSED_RES"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":-1},"path":"resources-debug.ap_","properties":{"packageId":"com.orhanobut.logger","split":""}}] \ No newline at end of file diff --git a/QYlogger/build/intermediates/res/symbol-table-with-package/androidTest/debug/package-aware-r.txt b/QYlogger/build/intermediates/res/symbol-table-with-package/androidTest/debug/package-aware-r.txt new file mode 100644 index 0000000..3824c50 --- /dev/null +++ b/QYlogger/build/intermediates/res/symbol-table-with-package/androidTest/debug/package-aware-r.txt @@ -0,0 +1 @@ +com.orhanobut.logger.test diff --git a/QYlogger/build/intermediates/res/symbol-table-with-package/debug/package-aware-r.txt b/QYlogger/build/intermediates/res/symbol-table-with-package/debug/package-aware-r.txt new file mode 100644 index 0000000..7648d8a --- /dev/null +++ b/QYlogger/build/intermediates/res/symbol-table-with-package/debug/package-aware-r.txt @@ -0,0 +1 @@ +com.orhanobut.logger diff --git a/QYlogger/build/intermediates/symbols/androidTest/debug/R.txt b/QYlogger/build/intermediates/symbols/androidTest/debug/R.txt new file mode 100644 index 0000000..e69de29 diff --git a/QYlogger/build/outputs/logs/manifest-merger-debug-report.txt b/QYlogger/build/outputs/logs/manifest-merger-debug-report.txt new file mode 100644 index 0000000..6773aa4 --- /dev/null +++ b/QYlogger/build/outputs/logs/manifest-merger-debug-report.txt @@ -0,0 +1,17 @@ +-- Merging decision tree log --- +manifest +ADDED from E:\Github\Android\QYLogger\QYlogger\src\main\AndroidManifest.xml:1:1-43 +INJECTED from E:\Github\Android\QYLogger\QYlogger\src\main\AndroidManifest.xml:1:1-43 +INJECTED from E:\Github\Android\QYLogger\QYlogger\src\main\AndroidManifest.xml:1:1-43 + package + ADDED from E:\Github\Android\QYLogger\QYlogger\src\main\AndroidManifest.xml:1:11-41 + INJECTED from E:\Github\Android\QYLogger\QYlogger\src\main\AndroidManifest.xml + INJECTED from E:\Github\Android\QYLogger\QYlogger\src\main\AndroidManifest.xml +uses-sdk +INJECTED from E:\Github\Android\QYLogger\QYlogger\src\main\AndroidManifest.xml reason: use-sdk injection requested +INJECTED from E:\Github\Android\QYLogger\QYlogger\src\main\AndroidManifest.xml +INJECTED from E:\Github\Android\QYLogger\QYlogger\src\main\AndroidManifest.xml + android:minSdkVersion + INJECTED from E:\Github\Android\QYLogger\QYlogger\src\main\AndroidManifest.xml + ADDED from E:\Github\Android\QYLogger\QYlogger\src\main\AndroidManifest.xml + INJECTED from E:\Github\Android\QYLogger\QYlogger\src\main\AndroidManifest.xml diff --git a/QYlogger/gradle.properties b/QYlogger/gradle.properties new file mode 100644 index 0000000..c090841 --- /dev/null +++ b/QYlogger/gradle.properties @@ -0,0 +1,3 @@ +POM_NAME=Logger +POM_ARTIFACT_ID=logger +POM_PACKAGING=aar \ No newline at end of file diff --git a/QYlogger/src/main/AndroidManifest.xml b/QYlogger/src/main/AndroidManifest.xml new file mode 100644 index 0000000..6022e0f --- /dev/null +++ b/QYlogger/src/main/AndroidManifest.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/QYlogger/src/main/java/com/orhanobut/logger/AndroidLogAdapter.java b/QYlogger/src/main/java/com/orhanobut/logger/AndroidLogAdapter.java new file mode 100644 index 0000000..3eaedab --- /dev/null +++ b/QYlogger/src/main/java/com/orhanobut/logger/AndroidLogAdapter.java @@ -0,0 +1,41 @@ +package com.orhanobut.logger; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import static com.orhanobut.logger.Utils.checkNotNull; + +/** + * Android terminal log output implementation for {@link LogAdapter}. + * + * Prints output to LogCat with pretty borders. + * + *
+ *  ┌──────────────────────────
+ *  │ Method stack history
+ *  ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
+ *  │ Log message
+ *  └──────────────────────────
+ * 
+ */ +public class AndroidLogAdapter implements LogAdapter { + + @NonNull private final FormatStrategy formatStrategy; + + public AndroidLogAdapter() { + this.formatStrategy = PrettyFormatStrategy.newBuilder().build(); + } + + public AndroidLogAdapter(@NonNull FormatStrategy formatStrategy) { + this.formatStrategy = checkNotNull(formatStrategy); + } + + @Override public boolean isLoggable(int priority, @Nullable String tag) { + return true; + } + + @Override public void log(int priority, @Nullable String tag, @NonNull String message) { + formatStrategy.log(priority, tag, message); + } + +} diff --git a/QYlogger/src/main/java/com/orhanobut/logger/CsvFormatStrategy.java b/QYlogger/src/main/java/com/orhanobut/logger/CsvFormatStrategy.java new file mode 100644 index 0000000..3c170ff --- /dev/null +++ b/QYlogger/src/main/java/com/orhanobut/logger/CsvFormatStrategy.java @@ -0,0 +1,175 @@ +package com.orhanobut.logger; + +import android.os.Environment; +import android.os.Handler; +import android.os.HandlerThread; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +import static com.orhanobut.logger.Utils.checkNotNull; + +/** + * CSV formatted file logging for Android. + * Writes to CSV the following data: + * epoch timestamp, ISO8601 timestamp (human-readable), log level, tag, log message. + */ +public class CsvFormatStrategy implements FormatStrategy { + + private static final String NEW_LINE = System.getProperty("line.separator"); + private static final String NEW_LINE_REPLACEMENT = "
"; + private static final String SEPARATOR = ","; + + @NonNull + private final Date date; + @NonNull + private final SimpleDateFormat dateFormat; + @NonNull + private final LogStrategy logStrategy; + @Nullable + private final String tag; + + private CsvFormatStrategy(@NonNull Builder builder) { + checkNotNull(builder); + + date = builder.date; + dateFormat = builder.dateFormat; + logStrategy = builder.logStrategy; + tag = builder.tag; + } + + @NonNull + public static Builder newBuilder() { + return new Builder(); + } + + @Override + public void log(int priority, @Nullable String onceOnlyTag, @NonNull String message) { + + checkNotNull(message); + + String tag = formatTag(onceOnlyTag); + + date.setTime(System.currentTimeMillis()); + + StringBuilder builder = new StringBuilder(); + + // machine-readable date/time +// builder.append(Long.toString(date.getTime())); + + // human-readable date/time +// builder.append(SEPARATOR); + builder.append(dateFormat.format(date)); + + // level +// builder.append(SEPARATOR); +// builder.append(Utils.logLevel(priority)); + + // tag +// builder.append(SEPARATOR); +// builder.append(tag); + + // message + if (message.contains(NEW_LINE)) { + // a new line would break the CSV format, so we replace it here + message = message.replaceAll(NEW_LINE, NEW_LINE_REPLACEMENT); + } + builder.append(SEPARATOR); + builder.append(message); + + // new line + builder.append(NEW_LINE); + + logStrategy.log(priority, tag, builder.toString()); + } + + @Nullable + private String formatTag(@Nullable String tag) { + if (!Utils.isEmpty(tag) && !Utils.equals(this.tag, tag)) { + return this.tag + "-" + tag; + } + return this.tag; + } + + public static final class Builder { + private static final int MAX_BYTES = 500 * 1024; // 500K averages to a 4000 lines per file + + String path; + int level = -1; + Date date; + SimpleDateFormat dateFormat; + LogStrategy logStrategy; + String tag = "PRETTY_LOGGER"; + + private Builder() { + } + + @NonNull + public Builder date(@Nullable Date val) { + date = val; + return this; + } + + @NonNull + public Builder Path(@Nullable String val) { + path = val; + return this; + } + @NonNull + public Builder Level(int val) { + level = val; + return this; + } + + @NonNull + public Builder dateFormat(@Nullable SimpleDateFormat val) { + dateFormat = val; + return this; + } + + @NonNull + public Builder logStrategy(@Nullable LogStrategy val) { + logStrategy = val; + return this; + } + + @NonNull + public Builder tag(@Nullable String tag) { + this.tag = tag; + return this; + } + + @NonNull + public CsvFormatStrategy build() { + if (date == null) { + date = new Date(); + } + if (dateFormat == null) { + dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss.SSS", Locale.UK); + } + if (logStrategy == null) { + String dateStr = dateFormat.format(date); + String diskPath = Environment.getExternalStorageDirectory().getAbsolutePath(); +// String folder = diskPath + File.separatorChar + "logger_" + dateStr; +// String folderName = "logger_" + dateStr; + + String folder; + if (path == null) { + folder = diskPath + File.separatorChar + "logger"; + } else { + folder = diskPath + File.separatorChar + path; + } + + HandlerThread ht = new HandlerThread("AndroidFileLogger." + folder); + ht.start(); + Handler handler = new DiskLogStrategy.WriteHandler(ht.getLooper(), folder, MAX_BYTES , level); + logStrategy = new DiskLogStrategy(handler); + } + return new CsvFormatStrategy(this); + } + } +} diff --git a/QYlogger/src/main/java/com/orhanobut/logger/DiskLogAdapter.java b/QYlogger/src/main/java/com/orhanobut/logger/DiskLogAdapter.java new file mode 100644 index 0000000..2d4fb5c --- /dev/null +++ b/QYlogger/src/main/java/com/orhanobut/logger/DiskLogAdapter.java @@ -0,0 +1,31 @@ +package com.orhanobut.logger; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import static com.orhanobut.logger.Utils.checkNotNull; + +/** + * This is used to saves log messages to the disk. + * By default it uses {@link CsvFormatStrategy} to translates text message into CSV format. + */ +public class DiskLogAdapter implements LogAdapter { + + @NonNull private final FormatStrategy formatStrategy; + + public DiskLogAdapter() { + formatStrategy = CsvFormatStrategy.newBuilder().build(); + } + + public DiskLogAdapter(@NonNull FormatStrategy formatStrategy) { + this.formatStrategy = checkNotNull(formatStrategy); + } + + @Override public boolean isLoggable(int priority, @Nullable String tag) { + return true; + } + + @Override public void log(int priority, @Nullable String tag, @NonNull String message) { + formatStrategy.log(priority, tag, message); + } +} diff --git a/QYlogger/src/main/java/com/orhanobut/logger/DiskLogStrategy.java b/QYlogger/src/main/java/com/orhanobut/logger/DiskLogStrategy.java new file mode 100644 index 0000000..f8e5566 --- /dev/null +++ b/QYlogger/src/main/java/com/orhanobut/logger/DiskLogStrategy.java @@ -0,0 +1,145 @@ +package com.orhanobut.logger; + +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +import static com.orhanobut.logger.Utils.checkNotNull; + +/** + * Abstract class that takes care of background threading the file log operation on Android. + * implementing classes are free to directly perform I/O operations there. + *

+ * Writes all logs to the disk with CSV format. + */ +public class DiskLogStrategy implements LogStrategy { + + @NonNull + private final Handler handler; + + public DiskLogStrategy(@NonNull Handler handler) { + this.handler = checkNotNull(handler); + } + + @Override + public void log(int level, @Nullable String tag, @NonNull String message) { + checkNotNull(message); + + // do nothing on the calling thread, simply pass the tag/msg to the background thread + handler.sendMessage(handler.obtainMessage(level, message)); + } + + static class WriteHandler extends Handler { + + @NonNull + private final String folder; + private final int maxFileSize; + + private int level ; + + WriteHandler(@NonNull Looper looper, @NonNull String folder, int maxFileSize , int level) { + super(checkNotNull(looper)); + this.folder = checkNotNull(folder); + this.maxFileSize = maxFileSize; + this.level = level; + } + + @SuppressWarnings("checkstyle:emptyblock") + @Override + public void handleMessage(@NonNull Message msg) { + String content = (String) msg.obj; + + int lev = msg.what; + + if(lev != this.level && level != -1){ + return; + } + + String fileName = "logs_" + getSystemDate(); + + FileWriter fileWriter = null; + + File logFile = getLogFile(folder, fileName); + + try { + fileWriter = new FileWriter(logFile, true); + + writeLog(fileWriter, content); + + fileWriter.flush(); + fileWriter.close(); + } catch (IOException e) { + if (fileWriter != null) { + try { + fileWriter.flush(); + fileWriter.close(); + } catch (IOException e1) { /* fail silently */ } + } + } + } + + /** + * This is always called on a single background thread. + * Implementing classes must ONLY write to the fileWriter and nothing more. + * The abstract class takes care of everything else including close the stream and catching IOException + * + * @param fileWriter an instance of FileWriter already initialised to the correct file + */ + private void writeLog(@NonNull FileWriter fileWriter, @NonNull String content) throws IOException { + checkNotNull(fileWriter); + checkNotNull(content); + + fileWriter.append(content); + } + + private File getLogFile(@NonNull String folderName, @NonNull String fileName) { + checkNotNull(folderName); + checkNotNull(fileName); + + File folder = new File(folderName); + if (!folder.exists()) { + //TODO: What if folder is not created, what happens then? + folder.mkdirs(); + } + + int newFileCount = 0; + File newFile; + File existingFile = null; + +// String dateStr = getSystemDate(); + + newFile = new File(folder, String.format("%s_%s.txt", fileName, newFileCount)); + + while (newFile.exists()) { + existingFile = newFile; + newFileCount++; + newFile = new File(folder, String.format("%s_%s.txt", fileName, newFileCount)); + } + + if (existingFile != null) { + if (existingFile.length() >= maxFileSize) { + return newFile; + } + return existingFile; + } + + return newFile; + } + + public static String getSystemDate() { + SimpleDateFormat sDateFormat = new SimpleDateFormat( + "yyyy-MM-dd", Locale.US); + String date = sDateFormat.format(new Date()); + return date; + } + } +} diff --git a/QYlogger/src/main/java/com/orhanobut/logger/FormatStrategy.java b/QYlogger/src/main/java/com/orhanobut/logger/FormatStrategy.java new file mode 100644 index 0000000..2256dc8 --- /dev/null +++ b/QYlogger/src/main/java/com/orhanobut/logger/FormatStrategy.java @@ -0,0 +1,15 @@ +package com.orhanobut.logger; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +/** + * Used to determine how messages should be printed or saved. + * + * @see PrettyFormatStrategy + * @see CsvFormatStrategy + */ +public interface FormatStrategy { + + void log(int priority, @Nullable String tag, @NonNull String message); +} diff --git a/QYlogger/src/main/java/com/orhanobut/logger/LogAdapter.java b/QYlogger/src/main/java/com/orhanobut/logger/LogAdapter.java new file mode 100644 index 0000000..f58e54d --- /dev/null +++ b/QYlogger/src/main/java/com/orhanobut/logger/LogAdapter.java @@ -0,0 +1,33 @@ +package com.orhanobut.logger; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +/** + * Provides a common interface to emits logs through. This is a required contract for Logger. + * + * @see AndroidLogAdapter + * @see DiskLogAdapter + */ +public interface LogAdapter { + + /** + * Used to determine whether log should be printed out or not. + * + * @param priority is the log level e.g. DEBUG, WARNING + * @param tag is the given tag for the log message + * + * @return is used to determine if log should printed. + * If it is true, it will be printed, otherwise it'll be ignored. + */ + boolean isLoggable(int priority, @Nullable String tag); + + /** + * Each log will use this pipeline + * + * @param priority is the log level e.g. DEBUG, WARNING + * @param tag is the given tag for the log message. + * @param message is the given message for the log message. + */ + void log(int priority, @Nullable String tag, @NonNull String message); +} \ No newline at end of file diff --git a/QYlogger/src/main/java/com/orhanobut/logger/LogStrategy.java b/QYlogger/src/main/java/com/orhanobut/logger/LogStrategy.java new file mode 100644 index 0000000..ad7040f --- /dev/null +++ b/QYlogger/src/main/java/com/orhanobut/logger/LogStrategy.java @@ -0,0 +1,23 @@ +package com.orhanobut.logger; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +/** + * Determines destination target for the logs such as Disk, Logcat etc. + * + * @see LogcatLogStrategy + * @see DiskLogStrategy + */ +public interface LogStrategy { + + /** + * This is invoked by Logger each time a log message is processed. + * Interpret this method as last destination of the log in whole pipeline. + * + * @param priority is the log level e.g. DEBUG, WARNING + * @param tag is the given tag for the log message. + * @param message is the given message for the log message. + */ + void log(int priority, @Nullable String tag, @NonNull String message); +} diff --git a/QYlogger/src/main/java/com/orhanobut/logger/LogcatLogStrategy.java b/QYlogger/src/main/java/com/orhanobut/logger/LogcatLogStrategy.java new file mode 100644 index 0000000..1ead622 --- /dev/null +++ b/QYlogger/src/main/java/com/orhanobut/logger/LogcatLogStrategy.java @@ -0,0 +1,27 @@ +package com.orhanobut.logger; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.util.Log; + +import static com.orhanobut.logger.Utils.checkNotNull; + +/** + * LogCat implementation for {@link LogStrategy} + * + * This simply prints out all logs to Logcat by using standard {@link Log} class. + */ +public class LogcatLogStrategy implements LogStrategy { + + static final String DEFAULT_TAG = "NO_TAG"; + + @Override public void log(int priority, @Nullable String tag, @NonNull String message) { + checkNotNull(message); + + if (tag == null) { + tag = DEFAULT_TAG; + } + + Log.println(priority, tag, message); + } +} diff --git a/QYlogger/src/main/java/com/orhanobut/logger/Logger.java b/QYlogger/src/main/java/com/orhanobut/logger/Logger.java new file mode 100644 index 0000000..6a538f2 --- /dev/null +++ b/QYlogger/src/main/java/com/orhanobut/logger/Logger.java @@ -0,0 +1,160 @@ +package com.orhanobut.logger; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import static com.orhanobut.logger.Utils.checkNotNull; + +/** + *

+ *  ┌────────────────────────────────────────────
+ *  │ LOGGER
+ *  ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
+ *  │ Standard logging mechanism
+ *  ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
+ *  │ But more pretty, simple and powerful
+ *  └────────────────────────────────────────────
+ * 
+ * + *

How to use it

+ * Initialize it first + *

+ *   Logger.addLogAdapter(new AndroidLogAdapter());
+ * 
+ * + * And use the appropriate static Logger methods. + * + *

+ *   Logger.d("debug");
+ *   Logger.e("error");
+ *   Logger.w("warning");
+ *   Logger.v("verbose");
+ *   Logger.i("information");
+ *   Logger.wtf("What a Terrible Failure");
+ * 
+ * + *

String format arguments are supported

+ *

+ *   Logger.d("hello %s", "world");
+ * 
+ * + *

Collections are support ed(only available for debug logs)

+ *

+ *   Logger.d(MAP);
+ *   Logger.d(SET);
+ *   Logger.d(LIST);
+ *   Logger.d(ARRAY);
+ * 
+ * + *

Json and Xml support (output will be in debug level)

+ *

+ *   Logger.json(JSON_CONTENT);
+ *   Logger.xml(XML_CONTENT);
+ * 
+ * + *

Customize Logger

+ * Based on your needs, you can change the following settings: + * + * + * @see LogAdapter + * @see FormatStrategy + * @see LogStrategy + */ +public final class Logger { + + public static final int VERBOSE = 2; + public static final int DEBUG = 3; + public static final int INFO = 4; + public static final int WARN = 5; + public static final int ERROR = 6; + public static final int ASSERT = 7; + + @NonNull private static Printer printer = new LoggerPrinter(); + + private Logger() { + //no instance + } + + public static void printer(@NonNull Printer printer) { + Logger.printer = checkNotNull(printer); + } + + public static void addLogAdapter(@NonNull LogAdapter adapter) { + printer.addAdapter(checkNotNull(adapter)); + } + + public static void clearLogAdapters() { + printer.clearLogAdapters(); + } + + /** + * Given tag will be used as tag only once for this method call regardless of the tag that's been + * set during initialization. After this invocation, the general tag that's been set will + * be used for the subsequent log calls + */ + public static Printer t(@Nullable String tag) { + return printer.t(tag); + } + + /** + * General log function that accepts all configurations as parameter + */ + public static void log(int priority, @Nullable String tag, @Nullable String message, @Nullable Throwable throwable) { + printer.log(priority, tag, message, throwable); + } + + public static void d(@NonNull String message, @Nullable Object... args) { + printer.d(message, args); + } + + public static void d(@Nullable Object object) { + printer.d(object); + } + + public static void e(@NonNull String message, @Nullable Object... args) { + printer.e(null, message, args); + } + + public static void e(@Nullable Throwable throwable, @NonNull String message, @Nullable Object... args) { + printer.e(throwable, message, args); + } + + public static void i(@NonNull String message, @Nullable Object... args) { + printer.i(message, args); + } + + public static void v(@NonNull String message, @Nullable Object... args) { + printer.v(message, args); + } + + public static void w(@NonNull String message, @Nullable Object... args) { + printer.w(message, args); + } + + /** + * Tip: Use this for exceptional situations to log + * ie: Unexpected errors etc + */ + public static void wtf(@NonNull String message, @Nullable Object... args) { + printer.wtf(message, args); + } + + /** + * Formats the given json content and print it + */ + public static void json(@Nullable String json) { + printer.json(json); + } + + /** + * Formats the given xml content and print it + */ + public static void xml(@Nullable String xml) { + printer.xml(xml); + } + +} diff --git a/QYlogger/src/main/java/com/orhanobut/logger/LoggerPrinter.java b/QYlogger/src/main/java/com/orhanobut/logger/LoggerPrinter.java new file mode 100644 index 0000000..bdd2553 --- /dev/null +++ b/QYlogger/src/main/java/com/orhanobut/logger/LoggerPrinter.java @@ -0,0 +1,185 @@ +package com.orhanobut.logger; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.StringReader; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; + +import static com.orhanobut.logger.Logger.ASSERT; +import static com.orhanobut.logger.Logger.DEBUG; +import static com.orhanobut.logger.Logger.ERROR; +import static com.orhanobut.logger.Logger.INFO; +import static com.orhanobut.logger.Logger.VERBOSE; +import static com.orhanobut.logger.Logger.WARN; +import static com.orhanobut.logger.Utils.checkNotNull; + +class LoggerPrinter implements Printer { + + /** + * It is used for json pretty print + */ + private static final int JSON_INDENT = 2; + + /** + * Provides one-time used tag for the log message + */ + private final ThreadLocal localTag = new ThreadLocal<>(); + + private final List logAdapters = new ArrayList<>(); + + @Override public Printer t(String tag) { + if (tag != null) { + localTag.set(tag); + } + return this; + } + + @Override public void d(@NonNull String message, @Nullable Object... args) { + log(DEBUG, null, message, args); + } + + @Override public void d(@Nullable Object object) { + log(DEBUG, null, Utils.toString(object)); + } + + @Override public void e(@NonNull String message, @Nullable Object... args) { + e(null, message, args); + } + + @Override public void e(@Nullable Throwable throwable, @NonNull String message, @Nullable Object... args) { + log(ERROR, throwable, message, args); + } + + @Override public void w(@NonNull String message, @Nullable Object... args) { + log(WARN, null, message, args); + } + + @Override public void i(@NonNull String message, @Nullable Object... args) { + log(INFO, null, message, args); + } + + @Override public void v(@NonNull String message, @Nullable Object... args) { + log(VERBOSE, null, message, args); + } + + @Override public void wtf(@NonNull String message, @Nullable Object... args) { + log(ASSERT, null, message, args); + } + + @Override public void json(@Nullable String json) { + if (Utils.isEmpty(json)) { + d("Empty/Null json content"); + return; + } + try { + json = json.trim(); + if (json.startsWith("{")) { + JSONObject jsonObject = new JSONObject(json); + String message = jsonObject.toString(JSON_INDENT); + d(message); + return; + } + if (json.startsWith("[")) { + JSONArray jsonArray = new JSONArray(json); + String message = jsonArray.toString(JSON_INDENT); + d(message); + return; + } + e("Invalid Json"); + } catch (JSONException e) { + e("Invalid Json"); + } + } + + @Override public void xml(@Nullable String xml) { + if (Utils.isEmpty(xml)) { + d("Empty/Null xml content"); + return; + } + try { + Source xmlInput = new StreamSource(new StringReader(xml)); + StreamResult xmlOutput = new StreamResult(new StringWriter()); + Transformer transformer = TransformerFactory.newInstance().newTransformer(); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); + transformer.transform(xmlInput, xmlOutput); + d(xmlOutput.getWriter().toString().replaceFirst(">", ">\n")); + } catch (TransformerException e) { + e("Invalid xml"); + } + } + + @Override public synchronized void log(int priority, + @Nullable String tag, + @Nullable String message, + @Nullable Throwable throwable) { + if (throwable != null && message != null) { + message += " : " + Utils.getStackTraceString(throwable); + } + if (throwable != null && message == null) { + message = Utils.getStackTraceString(throwable); + } + if (Utils.isEmpty(message)) { + message = "Empty/NULL log message"; + } + + for (LogAdapter adapter : logAdapters) { + if (adapter.isLoggable(priority, tag)) { + adapter.log(priority, tag, message); + } + } + } + + @Override public void clearLogAdapters() { + logAdapters.clear(); + } + + @Override public void addAdapter(@NonNull LogAdapter adapter) { + logAdapters.add(checkNotNull(adapter)); + } + + /** + * This method is synchronized in order to avoid messy of logs' order. + */ + private synchronized void log(int priority, + @Nullable Throwable throwable, + @NonNull String msg, + @Nullable Object... args) { + checkNotNull(msg); + + String tag = getTag(); + String message = createMessage(msg, args); + log(priority, tag, message, throwable); + } + + /** + * @return the appropriate tag based on local or global + */ + @Nullable private String getTag() { + String tag = localTag.get(); + if (tag != null) { + localTag.remove(); + return tag; + } + return null; + } + + @NonNull private String createMessage(@NonNull String message, @Nullable Object... args) { + return args == null || args.length == 0 ? message : String.format(message, args); + } +} diff --git a/QYlogger/src/main/java/com/orhanobut/logger/PrettyFormatStrategy.java b/QYlogger/src/main/java/com/orhanobut/logger/PrettyFormatStrategy.java new file mode 100644 index 0000000..74e33ad --- /dev/null +++ b/QYlogger/src/main/java/com/orhanobut/logger/PrettyFormatStrategy.java @@ -0,0 +1,256 @@ +package com.orhanobut.logger; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import static com.orhanobut.logger.Utils.checkNotNull; + +/** + * Draws borders around the given log message along with additional information such as : + * + *
    + *
  • Thread information
  • + *
  • Method stack trace
  • + *
+ * + *
+ *  ┌──────────────────────────
+ *  │ Method stack history
+ *  ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
+ *  │ Thread information
+ *  ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
+ *  │ Log message
+ *  └──────────────────────────
+ * 
+ * + *

Customize

+ *

+ *   FormatStrategy formatStrategy = PrettyFormatStrategy.newBuilder()
+ *       .showThreadInfo(false)  // (Optional) Whether to show thread info or not. Default true
+ *       .methodCount(0)         // (Optional) How many method line to show. Default 2
+ *       .methodOffset(7)        // (Optional) Hides internal method calls up to offset. Default 5
+ *       .logStrategy(customLog) // (Optional) Changes the log strategy to print out. Default LogCat
+ *       .tag("My custom tag")   // (Optional) Global tag for every log. Default PRETTY_LOGGER
+ *       .build();
+ * 
+ */ +public class PrettyFormatStrategy implements FormatStrategy { + + /** + * Android's max limit for a log entry is ~4076 bytes, + * so 4000 bytes is used as chunk size since default charset + * is UTF-8 + */ + private static final int CHUNK_SIZE = 4000; + + /** + * The minimum stack trace index, starts at this class after two native calls. + */ + private static final int MIN_STACK_OFFSET = 5; + + /** + * Drawing toolbox + */ + private static final char TOP_LEFT_CORNER = '┌'; + private static final char BOTTOM_LEFT_CORNER = '└'; + private static final char MIDDLE_CORNER = '├'; + private static final char HORIZONTAL_LINE = '│'; + private static final String DOUBLE_DIVIDER = "────────────────────────────────────────────────────────"; + private static final String SINGLE_DIVIDER = "┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄"; + private static final String TOP_BORDER = TOP_LEFT_CORNER + DOUBLE_DIVIDER + DOUBLE_DIVIDER; + private static final String BOTTOM_BORDER = BOTTOM_LEFT_CORNER + DOUBLE_DIVIDER + DOUBLE_DIVIDER; + private static final String MIDDLE_BORDER = MIDDLE_CORNER + SINGLE_DIVIDER + SINGLE_DIVIDER; + + private final int methodCount; + private final int methodOffset; + private final boolean showThreadInfo; + @NonNull private final LogStrategy logStrategy; + @Nullable private final String tag; + + private PrettyFormatStrategy(@NonNull Builder builder) { + checkNotNull(builder); + + methodCount = builder.methodCount; + methodOffset = builder.methodOffset; + showThreadInfo = builder.showThreadInfo; + logStrategy = builder.logStrategy; + tag = builder.tag; + } + + @NonNull public static Builder newBuilder() { + return new Builder(); + } + + @Override public void log(int priority, @Nullable String onceOnlyTag, @NonNull String message) { + checkNotNull(message); + + String tag = formatTag(onceOnlyTag); + + logTopBorder(priority, tag); + logHeaderContent(priority, tag, methodCount); + + //get bytes of message with system's default charset (which is UTF-8 for Android) + byte[] bytes = message.getBytes(); + int length = bytes.length; + if (length <= CHUNK_SIZE) { + if (methodCount > 0) { + logDivider(priority, tag); + } + logContent(priority, tag, message); + logBottomBorder(priority, tag); + return; + } + if (methodCount > 0) { + logDivider(priority, tag); + } + for (int i = 0; i < length; i += CHUNK_SIZE) { + int count = Math.min(length - i, CHUNK_SIZE); + //create a new String with system's default charset (which is UTF-8 for Android) + logContent(priority, tag, new String(bytes, i, count)); + } + logBottomBorder(priority, tag); + } + + private void logTopBorder(int logType, @Nullable String tag) { + logChunk(logType, tag, TOP_BORDER); + } + + @SuppressWarnings("StringBufferReplaceableByString") + private void logHeaderContent(int logType, @Nullable String tag, int methodCount) { + StackTraceElement[] trace = Thread.currentThread().getStackTrace(); + if (showThreadInfo) { + logChunk(logType, tag, HORIZONTAL_LINE + " Thread: " + Thread.currentThread().getName()); + logDivider(logType, tag); + } + String level = ""; + + int stackOffset = getStackOffset(trace) + methodOffset; + + //corresponding method count with the current stack may exceeds the stack trace. Trims the count + if (methodCount + stackOffset > trace.length) { + methodCount = trace.length - stackOffset - 1; + } + + for (int i = methodCount; i > 0; i--) { + int stackIndex = i + stackOffset; + if (stackIndex >= trace.length) { + continue; + } + StringBuilder builder = new StringBuilder(); + builder.append(HORIZONTAL_LINE) + .append(' ') + .append(level) + .append(getSimpleClassName(trace[stackIndex].getClassName())) + .append(".") + .append(trace[stackIndex].getMethodName()) + .append(" ") + .append(" (") + .append(trace[stackIndex].getFileName()) + .append(":") + .append(trace[stackIndex].getLineNumber()) + .append(")"); + level += " "; + logChunk(logType, tag, builder.toString()); + } + } + + private void logBottomBorder(int logType, @Nullable String tag) { + logChunk(logType, tag, BOTTOM_BORDER); + } + + private void logDivider(int logType, @Nullable String tag) { + logChunk(logType, tag, MIDDLE_BORDER); + } + + private void logContent(int logType, @Nullable String tag, @NonNull String chunk) { + checkNotNull(chunk); + + String[] lines = chunk.split(System.getProperty("line.separator")); + for (String line : lines) { + logChunk(logType, tag, HORIZONTAL_LINE + " " + line); + } + } + + private void logChunk(int priority, @Nullable String tag, @NonNull String chunk) { + checkNotNull(chunk); + + logStrategy.log(priority, tag, chunk); + } + + private String getSimpleClassName(@NonNull String name) { + checkNotNull(name); + + int lastIndex = name.lastIndexOf("."); + return name.substring(lastIndex + 1); + } + + /** + * Determines the starting index of the stack trace, after method calls made by this class. + * + * @param trace the stack trace + * @return the stack offset + */ + private int getStackOffset(@NonNull StackTraceElement[] trace) { + checkNotNull(trace); + + for (int i = MIN_STACK_OFFSET; i < trace.length; i++) { + StackTraceElement e = trace[i]; + String name = e.getClassName(); + if (!name.equals(LoggerPrinter.class.getName()) && !name.equals(Logger.class.getName())) { + return --i; + } + } + return -1; + } + + @Nullable private String formatTag(@Nullable String tag) { + if (!Utils.isEmpty(tag) && !Utils.equals(this.tag, tag)) { + return this.tag + "-" + tag; + } + return this.tag; + } + + public static class Builder { + int methodCount = 2; + int methodOffset = 0; + boolean showThreadInfo = true; + @Nullable LogStrategy logStrategy; + @Nullable String tag = "PRETTY_LOGGER"; + + private Builder() { + } + + @NonNull public Builder methodCount(int val) { + methodCount = val; + return this; + } + + @NonNull public Builder methodOffset(int val) { + methodOffset = val; + return this; + } + + @NonNull public Builder showThreadInfo(boolean val) { + showThreadInfo = val; + return this; + } + + @NonNull public Builder logStrategy(@Nullable LogStrategy val) { + logStrategy = val; + return this; + } + + @NonNull public Builder tag(@Nullable String tag) { + this.tag = tag; + return this; + } + + @NonNull public PrettyFormatStrategy build() { + if (logStrategy == null) { + logStrategy = new LogcatLogStrategy(); + } + return new PrettyFormatStrategy(this); + } + } + +} diff --git a/QYlogger/src/main/java/com/orhanobut/logger/Printer.java b/QYlogger/src/main/java/com/orhanobut/logger/Printer.java new file mode 100644 index 0000000..9fad8de --- /dev/null +++ b/QYlogger/src/main/java/com/orhanobut/logger/Printer.java @@ -0,0 +1,45 @@ +package com.orhanobut.logger; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +/** + * A proxy interface to enable additional operations. + * Contains all possible Log message usages. + */ +public interface Printer { + + void addAdapter(@NonNull LogAdapter adapter); + + Printer t(@Nullable String tag); + + void d(@NonNull String message, @Nullable Object... args); + + void d(@Nullable Object object); + + void e(@NonNull String message, @Nullable Object... args); + + void e(@Nullable Throwable throwable, @NonNull String message, @Nullable Object... args); + + void w(@NonNull String message, @Nullable Object... args); + + void i(@NonNull String message, @Nullable Object... args); + + void v(@NonNull String message, @Nullable Object... args); + + void wtf(@NonNull String message, @Nullable Object... args); + + /** + * Formats the given json content and print it + */ + void json(@Nullable String json); + + /** + * Formats the given xml content and print it + */ + void xml(@Nullable String xml); + + void log(int priority, @Nullable String tag, @Nullable String message, @Nullable Throwable throwable); + + void clearLogAdapters(); +} diff --git a/QYlogger/src/main/java/com/orhanobut/logger/Utils.java b/QYlogger/src/main/java/com/orhanobut/logger/Utils.java new file mode 100644 index 0000000..1789de2 --- /dev/null +++ b/QYlogger/src/main/java/com/orhanobut/logger/Utils.java @@ -0,0 +1,157 @@ +package com.orhanobut.logger; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.net.UnknownHostException; +import java.util.Arrays; + +import static com.orhanobut.logger.Logger.ASSERT; +import static com.orhanobut.logger.Logger.DEBUG; +import static com.orhanobut.logger.Logger.ERROR; +import static com.orhanobut.logger.Logger.INFO; +import static com.orhanobut.logger.Logger.VERBOSE; +import static com.orhanobut.logger.Logger.WARN; + +/** + * Provides convenient methods to some common operations + */ +final class Utils { + + private Utils() { + // Hidden constructor. + } + + /** + * Returns true if the string is null or 0-length. + * + * @param str the string to be examined + * @return true if str is null or zero length + */ + static boolean isEmpty(CharSequence str) { + return str == null || str.length() == 0; + } + + /** + * Returns true if a and b are equal, including if they are both null. + *

Note: In platform versions 1.1 and earlier, this method only worked well if + * both the arguments were instances of String.

+ * + * @param a first CharSequence to check + * @param b second CharSequence to check + * @return true if a and b are equal + *

+ * NOTE: Logic slightly change due to strict policy on CI - + * "Inner assignments should be avoided" + */ + static boolean equals(CharSequence a, CharSequence b) { + if (a == b) return true; + if (a != null && b != null) { + int length = a.length(); + if (length == b.length()) { + if (a instanceof String && b instanceof String) { + return a.equals(b); + } else { + for (int i = 0; i < length; i++) { + if (a.charAt(i) != b.charAt(i)) return false; + } + return true; + } + } + } + return false; + } + + /** + * Copied from "android.util.Log.getStackTraceString()" in order to avoid usage of Android stack + * in unit tests. + * + * @return Stack trace in form of String + */ + static String getStackTraceString(Throwable tr) { + if (tr == null) { + return ""; + } + + // This is to reduce the amount of log spew that apps do in the non-error + // condition of the network being unavailable. + Throwable t = tr; + while (t != null) { + if (t instanceof UnknownHostException) { + return ""; + } + t = t.getCause(); + } + + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + tr.printStackTrace(pw); + pw.flush(); + return sw.toString(); + } + + static String logLevel(int value) { + switch (value) { + case VERBOSE: + return "VERBOSE"; + case DEBUG: + return "DEBUG"; + case INFO: + return "INFO"; + case WARN: + return "WARN"; + case ERROR: + return "ERROR"; + case ASSERT: + return "ASSERT"; + default: + return "UNKNOWN"; + } + } + + public static String toString(Object object) { + if (object == null) { + return "null"; + } + if (!object.getClass().isArray()) { + return object.toString(); + } + if (object instanceof boolean[]) { + return Arrays.toString((boolean[]) object); + } + if (object instanceof byte[]) { + return Arrays.toString((byte[]) object); + } + if (object instanceof char[]) { + return Arrays.toString((char[]) object); + } + if (object instanceof short[]) { + return Arrays.toString((short[]) object); + } + if (object instanceof int[]) { + return Arrays.toString((int[]) object); + } + if (object instanceof long[]) { + return Arrays.toString((long[]) object); + } + if (object instanceof float[]) { + return Arrays.toString((float[]) object); + } + if (object instanceof double[]) { + return Arrays.toString((double[]) object); + } + if (object instanceof Object[]) { + return Arrays.deepToString((Object[]) object); + } + return "Couldn't find a correct type for the object"; + } + + @NonNull static T checkNotNull(@Nullable final T obj) { + if (obj == null) { + throw new NullPointerException(); + } + return obj; + } +} diff --git a/QYlogger/src/test/java/com.orhanobut.logger/AndroidLogAdapterTest.kt b/QYlogger/src/test/java/com.orhanobut.logger/AndroidLogAdapterTest.kt new file mode 100644 index 0000000..30851a5 --- /dev/null +++ b/QYlogger/src/test/java/com.orhanobut.logger/AndroidLogAdapterTest.kt @@ -0,0 +1,27 @@ +package com.orhanobut.logger + +import org.junit.Test + +import com.google.common.truth.Truth.assertThat +import com.orhanobut.logger.Logger.DEBUG +import org.mockito.Mockito.mock +import org.mockito.Mockito.verify + +class AndroidLogAdapterTest { + + @Test fun isLoggable() { + val logAdapter = AndroidLogAdapter() + + assertThat(logAdapter.isLoggable(DEBUG, "tag")).isTrue() + } + + @Test fun log() { + val formatStrategy = mock(FormatStrategy::class.java) + val logAdapter = AndroidLogAdapter(formatStrategy) + + logAdapter.log(DEBUG, null, "message") + + verify(formatStrategy).log(DEBUG, null, "message") + } + +} \ No newline at end of file diff --git a/QYlogger/src/test/java/com.orhanobut.logger/CsvFormatStrategyTest.kt b/QYlogger/src/test/java/com.orhanobut.logger/CsvFormatStrategyTest.kt new file mode 100644 index 0000000..0f26e52 --- /dev/null +++ b/QYlogger/src/test/java/com.orhanobut.logger/CsvFormatStrategyTest.kt @@ -0,0 +1,37 @@ +package com.orhanobut.logger + +import org.junit.Test + +import com.google.common.truth.Truth.assertThat + +class CsvFormatStrategyTest { + + @Test fun log() { + val formatStrategy = CsvFormatStrategy.newBuilder() + .logStrategy { priority, tag, message -> + assertThat(tag).isEqualTo("PRETTY_LOGGER-tag") + assertThat(priority).isEqualTo(Logger.VERBOSE) + assertThat(message).contains("VERBOSE,PRETTY_LOGGER-tag,message") + } + .build() + + formatStrategy.log(Logger.VERBOSE, "tag", "message") + } + + @Test fun defaultTag() { + val formatStrategy = CsvFormatStrategy.newBuilder() + .logStrategy { priority, tag, message -> assertThat(tag).isEqualTo("PRETTY_LOGGER") } + .build() + + formatStrategy.log(Logger.VERBOSE, null, "message") + } + + @Test fun customTag() { + val formatStrategy = CsvFormatStrategy.newBuilder() + .tag("custom") + .logStrategy { priority, tag, message -> assertThat(tag).isEqualTo("custom") } + .build() + + formatStrategy.log(Logger.VERBOSE, null, "message") + } +} diff --git a/QYlogger/src/test/java/com.orhanobut.logger/DiskLogAdapterTest.kt b/QYlogger/src/test/java/com.orhanobut.logger/DiskLogAdapterTest.kt new file mode 100644 index 0000000..ef0b6b8 --- /dev/null +++ b/QYlogger/src/test/java/com.orhanobut.logger/DiskLogAdapterTest.kt @@ -0,0 +1,42 @@ +package com.orhanobut.logger + +import com.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Test +import org.mockito.Mock +import org.mockito.Mockito.verify +import org.mockito.MockitoAnnotations.initMocks + +class DiskLogAdapterTest { + + @Mock private lateinit var formatStrategy: FormatStrategy + + @Before fun setup() { + initMocks(this) + } + + @Test fun isLoggableTrue() { + val logAdapter = DiskLogAdapter(formatStrategy) + + assertThat(logAdapter.isLoggable(Logger.VERBOSE, "tag")).isTrue() + } + + @Test fun isLoggableFalse() { + val logAdapter = object : DiskLogAdapter(formatStrategy) { + override fun isLoggable(priority: Int, tag: String?): Boolean { + return false + } + } + + assertThat(logAdapter.isLoggable(Logger.VERBOSE, "tag")).isFalse() + } + + @Test fun log() { + val logAdapter = DiskLogAdapter(formatStrategy) + + logAdapter.log(Logger.VERBOSE, "tag", "message") + + verify(formatStrategy).log(Logger.VERBOSE, "tag", "message") + } + +} diff --git a/QYlogger/src/test/java/com.orhanobut.logger/DiskLogStrategyTest.kt b/QYlogger/src/test/java/com.orhanobut.logger/DiskLogStrategyTest.kt new file mode 100644 index 0000000..b8c4acd --- /dev/null +++ b/QYlogger/src/test/java/com.orhanobut.logger/DiskLogStrategyTest.kt @@ -0,0 +1,22 @@ +package com.orhanobut.logger + +import android.os.Handler + +import org.junit.Test + +import com.orhanobut.logger.Logger.DEBUG +import org.mockito.Mockito.mock +import org.mockito.Mockito.verify + +class DiskLogStrategyTest { + + @Test fun log() { + val handler = mock(Handler::class.java) + val logStrategy = DiskLogStrategy(handler) + + logStrategy.log(DEBUG, "tag", "message") + + verify(handler).sendMessage(handler.obtainMessage(DEBUG, "message")) + } + +} \ No newline at end of file diff --git a/QYlogger/src/test/java/com.orhanobut.logger/LogAssert.kt b/QYlogger/src/test/java/com.orhanobut.logger/LogAssert.kt new file mode 100644 index 0000000..0fda48d --- /dev/null +++ b/QYlogger/src/test/java/com.orhanobut.logger/LogAssert.kt @@ -0,0 +1,70 @@ +package com.orhanobut.logger + +import com.google.common.truth.Truth.assertThat + +internal class LogAssert(private val items: MutableList, tag: String?, private val priority: Int) { + + private val tag: String + + private var index = 0 + + init { + this.tag = tag ?: DEFAULT_TAG + } + + fun hasTopBorder(): LogAssert { + return hasLog(priority, tag, TOP_BORDER) + } + + fun hasBottomBorder(): LogAssert { + return hasLog(priority, tag, BOTTOM_BORDER) + } + + fun hasMiddleBorder(): LogAssert { + return hasLog(priority, tag, MIDDLE_BORDER) + } + + fun hasThread(threadName: String): LogAssert { + return hasLog(priority, tag, "$HORIZONTAL_LINE Thread: $threadName") + } + + fun hasMethodInfo(methodInfo: String): LogAssert { + return hasLog(priority, tag, "$HORIZONTAL_LINE $methodInfo") + } + + fun hasMessage(message: String): LogAssert { + return hasLog(priority, tag, "$HORIZONTAL_LINE $message") + } + + private fun hasLog(priority: Int, tag: String, message: String): LogAssert = apply { + val item = items[index++] + assertThat(item.priority).isEqualTo(priority) + assertThat(item.tag).isEqualTo(tag) + assertThat(item.message).isEqualTo(message) + } + + fun skip(): LogAssert = apply { + index++ + } + + fun hasNoMoreMessages() { + assertThat(items).hasSize(index) + items.clear() + } + + internal class LogItem(val priority: Int, val tag: String, val message: String) + + companion object { + private const val DEFAULT_TAG = "PRETTY_LOGGER" + + private const val TOP_LEFT_CORNER = '┌' + private const val BOTTOM_LEFT_CORNER = '└' + private const val MIDDLE_CORNER = '├' + private const val HORIZONTAL_LINE = '│' + private const val DOUBLE_DIVIDER = "────────────────────────────────────────────────────────" + private const val SINGLE_DIVIDER = "┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄" + private val TOP_BORDER = TOP_LEFT_CORNER + DOUBLE_DIVIDER + DOUBLE_DIVIDER + private val BOTTOM_BORDER = BOTTOM_LEFT_CORNER + DOUBLE_DIVIDER + DOUBLE_DIVIDER + private val MIDDLE_BORDER = MIDDLE_CORNER + SINGLE_DIVIDER + SINGLE_DIVIDER + } +} diff --git a/QYlogger/src/test/java/com.orhanobut.logger/LogcatLogStrategyTest.kt b/QYlogger/src/test/java/com.orhanobut.logger/LogcatLogStrategyTest.kt new file mode 100644 index 0000000..a005219 --- /dev/null +++ b/QYlogger/src/test/java/com.orhanobut.logger/LogcatLogStrategyTest.kt @@ -0,0 +1,35 @@ +package com.orhanobut.logger + +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config +import org.robolectric.shadows.ShadowLog + +import com.google.common.truth.Truth.assertThat +import com.orhanobut.logger.Logger.DEBUG + +@RunWith(RobolectricTestRunner::class) +class LogcatLogStrategyTest { + + @Test fun log() { + val logStrategy = LogcatLogStrategy() + + logStrategy.log(DEBUG, "tag", "message") + + val logItems = ShadowLog.getLogs() + assertThat(logItems[0].type).isEqualTo(DEBUG) + assertThat(logItems[0].msg).isEqualTo("message") + assertThat(logItems[0].tag).isEqualTo("tag") + } + + @Test fun logWithNullTag() { + val logStrategy = LogcatLogStrategy() + + logStrategy.log(DEBUG, null, "message") + + val logItems = ShadowLog.getLogs() + assertThat(logItems[0].tag).isEqualTo(LogcatLogStrategy.DEFAULT_TAG) + } + +} diff --git a/QYlogger/src/test/java/com.orhanobut.logger/LoggerPrinterTest.kt b/QYlogger/src/test/java/com.orhanobut.logger/LoggerPrinterTest.kt new file mode 100644 index 0000000..6ebb556 --- /dev/null +++ b/QYlogger/src/test/java/com.orhanobut.logger/LoggerPrinterTest.kt @@ -0,0 +1,239 @@ +package com.orhanobut.logger + +import com.orhanobut.logger.Logger.* +import org.junit.Before +import org.junit.Test +import org.mockito.Matchers.any +import org.mockito.Matchers.contains +import org.mockito.Matchers.eq +import org.mockito.Matchers.isNull +import org.mockito.Mock +import org.mockito.Mockito.`when` +import org.mockito.Mockito.mock +import org.mockito.Mockito.never +import org.mockito.Mockito.times +import org.mockito.Mockito.verify +import org.mockito.Mockito.verifyZeroInteractions +import org.mockito.MockitoAnnotations.initMocks +import java.util.* + +class LoggerPrinterTest { + + private val printer = LoggerPrinter() + + @Mock private lateinit var adapter: LogAdapter + + @Before fun setup() { + initMocks(this) + `when`(adapter!!.isLoggable(any(Int::class.java), any(String::class.java))).thenReturn(true) + printer.addAdapter(adapter!!) + } + + @Test fun logDebug() { + printer.d("message %s", "sent") + + verify(adapter).log(DEBUG, null, "message sent") + } + + @Test fun logError() { + printer.e("message %s", "sent") + + verify(adapter).log(ERROR, null, "message sent") + } + + @Test fun logErrorWithThrowable() { + val throwable = Throwable("exception") + + printer.e(throwable, "message %s", "sent") + + verify(adapter).log(eq(ERROR), isNull(String::class.java), contains("message sent : java.lang.Throwable: exception")) + } + + @Test fun logWarning() { + printer.w("message %s", "sent") + + verify(adapter).log(WARN, null, "message sent") + } + + @Test fun logInfo() { + printer.i("message %s", "sent") + + verify(adapter).log(INFO, null, "message sent") + } + + @Test fun logWtf() { + printer.wtf("message %s", "sent") + + verify(adapter).log(ASSERT, null, "message sent") + } + + @Test fun logVerbose() { + printer.v("message %s", "sent") + + verify(adapter).log(VERBOSE, null, "message sent") + } + + @Test fun oneTimeTag() { + printer.t("tag").d("message") + + verify(adapter).log(DEBUG, "tag", "message") + } + + @Test fun logObject() { + val `object` = "Test" + + printer.d(`object`) + + verify(adapter).log(DEBUG, null, "Test") + } + + @Test fun logArray() { + val `object` = intArrayOf(1, 6, 7, 30, 33) + + printer.d(`object`) + + verify(adapter).log(DEBUG, null, "[1, 6, 7, 30, 33]") + } + + @Test fun logStringArray() { + val `object` = arrayOf("a", "b", "c") + + printer.d(`object`) + + verify(adapter).log(DEBUG, null, "[a, b, c]") + } + + @Test fun logMultiDimensionArray() { + val doubles = arrayOf(doubleArrayOf(1.0, 6.0), doubleArrayOf(1.2, 33.0)) + + printer.d(doubles) + + verify(adapter).log(DEBUG, null, "[[1.0, 6.0], [1.2, 33.0]]") + } + + @Test fun logList() { + val list = Arrays.asList("foo", "bar") + printer.d(list) + + verify(adapter).log(DEBUG, null, list.toString()) + } + + @Test fun logMap() { + val map = HashMap() + map["key"] = "value" + map["key2"] = "value2" + + printer.d(map) + + verify(adapter).log(DEBUG, null, map.toString()) + } + + @Test fun logSet() { + val set = HashSet() + set.add("key") + set.add("key1") + + printer.d(set) + + verify(adapter).log(DEBUG, null, set.toString()) + } + + @Test fun logJsonObject() { + printer.json(" {\"key\":3}") + + verify(adapter).log(DEBUG, null, "{\"key\": 3}") + } + + @Test fun logJsonArray() { + printer.json("[{\"key\":3}]") + + verify(adapter).log(DEBUG, null, "[{\"key\": 3}]") + } + + + @Test fun logInvalidJsonObject() { + printer.json("no json") + printer.json("{ missing end") + + verify(adapter, times(2)).log(ERROR, null, "Invalid Json") + } + + @Test fun jsonLogEmptyOrNull() { + printer.json(null) + printer.json("") + + verify(adapter, times(2)).log(DEBUG, null, "Empty/Null json content") + } + + @Test fun xmlLog() { + printer.xml("Test") + + verify(adapter).log(DEBUG, null, + "\nTest\n") + } + + @Test fun invalidXmlLog() { + printer.xml("xml>Test") + + verify(adapter).log(ERROR, null, "Invalid xml") + } + + @Test fun xmlLogNullOrEmpty() { + printer.xml(null) + printer.xml("") + + verify(adapter, times(2)).log(DEBUG, null, "Empty/Null xml content") + } + + @Test fun clearLogAdapters() { + printer.clearLogAdapters() + + printer.d("") + + verifyZeroInteractions(adapter) + } + + @Test fun addAdapter() { + printer.clearLogAdapters() + val adapter1 = mock(LogAdapter::class.java) + val adapter2 = mock(LogAdapter::class.java) + + printer.addAdapter(adapter1) + printer.addAdapter(adapter2) + + printer.d("message") + + verify(adapter1).isLoggable(DEBUG, null) + verify(adapter2).isLoggable(DEBUG, null) + } + + @Test fun doNotLogIfNotLoggable() { + printer.clearLogAdapters() + val adapter1 = mock(LogAdapter::class.java) + `when`(adapter1.isLoggable(DEBUG, null)).thenReturn(false) + + val adapter2 = mock(LogAdapter::class.java) + `when`(adapter2.isLoggable(DEBUG, null)).thenReturn(true) + + printer.addAdapter(adapter1) + printer.addAdapter(adapter2) + + printer.d("message") + + verify(adapter1, never()).log(DEBUG, null, "message") + verify(adapter2).log(DEBUG, null, "message") + } + + @Test fun logWithoutMessageAndThrowable() { + printer.log(DEBUG, null, null, null) + + verify(adapter).log(DEBUG, null, "Empty/NULL log message") + } + + @Test fun logWithOnlyThrowableWithoutMessage() { + val throwable = Throwable("exception") + printer.log(DEBUG, null, null, throwable) + + verify(adapter).log(eq(DEBUG), isNull(String::class.java), contains("java.lang.Throwable: exception")) + } +} \ No newline at end of file diff --git a/QYlogger/src/test/java/com.orhanobut.logger/LoggerTest.kt b/QYlogger/src/test/java/com.orhanobut.logger/LoggerTest.kt new file mode 100644 index 0000000..d2a0afe --- /dev/null +++ b/QYlogger/src/test/java/com.orhanobut.logger/LoggerTest.kt @@ -0,0 +1,112 @@ +package com.orhanobut.logger + +import org.junit.Before +import org.junit.Test +import org.mockito.Mock + +import org.mockito.Mockito.mock +import org.mockito.Mockito.verify +import org.mockito.Mockito.`when` +import org.mockito.MockitoAnnotations.initMocks + +class LoggerTest { + + @Mock private lateinit var printer: Printer + + @Before fun setup() { + initMocks(this) + + Logger.printer(printer) + } + + @Test fun log() { + val throwable = Throwable() + Logger.log(Logger.VERBOSE, "tag", "message", throwable) + + verify(printer).log(Logger.VERBOSE, "tag", "message", throwable) + } + + @Test fun debugLog() { + Logger.d("message %s", "arg") + + verify(printer).d("message %s", "arg") + } + + @Test fun verboseLog() { + Logger.v("message %s", "arg") + + verify(printer).v("message %s", "arg") + } + + @Test fun warningLog() { + Logger.w("message %s", "arg") + + verify(printer).w("message %s", "arg") + } + + @Test fun errorLog() { + Logger.e("message %s", "arg") + + verify(printer).e(null as Throwable?, "message %s", "arg") + } + + @Test fun errorLogWithThrowable() { + val throwable = Throwable("throwable") + Logger.e(throwable, "message %s", "arg") + + verify(printer).e(throwable, "message %s", "arg") + } + + @Test fun infoLog() { + Logger.i("message %s", "arg") + + verify(printer).i("message %s", "arg") + } + + @Test fun wtfLog() { + Logger.wtf("message %s", "arg") + + verify(printer).wtf("message %s", "arg") + } + + @Test fun logObject() { + val `object` = Any() + Logger.d(`object`) + + verify(printer).d(`object`) + } + + @Test fun jsonLog() { + Logger.json("json") + + verify(printer).json("json") + } + + @Test fun xmlLog() { + Logger.xml("xml") + + verify(printer).xml("xml") + } + + @Test fun oneTimeTag() { + `when`(printer.t("tag")).thenReturn(printer) + + Logger.t("tag").d("message") + + verify(printer).t("tag") + verify(printer).d("message") + } + + @Test fun addAdapter() { + val adapter = mock(LogAdapter::class.java) + Logger.addLogAdapter(adapter) + + verify(printer).addAdapter(adapter) + } + + @Test fun clearLogAdapters() { + Logger.clearLogAdapters() + + verify(printer).clearLogAdapters() + } +} diff --git a/QYlogger/src/test/java/com.orhanobut.logger/PrettyFormatStrategyTest.kt b/QYlogger/src/test/java/com.orhanobut.logger/PrettyFormatStrategyTest.kt new file mode 100644 index 0000000..417fbf2 --- /dev/null +++ b/QYlogger/src/test/java/com.orhanobut.logger/PrettyFormatStrategyTest.kt @@ -0,0 +1,185 @@ +package com.orhanobut.logger + +import org.junit.Test + +import java.util.ArrayList + +import com.orhanobut.logger.Logger.DEBUG + +class PrettyFormatStrategyTest { + + private val threadName = Thread.currentThread().name + private val logStrategy = MockLogStrategy() + private val builder = PrettyFormatStrategy.newBuilder().logStrategy(logStrategy) + + //TODO: Check the actual method info + @Test fun defaultLog() { + val formatStrategy = builder.build() + + formatStrategy.log(DEBUG, null, "message") + + assertLog(DEBUG) + .hasTopBorder() + .hasThread(threadName) + .hasMiddleBorder() + .skip() + .skip() + .hasMiddleBorder() + .hasMessage("message") + .hasBottomBorder() + .hasNoMoreMessages() + } + + @Test fun logWithoutThreadInfo() { + val formatStrategy = builder.showThreadInfo(false).build() + + formatStrategy.log(DEBUG, null, "message") + + assertLog(DEBUG) + .hasTopBorder() + .skip() + .skip() + .hasMiddleBorder() + .hasMessage("message") + .hasBottomBorder() + .hasNoMoreMessages() + } + + @Test fun logWithoutMethodInfo() { + val formatStrategy = builder.methodCount(0).build() + + formatStrategy.log(DEBUG, null, "message") + + assertLog(DEBUG) + .hasTopBorder() + .hasThread(threadName) + .hasMiddleBorder() + .hasMessage("message") + .hasBottomBorder() + .hasNoMoreMessages() + } + + @Test fun logWithOnlyMessage() { + val formatStrategy = builder + .methodCount(0) + .showThreadInfo(false) + .build() + + formatStrategy.log(DEBUG, null, "message") + + assertLog(DEBUG) + .hasTopBorder() + .hasMessage("message") + .hasBottomBorder() + .hasNoMoreMessages() + } + + //TODO: Check the actual method info + @Test fun logWithCustomMethodOffset() { + val formatStrategy = builder + .methodOffset(2) + .showThreadInfo(false) + .build() + + formatStrategy.log(DEBUG, null, "message") + + assertLog(DEBUG) + .hasTopBorder() + .skip() + .skip() + .hasMiddleBorder() + .hasMessage("message") + .hasBottomBorder() + .hasNoMoreMessages() + } + + @Test fun logWithCustomTag() { + val formatStrategy = builder + .tag("custom") + .build() + + formatStrategy.log(DEBUG, null, "message") + + assertLog("custom", DEBUG) + .hasTopBorder() + .hasThread(threadName) + .hasMiddleBorder() + .skip() + .skip() + .hasMiddleBorder() + .hasMessage("message") + .hasBottomBorder() + .hasNoMoreMessages() + } + + @Test fun logWithOneTimeTag() { + val formatStrategy = builder + .tag("custom") + .build() + + formatStrategy.log(DEBUG, "tag", "message") + + assertLog("custom-tag", DEBUG) + .hasTopBorder() + .hasThread(threadName) + .hasMiddleBorder() + .skip() + .skip() + .hasMiddleBorder() + .hasMessage("message") + .hasBottomBorder() + .hasNoMoreMessages() + } + + // TODO: assert values, for now this checks that Logger doesn't crash + @Test fun logWithExceedingMethodCount() { + val formatStrategy = builder + .methodCount(50) + .build() + + formatStrategy.log(DEBUG, null, "message") + } + + @Test fun logWithBigChunk() { + val formatStrategy = builder.build() + + val chunk1 = StringBuilder() + for (i in 0..399) { + chunk1.append("1234567890") + } + val chunk2 = StringBuilder() + for (i in 0..9) { + chunk2.append("ABCDEFGD") + } + + formatStrategy.log(DEBUG, null, chunk1.toString() + chunk2.toString()) + + assertLog(DEBUG) + .hasTopBorder() + .hasThread(threadName) + .hasMiddleBorder() + .skip() + .skip() + .hasMiddleBorder() + .hasMessage(chunk1.toString()) + .hasMessage(chunk2.toString()) + .hasBottomBorder() + .hasNoMoreMessages() + } + + private class MockLogStrategy : LogStrategy { + internal var logItems: MutableList = ArrayList() + + override fun log(priority: Int, tag: String?, message: String) { + logItems.add(LogAssert.LogItem(priority, tag ?: "", message)) + } + } + + private fun assertLog(priority: Int): LogAssert { + return assertLog(null, priority) + } + + private fun assertLog(tag: String?, priority: Int): LogAssert { + return LogAssert(logStrategy.logItems, tag, priority) + } +} diff --git a/QYlogger/src/test/java/com.orhanobut.logger/UtilsTest.kt b/QYlogger/src/test/java/com.orhanobut.logger/UtilsTest.kt new file mode 100644 index 0000000..2527142 --- /dev/null +++ b/QYlogger/src/test/java/com.orhanobut.logger/UtilsTest.kt @@ -0,0 +1,94 @@ +package com.orhanobut.logger + +import android.util.Log + +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config + +import java.net.UnknownHostException + +import com.google.common.truth.Truth.assertThat + +@RunWith(RobolectricTestRunner::class) +class UtilsTest { + + @Test fun isEmpty() { + assertThat(Utils.isEmpty("")).isTrue() + assertThat(Utils.isEmpty(null)).isTrue() + } + + @Test fun equals() { + assertThat(Utils.equals("a", "a")).isTrue() + assertThat(Utils.equals("as", "b")).isFalse() + assertThat(Utils.equals(null, "b")).isFalse() + assertThat(Utils.equals("a", null)).isFalse() + } + + @Test fun getStackTraceString() { + val throwable = Throwable("test") + val androidTraceString = Log.getStackTraceString(throwable) + assertThat(Utils.getStackTraceString(throwable)).isEqualTo(androidTraceString) + } + + @Test fun getStackTraceStringReturnsEmptyStringWithNull() { + assertThat(Utils.getStackTraceString(null)).isEqualTo("") + } + + @Test fun getStackTraceStringReturnEmptyStringWithUnknownHostException() { + assertThat(Utils.getStackTraceString(UnknownHostException())).isEqualTo("") + } + + @Test fun logLevels() { + assertThat(Utils.logLevel(Logger.DEBUG)).isEqualTo("DEBUG") + assertThat(Utils.logLevel(Logger.WARN)).isEqualTo("WARN") + assertThat(Utils.logLevel(Logger.INFO)).isEqualTo("INFO") + assertThat(Utils.logLevel(Logger.VERBOSE)).isEqualTo("VERBOSE") + assertThat(Utils.logLevel(Logger.ASSERT)).isEqualTo("ASSERT") + assertThat(Utils.logLevel(Logger.ERROR)).isEqualTo("ERROR") + assertThat(Utils.logLevel(100)).isEqualTo("UNKNOWN") + } + + @Test fun objectToString() { + val `object` = "Test" + + assertThat(Utils.toString(`object`)).isEqualTo("Test") + } + + @Test fun toStringWithNull() { + assertThat(Utils.toString(null)).isEqualTo("null") + } + + @Test fun primitiveArrayToString() { + val booleanArray = booleanArrayOf(true, false, true) + assertThat(Utils.toString(booleanArray)).isEqualTo("[true, false, true]") + + val byteArray = byteArrayOf(1, 0, 1) + assertThat(Utils.toString(byteArray)).isEqualTo("[1, 0, 1]") + + val charArray = charArrayOf('a', 'b', 'c') + assertThat(Utils.toString(charArray)).isEqualTo("[a, b, c]") + + val shortArray = shortArrayOf(1, 3, 5) + assertThat(Utils.toString(shortArray)).isEqualTo("[1, 3, 5]") + + val intArray = intArrayOf(1, 3, 5) + assertThat(Utils.toString(intArray)).isEqualTo("[1, 3, 5]") + + val longArray = longArrayOf(1, 3, 5) + assertThat(Utils.toString(longArray)).isEqualTo("[1, 3, 5]") + + val floatArray = floatArrayOf(1f, 3f, 5f) + assertThat(Utils.toString(floatArray)).isEqualTo("[1.0, 3.0, 5.0]") + + val doubleArray = doubleArrayOf(1.0, 3.0, 5.0) + assertThat(Utils.toString(doubleArray)).isEqualTo("[1.0, 3.0, 5.0]") + } + + @Test fun multiDimensionArrayToString() { + val `object` = arrayOf(intArrayOf(1, 2, 3), intArrayOf(4, 5, 6)) + + assertThat(Utils.toString(`object`)).isEqualTo("[[1, 2, 3], [4, 5, 6]]") + } +} \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..640a2a5 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,29 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 27 + defaultConfig { + applicationId "com.qj.logger" + minSdkVersion 21 + targetSdkVersion 27 + versionCode 1 + versionName "1.0" + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation 'com.android.support:appcompat-v7:27.1.1' + implementation 'com.android.support.constraint:constraint-layout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' + compile project(path: ':QYlogger') +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/app/src/androidTest/java/com/qj/logger/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/qj/logger/ExampleInstrumentedTest.java new file mode 100644 index 0000000..b693582 --- /dev/null +++ b/app/src/androidTest/java/com/qj/logger/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.qj.logger; + +import android.content.Context; +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() throws Exception { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getTargetContext(); + + assertEquals("com.qj.logger", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..77606b4 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..c7bd21d --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..d5fccc5 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..0d8ad42 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..eca70cf --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..eca70cf --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..a2f5908 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 0000000..1b52399 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..ff10afd Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 0000000..115a4c7 Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..dcd3cd8 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 0000000..459ca60 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..8ca12fe Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..8e19b41 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..b824ebd Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..4c19a13 Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..3ab3e9c --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,6 @@ + + + #3F51B5 + #303F9F + #FF4081 + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..79f29d0 --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + QYLogger + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..5885930 --- /dev/null +++ b/app/src/main/res/values/styles.xml @@ -0,0 +1,11 @@ + + + + + + diff --git a/app/src/test/java/com/qj/logger/ExampleUnitTest.java b/app/src/test/java/com/qj/logger/ExampleUnitTest.java new file mode 100644 index 0000000..96c31c1 --- /dev/null +++ b/app/src/test/java/com/qj/logger/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.qj.logger; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() throws Exception { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..97f22b3 --- /dev/null +++ b/build.gradle @@ -0,0 +1,27 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + + repositories { + google() + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:3.0.1' + + classpath 'com.novoda:bintray-release:0.8.0' + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..aac7c9b --- /dev/null +++ b/gradle.properties @@ -0,0 +1,17 @@ +# Project-wide Gradle settings. + +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. + +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html + +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx1536m + +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..13372ae Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..f617b16 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Thu Jan 31 11:51:32 CST 2019 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..9d82f78 --- /dev/null +++ b/gradlew @@ -0,0 +1,160 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..8a0b282 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..ad34526 --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +include ':app', ':QYlogger'