├── app ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ ├── drawable-mdpi │ │ │ │ ├── qqq.png │ │ │ │ ├── image1.jpg │ │ │ │ ├── image2.jpg │ │ │ │ ├── image3.jpg │ │ │ │ ├── image4.jpg │ │ │ │ └── ic_action_back.png │ │ │ ├── mipmap-hdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── drawable-hdpi │ │ │ │ └── ic_action_back.png │ │ │ ├── drawable-xhdpi │ │ │ │ └── ic_action_back.png │ │ │ ├── drawable-xxhdpi │ │ │ │ └── ic_action_back.png │ │ │ ├── values │ │ │ │ ├── strings.xml │ │ │ │ ├── colors.xml │ │ │ │ ├── styles.xml │ │ │ │ └── attrs.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ ├── ic_launcher.xml │ │ │ │ └── ic_launcher_round.xml │ │ │ ├── drawable-anydpi │ │ │ │ └── ic_action_back.xml │ │ │ ├── layout │ │ │ │ ├── item_viewpager.xml │ │ │ │ ├── content_main.xml │ │ │ │ ├── item_recyclerview.xml │ │ │ │ ├── fragment_content_main.xml │ │ │ │ ├── content_second.xml │ │ │ │ ├── activity_second.xml │ │ │ │ ├── activity_main1.xml │ │ │ │ ├── activity_keyboard2.xml │ │ │ │ ├── activity_main.xml │ │ │ │ ├── activity_keyboard.xml │ │ │ │ └── activity_keyboard3.xml │ │ │ ├── xml │ │ │ │ ├── keyboard_collapse.xml │ │ │ │ ├── keyboard_expand_to_panel.xml │ │ │ │ └── keyboard_expand_to_keyboard.xml │ │ │ ├── transition │ │ │ │ └── tt.xml │ │ │ └── drawable-v24 │ │ │ │ └── ic_launcher_foreground.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── myapplication │ │ │ │ ├── imkeyboard │ │ │ │ ├── IDispatchClipListener.kt │ │ │ │ ├── ClipRecyclerView.kt │ │ │ │ ├── DeviceInfo.kt │ │ │ │ ├── Constants.kt │ │ │ │ ├── RelativeKeyboardLayout.kt │ │ │ │ ├── SmoothPositionLinearLayoutManager.kt │ │ │ │ ├── DeviceRuntime.kt │ │ │ │ └── PaddingTransition.kt │ │ │ │ ├── temp │ │ │ │ └── Constant.java │ │ │ │ ├── MainActivity.kt │ │ │ │ ├── KeyboardActivity.kt │ │ │ │ └── ScrollSpeedManger.java │ │ └── AndroidManifest.xml │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── example │ │ │ └── myapplication │ │ │ └── ExampleUnitTest.kt │ └── androidTest │ │ └── java │ │ └── com │ │ └── example │ │ └── myapplication │ │ └── ExampleInstrumentedTest.kt ├── proguard-rules.pro └── build.gradle ├── mediabox ├── .gitignore ├── src │ ├── main │ │ ├── cpp │ │ │ ├── giflib │ │ │ │ ├── MODULE_LICENSE_MIT │ │ │ │ ├── README.version │ │ │ │ ├── config.h │ │ │ │ ├── NOTICE │ │ │ │ ├── gif_hash.h │ │ │ │ ├── openbsd-reallocarray.c │ │ │ │ ├── gif_lib_private.h │ │ │ │ ├── gif_err.c │ │ │ │ └── gif_hash.c │ │ │ ├── CMakeLists.txt │ │ │ ├── FrameSequenceJNI.h │ │ │ ├── utils │ │ │ │ └── math.h │ │ │ ├── JNIHelpers.h │ │ │ ├── Color.h │ │ │ ├── FrameSequence.cpp │ │ │ ├── JNIHelpers.cpp │ │ │ ├── BitmapDecoderJNI.cpp │ │ │ ├── Registry.h │ │ │ ├── Registry.cpp │ │ │ ├── FrameSequence.h │ │ │ ├── Stream.h │ │ │ ├── FrameSequence_gif.h │ │ │ └── Stream.cpp │ │ ├── res │ │ │ ├── values │ │ │ │ ├── strings.xml │ │ │ │ ├── colors.xml │ │ │ │ └── styles.xml │ │ │ ├── mipmap-hdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── drawable-hdpi │ │ │ │ ├── ic_action_back.png │ │ │ │ ├── ic_action_photo.png │ │ │ │ └── bg_face_quality_low.webp │ │ │ ├── drawable-mdpi │ │ │ │ ├── ic_action_back.png │ │ │ │ └── ic_action_photo.png │ │ │ ├── drawable-xhdpi │ │ │ │ ├── ic_action_back.png │ │ │ │ └── ic_action_photo.png │ │ │ ├── drawable-xxhdpi │ │ │ │ ├── ic_action_back.png │ │ │ │ └── ic_action_photo.png │ │ │ ├── drawable │ │ │ │ ├── media_type_tag_background.xml │ │ │ │ ├── background_share_stroke.xml │ │ │ │ ├── selector_preview_text_color.xml │ │ │ │ ├── select_media_bucket_bottom_sheet_background.xml │ │ │ │ ├── selector_preview_done_text_color.xml │ │ │ │ ├── selector_media_check_icon.xml │ │ │ │ ├── selector_media_origin_size_icon.xml │ │ │ │ ├── ic_round_uncheck_circle_24.xml │ │ │ │ ├── ic_round_check_24.xml │ │ │ │ ├── selector_preview_done_background.xml │ │ │ │ ├── ic_round_check_circle_24_c.xml │ │ │ │ ├── ic_round_check_circle_24.xml │ │ │ │ ├── ic_round_photo_camera_24.xml │ │ │ │ └── selector_media_select_count_background.xml │ │ │ ├── xml │ │ │ │ └── file_paths.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ ├── ic_launcher.xml │ │ │ │ └── ic_launcher_round.xml │ │ │ ├── values-v21 │ │ │ │ └── styles.xml │ │ │ ├── values-v23 │ │ │ │ └── styles.xml │ │ │ ├── drawable-anydpi │ │ │ │ ├── ic_action_photo.xml │ │ │ │ └── ic_action_back.xml │ │ │ ├── layout │ │ │ │ ├── activity_main.xml │ │ │ │ ├── recycler_view_item_media_camera.xml │ │ │ │ ├── recycler_view_item_media_select.xml │ │ │ │ ├── recycler_view_item_media_resource.xml │ │ │ │ └── recycler_view_item_media_bucket.xml │ │ │ └── drawable-v24 │ │ │ │ └── ic_launcher_foreground.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── mediabox │ │ │ │ ├── paging │ │ │ │ ├── MediaLifecycle.kt │ │ │ │ ├── MediaLifecycleOwner.kt │ │ │ │ └── MediaRepository.kt │ │ │ │ ├── MainActivity.kt │ │ │ │ ├── view │ │ │ │ ├── SquareFrameLayout.kt │ │ │ │ ├── SquareImageView.kt │ │ │ │ ├── SquareConstraintLayout.kt │ │ │ │ ├── PhotoMediaView.kt │ │ │ │ ├── NormalMediaView.kt │ │ │ │ └── LagerMediaView.kt │ │ │ │ ├── data │ │ │ │ ├── MediaBucket.kt │ │ │ │ ├── MediaData.kt │ │ │ │ └── MediaConfig.kt │ │ │ │ ├── glide │ │ │ │ ├── gif │ │ │ │ │ ├── GifResource.java │ │ │ │ │ └── GifDecoder.java │ │ │ │ └── MyAppGlideModule.kt │ │ │ │ ├── App.kt │ │ │ │ ├── adapter │ │ │ │ ├── CustomLinearLayoutManager.kt │ │ │ │ ├── PreviewAdapter.kt │ │ │ │ ├── MediaBucketAdapter.kt │ │ │ │ └── SelectAdapter.kt │ │ │ │ ├── MediaBox.kt │ │ │ │ └── SelectMediaBucketFragment.kt │ │ └── AndroidManifest.xml │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── example │ │ │ └── mediabox │ │ │ └── ExampleUnitTest.kt │ └── androidTest │ │ └── java │ │ └── com │ │ └── example │ │ └── mediabox │ │ └── ExampleInstrumentedTest.kt ├── proguard-rules.pro └── build.gradle ├── library ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ └── values │ │ │ │ └── strings.xml │ │ ├── jniLibs │ │ │ ├── x86 │ │ │ │ └── libluban.so │ │ │ ├── x86_64 │ │ │ │ └── libluban.so │ │ │ ├── arm64-v8a │ │ │ │ └── libluban.so │ │ │ └── armeabi-v7a │ │ │ │ └── libluban.so │ │ ├── AndroidManifest.xml │ │ └── java │ │ │ └── top │ │ │ └── zibin │ │ │ └── luban │ │ │ ├── InputStreamProvider2.java │ │ │ ├── InputStreamProvider.java │ │ │ ├── turbo │ │ │ └── TurboCompressor.java │ │ │ ├── OnRenameListener.java │ │ │ ├── CompressionPredicate.java │ │ │ ├── OnCompressListener.java │ │ │ ├── InputStreamAdapter.java │ │ │ ├── InputStreamAdapter2.java │ │ │ ├── Engine.java │ │ │ ├── Checker.java │ │ │ └── UriHelper.java │ ├── test │ │ └── java │ │ │ └── top │ │ │ └── zibin │ │ │ └── luban │ │ │ └── ExampleUnitTest.java │ └── androidTest │ │ └── java │ │ └── top │ │ └── zibin │ │ └── luban │ │ └── ApplicationTest.java ├── proguard-rules.pro └── build.gradle ├── README.md ├── settings.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── gradle.properties ├── gradlew.bat └── gradlew /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /mediabox/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /library/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | gradle.properties -------------------------------------------------------------------------------- /mediabox/src/main/cpp/giflib/MODULE_LICENSE_MIT: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # KeyboardHelper 2 | 完美复刻微信软键盘与表情面板切换 3 | 4 | usage: 5 | KeyboardHelper.startSmartEscrow 一键托管 6 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':mediabox',':library' 2 | //rootProject.name='My Application' 3 | include ':app' 4 | -------------------------------------------------------------------------------- /mediabox/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | MediaBox 3 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /library/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Luban 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/qqq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/app/src/main/res/drawable-mdpi/qqq.png -------------------------------------------------------------------------------- /library/src/main/jniLibs/x86/libluban.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/library/src/main/jniLibs/x86/libluban.so -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/image1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/app/src/main/res/drawable-mdpi/image1.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/image2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/app/src/main/res/drawable-mdpi/image2.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/image3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/app/src/main/res/drawable-mdpi/image3.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/image4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/app/src/main/res/drawable-mdpi/image4.jpg -------------------------------------------------------------------------------- /library/src/main/jniLibs/x86_64/libluban.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/library/src/main/jniLibs/x86_64/libluban.so -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /library/src/main/jniLibs/arm64-v8a/libluban.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/library/src/main/jniLibs/arm64-v8a/libluban.so -------------------------------------------------------------------------------- /library/src/main/jniLibs/armeabi-v7a/libluban.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/library/src/main/jniLibs/armeabi-v7a/libluban.so -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_action_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/app/src/main/res/drawable-hdpi/ic_action_back.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_action_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/app/src/main/res/drawable-mdpi/ic_action_back.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_action_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/app/src/main/res/drawable-xhdpi/ic_action_back.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /library/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /mediabox/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/mediabox/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /mediabox/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/mediabox/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /mediabox/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/mediabox/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_action_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/app/src/main/res/drawable-xxhdpi/ic_action_back.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /mediabox/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/mediabox/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /mediabox/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/mediabox/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /mediabox/src/main/res/drawable-hdpi/ic_action_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/mediabox/src/main/res/drawable-hdpi/ic_action_back.png -------------------------------------------------------------------------------- /mediabox/src/main/res/drawable-hdpi/ic_action_photo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/mediabox/src/main/res/drawable-hdpi/ic_action_photo.png -------------------------------------------------------------------------------- /mediabox/src/main/res/drawable-mdpi/ic_action_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/mediabox/src/main/res/drawable-mdpi/ic_action_back.png -------------------------------------------------------------------------------- /mediabox/src/main/res/drawable-mdpi/ic_action_photo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/mediabox/src/main/res/drawable-mdpi/ic_action_photo.png -------------------------------------------------------------------------------- /mediabox/src/main/res/drawable-xhdpi/ic_action_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/mediabox/src/main/res/drawable-xhdpi/ic_action_back.png -------------------------------------------------------------------------------- /mediabox/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/mediabox/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /mediabox/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/mediabox/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /mediabox/src/main/cpp/giflib/README.version: -------------------------------------------------------------------------------- 1 | URL: https://sourceforge.net/projects/giflib/files/giflib-5.1.1.tar.bz2/download 2 | Version: 5.1.1 3 | BugComponent: 24950 4 | -------------------------------------------------------------------------------- /mediabox/src/main/res/drawable-xhdpi/ic_action_photo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/mediabox/src/main/res/drawable-xhdpi/ic_action_photo.png -------------------------------------------------------------------------------- /mediabox/src/main/res/drawable-xxhdpi/ic_action_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/mediabox/src/main/res/drawable-xxhdpi/ic_action_back.png -------------------------------------------------------------------------------- /mediabox/src/main/res/drawable-xxhdpi/ic_action_photo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/mediabox/src/main/res/drawable-xxhdpi/ic_action_photo.png -------------------------------------------------------------------------------- /mediabox/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/mediabox/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /mediabox/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/mediabox/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /mediabox/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/mediabox/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /mediabox/src/main/res/drawable-hdpi/bg_face_quality_low.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuki93/KeyboardHelper/HEAD/mediabox/src/main/res/drawable-hdpi/bg_face_quality_low.webp -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | My Application 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #6200EE 4 | #3700B3 5 | #03DAC5 6 | 7 | -------------------------------------------------------------------------------- /mediabox/src/main/res/drawable/media_type_tag_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /mediabox/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FF222222 4 | #FF111111 5 | #FFFFFFFF 6 | -------------------------------------------------------------------------------- /mediabox/src/main/cpp/giflib/config.h: -------------------------------------------------------------------------------- 1 | 2 | // giflib config.h 3 | 4 | #ifndef GIF_CONFIG_H_DEFINED 5 | #define GIF_CONFIG_H_DEFINED 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | typedef uint32_t UINT32; 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /mediabox/src/main/java/com/example/mediabox/paging/MediaLifecycle.kt: -------------------------------------------------------------------------------- 1 | package com.example.mediabox.paging 2 | 3 | import androidx.lifecycle.LifecycleOwner 4 | import androidx.lifecycle.LifecycleRegistry 5 | 6 | class MediaLifecycle(provider: LifecycleOwner) : LifecycleRegistry(provider) -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jul 24 15:23:50 CST 2020 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | /.idea 14 | .externalNativeBuild 15 | .cxx 16 | -------------------------------------------------------------------------------- /mediabox/src/main/res/xml/file_paths.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 9 | -------------------------------------------------------------------------------- /mediabox/src/main/res/drawable/background_share_stroke.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /mediabox/src/main/res/drawable/selector_preview_text_color.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /mediabox/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /mediabox/src/main/res/drawable/select_media_bucket_bottom_sheet_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /mediabox/src/main/res/drawable/selector_preview_done_text_color.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /mediabox/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /mediabox/src/main/res/values-v21/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/myapplication/imkeyboard/IDispatchClipListener.kt: -------------------------------------------------------------------------------- 1 | package com.example.myapplication.imkeyboard 2 | 3 | interface IDispatchClipListener { 4 | 5 | var disableHandler: Boolean 6 | 7 | fun isDisableTouchEvent(): Boolean { 8 | return disableHandler.also { 9 | disableHandler = false 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /mediabox/src/main/res/drawable/selector_media_check_icon.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /mediabox/src/main/res/drawable/selector_media_origin_size_icon.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /mediabox/src/main/res/values-v23/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /library/src/test/java/top/zibin/luban/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package top.zibin.luban; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * To work on unit tests, switch the Test Artifact in the Build Variants view. 9 | */ 10 | public class ExampleUnitTest { 11 | @Test 12 | public void addition_isCorrect() throws Exception { 13 | assertEquals(4, 2 + 2); 14 | } 15 | } -------------------------------------------------------------------------------- /library/src/androidTest/java/top/zibin/luban/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package top.zibin.luban; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /library/src/main/java/top/zibin/luban/InputStreamProvider2.java: -------------------------------------------------------------------------------- 1 | package top.zibin.luban; 2 | 3 | import android.graphics.Bitmap; 4 | import android.net.Uri; 5 | 6 | import java.io.IOException; 7 | import java.io.InputStream; 8 | 9 | public interface InputStreamProvider2 { 10 | 11 | Uri getUri(); 12 | 13 | InputStream open() throws IOException; 14 | 15 | Bitmap getBitmap() throws IOException; 16 | 17 | String getMimeType(); 18 | } 19 | -------------------------------------------------------------------------------- /mediabox/src/main/java/com/example/mediabox/paging/MediaLifecycleOwner.kt: -------------------------------------------------------------------------------- 1 | package com.example.mediabox.paging 2 | 3 | import androidx.lifecycle.Lifecycle 4 | import androidx.lifecycle.LifecycleOwner 5 | 6 | class MediaLifecycleOwner(provider: LifecycleOwner) : LifecycleOwner { 7 | 8 | private val mLifecycleRegistry = MediaLifecycle(provider) 9 | 10 | override fun getLifecycle(): Lifecycle { 11 | return mLifecycleRegistry 12 | } 13 | } -------------------------------------------------------------------------------- /mediabox/src/test/java/com/example/mediabox/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.example.mediabox 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable-anydpi/ic_action_back.xml: -------------------------------------------------------------------------------- 1 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/test/java/com/example/myapplication/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.example.myapplication 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /library/src/main/java/top/zibin/luban/InputStreamProvider.java: -------------------------------------------------------------------------------- 1 | package top.zibin.luban; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | 6 | /** 7 | * 通过此接口获取输入流,以兼容文件、FileProvider方式获取到的图片 8 | *

9 | * Get the input stream through this interface, and obtain the picture using compatible files and FileProvider 10 | */ 11 | public interface InputStreamProvider { 12 | 13 | InputStream open() throws IOException; 14 | 15 | void close(); 16 | 17 | String getPath(); 18 | } 19 | -------------------------------------------------------------------------------- /mediabox/src/main/res/drawable-anydpi/ic_action_photo.xml: -------------------------------------------------------------------------------- 1 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_viewpager.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/layout/content_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | -------------------------------------------------------------------------------- /library/src/main/java/top/zibin/luban/turbo/TurboCompressor.java: -------------------------------------------------------------------------------- 1 | package top.zibin.luban.turbo; 2 | 3 | import android.graphics.Bitmap; 4 | 5 | /** 6 | * Author: zibin 7 | * Datetime: 2018/7/20 8 | */ 9 | public class TurboCompressor { 10 | 11 | public static void compress(Bitmap bitmap, int quality, String outfile) { 12 | nativeCompress(bitmap, quality, outfile); 13 | } 14 | 15 | static { 16 | System.loadLibrary("luban"); 17 | } 18 | 19 | private static native boolean nativeCompress(Bitmap bitmap, int quality, String outfile); 20 | } 21 | -------------------------------------------------------------------------------- /mediabox/src/main/res/drawable/ic_round_uncheck_circle_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 11 | 12 | -------------------------------------------------------------------------------- /library/src/main/java/top/zibin/luban/OnRenameListener.java: -------------------------------------------------------------------------------- 1 | package top.zibin.luban; 2 | 3 | /** 4 | * Author: zibin 5 | * Datetime: 2018/5/18 6 | *

7 | * 提供修改压缩图片命名接口 8 | *

9 | * A functional interface (callback) that used to rename the file after compress. 10 | */ 11 | public interface OnRenameListener { 12 | 13 | /** 14 | * 压缩前调用该方法用于修改压缩后文件名 15 | *

16 | * Call before compression begins. 17 | * 18 | * @param fileName 传入文件路径/ file name 19 | * @return 返回重命名后的字符串/ file name 20 | */ 21 | String rename(String fileName); 22 | } 23 | -------------------------------------------------------------------------------- /mediabox/src/main/res/drawable/ic_round_check_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /library/src/main/java/top/zibin/luban/CompressionPredicate.java: -------------------------------------------------------------------------------- 1 | package top.zibin.luban; 2 | 3 | /** 4 | * Created on 2018/1/3 19:43 5 | * 6 | * @author andy 7 | *

8 | * A functional interface (callback) that returns true or false for the given input path should be compressed. 9 | */ 10 | 11 | public interface CompressionPredicate { 12 | 13 | /** 14 | * Determine the given input path should be compressed and return a boolean. 15 | * 16 | * @param mimeType input mimeType 17 | * @return the boolean result 18 | */ 19 | boolean apply(String mimeType); 20 | } 21 | -------------------------------------------------------------------------------- /mediabox/src/main/res/drawable/selector_preview_done_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_recyclerview.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 15 | 16 | -------------------------------------------------------------------------------- /mediabox/src/main/cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.4.1) 2 | 3 | file(GLOB_RECURSE GIF_LIB ${CMAKE_SOURCE_DIR}/giflib/*.*) 4 | file(GLOB_RECURSE FRAME_SEQUENCE ${CMAKE_SOURCE_DIR}/*.cpp*) 5 | 6 | add_library(mygif 7 | SHARED 8 | ${FRAME_SEQUENCE} 9 | ${GIF_LIB}) 10 | 11 | list(APPEND LIBS 12 | jnigraphics 13 | android 14 | GLESv2 15 | log 16 | ) 17 | 18 | set(LIBS) 19 | list(APPEND LIBS 20 | jnigraphics 21 | android 22 | GLESv2 23 | log 24 | ) 25 | 26 | target_link_libraries(mygif ${LIBS}) 27 | -------------------------------------------------------------------------------- /mediabox/src/main/res/drawable-anydpi/ic_action_back.xml: -------------------------------------------------------------------------------- 1 | 8 | 12 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/myapplication/temp/Constant.java: -------------------------------------------------------------------------------- 1 | package com.example.myapplication.temp; 2 | 3 | 4 | import com.example.myapplication.R; 5 | 6 | /** 7 | * Created by zys on 16/11/4. 8 | */ 9 | 10 | public class Constant { 11 | 12 | public static final int IMAGE_ARRAY[] = { 13 | R.drawable.image1, R.drawable.image2, 14 | R.drawable.image3, R.drawable.image4 15 | }; 16 | public static final String TRANSITION_NAME = "image"; 17 | 18 | public static final String EXTRA_START_POSITION = "extra_start_position"; 19 | public static final String EXTRA_CURRENT_POSITION = "extra_current_position"; 20 | } 21 | -------------------------------------------------------------------------------- /library/src/main/java/top/zibin/luban/OnCompressListener.java: -------------------------------------------------------------------------------- 1 | package top.zibin.luban; 2 | 3 | import android.net.Uri; 4 | 5 | import java.io.File; 6 | 7 | public interface OnCompressListener { 8 | 9 | /** 10 | * Fired when the compression is started, override to handle in your own code 11 | */ 12 | void onStart(); 13 | 14 | /** 15 | * Fired when a compression returns successfully, override to handle in your own code 16 | */ 17 | void onSuccess(Uri uri); 18 | 19 | /** 20 | * Fired when a compression fails to complete, override to handle in your own code 21 | */ 22 | void onError(Throwable e); 23 | } 24 | -------------------------------------------------------------------------------- /mediabox/src/main/java/com/example/mediabox/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.mediabox 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AppCompatActivity 5 | import kotlinx.android.synthetic.main.activity_main.* 6 | 7 | class MainActivity : AppCompatActivity() { 8 | 9 | override fun onCreate(savedInstanceState: Bundle?) { 10 | super.onCreate(savedInstanceState) 11 | setContentView(R.layout.activity_main) 12 | btn_select.setOnClickListener { 13 | MediaBox.with() 14 | .setWithGif(true) 15 | .setWithCamera(true) 16 | .start(this) 17 | } 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /mediabox/src/main/res/drawable/ic_round_check_circle_24_c.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 13 | 14 | -------------------------------------------------------------------------------- /mediabox/src/main/res/drawable/ic_round_check_circle_24.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | -------------------------------------------------------------------------------- /library/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/sweetspot/Library/Android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/main/res/xml/keyboard_collapse.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 11 | 12 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/xml/keyboard_expand_to_panel.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 11 | 12 | 18 | 19 | -------------------------------------------------------------------------------- /mediabox/src/main/java/com/example/mediabox/view/SquareFrameLayout.kt: -------------------------------------------------------------------------------- 1 | package com.example.mediabox.view 2 | 3 | import android.content.Context 4 | import android.util.AttributeSet 5 | import android.widget.FrameLayout 6 | 7 | class SquareFrameLayout @JvmOverloads constructor( 8 | context: Context, 9 | attrs: AttributeSet? = null, 10 | def: Int = 0 11 | ) : FrameLayout(context, attrs, def) { 12 | 13 | override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { 14 | if (MeasureSpec.getSize(widthMeasureSpec) <= MeasureSpec.getSize(heightMeasureSpec)) { 15 | super.onMeasure(widthMeasureSpec, widthMeasureSpec) 16 | } else { 17 | super.onMeasure(heightMeasureSpec, heightMeasureSpec) 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /mediabox/src/main/java/com/example/mediabox/data/MediaBucket.kt: -------------------------------------------------------------------------------- 1 | package com.example.mediabox.data 2 | 3 | import android.net.Uri 4 | import android.os.Parcelable 5 | import kotlinx.android.parcel.Parcelize 6 | 7 | @Parcelize 8 | data class MediaBucket( 9 | val bucketId: Int, 10 | val displayName: String, 11 | var size: Int, 12 | var uri: Uri? = null 13 | ) : Parcelable { 14 | 15 | override fun equals(other: Any?): Boolean { 16 | if (this === other) return true 17 | if (javaClass != other?.javaClass) return false 18 | 19 | other as MediaBucket 20 | 21 | if (bucketId != other.bucketId) return false 22 | 23 | return true 24 | } 25 | 26 | override fun hashCode(): Int { 27 | return bucketId 28 | } 29 | } -------------------------------------------------------------------------------- /app/src/main/res/xml/keyboard_expand_to_keyboard.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 11 | 12 | 18 | 19 | -------------------------------------------------------------------------------- /mediabox/src/main/java/com/example/mediabox/view/SquareImageView.kt: -------------------------------------------------------------------------------- 1 | package com.example.mediabox.view 2 | 3 | import android.content.Context 4 | import android.util.AttributeSet 5 | import androidx.appcompat.widget.AppCompatImageView 6 | 7 | class SquareImageView @JvmOverloads constructor( 8 | context: Context, 9 | attrs: AttributeSet? = null, 10 | def: Int = 0 11 | ) : AppCompatImageView(context, attrs, def) { 12 | 13 | override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { 14 | if (MeasureSpec.getSize(widthMeasureSpec) <= MeasureSpec.getSize(heightMeasureSpec)) { 15 | super.onMeasure(widthMeasureSpec, widthMeasureSpec) 16 | } else { 17 | super.onMeasure(heightMeasureSpec, heightMeasureSpec) 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/myapplication/imkeyboard/ClipRecyclerView.kt: -------------------------------------------------------------------------------- 1 | package com.example.myapplication.imkeyboard 2 | 3 | import android.content.Context 4 | import android.util.AttributeSet 5 | import android.view.MotionEvent 6 | import androidx.recyclerview.widget.RecyclerView 7 | 8 | class ClipRecyclerView @JvmOverloads constructor( 9 | context: Context, 10 | attr: AttributeSet? = null, 11 | defStyleAttr: Int = 0 12 | ) : RecyclerView(context, attr, defStyleAttr), IDispatchClipListener { 13 | 14 | override var disableHandler: Boolean = false 15 | 16 | override fun dispatchTouchEvent(ev: MotionEvent?): Boolean { 17 | if (isDisableTouchEvent()) { 18 | return false 19 | } 20 | return super.dispatchTouchEvent(ev) 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /mediabox/src/main/res/drawable/ic_round_photo_camera_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/transition/tt.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 12 | 13 | 17 | -------------------------------------------------------------------------------- /mediabox/src/main/java/com/example/mediabox/view/SquareConstraintLayout.kt: -------------------------------------------------------------------------------- 1 | package com.example.mediabox.view 2 | 3 | import android.content.Context 4 | import android.util.AttributeSet 5 | import androidx.constraintlayout.widget.ConstraintLayout 6 | 7 | class SquareConstraintLayout @JvmOverloads constructor( 8 | context: Context, 9 | attrs: AttributeSet? = null, 10 | def: Int = 0 11 | ) : ConstraintLayout(context, attrs, def) { 12 | 13 | override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { 14 | if (MeasureSpec.getSize(widthMeasureSpec) <= MeasureSpec.getSize(heightMeasureSpec)) { 15 | super.onMeasure(widthMeasureSpec, widthMeasureSpec) 16 | } else { 17 | super.onMeasure(heightMeasureSpec, heightMeasureSpec) 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /mediabox/src/main/java/com/example/mediabox/glide/gif/GifResource.java: -------------------------------------------------------------------------------- 1 | package com.example.mediabox.glide.gif; 2 | 3 | import androidx.annotation.NonNull; 4 | 5 | import com.bumptech.glide.load.resource.drawable.DrawableResource; 6 | 7 | 8 | public class GifResource extends DrawableResource { 9 | 10 | public GifResource(FrameSequenceDrawable drawable) { 11 | super(drawable); 12 | } 13 | 14 | @NonNull 15 | @Override 16 | public Class getResourceClass() { 17 | return FrameSequenceDrawable.class; 18 | } 19 | 20 | @Override 21 | public int getSize() { 22 | return 0; 23 | } 24 | 25 | @Override 26 | public void recycle() { 27 | drawable.stop(); 28 | drawable.destroy(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /mediabox/src/androidTest/java/com/example/mediabox/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.example.mediabox 2 | 3 | import androidx.test.ext.junit.runners.AndroidJUnit4 4 | import androidx.test.platform.app.InstrumentationRegistry 5 | import org.junit.Assert.assertEquals 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | /** 10 | * Instrumented test, which will execute on an Android device. 11 | * 12 | * See [testing documentation](http://d.android.com/tools/testing). 13 | */ 14 | @RunWith(AndroidJUnit4::class) 15 | class ExampleInstrumentedTest { 16 | @Test 17 | fun useAppContext() { 18 | // Context of the app under test. 19 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 20 | assertEquals("com.example.mediabox", appContext.packageName) 21 | } 22 | } -------------------------------------------------------------------------------- /app/src/androidTest/java/com/example/myapplication/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.example.myapplication 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.example.myapplication", appContext.packageName) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /mediabox/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/myapplication/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.myapplication 2 | 3 | import android.content.Intent 4 | import androidx.appcompat.app.AppCompatActivity 5 | import android.os.Bundle 6 | import android.view.View 7 | import com.example.myapplication.imkeyboard.KeyboardHelper 8 | import kotlinx.android.synthetic.main.activity_main.* 9 | 10 | class MainActivity : AppCompatActivity() { 11 | 12 | private val helper = KeyboardHelper.from(this) 13 | 14 | override fun onCreate(savedInstanceState: Bundle?) { 15 | super.onCreate(savedInstanceState) 16 | setContentView(R.layout.activity_main) 17 | helper.startAutomaticMode(root) 18 | tv1.setOnClickListener { 19 | 20 | } 21 | } 22 | 23 | fun haha(v: View) { 24 | startActivity(Intent(this, KeyboardActivity::class.java)) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_content_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /mediabox/src/main/java/com/example/mediabox/glide/MyAppGlideModule.kt: -------------------------------------------------------------------------------- 1 | package com.example.mediabox.glide 2 | 3 | import android.content.Context 4 | import com.bumptech.glide.Glide 5 | import com.bumptech.glide.Registry 6 | import com.bumptech.glide.annotation.GlideModule 7 | import com.bumptech.glide.module.AppGlideModule 8 | import com.example.mediabox.glide.gif.FrameSequenceDrawable 9 | import com.example.mediabox.glide.gif.GifDecoder 10 | import java.io.InputStream 11 | 12 | 13 | @GlideModule 14 | class MyAppGlideModule : AppGlideModule() { 15 | 16 | override fun registerComponents(context: Context, glide: Glide, registry: Registry) { 17 | super.registerComponents(context, glide, registry) 18 | registry.append(Registry.BUCKET_GIF, InputStream::class.java, FrameSequenceDrawable::class.java, 19 | GifDecoder(glide.bitmapPool) 20 | ) 21 | } 22 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/content_second.xml: -------------------------------------------------------------------------------- 1 | 2 | 15 | 16 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /mediabox/src/main/java/com/example/mediabox/data/MediaData.kt: -------------------------------------------------------------------------------- 1 | package com.example.mediabox.data 2 | 3 | import android.net.Uri 4 | import android.os.Parcelable 5 | import com.example.mediabox.ext.JPG 6 | import kotlinx.android.parcel.IgnoredOnParcel 7 | import kotlinx.android.parcel.Parcelize 8 | import java.io.InputStream 9 | 10 | @Parcelize 11 | data class MediaData( 12 | val id: Int, 13 | val uri: Uri, 14 | var width: Int = 0, 15 | var height: Int = 0, 16 | var mimeType: String = JPG 17 | ) : Parcelable { 18 | companion object { 19 | val EMPTY = MediaData(-1, Uri.EMPTY) 20 | } 21 | @IgnoredOnParcel 22 | var selectIndex = 0 23 | 24 | @IgnoredOnParcel 25 | var sourceIndex = 0 26 | 27 | @IgnoredOnParcel 28 | var curSelected = false 29 | 30 | @IgnoredOnParcel 31 | var selected = true 32 | 33 | @IgnoredOnParcel 34 | var notFound = false 35 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/myapplication/imkeyboard/DeviceInfo.kt: -------------------------------------------------------------------------------- 1 | package com.example.myapplication.imkeyboard 2 | 3 | import android.view.Window 4 | 5 | data class DeviceInfo( 6 | val window: Window, 7 | val isPortrait: Boolean, 8 | val statusBarH: Int, 9 | val navigationBarH: Int, 10 | val toolbarH: Int, 11 | val screenH: Int, 12 | val screenWithoutSystemUiH: Int, 13 | val screenWithoutNavigationH: Int 14 | ) { 15 | 16 | /** 17 | * 由于pad的导航栏无论是横屏还是竖屏,都是在当前界面的底部 18 | * 而普通的手机,横屏状态下导航栏是在界面的两侧 19 | * 故需要做区分 20 | */ 21 | fun getCurrentNavigationBarHeightWhenVisible(isPortrait: Boolean, isPad: Boolean): Int { 22 | return if (isPortrait) { 23 | navigationBarH 24 | } else { 25 | if (isPad) { 26 | navigationBarH 27 | } else { 28 | 0 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /mediabox/src/main/cpp/FrameSequenceJNI.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef RASTERMILL_FRAMESEQUENCE_JNI 18 | #define RASTERMILL_FRAMESEQUENCE_JNI 19 | 20 | #include 21 | 22 | jint FrameSequence_OnLoad(JNIEnv* env); 23 | 24 | #endif // RASTERMILL_FRAMESEQUENCE_JNI 25 | -------------------------------------------------------------------------------- /mediabox/src/main/res/drawable/selector_media_select_count_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /mediabox/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 18 | 19 | -------------------------------------------------------------------------------- /library/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4' 9 | } 10 | } 11 | 12 | android { 13 | compileSdkVersion 29 14 | buildToolsVersion "29.0.3" 15 | 16 | defaultConfig { 17 | minSdkVersion 14 18 | targetSdkVersion 29 19 | versionCode 1 20 | versionName "1.0" 21 | } 22 | buildTypes { 23 | release { 24 | minifyEnabled false 25 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 26 | } 27 | } 28 | } 29 | 30 | dependencies { 31 | api 'androidx.documentfile:documentfile:1.0.1' 32 | api 'androidx.exifinterface:exifinterface:1.2.0' 33 | api 'com.davemorrissey.labs:subsampling-scale-image-view-androidx:3.10.0' 34 | api 'com.github.chrisbanes:PhotoView:2.3.0' 35 | } -------------------------------------------------------------------------------- /mediabox/src/main/java/com/example/mediabox/view/PhotoMediaView.kt: -------------------------------------------------------------------------------- 1 | package com.example.mediabox.view 2 | 3 | import android.content.Context 4 | import android.graphics.Bitmap 5 | import android.graphics.drawable.Drawable 6 | import android.net.Uri 7 | import android.util.AttributeSet 8 | import com.example.mediabox.ext.IMediaShowListener 9 | import com.github.chrisbanes.photoview.PhotoView 10 | 11 | class PhotoMediaView @JvmOverloads constructor( 12 | context: Context, 13 | attrs: AttributeSet? = null, 14 | defStyleAttr: Int = 0 15 | ) : PhotoView(context, attrs, defStyleAttr), IMediaShowListener { 16 | 17 | override fun showMedia(uri: Uri) { 18 | setImageURI(uri) 19 | } 20 | 21 | override fun showMedia(drawable: Drawable) { 22 | setImageDrawable(drawable) 23 | } 24 | 25 | override fun showMedia(bitmap: Bitmap) { 26 | setImageBitmap(bitmap) 27 | } 28 | 29 | override fun showMedia(resId: Int) { 30 | setImageResource(resId) 31 | } 32 | } -------------------------------------------------------------------------------- /mediabox/src/main/java/com/example/mediabox/view/NormalMediaView.kt: -------------------------------------------------------------------------------- 1 | package com.example.mediabox.view 2 | 3 | import android.content.Context 4 | import android.graphics.Bitmap 5 | import android.graphics.drawable.Drawable 6 | import android.net.Uri 7 | import android.util.AttributeSet 8 | import androidx.appcompat.widget.AppCompatImageView 9 | import com.example.mediabox.ext.IMediaShowListener 10 | 11 | class NormalMediaView @JvmOverloads constructor( 12 | context: Context, 13 | attrs: AttributeSet? = null, 14 | defStyleAttr: Int = 0 15 | ) : AppCompatImageView(context, attrs, defStyleAttr), IMediaShowListener { 16 | 17 | override fun showMedia(uri: Uri) { 18 | setImageURI(uri) 19 | } 20 | 21 | override fun showMedia(drawable: Drawable) { 22 | setImageDrawable(drawable) 23 | } 24 | 25 | override fun showMedia(bitmap: Bitmap) { 26 | setImageBitmap(bitmap) 27 | } 28 | 29 | override fun showMedia(resId: Int) { 30 | setImageResource(resId) 31 | } 32 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/myapplication/imkeyboard/Constants.kt: -------------------------------------------------------------------------------- 1 | package com.example.myapplication.imkeyboard 2 | 3 | object Constants { 4 | 5 | const val LOG_TAG = "Panel" 6 | //输入法高度 7 | const val KB_PANEL_PREFERENCE_NAME = "ky_panel_name" 8 | const val KEYBOARD_HEIGHT_FOR_L = "keyboard_height_for_l" 9 | const val KEYBOARD_HEIGHT_FOR_P = "keyboard_height_for_p" 10 | const val DEFAULT_KEYBOARD_HEIGHT_FOR_L = 263f 11 | const val DEFAULT_KEYBOARD_HEIGHT_FOR_P = 198f 12 | const val STATUS_BAR_HEIGHT_RES_NAME = "status_bar_height" 13 | const val NAVIGATION_BAR_HEIGHT_RES_NAME = "navigation_bar_height" 14 | const val DIMEN = "dimen" 15 | const val ANDROID = "android" 16 | /** 17 | * panel id, custom panel (PanelView) id is panelView's triggerViewId 18 | * [PanelView.getTriggerViewId] 19 | */ 20 | const val PANEL_NONE = -1 21 | const val PANEL_KEYBOARD = 0 22 | const val PROTECT_KEY_CLICK_DURATION = 500L 23 | 24 | @JvmField 25 | var DEBUG = false 26 | } 27 | -------------------------------------------------------------------------------- /library/src/main/java/top/zibin/luban/InputStreamAdapter.java: -------------------------------------------------------------------------------- 1 | package top.zibin.luban; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | 6 | /** 7 | * Automatically close the previous InputStream when opening a new InputStream, 8 | * and finally need to manually call {@link #close()} to release the resource. 9 | */ 10 | public abstract class InputStreamAdapter implements InputStreamProvider { 11 | 12 | private InputStream inputStream; 13 | 14 | @Override 15 | public InputStream open() throws IOException { 16 | close(); 17 | inputStream = openInternal(); 18 | return inputStream; 19 | } 20 | 21 | public abstract InputStream openInternal() throws IOException; 22 | 23 | @Override 24 | public void close() { 25 | if (inputStream != null) { 26 | try { 27 | inputStream.close(); 28 | } catch (IOException ignore) { 29 | } finally { 30 | inputStream = null; 31 | } 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /mediabox/src/main/cpp/utils/math.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef MATH_H_ 18 | #define MATH_H_ 19 | 20 | #define max(a,b) \ 21 | ({ __typeof__ (a) _a = (a); \ 22 | __typeof__ (b) _b = (b); \ 23 | _a > _b ? _a : _b; }) 24 | 25 | #define min(a,b) \ 26 | ({ __typeof__ (a) _a = (a); \ 27 | __typeof__ (b) _b = (b); \ 28 | _a < _b ? _a : _b; }) 29 | 30 | #endif /* MATH_H_ */ 31 | -------------------------------------------------------------------------------- /mediabox/src/main/java/com/example/mediabox/paging/MediaRepository.kt: -------------------------------------------------------------------------------- 1 | package com.example.mediabox.paging 2 | 3 | import android.content.Context 4 | import android.net.Uri 5 | import androidx.paging.Pager 6 | import androidx.paging.PagingConfig 7 | import com.example.mediabox.data.MediaConfig 8 | 9 | internal class MediaRepository( 10 | context: Context, 11 | config: MediaConfig, 12 | mediaUri: Uri, 13 | private var bucket: String? 14 | ) { 15 | 16 | private var initialLoadSize = 60 17 | 18 | val mediaData by lazy { 19 | Pager(PagingConfig(pageSize = 100, initialLoadSize = 60)) { 20 | MediaListDataSource( 21 | context, 22 | config, 23 | mediaUri, 24 | bucket, 25 | initialLoadSize 26 | ) 27 | }.flow 28 | } 29 | 30 | fun refresh(initSize: Int? = null) { 31 | this.initialLoadSize = initSize ?: 60 32 | } 33 | 34 | fun refresh(bucket: String?) { 35 | this.bucket = bucket 36 | } 37 | } -------------------------------------------------------------------------------- /mediabox/src/main/java/com/example/mediabox/App.kt: -------------------------------------------------------------------------------- 1 | package com.example.mediabox 2 | 3 | import android.app.Application 4 | 5 | class App : Application() { 6 | 7 | override fun onCreate() { 8 | super.onCreate() 9 | // registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks { 10 | // override fun onActivityPaused(activity: Activity) { 11 | // } 12 | // 13 | // override fun onActivityStarted(activity: Activity) { 14 | // } 15 | // 16 | // override fun onActivityDestroyed(activity: Activity) { 17 | // } 18 | // 19 | // override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) { 20 | // } 21 | // 22 | // override fun onActivityStopped(activity: Activity) { 23 | // } 24 | // 25 | // override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) { 26 | // 27 | // } 28 | // 29 | // override fun onActivityResumed(activity: Activity) { 30 | // } 31 | // }) 32 | } 33 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_second.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 14 | 15 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /mediabox/src/main/cpp/JNIHelpers.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef RASTERMILL_JNIHELPERS_H 18 | #define RASTERMILL_JNIHELPERS_H 19 | 20 | #include 21 | 22 | #define METHOD_COUNT(methodArray) (sizeof(methodArray) / sizeof((methodArray)[0])) 23 | 24 | #define ILLEGAL_STATE_EXEPTION "java/lang/IllegalStateException" 25 | 26 | void jniThrowException(JNIEnv* env, const char* className, const char* msg); 27 | 28 | 29 | #endif //RASTERMILL_JNIHELPERS_H 30 | -------------------------------------------------------------------------------- /mediabox/src/main/cpp/Color.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef RASTERMILL_COLOR_H 18 | #define RASTERMILL_COLOR_H 19 | 20 | #include 21 | 22 | typedef uint32_t Color8888; 23 | 24 | static const Color8888 COLOR_8888_ALPHA_MASK = 0xff000000; // TODO: handle endianness 25 | static const Color8888 TRANSPARENT = 0x0; 26 | 27 | // TODO: handle endianness 28 | #define ARGB_TO_COLOR8888(a, r, g, b) \ 29 | ((a) << 24 | (b) << 16 | (g) << 8 | (r)) 30 | 31 | #endif // RASTERMILL_COLOR_H 32 | -------------------------------------------------------------------------------- /mediabox/src/main/cpp/giflib/NOTICE: -------------------------------------------------------------------------------- 1 | The GIFLIB distribution is Copyright (c) 1997 Eric S. Raymond 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /mediabox/src/main/java/com/example/mediabox/adapter/CustomLinearLayoutManager.kt: -------------------------------------------------------------------------------- 1 | package com.example.mediabox.adapter 2 | 3 | import android.content.Context 4 | import androidx.recyclerview.widget.LinearLayoutManager 5 | import androidx.recyclerview.widget.LinearSmoothScroller 6 | import androidx.recyclerview.widget.RecyclerView 7 | 8 | class CustomLinearLayoutManager( 9 | context: Context?, 10 | orientation: Int = RecyclerView.VERTICAL, 11 | reverseLayout: Boolean = false 12 | ) : LinearLayoutManager(context, orientation, reverseLayout) { 13 | 14 | private val scroller: LinearSmoothScroller 15 | 16 | init { 17 | scroller = CustomSmoothScroller(context) 18 | } 19 | 20 | override fun smoothScrollToPosition( 21 | recyclerView: RecyclerView, 22 | state: RecyclerView.State, 23 | position: Int 24 | ) { 25 | scroller.targetPosition = position 26 | startSmoothScroll(scroller) 27 | } 28 | 29 | internal inner class CustomSmoothScroller(context: Context?) : 30 | LinearSmoothScroller(context) { 31 | 32 | override fun getVerticalSnapPreference(): Int { 33 | return SNAP_TO_START //设置滚动位置 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx1536m 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app's APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Automatically convert third-party libraries to use AndroidX 19 | android.enableJetifier=true 20 | # Kotlin code style for this project: "official" or "obsolete": 21 | kotlin.code.style=official 22 | -------------------------------------------------------------------------------- /mediabox/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | 14 | 15 | 20 | 21 | 26 | 27 | -------------------------------------------------------------------------------- /mediabox/src/main/java/com/example/mediabox/view/LagerMediaView.kt: -------------------------------------------------------------------------------- 1 | package com.example.mediabox.view 2 | 3 | import android.content.Context 4 | import android.graphics.Bitmap 5 | import android.graphics.drawable.Drawable 6 | import android.net.Uri 7 | import android.util.AttributeSet 8 | import android.view.MotionEvent 9 | import com.example.mediabox.data.ImageSource 10 | import com.example.mediabox.ext.IMediaShowListener 11 | 12 | class LagerMediaView @JvmOverloads constructor( 13 | context: Context, 14 | attrs: AttributeSet? = null 15 | ) : SubsamplingScalePlusImageView(context, attrs), IMediaShowListener { 16 | 17 | override fun isSupportLargeMedia() = true 18 | 19 | override fun showMedia(uri: Uri) { 20 | setImage(ImageSource.uri(uri)) 21 | } 22 | 23 | override fun showMedia(drawable: Drawable) { 24 | throw IllegalArgumentException("not support set drawable") 25 | 26 | } 27 | 28 | override fun showMedia(bitmap: Bitmap) { 29 | setImage(ImageSource.bitmap(bitmap)) 30 | } 31 | 32 | override fun showMedia(resId: Int) { 33 | setImage(ImageSource.resource(resId)) 34 | } 35 | 36 | override fun showMediaCache(bitmap: Bitmap) { 37 | setImage(ImageSource.cachedBitmap(bitmap)) 38 | } 39 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main1.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 13 | 14 | 19 | 20 | 21 | 22 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /mediabox/src/main/cpp/FrameSequence.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "FrameSequence.h" 18 | 19 | #include "Registry.h" 20 | 21 | FrameSequence* FrameSequence::create(Stream* stream) { 22 | const RegistryEntry* entry = Registry::Find(stream); 23 | 24 | if (!entry) return NULL; 25 | 26 | FrameSequence* frameSequence = entry->createFrameSequence(stream); 27 | if (!frameSequence->getFrameCount() || 28 | !frameSequence->getWidth() || !frameSequence->getHeight()) { 29 | // invalid contents, abort 30 | delete frameSequence; 31 | return NULL; 32 | } 33 | 34 | return frameSequence; 35 | } 36 | -------------------------------------------------------------------------------- /mediabox/src/main/cpp/JNIHelpers.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "JNIHelpers.h" 18 | #include "utils/log.h" 19 | 20 | void jniThrowException(JNIEnv* env, const char* className, const char* msg) { 21 | jclass clazz = env->FindClass(className); 22 | if (!clazz) { 23 | ALOGE("Unable to find exception class %s", className); 24 | /* ClassNotFoundException now pending */ 25 | return; 26 | } 27 | 28 | if (env->ThrowNew(clazz, msg) != JNI_OK) { 29 | ALOGE("Failed throwing '%s' '%s'", className, msg); 30 | /* an exception, most likely OOM, will now be pending */ 31 | } 32 | env->DeleteLocalRef(clazz); 33 | } 34 | -------------------------------------------------------------------------------- /mediabox/src/main/res/layout/recycler_view_item_media_camera.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 18 | 19 | 30 | 31 | -------------------------------------------------------------------------------- /mediabox/src/main/res/layout/recycler_view_item_media_select.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 12 | 13 | 18 | 19 | 34 | 35 | -------------------------------------------------------------------------------- /mediabox/src/main/cpp/giflib/gif_hash.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | 3 | gif_hash.h - magfic constants and declarations for GIF LZW 4 | 5 | ******************************************************************************/ 6 | 7 | #ifndef _GIF_HASH_H_ 8 | #define _GIF_HASH_H_ 9 | 10 | #include 11 | #include 12 | 13 | #define HT_SIZE 8192 /* 12bits = 4096 or twice as big! */ 14 | #define HT_KEY_MASK 0x1FFF /* 13bits keys */ 15 | #define HT_KEY_NUM_BITS 13 /* 13bits keys */ 16 | #define HT_MAX_KEY 8191 /* 13bits - 1, maximal code possible */ 17 | #define HT_MAX_CODE 4095 /* Biggest code possible in 12 bits. */ 18 | 19 | /* The 32 bits of the long are divided into two parts for the key & code: */ 20 | /* 1. The code is 12 bits as our compression algorithm is limited to 12bits */ 21 | /* 2. The key is 12 bits Prefix code + 8 bit new char or 20 bits. */ 22 | /* The key is the upper 20 bits. The code is the lower 12. */ 23 | #define HT_GET_KEY(l) (l >> 12) 24 | #define HT_GET_CODE(l) (l & 0x0FFF) 25 | #define HT_PUT_KEY(l) (l << 12) 26 | #define HT_PUT_CODE(l) (l & 0x0FFF) 27 | 28 | typedef struct GifHashTableType { 29 | uint32_t HTable[HT_SIZE]; 30 | } GifHashTableType; 31 | 32 | GifHashTableType *_InitHashTable(void); 33 | void _ClearHashTable(GifHashTableType *HashTable); 34 | void _InsertHashTable(GifHashTableType *HashTable, uint32_t Key, int Code); 35 | int _ExistsHashTable(GifHashTableType *HashTable, uint32_t Key); 36 | 37 | #endif /* _GIF_HASH_H_ */ 38 | 39 | /* end */ 40 | -------------------------------------------------------------------------------- /mediabox/src/main/cpp/giflib/openbsd-reallocarray.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: reallocarray.c,v 1.1 2014/05/08 21:43:49 deraadt Exp $ */ 2 | /* 3 | * Copyright (c) 2008 Otto Moerbeek 4 | * 5 | * Permission to use, copy, modify, and distribute this software for any 6 | * purpose with or without fee is hereby granted, provided that the above 7 | * copyright notice and this permission notice appear in all copies. 8 | * 9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include //为什么没有引用这个文件尼? 23 | 24 | /* 25 | * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX 26 | * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW 27 | */ 28 | #define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4)) 29 | 30 | void * 31 | reallocarray(void *optr, size_t nmemb, size_t size) 32 | { 33 | if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && 34 | nmemb > 0 && SIZE_MAX / nmemb < size) { 35 | errno = ENOMEM; 36 | return NULL; 37 | } 38 | return realloc(optr, size * nmemb); 39 | } 40 | -------------------------------------------------------------------------------- /mediabox/src/main/cpp/BitmapDecoderJNI.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #define LOG_TAG "FancyDecoding" 18 | 19 | #include 20 | #include 21 | #include 22 | #include "FrameSequenceJNI.h" 23 | #include "JNIHelpers.h" 24 | #include "Stream.h" 25 | #include "utils/log.h" 26 | 27 | void throwException(JNIEnv* env, const char* error) { 28 | jclass clazz = env->FindClass("java/lang/RuntimeException"); 29 | env->ThrowNew(clazz, error); 30 | } 31 | 32 | jint JNI_OnLoad(JavaVM* vm, void* reserved) { 33 | JNIEnv* env; 34 | if (vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6) != JNI_OK) { 35 | return -1; 36 | } 37 | if (FrameSequence_OnLoad(env)) { 38 | ALOGE("Failed to load FrameSequence"); 39 | return -1; 40 | } 41 | if (JavaStream_OnLoad(env)) { 42 | ALOGE("Failed to load JavaStream"); 43 | return -1; 44 | } 45 | 46 | return JNI_VERSION_1_6; 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/myapplication/imkeyboard/RelativeKeyboardLayout.kt: -------------------------------------------------------------------------------- 1 | package com.example.myapplication.imkeyboard 2 | 3 | import android.content.Context 4 | import android.util.AttributeSet 5 | import android.view.View 6 | import android.widget.RelativeLayout 7 | 8 | /** 9 | * TODO: 未完成 10 | */ 11 | @Deprecated("待完成") 12 | class RelativeKeyboardLayout @JvmOverloads constructor( 13 | context: Context, 14 | attr: AttributeSet? = null, 15 | defStyleAttr: Int = 0 16 | ) : RelativeLayout(context, attr, defStyleAttr), IKeyboardLayout { 17 | 18 | override var contentView: View? = null 19 | 20 | override lateinit var panelView: View 21 | 22 | override var lastState: KeyboardPanelState = KeyboardPanelState.KEYBOARD_PANEL_STATE_NONE 23 | 24 | override var curState: KeyboardPanelState = KeyboardPanelState.KEYBOARD_PANEL_STATE_NONE 25 | 26 | override var keyboardHelper: KeyboardHelper? = null 27 | 28 | init { 29 | isChildrenDrawingOrderEnabled = true 30 | } 31 | 32 | override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) { 33 | super.onLayout(changed, l, t, r, b) 34 | getChildAt(1)?.apply { 35 | layout(left, top.plus(150), right, bottom.plus(150)) 36 | } 37 | } 38 | 39 | override fun getChildDrawingOrder(childCount: Int, drawingPosition: Int): Int { 40 | if (drawingPosition == 0) { 41 | return childCount.minus(1) 42 | } 43 | if (drawingPosition == childCount.minus(1)) { 44 | return 0 45 | } 46 | return super.getChildDrawingOrder(childCount, drawingPosition) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/myapplication/imkeyboard/SmoothPositionLinearLayoutManager.kt: -------------------------------------------------------------------------------- 1 | package com.example.myapplication.imkeyboard 2 | 3 | import android.content.Context 4 | import android.util.AttributeSet 5 | import androidx.recyclerview.widget.LinearLayoutManager 6 | import androidx.recyclerview.widget.LinearSmoothScroller 7 | import androidx.recyclerview.widget.RecyclerView 8 | 9 | class SmoothPositionLinearLayoutManager : LinearLayoutManager { 10 | 11 | constructor(context: Context?) : super(context) 12 | 13 | constructor( 14 | context: Context?, 15 | orientation: Int, 16 | reverseLayout: Boolean 17 | ) : super(context, orientation, reverseLayout) 18 | 19 | constructor( 20 | context: Context?, 21 | attrs: AttributeSet?, 22 | defStyleAttr: Int, 23 | defStyleRes: Int 24 | ) : super(context, attrs, defStyleAttr, defStyleRes) 25 | 26 | override fun smoothScrollToPosition( 27 | recyclerView: RecyclerView, 28 | state: RecyclerView.State, 29 | position: Int 30 | ) { 31 | val topSnappedSmoothScroller = TopSnappedSmoothScroller(recyclerView.context) 32 | topSnappedSmoothScroller.targetPosition = position 33 | startSmoothScroll(topSnappedSmoothScroller) 34 | } 35 | 36 | internal inner class TopSnappedSmoothScroller(context: Context?) : 37 | LinearSmoothScroller(context) { 38 | 39 | override fun calculateTimeForDeceleration(dx: Int): Int { 40 | return 250 41 | } 42 | 43 | override fun getVerticalSnapPreference(): Int { 44 | return SNAP_TO_END //设置滚动位置 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 17 | 18 | 23 | 24 | 33 | 34 | -------------------------------------------------------------------------------- /mediabox/src/main/cpp/Registry.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef RASTERMILL_REGISTRY_H 18 | #define RASTERMILL_REGISTRY_H 19 | 20 | #include "jni.h" 21 | #include 22 | 23 | class FrameSequence; 24 | class Decoder; 25 | class Stream; 26 | 27 | struct RegistryEntry { 28 | int requiredHeaderBytes; 29 | bool (*checkHeader)(void* header, int header_size); 30 | FrameSequence* (*createFrameSequence)(Stream* stream); 31 | Decoder* (*createDecoder)(Stream* stream); 32 | bool (*acceptsBuffer)(); 33 | }; 34 | 35 | /** 36 | * Template class for registering subclasses that can produce instances of themselves given a 37 | * DataStream pointer. 38 | * 39 | * The super class / root constructable type only needs to define a single static construction 40 | * meathod that creates an instance by iterating through all factory methods. 41 | */ 42 | class Registry { 43 | public: 44 | Registry(const RegistryEntry& entry); 45 | 46 | static const RegistryEntry* Find(Stream* stream); 47 | 48 | private: 49 | RegistryEntry mImpl; 50 | Registry* mNext; 51 | }; 52 | 53 | #endif // RASTERMILL_REGISTRY_H 54 | -------------------------------------------------------------------------------- /mediabox/src/main/java/com/example/mediabox/glide/gif/GifDecoder.java: -------------------------------------------------------------------------------- 1 | package com.example.mediabox.glide.gif; 2 | 3 | import android.graphics.Bitmap; 4 | 5 | import androidx.annotation.NonNull; 6 | import androidx.annotation.Nullable; 7 | 8 | import com.bumptech.glide.load.Options; 9 | import com.bumptech.glide.load.ResourceDecoder; 10 | import com.bumptech.glide.load.engine.Resource; 11 | import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool; 12 | 13 | import java.io.IOException; 14 | import java.io.InputStream; 15 | 16 | public class GifDecoder implements ResourceDecoder { 17 | 18 | private BitmapPool bitmapPool; 19 | 20 | public GifDecoder(BitmapPool bitmapPool) { 21 | this.bitmapPool = bitmapPool; 22 | } 23 | 24 | @Override 25 | public boolean handles(@NonNull InputStream source, @NonNull Options options) { 26 | return true; 27 | } 28 | 29 | @Nullable 30 | @Override 31 | public Resource decode(@NonNull InputStream source, int width, final int height, @NonNull Options options) throws IOException { 32 | FrameSequence frameSequence = FrameSequence.decodeStream(source); 33 | FrameSequenceDrawable frameSequenceDrawable = new FrameSequenceDrawable(frameSequence, new FrameSequenceDrawable.BitmapProvider() { 34 | @Override 35 | public Bitmap acquireBitmap(int minWidth, int minHeight) { 36 | return bitmapPool.get(minWidth, minHeight, Bitmap.Config.ARGB_8888); 37 | } 38 | 39 | @Override 40 | public void releaseBitmap(Bitmap bitmap) { 41 | bitmapPool.put(bitmap); 42 | } 43 | }); 44 | return new GifResource(frameSequenceDrawable); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /library/src/main/java/top/zibin/luban/InputStreamAdapter2.java: -------------------------------------------------------------------------------- 1 | package top.zibin.luban; 2 | 3 | import android.content.ContentResolver; 4 | import android.graphics.Bitmap; 5 | import android.graphics.BitmapFactory; 6 | import android.net.Uri; 7 | import android.os.ParcelFileDescriptor; 8 | 9 | import java.io.FileDescriptor; 10 | import java.io.FileNotFoundException; 11 | import java.io.IOException; 12 | import java.io.InputStream; 13 | 14 | public class InputStreamAdapter2 implements InputStreamProvider2 { 15 | 16 | private Uri uri; 17 | private ContentResolver contentResolver; 18 | 19 | private Bitmap bitmap; 20 | 21 | InputStreamAdapter2(Uri uri, ContentResolver contentResolver) { 22 | this.uri = uri; 23 | this.contentResolver = contentResolver; 24 | } 25 | 26 | @Override 27 | public Uri getUri() { 28 | return uri; 29 | } 30 | 31 | @Override 32 | public InputStream open() throws IOException { 33 | return contentResolver.openInputStream(uri); 34 | } 35 | 36 | @Override 37 | public Bitmap getBitmap() throws IOException { 38 | if (bitmap == null) { 39 | ParcelFileDescriptor parcelFileDescriptor = contentResolver.openFileDescriptor(uri, "r"); 40 | if (parcelFileDescriptor != null) { 41 | FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor(); 42 | bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor); 43 | parcelFileDescriptor.close(); 44 | } 45 | } 46 | if (bitmap == null) { 47 | throw new FileNotFoundException("Resource does not exist: " + uri); 48 | } 49 | return bitmap; 50 | } 51 | 52 | @Override 53 | public String getMimeType() { 54 | return contentResolver.getType(uri); 55 | } 56 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 15 | 18 | 21 | 22 | 23 | 24 | 30 | -------------------------------------------------------------------------------- /mediabox/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 15 | 18 | 21 | 22 | 23 | 24 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_keyboard2.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 15 | 16 | 23 | 24 | 29 | 30 |