├── .github └── workflows │ └── build.yml ├── .gitignore ├── .idea ├── encodings.xml ├── misc.xml ├── modules.xml └── vcs.xml ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── jni │ └── Application.mk ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── assets │ ├── GattUUIDs.json │ ├── imagetransfer │ │ └── eink3color.png │ └── neopixel │ │ ├── NeopixelBoards.json │ │ └── NeopixelDefaultPalette.json │ ├── ic_launcher-playstore.png │ ├── ic_launcher-web.png │ ├── java │ ├── com │ │ └── adafruit │ │ │ └── bluefruit │ │ │ └── le │ │ │ └── connect │ │ │ ├── BluefruitApplication.java │ │ │ ├── app │ │ │ ├── AboutFragment.java │ │ │ ├── BlePeripheralsAdapter.java │ │ │ ├── CommonHelpFragment.java │ │ │ ├── ConnectedPeripheralFragment.java │ │ │ ├── ControllerColorPickerFragment.java │ │ │ ├── ControllerFragment.java │ │ │ ├── ControllerPadFragment.java │ │ │ ├── DeviceInformationServiceFragment.java │ │ │ ├── DfuFragment.java │ │ │ ├── InfoFragment.java │ │ │ ├── MainActivity.java │ │ │ ├── MainFragment.java │ │ │ ├── MqttSettingsCodeReaderFragment.java │ │ │ ├── MqttSettingsFragment.java │ │ │ ├── PeripheralModeFragment.java │ │ │ ├── PeripheralModulesFragment.java │ │ │ ├── PinIOFragment.java │ │ │ ├── PlotterFragment.java │ │ │ ├── ScannerFragment.java │ │ │ ├── ScannerStatusFragmentDialog.java │ │ │ ├── SplashActivity.java │ │ │ ├── ThermalCameraFragment.java │ │ │ ├── ThermalGradientView.java │ │ │ ├── UartBaseFragment.java │ │ │ ├── UartDataExport.java │ │ │ ├── UartModeFragment.java │ │ │ ├── UartServiceFragment.java │ │ │ ├── barcode │ │ │ │ ├── BarcodeGraphic.java │ │ │ │ ├── BarcodeGraphicTracker.java │ │ │ │ ├── BarcodeTrackerFactory.java │ │ │ │ ├── CameraSource.java │ │ │ │ ├── CameraSourcePreview.java │ │ │ │ └── GraphicOverlay.java │ │ │ ├── imagetransfer │ │ │ │ ├── ImageCropFragment.java │ │ │ │ ├── ImageTransferFormatSelectorDialogFragment.java │ │ │ │ ├── ImageTransferFormatSelectorPageFragment.java │ │ │ │ └── ImageTransferFragment.java │ │ │ └── neopixel │ │ │ │ ├── NeopixelBoardSelectorFragment.java │ │ │ │ ├── NeopixelColorPickerFragment.java │ │ │ │ ├── NeopixelComponentSelectorFragment.java │ │ │ │ ├── NeopixelComponentWBar.java │ │ │ │ ├── NeopixelComponents.java │ │ │ │ └── NeopixelFragment.java │ │ │ ├── ble │ │ │ ├── BleUtils.java │ │ │ ├── UartPacket.java │ │ │ ├── UartPacketManagerBase.java │ │ │ ├── central │ │ │ │ ├── BleManager.java │ │ │ │ ├── BlePeripheral.java │ │ │ │ ├── BlePeripheralBattery.java │ │ │ │ ├── BlePeripheralDfu.java │ │ │ │ ├── BlePeripheralUart.java │ │ │ │ ├── BleScanner.java │ │ │ │ ├── BleUUIDNames.java │ │ │ │ ├── UartDataManager.java │ │ │ │ └── UartPacketManager.java │ │ │ └── peripheral │ │ │ │ ├── DeviceInformationPeripheralService.java │ │ │ │ ├── GattServer.java │ │ │ │ ├── PeripheralService.java │ │ │ │ ├── UartPeripheralModePacketManager.java │ │ │ │ └── UartPeripheralService.java │ │ │ ├── dfu │ │ │ ├── DfuFilePickerFragment.java │ │ │ ├── DfuProgressFragmentDialog.java │ │ │ ├── DfuService.java │ │ │ ├── DfuUpdater.java │ │ │ ├── DownloadTask.java │ │ │ ├── NotificationActivity.java │ │ │ ├── ProgressFragmentDialog.java │ │ │ └── ReleasesParser.java │ │ │ ├── models │ │ │ ├── DeviceInformationServiceViewModel.java │ │ │ ├── DfuViewModel.java │ │ │ ├── PeripheralModeManager.java │ │ │ ├── PeripheralModeViewModel.java │ │ │ └── ScannerViewModel.java │ │ │ ├── mqtt │ │ │ ├── MqttManager.java │ │ │ └── MqttSettings.java │ │ │ ├── style │ │ │ ├── RssiUI.java │ │ │ ├── StyledSnackBar.java │ │ │ └── UartStyle.java │ │ │ └── utils │ │ │ ├── AdapterUtils.java │ │ │ ├── DialogUtils.java │ │ │ ├── FileHelper.java │ │ │ ├── FileUtils.java │ │ │ ├── ImageMagickUtils.java │ │ │ ├── ImageUtils.java │ │ │ ├── KeyboardUtils.java │ │ │ ├── LegacyCompatFileProvider.java │ │ │ ├── LocalizationManager.java │ │ │ ├── MetricsUtils.java │ │ │ ├── NetworkUtils.java │ │ │ ├── PermissionsUtils.java │ │ │ ├── ScreenUtils.java │ │ │ ├── SingleLiveEvent.java │ │ │ ├── ThreadUtils.java │ │ │ ├── TwoDimensionScrollView.java │ │ │ └── UriBeaconUtils.java │ ├── fakeawt │ │ ├── Dimension.java │ │ ├── Point.java │ │ └── Rectangle.java │ ├── magick │ │ ├── ClassType.java │ │ ├── ColorspaceType.java │ │ ├── CompositeOperator.java │ │ ├── CompressionType.java │ │ ├── DecorationType.java │ │ ├── DrawInfo.java │ │ ├── ExceptionType.java │ │ ├── FilterType.java │ │ ├── GeometryFlags.java │ │ ├── GravityType.java │ │ ├── ImageInfo.java │ │ ├── ImageMagick.java │ │ ├── ImageType.java │ │ ├── InterlaceType.java │ │ ├── Magick.java │ │ ├── MagickApiException.java │ │ ├── MagickException.java │ │ ├── MagickImage.java │ │ ├── MagickInfo.java │ │ ├── MagickLoader.java │ │ ├── MapMode.java │ │ ├── MontageInfo.java │ │ ├── MontageMode.java │ │ ├── NoiseType.java │ │ ├── PaintMethod.java │ │ ├── PixelPacket.java │ │ ├── PreviewType.java │ │ ├── PrimitiveType.java │ │ ├── ProfileInfo.java │ │ ├── QuantizeInfo.java │ │ ├── QuantumTypes.java │ │ ├── RenderingIntent.java │ │ ├── ResolutionType.java │ │ ├── StorageType.java │ │ ├── TimerState.java │ │ └── util │ │ │ ├── DisplayImageMetaData.java │ │ │ ├── MagickBitmap.java │ │ │ └── Makefile │ └── org │ │ └── eclipse │ │ └── paho │ │ └── android │ │ └── service │ │ ├── AlarmPingSender.java │ │ ├── DatabaseMessageStore.java │ │ ├── MessageStore.java │ │ ├── MqttAndroidClient.java │ │ ├── MqttConnection.java │ │ ├── MqttDeliveryTokenAndroid.java │ │ ├── MqttService.java │ │ ├── MqttServiceBinder.java │ │ ├── MqttServiceConstants.java │ │ ├── MqttTokenAndroid.java │ │ ├── MqttTraceHandler.java │ │ ├── ParcelableMqttMessage.java │ │ └── Status.java │ ├── jniLibs │ ├── arm64-v8a │ │ └── libimagemagick.so │ ├── armeabi-v7a │ │ └── libimagemagick.so │ ├── armeabi │ │ └── libimagemagick.so │ ├── mips │ │ └── libimagemagick.so │ ├── mips64 │ │ └── libimagemagick.so │ ├── x86 │ │ └── libimagemagick.so │ └── x86_64 │ │ └── libimagemagick.so │ └── res │ ├── anim │ ├── slide_down.xml │ ├── slide_in_left.xml │ ├── slide_in_right.xml │ ├── slide_out_left.xml │ ├── slide_out_right.xml │ └── slide_up.xml │ ├── color │ └── main_bottomnavigationbar.xml │ ├── drawable-hdpi │ └── info_adafruit_logo.png │ ├── drawable-mdpi │ └── info_adafruit_logo.png │ ├── drawable-xhdpi │ ├── info_adafruit_logo.png │ ├── pad_arrow_button_down.png │ ├── pad_arrow_button_left.png │ ├── pad_arrow_button_right.png │ ├── pad_arrow_button_up.png │ ├── pad_button_numbers_1.png │ ├── pad_button_numbers_2.png │ ├── pad_button_numbers_3.png │ ├── pad_button_numbers_4.png │ └── scanner_adaflower.png │ ├── drawable-xxhdpi │ ├── batterylevel.png │ ├── imagetransfer_default.png │ ├── imagetransfer_rotate_left.png │ ├── imagetransfer_rotate_right.png │ ├── imagetransfer_test1.png │ ├── imagetransfer_test2.png │ ├── mqtt_connected.png │ ├── mqtt_connecting1.png │ ├── mqtt_connecting2.png │ ├── mqtt_connecting3.png │ ├── mqtt_disconnected.png │ ├── tab_calibration_icon.png │ ├── tab_circuitpython_icon.png │ ├── tab_controller_icon.png │ ├── tab_dfu_icon.png │ ├── tab_imagetransfer_icon.png │ ├── tab_info_icon.png │ ├── tab_neopixel_icon.png │ ├── tab_pinio_icon.png │ ├── tab_plotter_icon.png │ ├── tab_thermalcamera_icon.png │ └── tab_uart_icon.png │ ├── drawable-xxxhdpi │ └── disclosure_24dp.png │ ├── drawable │ ├── about_message_background.xml │ ├── border_gray.xml │ ├── border_white.xml │ ├── ic_cancel_black_18dp.xml │ ├── ic_expand_more_black_24dp.xml │ ├── ic_info_outline_white_24dp.xml │ ├── ic_more_vert_black_24dp.xml │ ├── ic_notifications_black_24dp.xml │ ├── ic_pie_chart_outlined_white_24dp.xml │ ├── ic_rotate_right_white_36dp.xml │ ├── ic_select_all_white_36dp.xml │ ├── ic_settings_white_24dp.xml │ ├── ic_speaker_phone_white_24dp.xml │ ├── ic_tap_and_play_white_24dp.xml │ ├── neopixel_colorpicker_border_black.xml │ ├── neopixel_led.xml │ ├── neopixel_palettecolor.xml │ ├── neopixel_palettecolor_bottom.xml │ ├── roundedborders_blue.xml │ ├── roundedborders_border_black.xml │ ├── roundedborders_gray.xml │ ├── roundedbutton.xml │ ├── scanresult_advertisementbackground.xml │ ├── signalstrength0.png │ ├── signalstrength1.png │ ├── signalstrength2.png │ ├── signalstrength3.png │ ├── signalstrength4.png │ ├── simpledivideritemdecoration.xml │ └── splash_screen.xml │ ├── layout │ ├── activity_main.xml │ ├── dialog_imagetransfer_chooseresolution.xml │ ├── fragment_about.xml │ ├── fragment_commonhelp.xml │ ├── fragment_controller.xml │ ├── fragment_controller_colorpicker.xml │ ├── fragment_controller_pad.xml │ ├── fragment_deviceinformationservice.xml │ ├── fragment_dfu.xml │ ├── fragment_dfu_filepicker.xml │ ├── fragment_imagecrop.xml │ ├── fragment_imagetransfer.xml │ ├── fragment_imagetransfer_formatselector_page.xml │ ├── fragment_info.xml │ ├── fragment_main.xml │ ├── fragment_mqttsettings.xml │ ├── fragment_mqttsettings_codereader.xml │ ├── fragment_neopixel.xml │ ├── fragment_neopixel_boardselector.xml │ ├── fragment_neopixel_colorpicker.xml │ ├── fragment_neopixel_componentselector.xml │ ├── fragment_peripheralmode.xml │ ├── fragment_peripheralmodules.xml │ ├── fragment_pinio.xml │ ├── fragment_plotter.xml │ ├── fragment_scanner.xml │ ├── fragment_thermalcamera.xml │ ├── fragment_uart.xml │ ├── layout_common_edittext_item.xml │ ├── layout_common_message_dialog.xml │ ├── layout_common_section_item.xml │ ├── layout_common_switch_item.xml │ ├── layout_common_textview_item.xml │ ├── layout_controller_sensordata_item.xml │ ├── layout_dfu_custom_item.xml │ ├── layout_dfu_release_item.xml │ ├── layout_info_characteristic_item.xml │ ├── layout_info_descriptor_item.xml │ ├── layout_info_service_item.xml │ ├── layout_neopixel_led.xml │ ├── layout_neopixel_list_item.xml │ ├── layout_neopixel_palette_item.xml │ ├── layout_peripheralmode_name_item.xml │ ├── layout_peripheralmodules_module.xml │ ├── layout_peripheralmodules_peripheraldetails.xml │ ├── layout_pinio_item.xml │ ├── layout_scan_item.xml │ └── layout_uart_packetitem.xml │ ├── menu │ ├── menu_centralmode.xml │ ├── menu_empty.xml │ ├── menu_help.xml │ ├── menu_neopixel.xml │ ├── menu_scan_filters_name.xml │ ├── menu_uart.xml │ └── navigation.xml │ ├── mipmap-anydpi-v26 │ ├── ic_launcher.xml │ └── ic_launcher_round.xml │ ├── mipmap-hdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-mdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-xhdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-xxhdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-xxxhdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── values-w820dp │ └── dimens.xml │ ├── values │ ├── colors.xml │ ├── dimens.xml │ ├── ic_launcher_background.xml │ ├── material_colors.xml │ ├── strings.xml │ └── styles.xml │ └── xml │ ├── backup_scheme.xml │ ├── data_extraction_rules.xml │ └── provider_paths.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build debug app APK 2 | 3 | on: 4 | push: 5 | branches: 6 | - '**' 7 | pull_request: 8 | - main 9 | 10 | jobs: 11 | 12 | apk-debug: 13 | name: Generate debug APK 14 | runs-on: ubuntu-latest 15 | steps: 16 | 17 | - name: Checkout code 18 | uses: actions/checkout@v3 19 | with: 20 | submodules: recursive 21 | 22 | - name: Setup JDK 11 23 | uses: actions/setup-java@v3 24 | with: 25 | java-version: 11 26 | distribution: 'adopt' 27 | 28 | - name: Setup Gradle 29 | uses: gradle/gradle-build-action@v2 30 | 31 | - name: Build APK 32 | run: ./gradlew assembleDebug --stacktrace 33 | 34 | - name: Upload APK 35 | uses: actions/upload-artifact@v4 36 | with: 37 | name: Blueffruit Connect debug APK 38 | path: app/build/outputs/apk/debug/*.apk 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the ART/Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | out/ 15 | 16 | # Gradle files 17 | .gradle/ 18 | build/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | local.properties 22 | 23 | # Proguard folder generated by Eclipse 24 | proguard/ 25 | 26 | # Log Files 27 | *.log 28 | 29 | # Android Studio Navigation editor temp files 30 | .navigation/ 31 | 32 | # Android Studio captures folder 33 | captures/ 34 | 35 | # IntelliJ 36 | *.iml 37 | .idea/workspace.xml 38 | .idea/tasks.xml 39 | .idea/gradle.xml 40 | .idea/assetWizardSettings.xml 41 | .idea/dictionaries 42 | .idea/libraries 43 | .idea/caches 44 | 45 | # Keystore files 46 | # Uncomment the following line if you do not want to check your keystore files in. 47 | #*.jks 48 | 49 | # External native build folder generated in Android Studio 2.2 and later 50 | .externalNativeBuild 51 | 52 | # Google Services (e.g. APIs or Firebase) 53 | google-services.json 54 | 55 | # Freeline 56 | freeline.py 57 | freeline/ 58 | freeline_project_description.json 59 | 60 | # fastlane 61 | fastlane/report.xml 62 | fastlane/Preview.html 63 | fastlane/screenshots 64 | fastlane/test_output 65 | fastlane/readme.md 66 | app/debug 67 | app/release 68 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 23 | 40 | 41 | 42 | 43 | 44 | 45 | 47 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Adafruit Industries 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Bluefruit_LE_Connect_Android_V2 2 | 3 | Android app for use with Bluefruit Bluetooth LE modules and dev boards from Adafruit. 4 | 5 | 6 | ## App Versions 7 | 8 | - Master branch is for version 3.x of the app (Android) 9 | 10 | - The source code for previous unsupported versions is available at [Bluefruit_LE_Connect_Android](https://github.com/adafruit/Bluefruit_LE_Connect_Android). 11 | 12 | 13 | ## Supported Hardware 14 | 15 | Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! 16 | 17 | This application works with the following Bluefruit LE devices from Adafruit: 18 | 19 | - [Bluefruit LE Friend](https://www.adafruit.com/product/2267) 20 | - [Bluefruit LE UART Friend](https://www.adafruit.com/product/2479) 21 | - [Bluefruit LE SPI Friend](https://www.adafruit.com/product/2633) 22 | - [Bluefruit LE Shield](https://www.adafruit.com/products/2746) 23 | - [Bluefruit LE Micro](https://www.adafruit.com/product/2661) (Retired) 24 | - [Feather 32u4 Bluefruit LE](https://www.adafruit.com/product/2829) 25 | - [Feather M0 Bluefruit LE](https://www.adafruit.com/products/2995) 26 | 27 | ## License 28 | 29 | Unless otherwise specified, all files produced by Adafruit are covered by an [MIT license](https://github.com/adafruit/Bluefruit_LE_Connect_Android/blob/master/license.txt). 30 | 31 | Files produced by Nordic Semiconductors are covered by their own license terms, as detailed in the file headers and appropriate folders. Please carefully review the license requirements before using this source code in your own application. 32 | 33 | 34 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/jni/Application.mk: -------------------------------------------------------------------------------- 1 | APP_ABI := all -------------------------------------------------------------------------------- /app/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/antonio/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 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | -keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | -renamesourcefileattribute SourceFile 26 | 27 | # Remove logs on release builds 28 | -assumenosideeffects class android.util.Log { 29 | public static boolean isLoggable(java.lang.String, int); 30 | public static int v(...); 31 | public static int i(...); 32 | public static int w(...); 33 | public static int d(...); 34 | public static int e(...); 35 | } 36 | 37 | # Keep anonymous class declaration 38 | -keepattributes EnclosingMethod 39 | 40 | # Nordic DFU library 41 | -keep class no.nordicsemi.android.dfu.** { *; } 42 | 43 | # Paho library logger 44 | -keep class org.eclipse.paho.client.mqttv3.logging.JSR47Logger { 45 | *; 46 | } 47 | 48 | # Avoid warnings for old code in Paho 1.0.2 on Android Studio 2 49 | -keep class org.eclipse.paho.client.mqttv3.persist.** { *; } 50 | -dontwarn org.eclipse.paho.client.mqttv3.persist.** 51 | -keepattributes Exceptions, Signature, InnerClasses 52 | 53 | # ImageMagick 54 | -keep class magick.** { *; } -------------------------------------------------------------------------------- /app/src/main/assets/imagetransfer/eink3color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/assets/imagetransfer/eink3color.png -------------------------------------------------------------------------------- /app/src/main/assets/neopixel/NeopixelBoards.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "height": 4, 4 | "stride": 8, 5 | "width": 8, 6 | "name": "8x4" 7 | }, 8 | { 9 | "height": 8, 10 | "stride": 8, 11 | "width": 8, 12 | "name": "8x8" 13 | }, 14 | { 15 | "height": 1, 16 | "stride": 8, 17 | "width": 8, 18 | "name": "1x8" 19 | } 20 | ] -------------------------------------------------------------------------------- /app/src/main/assets/neopixel/NeopixelDefaultPalette.json: -------------------------------------------------------------------------------- 1 | [ 2 | "FF0000", 3 | "FF8000", 4 | "FFFF00", 5 | "80FF00", 6 | "00FF00", 7 | "00FF80", 8 | "00FFFF", 9 | "0080FF", 10 | "0000FF", 11 | "7F00FF", 12 | "FF00FF", 13 | "FF007F", 14 | "808080", 15 | "000000", 16 | "FFFFFF" 17 | ] -------------------------------------------------------------------------------- /app/src/main/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/ic_launcher-playstore.png -------------------------------------------------------------------------------- /app/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /app/src/main/java/com/adafruit/bluefruit/le/connect/BluefruitApplication.java: -------------------------------------------------------------------------------- 1 | package com.adafruit.bluefruit.le.connect; 2 | 3 | import android.app.Application; 4 | 5 | 6 | public class BluefruitApplication extends Application { 7 | // Log 8 | @SuppressWarnings("unused") 9 | private final static String TAG = BluefruitApplication.class.getSimpleName(); 10 | 11 | // Data 12 | private static boolean mIsActivityVisible; 13 | 14 | // region Lifecycle 15 | @Override 16 | public void onCreate() { 17 | super.onCreate(); 18 | 19 | /* 20 | StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder(StrictMode.getVmPolicy()) 21 | .detectLeakedClosableObjects() 22 | .build()); 23 | */ 24 | 25 | // Setup handler for uncaught exceptions. 26 | // Thread.setDefaultUncaughtExceptionHandler(this::handleUncaughtException); 27 | } 28 | 29 | // endregion 30 | 31 | /* 32 | private void handleUncaughtException(Thread thread, Throwable e) { 33 | Log.e(TAG, "Error: handleUncaughtException"); 34 | e.printStackTrace(); 35 | BleScanner.getInstance().disconnectFromAll(); 36 | 37 | System.exit(1); 38 | }*/ 39 | 40 | 41 | // region Detect app in background: https://stackoverflow.com/questions/3667022/checking-if-an-android-application-is-running-in-the-background 42 | 43 | public static boolean isActivityVisible() { 44 | return mIsActivityVisible; 45 | } 46 | 47 | public static void activityResumed() { 48 | mIsActivityVisible = true; 49 | } 50 | 51 | public static void activityPaused() { 52 | mIsActivityVisible = false; 53 | } 54 | 55 | // endregion 56 | } 57 | -------------------------------------------------------------------------------- /app/src/main/java/com/adafruit/bluefruit/le/connect/app/AboutFragment.java: -------------------------------------------------------------------------------- 1 | package com.adafruit.bluefruit.le.connect.app; 2 | 3 | import android.os.Bundle; 4 | import androidx.annotation.NonNull; 5 | import androidx.annotation.Nullable; 6 | import androidx.appcompat.app.ActionBar; 7 | import androidx.appcompat.app.AppCompatActivity; 8 | import androidx.fragment.app.Fragment; 9 | import androidx.fragment.app.FragmentActivity; 10 | 11 | import android.view.LayoutInflater; 12 | import android.view.View; 13 | import android.view.ViewGroup; 14 | import android.widget.TextView; 15 | 16 | import com.adafruit.bluefruit.le.connect.BuildConfig; 17 | import com.adafruit.bluefruit.le.connect.R; 18 | 19 | public class AboutFragment extends Fragment { 20 | 21 | public AboutFragment() { 22 | // Required empty public constructor 23 | } 24 | 25 | @SuppressWarnings("UnnecessaryLocalVariable") 26 | public static AboutFragment newInstance() { 27 | AboutFragment fragment = new AboutFragment(); 28 | return fragment; 29 | } 30 | 31 | @Override 32 | public void onCreate(Bundle savedInstanceState) { 33 | super.onCreate(savedInstanceState); 34 | } 35 | 36 | @Override 37 | public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 38 | // Inflate the layout for this fragment 39 | return inflater.inflate(R.layout.fragment_about, container, false); 40 | } 41 | 42 | @Override 43 | public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { 44 | super.onViewCreated(view, savedInstanceState); 45 | 46 | // Update ActionBar 47 | setActionBarTitle(R.string.about_title); 48 | 49 | TextView versionTextView = view.findViewById(R.id.versionTextView); 50 | if (versionTextView != null) { 51 | versionTextView.setText(String.format("v%s", BuildConfig.VERSION_NAME)); 52 | } 53 | 54 | FragmentActivity activity = getActivity(); 55 | if (activity != null) { 56 | activity.invalidateOptionsMenu(); // update options menu with current values 57 | } 58 | } 59 | 60 | 61 | // region Action Bar 62 | protected void setActionBarTitle(int titleStringId) { 63 | AppCompatActivity activity = (AppCompatActivity) getActivity(); 64 | if (activity != null) { 65 | ActionBar actionBar = activity.getSupportActionBar(); 66 | if (actionBar != null) { 67 | actionBar.setTitle(titleStringId); 68 | actionBar.setDisplayHomeAsUpEnabled(true); 69 | } 70 | } 71 | } 72 | 73 | // endregion 74 | } 75 | -------------------------------------------------------------------------------- /app/src/main/java/com/adafruit/bluefruit/le/connect/app/CommonHelpFragment.java: -------------------------------------------------------------------------------- 1 | package com.adafruit.bluefruit.le.connect.app; 2 | 3 | import android.os.Bundle; 4 | import androidx.annotation.NonNull; 5 | import androidx.annotation.Nullable; 6 | import androidx.appcompat.app.ActionBar; 7 | import androidx.appcompat.app.AppCompatActivity; 8 | import androidx.fragment.app.Fragment; 9 | 10 | import android.view.LayoutInflater; 11 | import android.view.View; 12 | import android.view.ViewGroup; 13 | import android.widget.TextView; 14 | 15 | import com.adafruit.bluefruit.le.connect.R; 16 | 17 | public class CommonHelpFragment extends Fragment { 18 | private static final String ARG_TITLE = "title"; 19 | private static final String ARG_TEXT = "text"; 20 | 21 | private String mText; 22 | 23 | public static CommonHelpFragment newInstance(String title, String text) { 24 | CommonHelpFragment fragment = new CommonHelpFragment(); 25 | Bundle args = new Bundle(); 26 | args.putString(ARG_TITLE, title); 27 | args.putString(ARG_TEXT, text); 28 | fragment.setArguments(args); 29 | return fragment; 30 | } 31 | 32 | public CommonHelpFragment() { 33 | // Required empty public constructor 34 | } 35 | 36 | @Override 37 | public void onCreate(Bundle savedInstanceState) { 38 | super.onCreate(savedInstanceState); 39 | String title = null; 40 | if (getArguments() != null) { 41 | title = getArguments().getString(ARG_TITLE); 42 | mText = getArguments().getString(ARG_TEXT); 43 | } 44 | 45 | // Update ActionBar 46 | AppCompatActivity activity = (AppCompatActivity) getActivity(); 47 | if (activity != null) { 48 | ActionBar actionBar = activity.getSupportActionBar(); 49 | if (actionBar != null) { 50 | actionBar.setTitle(title); 51 | actionBar.setDisplayHomeAsUpEnabled(true); 52 | } 53 | } 54 | } 55 | 56 | @Override 57 | public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 58 | // Inflate the layout for this fragment 59 | return inflater.inflate(R.layout.fragment_commonhelp, container, false); 60 | } 61 | 62 | @Override 63 | public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { 64 | super.onViewCreated(view, savedInstanceState); 65 | 66 | // UI 67 | TextView infoTextView = view.findViewById(R.id.infoTextView); 68 | infoTextView.setText(mText); 69 | 70 | /* 71 | WebView infoWebView = view.findViewById(R.id.infoWebView); 72 | if (infoWebView != null) { 73 | infoWebView.setBackgroundColor(Color.TRANSPARENT); 74 | infoWebView.loadUrl("file:///android_asset/help/" + mText); 75 | }*/ 76 | 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /app/src/main/java/com/adafruit/bluefruit/le/connect/app/ConnectedPeripheralFragment.java: -------------------------------------------------------------------------------- 1 | package com.adafruit.bluefruit.le.connect.app; 2 | 3 | import android.os.Bundle; 4 | 5 | import androidx.annotation.Nullable; 6 | import androidx.appcompat.app.ActionBar; 7 | import androidx.appcompat.app.AppCompatActivity; 8 | import androidx.fragment.app.Fragment; 9 | 10 | import com.adafruit.bluefruit.le.connect.ble.central.BlePeripheral; 11 | import com.adafruit.bluefruit.le.connect.ble.central.BleScanner; 12 | 13 | // helper class with common behaviour for all peripheral modules 14 | public class ConnectedPeripheralFragment extends Fragment { 15 | // Constants 16 | @SuppressWarnings("unused") 17 | private final static String TAG = ConnectedPeripheralFragment.class.getSimpleName(); 18 | 19 | // Fragment parameters 20 | protected static final String ARG_SINGLEPERIPHERALIDENTIFIER = "SinglePeripheralIdentifier"; 21 | 22 | // Common interfaces 23 | public interface SuccessHandler { 24 | void result(boolean success); 25 | } 26 | 27 | // Data 28 | protected BlePeripheral mBlePeripheral; 29 | 30 | // region Fragment Lifecycle 31 | protected static Bundle createFragmentArgs(@Nullable String singlePeripheralIdentifier) { // if singlePeripheralIdentifier is null, uses multi-connect 32 | Bundle args = new Bundle(); 33 | args.putString(ARG_SINGLEPERIPHERALIDENTIFIER, singlePeripheralIdentifier); 34 | return args; 35 | } 36 | 37 | @Override 38 | public void onCreate(Bundle savedInstanceState) { 39 | super.onCreate(savedInstanceState); 40 | if (getArguments() != null) { 41 | String singlePeripheralIdentifier = getArguments().getString(ARG_SINGLEPERIPHERALIDENTIFIER); 42 | mBlePeripheral = BleScanner.getInstance().getPeripheralWithIdentifier(singlePeripheralIdentifier); 43 | } 44 | 45 | setHasOptionsMenu(true); 46 | } 47 | 48 | // endregion 49 | 50 | // region Action Bar 51 | protected void setActionBarTitle(int titleStringId) { 52 | AppCompatActivity activity = (AppCompatActivity) getActivity(); 53 | if (activity != null) { 54 | ActionBar actionBar = activity.getSupportActionBar(); 55 | if (actionBar != null) { 56 | actionBar.setTitle(titleStringId); 57 | actionBar.setDisplayHomeAsUpEnabled(true); 58 | } 59 | } 60 | } 61 | 62 | // endregion 63 | } 64 | -------------------------------------------------------------------------------- /app/src/main/java/com/adafruit/bluefruit/le/connect/app/SplashActivity.java: -------------------------------------------------------------------------------- 1 | package com.adafruit.bluefruit.le.connect.app; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | 6 | import androidx.appcompat.app.AppCompatActivity; 7 | 8 | // based on: https://www.bignerdranch.com/blog/splash-screens-the-right-way/ 9 | public class SplashActivity extends AppCompatActivity { 10 | 11 | @Override 12 | protected void onCreate(Bundle savedInstanceState) { 13 | super.onCreate(savedInstanceState); 14 | 15 | Intent intent = new Intent(this, MainActivity.class); 16 | startActivity(intent); 17 | finish(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/com/adafruit/bluefruit/le/connect/app/barcode/BarcodeGraphicTracker.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 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 | package com.adafruit.bluefruit.le.connect.app.barcode; 17 | 18 | import com.google.android.gms.vision.Detector; 19 | import com.google.android.gms.vision.Tracker; 20 | import com.google.android.gms.vision.barcode.Barcode; 21 | 22 | /** 23 | * Generic tracker which is used for tracking or reading a barcode (and can really be used for 24 | * any type of item). This is used to receive newly detected items, add a graphical representation 25 | * to an overlay, update the graphics as the item changes, and remove the graphics when the item 26 | * goes away. 27 | */ 28 | public class BarcodeGraphicTracker extends Tracker { 29 | 30 | public interface BarcodeTrackerListener { 31 | void onCodeScanned(String contents); 32 | } 33 | 34 | 35 | private GraphicOverlay mOverlay; 36 | private BarcodeGraphic mGraphic; 37 | private BarcodeTrackerListener mListener; 38 | 39 | BarcodeGraphicTracker(GraphicOverlay overlay, BarcodeGraphic graphic, BarcodeGraphicTracker.BarcodeTrackerListener listener) { 40 | mOverlay = overlay; 41 | mGraphic = graphic; 42 | mListener = listener; 43 | } 44 | 45 | /** 46 | * Start tracking the detected item instance within the item overlay. 47 | */ 48 | @Override 49 | public void onNewItem(int id, Barcode item) { 50 | mGraphic.setId(id); 51 | } 52 | 53 | /** 54 | * Update the position/characteristics of the item within the overlay. 55 | */ 56 | @Override 57 | public void onUpdate(Detector.Detections detectionResults, Barcode item) { 58 | mOverlay.add(mGraphic); 59 | mGraphic.updateItem(item); 60 | if (mListener != null) { 61 | mListener.onCodeScanned(item.rawValue); 62 | } 63 | } 64 | 65 | /** 66 | * Hide the graphic when the corresponding object was not detected. This can happen for 67 | * intermediate frames temporarily, for example if the object was momentarily blocked from 68 | * view. 69 | */ 70 | @Override 71 | public void onMissing(Detector.Detections detectionResults) { 72 | mOverlay.remove(mGraphic); 73 | } 74 | 75 | /** 76 | * Called when the item is assumed to be gone for good. Remove the graphic annotation from 77 | * the overlay. 78 | */ 79 | @Override 80 | public void onDone() { 81 | mOverlay.remove(mGraphic); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /app/src/main/java/com/adafruit/bluefruit/le/connect/app/barcode/BarcodeTrackerFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 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 | package com.adafruit.bluefruit.le.connect.app.barcode; 17 | 18 | import androidx.annotation.NonNull; 19 | 20 | import com.google.android.gms.vision.MultiProcessor; 21 | import com.google.android.gms.vision.Tracker; 22 | import com.google.android.gms.vision.barcode.Barcode; 23 | 24 | /** 25 | * Factory for creating a tracker and associated graphic to be associated with a new barcode. The 26 | * multi-processor uses this factory to create barcode trackers as needed -- one for each barcode. 27 | */ 28 | public class BarcodeTrackerFactory implements MultiProcessor.Factory { 29 | private final GraphicOverlay mGraphicOverlay; 30 | public BarcodeGraphicTracker.BarcodeTrackerListener mListener; 31 | 32 | public BarcodeTrackerFactory(GraphicOverlay barcodeGraphicOverlay, BarcodeGraphicTracker.BarcodeTrackerListener listener) { 33 | mGraphicOverlay = barcodeGraphicOverlay; 34 | mListener = listener; 35 | } 36 | 37 | @NonNull 38 | @Override 39 | public Tracker create(@NonNull Barcode barcode) { 40 | BarcodeGraphic graphic = new BarcodeGraphic(mGraphicOverlay); 41 | return new BarcodeGraphicTracker(mGraphicOverlay, graphic, mListener); 42 | } 43 | 44 | } 45 | 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/adafruit/bluefruit/le/connect/ble/UartPacket.java: -------------------------------------------------------------------------------- 1 | package com.adafruit.bluefruit.le.connect.ble; 2 | 3 | import java.util.Arrays; 4 | 5 | public class UartPacket { 6 | public static final int TRANSFERMODE_TX = 0; 7 | public static final int TRANSFERMODE_RX = 1; 8 | 9 | private final String mPeripheralId; 10 | private final long mTimestamp; // in millis 11 | private final int mMode; 12 | private byte[] mData; 13 | 14 | public UartPacket(String peripheralId, int mode, byte[] data) { 15 | this(peripheralId, System.currentTimeMillis(), mode, data); 16 | } 17 | 18 | public UartPacket(UartPacket uartPacket) { 19 | mPeripheralId = uartPacket.mPeripheralId; 20 | mTimestamp = uartPacket.mTimestamp; 21 | mMode = uartPacket.mMode; 22 | if (uartPacket.mData != null) { 23 | mData = Arrays.copyOf(uartPacket.mData, uartPacket.mData.length); 24 | } 25 | } 26 | 27 | @SuppressWarnings("WeakerAccess") 28 | public UartPacket(String peripheralId, long timestamp, int mode, byte[] data) { 29 | mPeripheralId = peripheralId; 30 | mTimestamp = timestamp; 31 | mMode = mode; 32 | mData = data; 33 | } 34 | 35 | public String getPeripheralId() { 36 | return mPeripheralId; 37 | } 38 | 39 | public long getTimestamp() { 40 | return mTimestamp; 41 | } 42 | 43 | public int getMode() { 44 | return mMode; 45 | } 46 | 47 | public byte[] getData() { 48 | return mData; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /app/src/main/java/com/adafruit/bluefruit/le/connect/ble/central/BleManager.java: -------------------------------------------------------------------------------- 1 | package com.adafruit.bluefruit.le.connect.ble.central; 2 | 3 | import static android.Manifest.permission.BLUETOOTH_CONNECT; 4 | import static android.Manifest.permission.BLUETOOTH_SCAN; 5 | 6 | import android.annotation.SuppressLint; 7 | import android.bluetooth.BluetoothAdapter; 8 | import android.bluetooth.BluetoothDevice; 9 | import android.bluetooth.BluetoothManager; 10 | import android.bluetooth.BluetoothProfile; 11 | import android.content.Context; 12 | import android.util.Log; 13 | 14 | import androidx.annotation.NonNull; 15 | import androidx.annotation.RequiresPermission; 16 | 17 | import java.util.ArrayList; 18 | import java.util.List; 19 | 20 | public class BleManager { 21 | // Log 22 | private final static String TAG = BleManager.class.getSimpleName(); 23 | 24 | // Singleton 25 | private static BleManager mInstance = null; 26 | 27 | // Data 28 | private BluetoothManager mManager; 29 | private BluetoothAdapter mAdapter; 30 | 31 | public static BleManager getInstance() { 32 | if (mInstance == null) { 33 | mInstance = new BleManager(); 34 | } 35 | return mInstance; 36 | } 37 | 38 | private BleManager() { 39 | } 40 | 41 | public boolean start(Context context) { 42 | 43 | // Init Manager 44 | mManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE); 45 | 46 | // Init Adapter 47 | if (mManager != null) { 48 | mAdapter = mManager.getAdapter(); 49 | } else { 50 | mAdapter = null; 51 | } 52 | 53 | final boolean isEnabled = mAdapter != null && mAdapter.isEnabled(); 54 | if (!isEnabled) { 55 | Log.e(TAG, "Unable to obtain a BluetoothAdapter."); 56 | } 57 | 58 | return isEnabled; 59 | } 60 | 61 | /* 62 | public @Nullable 63 | BluetoothAdapter getAdapter() { 64 | return mAdapter; 65 | }*/ 66 | 67 | @SuppressLint("InlinedApi") 68 | @RequiresPermission(value = BLUETOOTH_SCAN) 69 | public void cancelDiscovery() { 70 | if (mAdapter != null) { 71 | mAdapter.cancelDiscovery(); 72 | } 73 | } 74 | 75 | public boolean isAdapterEnabled() { 76 | return mAdapter != null && mAdapter.isEnabled(); 77 | } 78 | 79 | @SuppressLint("InlinedApi") 80 | @RequiresPermission(value = BLUETOOTH_CONNECT) 81 | public @NonNull 82 | List getConnectedDevices() { 83 | List connectedDevices = new ArrayList<>(); 84 | 85 | // Check if already initialized 86 | if (mManager == null) { 87 | return connectedDevices; 88 | } 89 | 90 | List devices = mManager.getConnectedDevices(BluetoothProfile.GATT); 91 | for (BluetoothDevice device : devices) { 92 | final int type = device.getType(); 93 | if (type == BluetoothDevice.DEVICE_TYPE_LE || type == BluetoothDevice.DEVICE_TYPE_DUAL) { 94 | connectedDevices.add(device); 95 | } 96 | } 97 | 98 | return connectedDevices; 99 | } 100 | } -------------------------------------------------------------------------------- /app/src/main/java/com/adafruit/bluefruit/le/connect/ble/central/BlePeripheralDfu.java: -------------------------------------------------------------------------------- 1 | package com.adafruit.bluefruit.le.connect.ble.central; 2 | 3 | import java.util.UUID; 4 | 5 | public class BlePeripheralDfu { 6 | private static final UUID kDfuServiceUuid = UUID.fromString("00001530-1212-EFDE-1523-785FEABCD123"); 7 | 8 | public static boolean hasDfu(BlePeripheral peripheral) { 9 | return peripheral.getService(kDfuServiceUuid) != null; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/com/adafruit/bluefruit/le/connect/ble/central/BleUUIDNames.java: -------------------------------------------------------------------------------- 1 | package com.adafruit.bluefruit.le.connect.ble.central; 2 | 3 | import android.content.Context; 4 | import androidx.annotation.NonNull; 5 | import android.util.Log; 6 | 7 | import org.json.JSONException; 8 | import org.json.JSONObject; 9 | 10 | import java.io.IOException; 11 | import java.io.InputStream; 12 | import java.nio.charset.StandardCharsets; 13 | 14 | public class BleUUIDNames { 15 | // Log 16 | private final static String TAG = BleUUIDNames.class.getSimpleName(); 17 | 18 | // Constants 19 | private final static String kFilename = "GattUUIDs.json"; 20 | 21 | // Data 22 | private static JSONObject mGatUUIDs; 23 | 24 | public static String getNameForUUID(Context context, @NonNull String uuidString) { 25 | if (mGatUUIDs == null) { 26 | String gattUUIDsString = loadStringFromAsset(context); 27 | try { 28 | mGatUUIDs = new JSONObject(gattUUIDsString); 29 | } catch (JSONException e) { 30 | Log.e(TAG, "Error: can't load known service UUIDs"); 31 | } 32 | } 33 | 34 | String result = null; 35 | String uppercaseUuidString = uuidString.toUpperCase(); 36 | try { 37 | result = mGatUUIDs.getString(uppercaseUuidString); 38 | 39 | } catch (JSONException ignored) { 40 | // Check 16 bit uuids (0000xxxx-0000-1000-8000-00805F9B34FB) 41 | if (uppercaseUuidString.startsWith("0000") && uppercaseUuidString.endsWith("-0000-1000-8000-00805F9B34FB")) { 42 | final String shortUuidString = uppercaseUuidString.substring(4, 8); 43 | try { 44 | result = mGatUUIDs.getString(shortUuidString); 45 | } catch (JSONException ignored2) { 46 | } 47 | } 48 | 49 | } 50 | 51 | return result; 52 | } 53 | 54 | @SuppressWarnings("ResultOfMethodCallIgnored") 55 | private static String loadStringFromAsset(Context context) { 56 | String json; 57 | try { 58 | InputStream is = context.getAssets().open(kFilename); 59 | int size = is.available(); 60 | byte[] buffer = new byte[size]; 61 | is.read(buffer); 62 | is.close(); 63 | json = new String(buffer, StandardCharsets.UTF_8); 64 | } catch (IOException ex) { 65 | ex.printStackTrace(); 66 | return null; 67 | } 68 | return json; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /app/src/main/java/com/adafruit/bluefruit/le/connect/ble/peripheral/UartPeripheralModePacketManager.java: -------------------------------------------------------------------------------- 1 | package com.adafruit.bluefruit.le.connect.ble.peripheral; 2 | 3 | import android.content.Context; 4 | import android.util.Log; 5 | 6 | import androidx.annotation.NonNull; 7 | import androidx.annotation.Nullable; 8 | 9 | import com.adafruit.bluefruit.le.connect.ble.UartPacket; 10 | import com.adafruit.bluefruit.le.connect.ble.UartPacketManagerBase; 11 | import com.adafruit.bluefruit.le.connect.mqtt.MqttManager; 12 | import com.adafruit.bluefruit.le.connect.mqtt.MqttSettings; 13 | 14 | public class UartPeripheralModePacketManager extends UartPacketManagerBase { 15 | // Log 16 | private final static String TAG = UartPeripheralModePacketManager.class.getSimpleName(); 17 | 18 | // region Lifecycle 19 | public UartPeripheralModePacketManager(@NonNull Context context, @Nullable Listener listener, boolean isPacketCacheEnabled, @Nullable MqttManager mqttManager) { 20 | super(context, listener, isPacketCacheEnabled, mqttManager); 21 | } 22 | // endregion 23 | 24 | // region Send data 25 | 26 | public void send(@NonNull UartPeripheralService uartPeripheralService, @NonNull byte[] data/*, BlePeripheral.UpdateDatabaseCompletionHandler completionHandler*/) { 27 | mSentBytes += data.length; 28 | uartPeripheralService.setRx(data); 29 | } 30 | 31 | public void send(@NonNull UartPeripheralService uartPeripheralService, byte[] data, boolean wasReceivedFromMqtt) { 32 | if (mMqttManager != null) { 33 | // Mqtt publish to TX 34 | if (MqttSettings.isPublishEnabled(mContext)) { 35 | final String topic = MqttSettings.getPublishTopic(mContext, MqttSettings.kPublishFeed_TX); 36 | if (topic != null) { 37 | final int qos = MqttSettings.getPublishQos(mContext, MqttSettings.kPublishFeed_TX); 38 | mMqttManager.publish(topic, data, qos); 39 | } 40 | } 41 | } 42 | 43 | // Create data and send to Uart 44 | UartPacket uartPacket = new UartPacket(null, UartPacket.TRANSFERMODE_TX, data); 45 | 46 | try { 47 | mPacketsSemaphore.acquire(); // don't append more data, till the delegate has finished processing it 48 | } catch (InterruptedException e) { 49 | Log.w(TAG, "InterruptedException: " + e.toString()); 50 | } 51 | mPackets.add(uartPacket); 52 | mPacketsSemaphore.release(); 53 | 54 | Listener listener = mWeakListener.get(); 55 | if (listener != null) { 56 | mMainHandler.post(() -> listener.onUartPacket(uartPacket)); 57 | } 58 | 59 | final boolean isMqttEnabled = mMqttManager != null; 60 | final boolean shouldBeSent = !wasReceivedFromMqtt || (isMqttEnabled && MqttSettings.getSubscribeBehaviour(mContext) == MqttSettings.kSubscribeBehaviour_Transmit); 61 | 62 | if (shouldBeSent) { 63 | send(uartPeripheralService, data); 64 | } 65 | } 66 | 67 | // endregion 68 | } 69 | -------------------------------------------------------------------------------- /app/src/main/java/com/adafruit/bluefruit/le/connect/dfu/DfuService.java: -------------------------------------------------------------------------------- 1 | package com.adafruit.bluefruit.le.connect.dfu; 2 | 3 | import android.app.Activity; 4 | 5 | import androidx.annotation.NonNull; 6 | import androidx.core.app.NotificationCompat; 7 | 8 | import com.adafruit.bluefruit.le.connect.BuildConfig; 9 | 10 | import no.nordicsemi.android.dfu.DfuBaseService; 11 | 12 | public class DfuService extends DfuBaseService { 13 | 14 | @Override 15 | protected Class getNotificationTarget() { 16 | /* 17 | * As a target activity the NotificationActivity is returned, not the MainActivity. This is because the notification must create a new task: 18 | * 19 | * intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 20 | * 21 | * when user press it. Using NotificationActivity we can check whether the new activity is a root activity (that means no other activity was open before) 22 | * or that there is other activity already open. In the later case the notificationActivity will just be closed. System will restore the previous activity from 23 | * this application - the MainActivity. However if nRF Beacon has been closed during upload and user click the notification a NotificationActivity will 24 | * be launched as a root activity. It will create and start the MainActivity and finish itself. 25 | * 26 | * This method may be used to restore the target activity in case the application was closed or is open. It may also be used to recreate an activity history (see NotificationActivity). 27 | */ 28 | return NotificationActivity.class; 29 | } 30 | 31 | 32 | @Override 33 | protected boolean isDebug() { 34 | // Here return true if you want the service to print more logs in LogCat. 35 | // Library's BuildConfig in current version of Android Studio is always set to DEBUG=false, so 36 | // make sure you return true or your.app.BuildConfig.DEBUG here. 37 | return BuildConfig.DEBUG; 38 | } 39 | 40 | @Override 41 | protected void updateForegroundNotification(@NonNull final NotificationCompat.Builder builder) { 42 | // Customize the foreground service notification here. 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/adafruit/bluefruit/le/connect/dfu/NotificationActivity.java: -------------------------------------------------------------------------------- 1 | package com.adafruit.bluefruit.le.connect.dfu; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | 7 | import com.adafruit.bluefruit.le.connect.app.MainActivity; 8 | 9 | public class NotificationActivity extends Activity { 10 | @Override 11 | protected void onCreate(Bundle savedInstanceState) { 12 | super.onCreate(savedInstanceState); 13 | 14 | // If this activity is the root activity of the task, the app is not running 15 | if (isTaskRoot()) { 16 | // Start the app before finishing 17 | final Intent intent = new Intent(this, MainActivity.class); 18 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 19 | Bundle extras = getIntent().getExtras(); 20 | if (extras != null) { 21 | intent.putExtras(extras); // copy all extras 22 | } 23 | startActivity(intent); 24 | } 25 | 26 | // Now finish, which will drop the user in to the activity that was at the top of the task stack 27 | finish(); 28 | } 29 | } -------------------------------------------------------------------------------- /app/src/main/java/com/adafruit/bluefruit/le/connect/models/DeviceInformationServiceViewModel.java: -------------------------------------------------------------------------------- 1 | package com.adafruit.bluefruit.le.connect.models; 2 | 3 | import android.app.Application; 4 | import androidx.annotation.NonNull; 5 | import androidx.lifecycle.AndroidViewModel; 6 | 7 | import com.adafruit.bluefruit.le.connect.ble.peripheral.DeviceInformationPeripheralService; 8 | 9 | public class DeviceInformationServiceViewModel extends AndroidViewModel { 10 | 11 | public DeviceInformationServiceViewModel(@NonNull Application application) { 12 | super(application); 13 | } 14 | 15 | public DeviceInformationPeripheralService getDeviceInfomationPeripheralService() { 16 | return PeripheralModeManager.getInstance().getDeviceInformationPeripheralService(); 17 | } 18 | 19 | @Override 20 | protected void onCleared() { 21 | super.onCleared(); 22 | 23 | // Save current characteristic values 24 | PeripheralModeManager.getInstance().getDeviceInformationPeripheralService().saveValues(getApplication()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/adafruit/bluefruit/le/connect/style/RssiUI.java: -------------------------------------------------------------------------------- 1 | package com.adafruit.bluefruit.le.connect.style; 2 | 3 | import com.adafruit.bluefruit.le.connect.R; 4 | 5 | public class RssiUI { 6 | public static int getDrawableIdForRssi(int rssi) { 7 | int index; 8 | if (rssi == 127 || rssi <= -84) { // 127 reserved for RSSI not available 9 | index = 0; 10 | } else if (rssi <= -72) { 11 | index = 1; 12 | } else if (rssi <= -60) { 13 | index = 2; 14 | } else if (rssi <= -48) { 15 | index = 3; 16 | } else { 17 | index = 4; 18 | } 19 | 20 | final int[] kSignalDrawables = { 21 | R.drawable.signalstrength0, 22 | R.drawable.signalstrength1, 23 | R.drawable.signalstrength2, 24 | R.drawable.signalstrength3, 25 | R.drawable.signalstrength4}; 26 | return kSignalDrawables[index]; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/com/adafruit/bluefruit/le/connect/style/StyledSnackBar.java: -------------------------------------------------------------------------------- 1 | package com.adafruit.bluefruit.le.connect.style; 2 | 3 | import android.content.Context; 4 | import android.widget.TextView; 5 | 6 | import androidx.core.content.ContextCompat; 7 | 8 | import com.adafruit.bluefruit.le.connect.R; 9 | import com.google.android.material.snackbar.Snackbar; 10 | 11 | public class StyledSnackBar { 12 | 13 | public static void styleSnackBar(Snackbar snackbar, Context context) { 14 | snackbar.getView().setBackgroundColor(ContextCompat.getColor(context, R.color.colorAccent)); 15 | TextView textView = snackbar.getView().findViewById(R.id.snackbar_text); // Manually changing colors till theme styling is available for snackbars 16 | textView.setTextColor(ContextCompat.getColor(context, R.color.infotext)); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/adafruit/bluefruit/le/connect/style/UartStyle.java: -------------------------------------------------------------------------------- 1 | package com.adafruit.bluefruit.le.connect.style; 2 | 3 | import android.graphics.Color; 4 | import android.graphics.DashPathEffect; 5 | import androidx.annotation.NonNull; 6 | 7 | public class UartStyle { 8 | public static @NonNull 9 | int[] defaultColors() { 10 | // Based on Chart joyful and colorful colors: https://github.com/danielgindi/Charts 11 | return new int[]{ 12 | Color.rgb(193, 37, 82), 13 | Color.rgb(58, 95, 201), // extra blue 14 | Color.rgb(255, 102, 0), 15 | Color.rgb(245, 199, 0), 16 | Color.rgb(106, 150, 31), 17 | Color.rgb(179, 100, 53), 18 | 19 | Color.rgb(217, 80, 138), 20 | Color.rgb(254, 149, 7), 21 | Color.rgb(254, 247, 120), 22 | Color.rgb(106, 167, 134), 23 | Color.rgb(53, 194, 209) 24 | }; 25 | } 26 | 27 | public static @NonNull 28 | DashPathEffect[] defaultDashPathEffects() { 29 | return new DashPathEffect[]{ 30 | null, // ----------------------- 31 | new DashPathEffect(new float[]{10, 4}, 0), // ----- ----- ----- ----- 32 | new DashPathEffect(new float[]{4, 6}, 0), // -- -- -- -- -- 33 | new DashPathEffect(new float[]{8, 8}, 0), // ---- ---- ----- 34 | new DashPathEffect(new float[]{2, 4}, 0), // - - - - - - - - 35 | new DashPathEffect(new float[]{6, 4, 2, 1}, 0), // --- - --- - 36 | }; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/com/adafruit/bluefruit/le/connect/utils/AdapterUtils.java: -------------------------------------------------------------------------------- 1 | package com.adafruit.bluefruit.le.connect.utils; 2 | 3 | import android.view.View; 4 | import android.view.ViewGroup; 5 | import android.view.animation.Animation; 6 | import android.view.animation.Transformation; 7 | 8 | public class AdapterUtils { 9 | 10 | // from: https://stackoverflow.com/questions/4946295/android-expand-collapse-animation 11 | public static void expand(final View v) { 12 | v.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); 13 | final int targetHeight = v.getMeasuredHeight(); 14 | 15 | // Older versions of android (pre API 21) cancel animations for views with a height of 0. 16 | v.getLayoutParams().height = 1; 17 | v.setVisibility(View.VISIBLE); 18 | Animation a = new Animation() { 19 | @Override 20 | protected void applyTransformation(float interpolatedTime, Transformation t) { 21 | v.getLayoutParams().height = interpolatedTime == 1 22 | ? ViewGroup.LayoutParams.WRAP_CONTENT 23 | : (int) (targetHeight * interpolatedTime); 24 | v.requestLayout(); 25 | } 26 | 27 | @Override 28 | public boolean willChangeBounds() { 29 | return true; 30 | } 31 | }; 32 | 33 | // 1dp/ms 34 | a.setDuration((int) (targetHeight / v.getContext().getResources().getDisplayMetrics().density)); 35 | v.startAnimation(a); 36 | } 37 | 38 | public static void collapse(final View v) { 39 | final int initialHeight = v.getMeasuredHeight(); 40 | 41 | Animation a = new Animation() { 42 | @Override 43 | protected void applyTransformation(float interpolatedTime, Transformation t) { 44 | if (interpolatedTime == 1) { 45 | v.setVisibility(View.GONE); 46 | } else { 47 | v.getLayoutParams().height = initialHeight - (int) (initialHeight * interpolatedTime); 48 | v.requestLayout(); 49 | } 50 | } 51 | 52 | @Override 53 | public boolean willChangeBounds() { 54 | return true; 55 | } 56 | }; 57 | 58 | // 1dp/ms 59 | a.setDuration((int) (initialHeight / v.getContext().getResources().getDisplayMetrics().density)); 60 | v.startAnimation(a); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /app/src/main/java/com/adafruit/bluefruit/le/connect/utils/DialogUtils.java: -------------------------------------------------------------------------------- 1 | package com.adafruit.bluefruit.le.connect.utils; 2 | 3 | import android.app.Dialog; 4 | import android.view.Window; 5 | import android.view.WindowManager; 6 | 7 | import androidx.annotation.NonNull; 8 | import androidx.fragment.app.DialogFragment; 9 | import androidx.fragment.app.Fragment; 10 | import androidx.fragment.app.FragmentActivity; 11 | 12 | import java.util.List; 13 | 14 | public class DialogUtils { 15 | 16 | // Prevent dialog dismiss when orientation changes 17 | // http://stackoverflow.com/questions/7557265/prevent-dialog-dismissal-on-screen-rotation-in-android 18 | public static void keepDialogOnOrientationChanges(@NonNull Dialog dialog) { 19 | WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 20 | Window window = dialog.getWindow(); 21 | if (window != null) { 22 | WindowManager.LayoutParams attributes = window.getAttributes(); 23 | if (attributes != null) { 24 | lp.copyFrom(attributes); 25 | lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 26 | lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 27 | dialog.getWindow().setAttributes(lp); 28 | } 29 | } 30 | } 31 | 32 | // https://stackoverflow.com/questions/11026234/how-to-check-if-the-current-activity-has-a-dialog-in-front/27239319 33 | public static boolean hasOpenedDialogs(@NonNull FragmentActivity activity) { 34 | List fragments = activity.getSupportFragmentManager().getFragments(); 35 | for (Fragment fragment : fragments) { 36 | if (fragment instanceof DialogFragment) { 37 | return true; 38 | } 39 | } 40 | 41 | return false; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/adafruit/bluefruit/le/connect/utils/FileUtils.java: -------------------------------------------------------------------------------- 1 | package com.adafruit.bluefruit.le.connect.utils; 2 | 3 | import android.content.res.AssetManager; 4 | import android.os.Environment; 5 | 6 | import java.io.File; 7 | import java.io.FileOutputStream; 8 | import java.io.IOException; 9 | import java.io.InputStream; 10 | import java.io.OutputStream; 11 | import java.nio.charset.StandardCharsets; 12 | 13 | public class FileUtils { 14 | 15 | public static String readAssetsFile(String filename, AssetManager assetManager) { 16 | String result = null; 17 | 18 | try { 19 | InputStream is = assetManager.open(filename); 20 | int size = is.available(); 21 | 22 | byte[] buffer = new byte[size]; 23 | //noinspection ResultOfMethodCallIgnored 24 | is.read(buffer); 25 | is.close(); 26 | 27 | result = new String(buffer, StandardCharsets.UTF_8); 28 | 29 | } catch (IOException e) { 30 | e.printStackTrace(); 31 | } 32 | 33 | return result; 34 | } 35 | 36 | public static String copyAssetFile(AssetManager assetManager, String inputFilename, String outputFilename) { 37 | 38 | String outPath = null; 39 | 40 | try { 41 | InputStream input = assetManager.open(inputFilename); 42 | 43 | // Create new file to copy into. 44 | outPath = Environment.getExternalStorageDirectory() + java.io.File.separator + outputFilename; 45 | File outFile = new File(outPath); 46 | OutputStream output = new FileOutputStream(outFile); 47 | copyFile(input, output); 48 | input.close(); 49 | output.flush(); 50 | output.close(); 51 | 52 | } catch (IOException e) { 53 | e.printStackTrace(); 54 | } 55 | 56 | return outPath; 57 | } 58 | 59 | private static void copyFile(InputStream in, OutputStream out) throws IOException { 60 | byte[] buffer = new byte[1024]; 61 | int read; 62 | while ((read = in.read(buffer)) != -1) { 63 | out.write(buffer, 0, read); 64 | } 65 | } 66 | } -------------------------------------------------------------------------------- /app/src/main/java/com/adafruit/bluefruit/le/connect/utils/ImageMagickUtils.java: -------------------------------------------------------------------------------- 1 | package com.adafruit.bluefruit.le.connect.utils; 2 | 3 | import android.content.Context; 4 | import android.util.Log; 5 | 6 | import java.io.File; 7 | 8 | import magick.Magick; 9 | 10 | // Based on: https://github.com/paulasiimwe/Android-ImageMagick 11 | public class ImageMagickUtils { 12 | // Log 13 | private final static String TAG = ImageMagickUtils.class.getSimpleName(); 14 | 15 | public static void setCacheDir(Context context) { 16 | File maxDir = null; 17 | long maxSpace = -1; 18 | String path; 19 | 20 | File[] dirs = context.getExternalCacheDirs(); 21 | 22 | for (int k = 0; k < dirs.length; ++k) { 23 | File dir = dirs[k]; 24 | long dirFreeSpace = dir.getFreeSpace(); 25 | 26 | // testing: 27 | path = dir.getAbsolutePath(); 28 | Log.d(TAG, "- #" + k + " cache path: " + path); 29 | 30 | if (dirFreeSpace > maxSpace) { 31 | maxSpace = dirFreeSpace; 32 | maxDir = dir; 33 | } 34 | } 35 | 36 | if (maxDir != null) { 37 | path = maxDir.getAbsolutePath(); 38 | Log.d(TAG, "- best cache path: " + path); 39 | Magick.setCacheDir(path); 40 | } else 41 | Log.d(TAG, "- best cache dir null"); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/adafruit/bluefruit/le/connect/utils/LegacyCompatFileProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 CommonsWare, LLC 3 | Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 | use this file except in compliance with the License. You may obtain a copy 5 | of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless required 6 | by applicable law or agreed to in writing, software distributed under the 7 | License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 8 | OF ANY KIND, either express or implied. See the License for the specific 9 | language governing permissions and limitations under the License. 10 | 11 | Covered in detail in the book _The Busy Coder's Guide to Android Development_ 12 | https://commonsware.com/Android 13 | */ 14 | 15 | package com.adafruit.bluefruit.le.connect.utils; 16 | 17 | import android.database.Cursor; 18 | import android.net.Uri; 19 | 20 | import androidx.core.content.FileProvider; 21 | import androidx.annotation.NonNull; 22 | 23 | import com.commonsware.cwac.provider.LegacyCompatCursorWrapper; 24 | 25 | public class LegacyCompatFileProvider extends FileProvider { 26 | @Override 27 | public Cursor query(@NonNull Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { 28 | return (new LegacyCompatCursorWrapper(super.query(uri, projection, selection, selectionArgs, sortOrder))); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/com/adafruit/bluefruit/le/connect/utils/LocalizationManager.java: -------------------------------------------------------------------------------- 1 | package com.adafruit.bluefruit.le.connect.utils; 2 | 3 | import android.content.Context; 4 | 5 | public class LocalizationManager { 6 | // Constants 7 | private final static String TAG = LocalizationManager.class.getSimpleName(); 8 | 9 | //private final static String kLanguageSettingsFile = "LanguageFile"; 10 | 11 | // Singleton 12 | private static LocalizationManager sInstance = null; 13 | 14 | public static synchronized LocalizationManager getInstance() { 15 | if (sInstance == null) { 16 | sInstance = new LocalizationManager(); 17 | } 18 | 19 | return sInstance; 20 | } 21 | 22 | private LocalizationManager() { 23 | } 24 | 25 | /* 26 | public void initLanguage(Context context) { 27 | SharedPreferences settings = context.getSharedPreferences(LocalizationManager.kLanguageSettingsFile, 0); 28 | String currentLanguage = settings.getString("language", null); 29 | 30 | if (currentLanguage == null) { 31 | // Set the default language 32 | currentLanguage = Locale.getDefault().getLanguage(); 33 | } 34 | 35 | Log.v(TAG, "language:"+currentLanguage); 36 | }*/ 37 | 38 | public String getString(Context context, String stringName) { 39 | int id = context.getResources().getIdentifier(stringName, "string", context.getPackageName()); 40 | if (id == 0) return null; 41 | else return context.getResources().getString(id); 42 | } 43 | 44 | /* 45 | public void changeLocaleLanguage(Context context) { 46 | saveCurrentLanguage(context); 47 | } 48 | 49 | public void setLanguageCode(Context context, String languageCode) { 50 | saveCurrentLanguage(context); 51 | } 52 | 53 | private void saveCurrentLanguage(Context context) { 54 | SharedPreferences settings = context.getSharedPreferences(LocalizationManager.kLanguageSettingsFile, 0); 55 | SharedPreferences.Editor editor = settings.edit(); 56 | editor.putString("language", "en"); 57 | editor.apply(); 58 | } 59 | 60 | public String getLanguageCode() { 61 | return "en"; 62 | } 63 | */ 64 | } 65 | -------------------------------------------------------------------------------- /app/src/main/java/com/adafruit/bluefruit/le/connect/utils/MetricsUtils.java: -------------------------------------------------------------------------------- 1 | package com.adafruit.bluefruit.le.connect.utils; 2 | 3 | import android.content.Context; 4 | 5 | // http://stackoverflow.com/questions/4605527/converting-pixels-to-dp 6 | public class MetricsUtils { 7 | 8 | public static float convertPixelsToDp(final Context context, final float px) { 9 | if (context != null) { 10 | return px / context.getResources().getDisplayMetrics().density; 11 | } else { 12 | return 0f; 13 | } 14 | } 15 | 16 | public static float convertDpToPixel(final Context context, final float dp) { 17 | if (context != null) { 18 | return dp * context.getResources().getDisplayMetrics().density; 19 | } else { 20 | return 0f; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /app/src/main/java/com/adafruit/bluefruit/le/connect/utils/NetworkUtils.java: -------------------------------------------------------------------------------- 1 | package com.adafruit.bluefruit.le.connect.utils; 2 | 3 | import android.content.Context; 4 | import android.net.ConnectivityManager; 5 | import android.net.NetworkInfo; 6 | import androidx.annotation.NonNull; 7 | import androidx.annotation.RequiresPermission; 8 | 9 | import static android.Manifest.permission.ACCESS_NETWORK_STATE; 10 | 11 | 12 | public class NetworkUtils { 13 | 14 | @RequiresPermission(ACCESS_NETWORK_STATE) 15 | public static boolean isNetworkAvailable(@NonNull Context context) { 16 | 17 | boolean result = false; 18 | ConnectivityManager connectivityManager = (ConnectivityManager) context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE); // Use getApplicationContext to solve a bug on Android M: https://stackoverflow.com/questions/41431409/connectivitymanager-leaking-not-sure-how-to-resolve 19 | if (connectivityManager != null) { 20 | NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo(); 21 | if (activeNetworkInfo != null) { 22 | result = activeNetworkInfo.isConnected(); 23 | } 24 | } 25 | 26 | return result; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/com/adafruit/bluefruit/le/connect/utils/PermissionsUtils.java: -------------------------------------------------------------------------------- 1 | package com.adafruit.bluefruit.le.connect.utils; 2 | 3 | import android.Manifest; 4 | import android.content.Context; 5 | import android.content.pm.PackageManager; 6 | import android.os.Build; 7 | import android.provider.Settings; 8 | 9 | import androidx.annotation.NonNull; 10 | import androidx.core.app.ActivityCompat; 11 | 12 | public class PermissionsUtils { 13 | public static String[] getNeededPermissionsForScanning() { 14 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { 15 | return new String[]{ 16 | Manifest.permission.BLUETOOTH_SCAN, 17 | Manifest.permission.BLUETOOTH_CONNECT 18 | }; 19 | } else { 20 | return new String[]{ 21 | Manifest.permission.ACCESS_FINE_LOCATION 22 | }; 23 | } 24 | } 25 | 26 | public static boolean manageLocationServiceAvailabilityForScanning(@NonNull Context context) { 27 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { 28 | return true; 29 | } else { 30 | int locationMode = Settings.Secure.LOCATION_MODE_OFF; 31 | try { 32 | locationMode = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE); 33 | 34 | } catch (Settings.SettingNotFoundException e) { 35 | e.printStackTrace(); 36 | } 37 | return locationMode != Settings.Secure.LOCATION_MODE_OFF; 38 | } 39 | } 40 | 41 | public static boolean hasPermissions(@NonNull Context context, @NonNull String... permissions) { 42 | for (String permission : permissions) { 43 | if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) { 44 | return false; 45 | } 46 | } 47 | return true; 48 | } 49 | 50 | public static boolean hasPermissionsForScanning(@NonNull Context context) { 51 | boolean result = false; 52 | 53 | final boolean areLocationServicesReadyForScanning = PermissionsUtils.manageLocationServiceAvailabilityForScanning(context); 54 | if (areLocationServicesReadyForScanning) { 55 | String[] permissions = PermissionsUtils.getNeededPermissionsForScanning(); 56 | if (PermissionsUtils.hasPermissions(context, permissions)) { 57 | result = true; 58 | } 59 | } 60 | 61 | return result; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /app/src/main/java/com/adafruit/bluefruit/le/connect/utils/ScreenUtils.java: -------------------------------------------------------------------------------- 1 | package com.adafruit.bluefruit.le.connect.utils; 2 | 3 | import android.app.Activity; 4 | import android.view.Window; 5 | import android.view.WindowManager; 6 | 7 | import androidx.annotation.NonNull; 8 | 9 | public class ScreenUtils { 10 | 11 | public static void keepScreenOn(@NonNull Activity activity, boolean enabled) { 12 | Window window = activity.getWindow(); 13 | if (enabled) 14 | window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 15 | else 16 | window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/adafruit/bluefruit/le/connect/utils/SingleLiveEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google Inc. 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 | package com.adafruit.bluefruit.le.connect.utils; 18 | 19 | import androidx.annotation.MainThread; 20 | import androidx.annotation.NonNull; 21 | import androidx.annotation.Nullable; 22 | import androidx.lifecycle.LifecycleOwner; 23 | import androidx.lifecycle.MutableLiveData; 24 | import androidx.lifecycle.Observer; 25 | 26 | import android.util.Log; 27 | 28 | import java.util.concurrent.atomic.AtomicBoolean; 29 | 30 | /** 31 | * A lifecycle-aware observable that sends only new updates after subscription, used for events like 32 | * navigation and Snackbar messages. 33 | *

34 | * This avoids a common problem with events: on configuration change (like rotation) an update 35 | * can be emitted if the observer is active. This LiveData only calls the observable if there's an 36 | * explicit call to setValue() or call(). 37 | *

38 | * Note that only one observer is going to be notified of changes. 39 | */ 40 | public class SingleLiveEvent extends MutableLiveData { 41 | 42 | private static final String TAG = "SingleLiveEvent"; 43 | 44 | private final AtomicBoolean mPending = new AtomicBoolean(false); 45 | 46 | @MainThread 47 | public void observe(@NonNull LifecycleOwner owner, @NonNull final Observer observer) { 48 | 49 | if (hasActiveObservers()) { 50 | Log.w(TAG, "Multiple observers registered but only one will be notified of changes."); 51 | } 52 | 53 | // Observe the internal MutableLiveData 54 | super.observe(owner, t -> { 55 | if (mPending.compareAndSet(true, false)) { 56 | observer.onChanged(t); 57 | } 58 | }); 59 | } 60 | 61 | @MainThread 62 | public void setValue(@Nullable T t) { 63 | mPending.set(true); 64 | super.setValue(t); 65 | } 66 | 67 | /** 68 | * Used for cases where T is Void, to make calls cleaner. 69 | */ 70 | @MainThread 71 | public void call() { 72 | setValue(null); 73 | } 74 | } -------------------------------------------------------------------------------- /app/src/main/java/com/adafruit/bluefruit/le/connect/utils/ThreadUtils.java: -------------------------------------------------------------------------------- 1 | package com.adafruit.bluefruit.le.connect.utils; 2 | 3 | public class ThreadUtils { 4 | 5 | // https://stackoverflow.com/questions/34871580/android-how-to-group-async-tasks-together-like-in-ios 6 | public static class DispatchGroup { 7 | 8 | private int mCount; 9 | private Runnable mRunnable; 10 | 11 | public DispatchGroup() { 12 | super(); 13 | mCount = 0; 14 | } 15 | 16 | public synchronized void enter() { 17 | mCount++; 18 | } 19 | 20 | public synchronized void leave() { 21 | mCount--; 22 | notifyGroup(); 23 | } 24 | 25 | public void notify(Runnable r) { 26 | mRunnable = r; 27 | notifyGroup(); 28 | } 29 | 30 | private void notifyGroup() { 31 | if (mCount <= 0 && mRunnable != null) { 32 | mRunnable.run(); 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/adafruit/bluefruit/le/connect/utils/UriBeaconUtils.java: -------------------------------------------------------------------------------- 1 | package com.adafruit.bluefruit.le.connect.utils; 2 | 3 | import com.adafruit.bluefruit.le.connect.ble.BleUtils; 4 | 5 | import java.nio.charset.StandardCharsets; 6 | import java.util.Arrays; 7 | 8 | public class UriBeaconUtils { 9 | 10 | private static String getSchemeFromPrefix(byte schemePrefix) { 11 | switch (schemePrefix) { 12 | case 0: 13 | return "http://www."; 14 | case 1: 15 | return "https://www."; 16 | case 2: 17 | return "http://"; 18 | case 3: 19 | return "https://"; 20 | case 4: 21 | return "urn:uuid:"; 22 | default: 23 | return null; 24 | } 25 | } 26 | 27 | private static String getUrlEncodingFromByte(byte value) { 28 | switch (value) { 29 | case 0: 30 | return ".com/"; 31 | case 1: 32 | return ".org/"; 33 | case 2: 34 | return ".edu/"; 35 | case 3: 36 | return ".net/"; 37 | case 4: 38 | return ".info/"; 39 | case 5: 40 | return ".biz/"; 41 | case 6: 42 | return ".gov/"; 43 | case 7: 44 | return ".com/"; 45 | case 8: 46 | return ".org/"; 47 | case 9: 48 | return ".edu/"; 49 | case 10: 50 | return ".net/"; 51 | case 11: 52 | return ".info/"; 53 | case 12: 54 | return ".biz/"; 55 | case 13: 56 | return ".gov/"; 57 | default: 58 | return null; 59 | } 60 | } 61 | 62 | public static String getUriFromAdvertisingPacket(byte[] scanRecord) { 63 | byte schemeByte = scanRecord[10]; 64 | String scheme = UriBeaconUtils.getSchemeFromPrefix(schemeByte); 65 | 66 | String url; 67 | if (schemeByte == 0x04) // Special case for urn:uuid 68 | { 69 | byte[] urlBytes = Arrays.copyOfRange(scanRecord, 11, 11 + 16); 70 | url = BleUtils.getUuidStringFromByteArray(urlBytes); 71 | } else { 72 | final int length = scanRecord[4] - 6; // 6 fixed fields bytes (uri length is total lenght-6) 73 | byte[] urlBytes = Arrays.copyOfRange(scanRecord, 11, 11 + length); 74 | 75 | url = new String(urlBytes, StandardCharsets.UTF_8); 76 | 77 | for (int i = urlBytes.length - 1; i >= 0; i--) // Go backwards because we are replacing single characters with strings that will change the url lenght 78 | { 79 | String urlEncoding = getUrlEncodingFromByte(urlBytes[i]); 80 | if (urlEncoding != null) { 81 | url = new StringBuffer(url).insert(i, urlEncoding).toString(); 82 | } 83 | } 84 | } 85 | 86 | return scheme + url; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /app/src/main/java/magick/ClassType.java: -------------------------------------------------------------------------------- 1 | package magick; 2 | 3 | public interface ClassType { 4 | 5 | public final static int UndefinedClass = 0; 6 | public final static int DirectClass = 1; 7 | public final static int PseudoClass = 2; 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/magick/ColorspaceType.java: -------------------------------------------------------------------------------- 1 | package magick; 2 | 3 | public interface ColorspaceType { 4 | 5 | public final static int UndefinedColorspace = 0; 6 | public final static int RGBColorspace = 1; 7 | public final static int GRAYColorspace = 2; 8 | public final static int TransparentColorspace = 3; 9 | public final static int OHTAColorspace = 4; 10 | public final static int LABColorspace = 5; 11 | public final static int XYZColorspace = 6; 12 | public final static int YCbCrColorspace = 7; 13 | public final static int YCCColorspace = 8; 14 | public final static int YIQColorspace = 9; 15 | public final static int YPbPrColorspace = 10; 16 | public final static int YUVColorspace = 11; 17 | public final static int CMYKColorspace = 12; 18 | public final static int sRGBColorspace = 13; 19 | public final static int HSBColorspace = 14; 20 | public final static int HSLColorspace = 15; 21 | public final static int HWBColorspace = 16; 22 | public final static int Rec601LumaColorspace = 17; 23 | public final static int Rec601YCbCrColorspace = 18; 24 | public final static int Rec709LumaColorspace = 19; 25 | public final static int Rec709YCbCrColorspace = 20; 26 | public final static int LogColorspace = 21; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/magick/CompositeOperator.java: -------------------------------------------------------------------------------- 1 | package magick; 2 | 3 | public interface CompositeOperator { 4 | 5 | public static final int UndefinedCompositeOp = 0; 6 | public static final int NoCompositeOp = 1; 7 | public static final int AddCompositeOp = 2; 8 | public static final int AtopCompositeOp = 3; 9 | public static final int BlendCompositeOp = 4; 10 | public static final int BumpmapCompositeOp = 5; 11 | public static final int ChangeMaskCompositeOp = 6; 12 | public static final int ClearCompositeOp = 7; 13 | public static final int ColorBurnCompositeOp = 8; 14 | public static final int ColorDodgeCompositeOp = 9; 15 | public static final int ColorizeCompositeOp = 10; 16 | public static final int CopyBlackCompositeOp = 11; 17 | public static final int CopyBlueCompositeOp = 12; 18 | public static final int CopyCompositeOp = 13; 19 | public static final int CopyCyanCompositeOp = 14; 20 | public static final int CopyGreenCompositeOp = 15; 21 | public static final int CopyMagentaCompositeOp = 16; 22 | public static final int CopyOpacityCompositeOp = 17; 23 | public static final int CopyRedCompositeOp = 18; 24 | public static final int CopyYellowCompositeOp = 19; 25 | public static final int DarkenCompositeOp = 20; 26 | public static final int DstAtopCompositeOp = 21; 27 | public static final int DstCompositeOp = 22; 28 | public static final int DstInCompositeOp = 23; 29 | public static final int DstOutCompositeOp = 24; 30 | public static final int DstOverCompositeOp = 25; 31 | public static final int DifferenceCompositeOp = 26; 32 | public static final int DisplaceCompositeOp = 27; 33 | public static final int DissolveCompositeOp = 28; 34 | public static final int ExclusionCompositeOp = 29; 35 | public static final int HardLightCompositeOp = 30; 36 | public static final int HueCompositeOp = 31; 37 | public static final int InCompositeOp = 32; 38 | public static final int LightenCompositeOp = 33; 39 | public static final int LinearLightCompositeOp = 34; 40 | public static final int LuminizeCompositeOp = 35; 41 | public static final int MinusCompositeOp = 36; 42 | public static final int ModulateCompositeOp = 37; 43 | public static final int MultiplyCompositeOp = 38; 44 | public static final int OutCompositeOp = 39; 45 | public static final int OverCompositeOp = 40; 46 | public static final int OverlayCompositeOp = 41; 47 | public static final int PlusCompositeOp = 42; 48 | public static final int ReplaceCompositeOp = 43; 49 | public static final int SaturateCompositeOp = 44; 50 | public static final int ScreenCompositeOp = 45; 51 | public static final int SoftLightCompositeOp = 46; 52 | public static final int SrcAtopCompositeOp = 47; 53 | public static final int SrcCompositeOp = 48; 54 | public static final int SrcInCompositeOp = 49; 55 | public static final int SrcOutCompositeOp = 50; 56 | public static final int SrcOverCompositeOp = 51; 57 | public static final int SubtractCompositeOp = 52; 58 | public static final int ThresholdCompositeOp = 53; 59 | public static final int XorCompositeOp = 54; 60 | public static final int DivideCompositeOp = 55; 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/java/magick/CompressionType.java: -------------------------------------------------------------------------------- 1 | package magick; 2 | 3 | public interface CompressionType { 4 | 5 | public final static int UndefinedCompression = 0; 6 | public final static int NoCompression = 1; 7 | public final static int BZipCompression = 2; 8 | public final static int FaxCompression = 3; 9 | public final static int Group4Compression = 4; 10 | public final static int JPEGCompression = 5; 11 | public final static int JPEG2000Compression = 6; 12 | public final static int LosslessJPEGCompression = 7; 13 | public final static int LZWCompression = 8; 14 | public final static int RLECompression = 9; 15 | public final static int ZipCompression = 10; 16 | 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/magick/DecorationType.java: -------------------------------------------------------------------------------- 1 | package magick; 2 | 3 | /** 4 | * Interface to contain definition for Image Magick's DecorationType. 5 | * 6 | * @author Eric Yeo 7 | */ 8 | public interface DecorationType { 9 | 10 | public final static int UndefinedDecoration = 0; 11 | public final static int NoDecoration = 1; 12 | public final static int UnderlineDecoration = 2; 13 | public final static int OverlineDecoration = 3; 14 | public final static int LineThroughDecoration = 4; 15 | 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/magick/FilterType.java: -------------------------------------------------------------------------------- 1 | package magick; 2 | 3 | public interface FilterType { 4 | 5 | public final static int UndefinedFilter = 0; 6 | public final static int PointFilter = 1; 7 | public final static int BoxFilter = 2; 8 | public final static int TriangleFilter = 3; 9 | public final static int HermiteFilter = 4; 10 | public final static int HanningFilter = 5; 11 | public final static int HammingFilter = 6; 12 | public final static int BlackmanFilter = 7; 13 | public final static int GuassianFilter = 8; 14 | public final static int QuadraticFilter = 9; 15 | public final static int CubicFilter = 10; 16 | public final static int CatromFilter = 11; 17 | public final static int MitchellFilter = 12; 18 | public final static int LanczosFilter = 13; 19 | public final static int BesselFilter = 14; 20 | public final static int SincFilter = 15; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/magick/GeometryFlags.java: -------------------------------------------------------------------------------- 1 | package magick; 2 | 3 | public interface GeometryFlags { 4 | 5 | public static final int NoValue = 0x0000; 6 | public static final int PsiValue = 0x0001; 7 | public static final int XValue = 0x0001; 8 | public static final int XiValue = 0x0002; 9 | public static final int YValue = 0x0002; 10 | public static final int RhoValue = 0x0004; 11 | public static final int WidthValue = 0x0004; 12 | public static final int SigmaValue = 0x0008; 13 | public static final int HeightValue = 0x0008; 14 | public static final int ChiValue = 0x0010; 15 | public static final int XiNegative = 0x0020; 16 | public static final int XNegative = 0x0020; 17 | public static final int PsiNegative = 0x0040; 18 | public static final int YNegative = 0x0040; 19 | public static final int ChiNegative = 0x0080; 20 | public static final int PercentValue = 0x1000; 21 | public static final int AspectValue = 0x2000; 22 | public static final int LessValue = 0x4000; 23 | public static final int GreaterValue = 0x8000; 24 | public static final int MinimumValue = 0x10000; 25 | public static final int AreaValue = 0x20000; 26 | public static final int DecimalValue = 0x40000; 27 | public static final int AllValues = 0x7fffffff; 28 | 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/magick/GravityType.java: -------------------------------------------------------------------------------- 1 | package magick; 2 | 3 | /** 4 | * Corresponds to the ImageMagick enumerated type of the same name. 5 | * 6 | * @author Eric Yeo 7 | */ 8 | public interface GravityType { 9 | 10 | public final static int UndefinedGravity = 0; 11 | public final static int ForgetGravity = 0; 12 | public final static int NorthWestGravity = 1; 13 | public final static int NorthGravity = 2; 14 | public final static int NorthEastGravity = 3; 15 | public final static int WestGravity = 4; 16 | public final static int CenterGravity = 5; 17 | public final static int EastGravity = 6; 18 | public final static int SouthWestGravity = 7; 19 | public final static int SouthGravity = 8; 20 | public final static int SouthEastGravity = 9; 21 | public final static int StaticGravity = 10; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/magick/ImageMagick.java: -------------------------------------------------------------------------------- 1 | package magick; 2 | 3 | public class ImageMagick { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/magick/ImageType.java: -------------------------------------------------------------------------------- 1 | package magick; 2 | 3 | /** 4 | * Corresponds to the ImageMagick enumerated type of the same name. 5 | * 6 | * @author Eric Yeo 7 | */ 8 | public interface ImageType { 9 | 10 | public final static int UndefinedType = 0; 11 | public final static int BilevelType = 1; 12 | public final static int GrayscaleType = 2; 13 | public final static int GrayscaleMatteType = 3; 14 | public final static int PaletteType = 4; 15 | public final static int PaletteMatteType = 5; 16 | public final static int TrueColorType = 6; 17 | public final static int TrueColorMatteType = 7; 18 | public final static int ColorSeparationType = 8; 19 | public final static int ColorSeparationMatteType = 9; 20 | public final static int OptimizeType = 10; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/magick/InterlaceType.java: -------------------------------------------------------------------------------- 1 | package magick; 2 | 3 | /** 4 | * Corresponds to the ImageMagick enumerated type of the same name. 5 | * 6 | * @author Eric Yeo 7 | */ 8 | public interface InterlaceType { 9 | 10 | public final static int UndefinedInterlace = 0; 11 | public final static int NoInterlace = 1; 12 | public final static int LineInterlace = 2; 13 | public final static int PlaneInterlace = 3; 14 | public final static int PartitionInterlace = 4; 15 | 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/magick/Magick.java: -------------------------------------------------------------------------------- 1 | package magick; 2 | 3 | 4 | import fakeawt.Rectangle; 5 | 6 | 7 | /** 8 | * The sole purchase of this class is to cause the native 9 | * library to be loaded whenever a concrete class is used 10 | * and provide utility methods. 11 | * 12 | * @author Eric Yeo 13 | * @author Max Kollegov <virtual_max@geocities.com> 14 | */ 15 | //////////////////////////////////////////////////////////////////////////////////////////// 16 | // 17 | // 2016/04/22 D.Slamnig added support for setting image cache directory (JNI _magick_Cache.c) 18 | // 19 | //////////////////////////////////////////////////////////////////////////////////////////// 20 | 21 | public class Magick { 22 | 23 | static { 24 | /*String clprop = System.getProperty("jmagick.systemclassloader"); 25 | if (clprop == null || clprop.equalsIgnoreCase("yes")) { 26 | try { 27 | ClassLoader.getSystemClassLoader() 28 | .loadClass("magick.MagickLoader").newInstance(); 29 | } 30 | catch(ClassNotFoundException e) { 31 | throw new RuntimeException("Can't load MagickLoader " + 32 | "(class not found)"); 33 | } 34 | catch(IllegalAccessException e) { 35 | throw new RuntimeException("Access to SystemClassLoader "+ 36 | "denied (IllegalAccessException)"); 37 | } 38 | catch(InstantiationException e) { 39 | throw new RuntimeException("Can't instantiate MagicLoader " + 40 | "(InstantiationException)"); 41 | } 42 | } 43 | else { 44 | System.loadLibrary("JMagick"); 45 | }*/ 46 | 47 | System.loadLibrary("imagemagick"); 48 | 49 | init(); 50 | } 51 | 52 | 53 | /** 54 | * Initializes the ImageMagic system 55 | */ 56 | private static native void init(); 57 | 58 | 59 | /** 60 | * Parses a geometry specification and returns the 61 | * width, height, x, and y values in the rectangle. 62 | * It also returns flags that indicates which of the 63 | * four values (width, height, xoffset, yoffset) were 64 | * located in the string, and whether the x and y values 65 | * are negative. In addition, there are flags to report 66 | * any meta characters (%, !, <, and >). 67 | * @param geometry String containing the geometry specifications 68 | * @param rect The rectangle of values x, y, width and height 69 | * @return bitmask indicating the values in the geometry string 70 | * @see magick.GeometryFlags 71 | */ 72 | public static native int parseImageGeometry(String geometry, 73 | Rectangle rect); 74 | 75 | //////////////////////////////////////////////////////////////////////////////////////////// 76 | // 77 | // 2016/04/22 D.Slamnig added support for setting image cache directory (see JNI ...magick_Cache.c) 78 | // 79 | //////////////////////////////////////////////////////////////////////////////////////////// 80 | public static native void setCacheDir(String dir); 81 | // 82 | } 83 | -------------------------------------------------------------------------------- /app/src/main/java/magick/MagickApiException.java: -------------------------------------------------------------------------------- 1 | package magick; 2 | 3 | /** 4 | * Encapsulation of the ImageMagick ExceptionInfo structure as 5 | * well as the exception that is thrown when an ImageMagick 6 | * API failed. 7 | * 8 | * @author Eric Yeo 9 | */ 10 | public class MagickApiException extends MagickException { 11 | 12 | /** 13 | * Takes a value in ExceptionType. 14 | */ 15 | private int severity; 16 | 17 | /** 18 | * An reason for failure. 19 | */ 20 | private String reason; 21 | 22 | /** 23 | * A description of the problem. 24 | */ 25 | private String description; 26 | 27 | 28 | /** 29 | * Construct an API exception. 30 | * 31 | * @param mesg error message 32 | * @param severity one of the value in ExceptionType 33 | * @qualifier error qualifier 34 | */ 35 | private MagickApiException(int severity, 36 | String reason, 37 | String description) 38 | { 39 | super(reason); 40 | this.severity = severity; 41 | this.reason = reason; 42 | this.description = description; 43 | } 44 | 45 | /* 46 | * Get the severity of the exception. 47 | * 48 | * @return severity of the Exception 49 | */ 50 | public int getSeverity() 51 | { 52 | return severity; 53 | } 54 | 55 | /* 56 | * Get the reason of the exception. 57 | * 58 | * @return reason of the exception. 59 | */ 60 | public String getReason() 61 | { 62 | return reason; 63 | } 64 | 65 | /** 66 | * Get the description of the exception. 67 | * 68 | * @return description of the exception. 69 | */ 70 | public String getDescription() 71 | { 72 | return description; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /app/src/main/java/magick/MagickException.java: -------------------------------------------------------------------------------- 1 | package magick; 2 | 3 | /** 4 | * Exception class for all encompassing Exception. 5 | * 6 | * @see MagickApiException 7 | * @author Eric Yeo 8 | */ 9 | public class MagickException extends Exception { 10 | 11 | /** 12 | * Construct an exception with a message. 13 | * 14 | * @param mesg message attached to the exception 15 | */ 16 | public MagickException(String mesg) 17 | { 18 | super(mesg); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/magick/MagickInfo.java: -------------------------------------------------------------------------------- 1 | package magick; 2 | 3 | /** 4 | * Encapsulation of the MagickInfo structure. 5 | * 6 | * @author Susan Dorr 7 | */ 8 | public class MagickInfo extends Magick { 9 | 10 | // Internal handle. Used as pointer to MagickInfo 11 | // structure in memory. We use long (64-bits) for 12 | // portibility. 13 | private long magickInfoHandle = 0; 14 | 15 | /** 16 | * Constructor. 17 | */ 18 | public MagickInfo(String name) 19 | throws MagickException 20 | { 21 | init(name); 22 | } 23 | 24 | /** 25 | * Automated destructor. 26 | */ 27 | 28 | public void finalize() 29 | { 30 | destroyMagickInfo(); 31 | } 32 | 33 | /** 34 | * Initialise the MagickInfo structure. 35 | */ 36 | public native void init(String name) 37 | throws MagickException; 38 | 39 | /** 40 | * Deallocate the MagickInfo structure. 41 | */ 42 | private native void destroyMagickInfo(); 43 | 44 | 45 | /** 46 | * Return the description attribute of the handle. 47 | */ 48 | public native String getDescription() 49 | throws MagickException; 50 | } 51 | -------------------------------------------------------------------------------- /app/src/main/java/magick/MagickLoader.java: -------------------------------------------------------------------------------- 1 | package magick; 2 | 3 | /** 4 | * The sole purpouse of this class is to cause the native 5 | * library to be loaded in SYSTEM classloader whenever a 6 | * concrete class is used. 7 | * 8 | * @author Max Kollegov <Virtual_Max@geocities.com> 9 | */ 10 | public class MagickLoader { 11 | 12 | static { 13 | System.loadLibrary("imagemagick"); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/magick/MapMode.java: -------------------------------------------------------------------------------- 1 | package magick; 2 | 3 | /** 4 | * Corresponds to ImageMagick enumerated type of the same name. 5 | * 6 | * @author Eric Yeo 7 | */ 8 | public interface MapMode { 9 | 10 | public final int ReadMode = 0; 11 | public final int WriteMode = 1; 12 | public final int IOMode = 2; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/magick/MontageMode.java: -------------------------------------------------------------------------------- 1 | package magick; 2 | 3 | /** 4 | * Corresponds to ImageMagick enumerated type of the same name. 5 | * 6 | * @author Eric Yeo 7 | */ 8 | public interface MontageMode { 9 | 10 | public final int UndefinedMode = 0; 11 | public final int FrameMode = 1; 12 | public final int UnframeMode = 2; 13 | public final int ConcatenateMode = 3; 14 | 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/magick/NoiseType.java: -------------------------------------------------------------------------------- 1 | package magick; 2 | 3 | public interface NoiseType { 4 | 5 | public final static int UndefinedNoise = 0; 6 | public final static int UniformNoise = 1; 7 | public final static int GaussianNoise = 2; 8 | public final static int MultiplicativeGaussianNoise = 3; 9 | public final static int ImpulseNoise = 4; 10 | public final static int LaplacianNoise = 5; 11 | public final static int PoissonNoise = 6; 12 | 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/magick/PaintMethod.java: -------------------------------------------------------------------------------- 1 | package magick; 2 | 3 | public interface PaintMethod { 4 | 5 | public final int UndefinedMethod = 0; 6 | public final int PointMethod = 1; 7 | public final int ReplaceMethod = 2; 8 | public final int FloodfillMethod = 3; 9 | public final int FillToBorderMethod = 4; 10 | public final int ResetMethod = 5; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/java/magick/PixelPacket.java: -------------------------------------------------------------------------------- 1 | package magick; 2 | 3 | 4 | 5 | public class PixelPacket extends Magick { 6 | 7 | private int red, green, blue, opacity; 8 | 9 | // Constructor 10 | public PixelPacket(int red, int green, int blue, int opacity) 11 | { 12 | this.red = red; 13 | this.green = green; 14 | this.blue = blue; 15 | this.opacity = opacity; 16 | } 17 | 18 | // Set methods. 19 | public void setRed(int red) 20 | { 21 | this.red = red; 22 | } 23 | 24 | public void setGreen(int green) 25 | { 26 | this.green = green; 27 | } 28 | 29 | public void setBlue(int blue) 30 | { 31 | this.blue = blue; 32 | } 33 | 34 | public void setOpacity(int opacity) 35 | { 36 | this.opacity = opacity; 37 | } 38 | 39 | 40 | // Get Methods 41 | public int getRed() 42 | { 43 | return red; 44 | } 45 | 46 | public int getGreen() 47 | { 48 | return green; 49 | } 50 | 51 | public int getBlue() 52 | { 53 | return blue; 54 | } 55 | 56 | public int getOpacity() 57 | { 58 | return opacity; 59 | } 60 | 61 | /** 62 | * looks up a RGB values for a color given in the target string. 63 | * 64 | * @param target Specifies the color to lookup in the X color database 65 | * @return a PixelPacket that represents the target 66 | */ 67 | public static native PixelPacket queryColorDatabase(String target) 68 | throws MagickException; 69 | 70 | 71 | /** 72 | * Display the object as a String 73 | * @see java.lang.Object#toString() 74 | */ 75 | public String toString() { 76 | return "PixelPacket("+getRed()+","+getBlue()+","+getGreen()+","+getOpacity()+")"; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /app/src/main/java/magick/PreviewType.java: -------------------------------------------------------------------------------- 1 | package magick; 2 | 3 | 4 | /** 5 | * Corresponds to the ImageMagick enumerated type of the same name. 6 | * 7 | * @author Eric Yeo 8 | */ 9 | public interface PreviewType { 10 | 11 | public final static int UndefinedPreview = 0; 12 | public final static int RotatePreview = 1; 13 | public final static int ShearPreview = 2; 14 | public final static int RollPreview = 3; 15 | public final static int HuePreview = 4; 16 | public final static int SaturationPreview = 5; 17 | public final static int BrightnessPreview = 6; 18 | public final static int GammaPreview = 7; 19 | public final static int SpiffPreview = 8; 20 | public final static int DullPreview = 9; 21 | public final static int GrayscalePreview = 10; 22 | public final static int QuantizePreview = 11; 23 | public final static int DespecklePreview = 12; 24 | public final static int ReduceNoisePreview = 13; 25 | public final static int AddNoisePreview = 14; 26 | public final static int SharpenPreview = 15; 27 | public final static int BlurPreview = 16; 28 | public final static int ThresholdPreview = 17; 29 | public final static int EdgeDetectPreview = 18; 30 | public final static int SpreadPreview = 19; 31 | public final static int SolarizePreview = 20; 32 | public final static int ShadePreview = 21; 33 | public final static int RaisePreview = 22; 34 | public final static int SegmentPreview = 23; 35 | public final static int SwirlPreview = 24; 36 | public final static int ImplodePreview = 25; 37 | public final static int WavePreview = 26; 38 | public final static int OilPaintPreview = 27; 39 | public final static int CharcoalDrawingPreview = 28; 40 | public final static int JPEGPreview = 29; 41 | 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/magick/PrimitiveType.java: -------------------------------------------------------------------------------- 1 | package magick; 2 | 3 | /** 4 | * Corresponds to the ImageMagick enumerated type of the same name. 5 | * 6 | * @author Eric Yeo 7 | */ 8 | public interface PrimitiveType { 9 | 10 | public final static int UndefinedPrimitive = 0; 11 | public final static int PointPrimitive = 1; 12 | public final static int LinePrimitive = 2; 13 | public final static int RectanglePrimitive = 3; 14 | public final static int RoundRectanglePrimitive = 4; 15 | public final static int ArcPrimitive = 5; 16 | public final static int EllipsePrimitive = 6; 17 | public final static int CirclePrimitive = 7; 18 | public final static int PolylinePrimitive = 8; 19 | public final static int PolygonPrimitive = 9; 20 | public final static int BezierPrimitive = 10; 21 | public final static int ColorPrimitive = 11; 22 | public final static int MattePrimitive = 12; 23 | public final static int TextPrimitive = 13; 24 | public final static int ImagePrimitive = 14; 25 | public final static int PathPrimitive = 15; 26 | 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/magick/ProfileInfo.java: -------------------------------------------------------------------------------- 1 | package magick; 2 | 3 | /** 4 | * Class encapsulating some profile related to a image. 5 | * This class corresponds to the ProfileInfo structure in 6 | * the C API. ProfileInfo is currently used in the Image 7 | * structure to store the ICC and IPTC profiles. 8 | * @deprecated This class is only needed for the old (ImageMagick 5.5.7 ?) 9 | * methods get/setColorProfile() and get/setIptcProfile(). 10 | * Recommended is to use the new generic methods getImageProfile() and 11 | * setImageProfile() instead 12 | * @see MagickImage#setColorProfile 13 | * @author Eric Yeo <ttey@yeo.nu> 14 | */ 15 | public class ProfileInfo { 16 | 17 | /** 18 | * Name of the profile. 19 | */ 20 | String name = null; 21 | 22 | /** 23 | * Profile information. 24 | */ 25 | byte[] info = null; 26 | 27 | /** 28 | * Constructor. 29 | */ 30 | public ProfileInfo() 31 | { 32 | } 33 | 34 | /** 35 | * Constructor. 36 | * @param name name of the profile 37 | * @param info the profile information 38 | */ 39 | public ProfileInfo(String name, byte[] info) 40 | { 41 | this.name = name; 42 | this.info = info; 43 | } 44 | 45 | /** 46 | * Get the profile name. 47 | * @Deprecated After ImageMagick 5.5.7 (?) names are not available 48 | * @return the profile name 49 | */ 50 | public String getName() 51 | { 52 | return name; 53 | } 54 | 55 | /** 56 | * Set the profile name. 57 | */ 58 | public void setName(String name) 59 | { 60 | this.name = name; 61 | } 62 | 63 | /** 64 | * Get the profile info. 65 | * @return the profile info 66 | */ 67 | public byte[] getInfo() 68 | { 69 | return info; 70 | } 71 | 72 | /** 73 | * Set the profile info. 74 | */ 75 | public void setInfo(byte[] info) 76 | { 77 | this.info = info; 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /app/src/main/java/magick/QuantumTypes.java: -------------------------------------------------------------------------------- 1 | package magick; 2 | 3 | /** 4 | * Corresponds to the ImageMagick enumerated type of the same name. 5 | * 6 | * @author Eric Yeo 7 | */ 8 | public interface QuantumTypes { 9 | 10 | public static final int UndefinedQuantum = 0; 11 | public static final int AlphaQuantum = 1; 12 | public static final int BlackQuantum = 2; 13 | public static final int BlueQuantum = 3; 14 | public static final int CMYKAQuantum = 4; 15 | public static final int CMYKQuantum = 5; 16 | public static final int CyanQuantum = 6; 17 | public static final int GrayAlphaQuantum = 7; 18 | public static final int GrayQuantum = 8; 19 | public static final int GreenQuantum = 9; 20 | public static final int IndexAlphaQuantum = 10; 21 | public static final int IndexQuantum = 11; 22 | public static final int MagentaQuantum = 12; 23 | public static final int OpacityQuantum = 13; 24 | public static final int RedQuantum = 14; 25 | public static final int RGBAQuantum = 15; 26 | public static final int RGBOQuantum = 16; 27 | public static final int RGBQuantum = 17; 28 | public static final int YellowQuantum = 18; 29 | public static final int GrayPadQuantum = 19; 30 | public static final int RGBPadQuantum = 20; 31 | 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/magick/RenderingIntent.java: -------------------------------------------------------------------------------- 1 | package magick; 2 | 3 | /** 4 | * Corresponds to the ImageMagick enumerated type of the same name. 5 | * 6 | * @author Eric Yeo 7 | */ 8 | public interface RenderingIntent { 9 | 10 | public final int UndefinedIntent = 0; 11 | public final int SaturationIntent = 1; 12 | public final int PerceptualIntent = 2; 13 | public final int AbsoluteIntent = 3; 14 | public final int RelativeIntent = 4; 15 | 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/magick/ResolutionType.java: -------------------------------------------------------------------------------- 1 | package magick; 2 | 3 | public interface ResolutionType { 4 | 5 | public final static int UndefinedResolution = 0; 6 | public final static int PixelsPerInchResolution = 1; 7 | public final static int PixelsPerCentimeterResolution = 2; 8 | 9 | } 10 | -------------------------------------------------------------------------------- /app/src/main/java/magick/StorageType.java: -------------------------------------------------------------------------------- 1 | package magick; 2 | 3 | /** 4 | * Used in MagickImage.createImage to specify the size 5 | * of component. 6 | * 7 | * @author Eric Yeo 8 | */ 9 | public interface StorageType { 10 | 11 | public final static int UndefinedPixel = 0; 12 | public final static int CharPixel = 1; 13 | public final static int DoublePixel = 2; 14 | public final static int FloatPixel = 3; 15 | public final static int IntegerPixel = 4; 16 | public final static int LongPixel = 5; 17 | public final static int QuantumPixel = 6; 18 | public final static int ShortPixel = 7; 19 | 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/magick/TimerState.java: -------------------------------------------------------------------------------- 1 | package magick; 2 | 3 | /** 4 | * Used in MagickImage.createImage to specify the size 5 | * of component. 6 | * 7 | * @author Eric Yeo 8 | */ 9 | public interface TimerState { 10 | 11 | public final int UndefinedTimerState = 0; 12 | public final int StoppedTimerState = 1; 13 | public final int RunningTimerState = 2; 14 | 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/magick/util/Makefile: -------------------------------------------------------------------------------- 1 | include ../../../Make.def 2 | 3 | JAVA_SRC_FILES = \ 4 | DisplayImageMetaData.java \ 5 | MagickCanvas.java \ 6 | MagickViewer.java \ 7 | MagickWindow.java 8 | 9 | include ../../../Make.rules 10 | -------------------------------------------------------------------------------- /app/src/main/java/org/eclipse/paho/android/service/MqttDeliveryTokenAndroid.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 1999, 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | */ 13 | package org.eclipse.paho.android.service; 14 | 15 | import org.eclipse.paho.client.mqttv3.IMqttActionListener; 16 | import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken; 17 | import org.eclipse.paho.client.mqttv3.MqttException; 18 | import org.eclipse.paho.client.mqttv3.MqttMessage; 19 | 20 | /** 21 | *

22 | * Implementation of the IMqttDeliveryToken interface for use from within the 23 | * MqttAndroidClient implementation 24 | */ 25 | class MqttDeliveryTokenAndroid extends MqttTokenAndroid 26 | implements IMqttDeliveryToken { 27 | 28 | // The message which is being tracked by this token 29 | private MqttMessage message; 30 | 31 | MqttDeliveryTokenAndroid(MqttAndroidClient client, 32 | Object userContext, IMqttActionListener listener, MqttMessage message) { 33 | super(client, userContext, listener); 34 | this.message = message; 35 | } 36 | 37 | /** 38 | * @see org.eclipse.paho.client.mqttv3.IMqttDeliveryToken#getMessage() 39 | */ 40 | @Override 41 | public MqttMessage getMessage() throws MqttException { 42 | return message; 43 | } 44 | 45 | void setMessage(MqttMessage message) { 46 | this.message = message; 47 | } 48 | 49 | void notifyDelivery(MqttMessage delivered) { 50 | message = delivered; 51 | super.notifyComplete(); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/org/eclipse/paho/android/service/MqttServiceBinder.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 1999, 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | */ 13 | package org.eclipse.paho.android.service; 14 | 15 | import android.os.Binder; 16 | 17 | /** 18 | * What the Service passes to the Activity on binding:- 19 | *

    20 | *
  • a reference to the Service 21 | *
  • the activityToken provided when the Service was started 22 | *
23 | * 24 | */ 25 | class MqttServiceBinder extends Binder { 26 | 27 | private MqttService mqttService; 28 | private String activityToken; 29 | 30 | MqttServiceBinder(MqttService mqttService) { 31 | this.mqttService = mqttService; 32 | } 33 | 34 | /** 35 | * @return a reference to the Service 36 | */ 37 | public MqttService getService() { 38 | return mqttService; 39 | } 40 | 41 | void setActivityToken(String activityToken) { 42 | this.activityToken = activityToken; 43 | } 44 | 45 | /** 46 | * @return the activityToken provided when the Service was started 47 | */ 48 | public String getActivityToken() { 49 | return activityToken; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /app/src/main/java/org/eclipse/paho/android/service/MqttTraceHandler.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 1999, 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | */ 13 | package org.eclipse.paho.android.service; 14 | 15 | /** 16 | * Interface for simple trace handling, pass the trace message to trace 17 | * callback. 18 | * 19 | */ 20 | 21 | public interface MqttTraceHandler { 22 | 23 | /** 24 | * Trace debugging information 25 | * 26 | * @param tag 27 | * identifier for the source of the trace 28 | * @param message 29 | * the text to be traced 30 | */ 31 | void traceDebug(String tag, String message); 32 | 33 | /** 34 | * Trace error information 35 | * 36 | * @param tag 37 | * identifier for the source of the trace 38 | * @param message 39 | * the text to be traced 40 | */ 41 | void traceError(String tag, String message); 42 | 43 | /** 44 | * trace exceptions 45 | * 46 | * @param tag 47 | * identifier for the source of the trace 48 | * @param message 49 | * the text to be traced 50 | * @param e 51 | * the exception 52 | */ 53 | void traceException(String tag, String message, 54 | Exception e); 55 | 56 | } -------------------------------------------------------------------------------- /app/src/main/java/org/eclipse/paho/android/service/Status.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 1999, 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | */ 13 | package org.eclipse.paho.android.service; 14 | 15 | /** 16 | * Enumeration representing the success or failure of an operation 17 | */ 18 | enum Status { 19 | /** 20 | * Indicates that the operation succeeded 21 | */ 22 | OK, 23 | 24 | /** 25 | * Indicates that the operation failed 26 | */ 27 | ERROR, 28 | 29 | /** 30 | * Indicates that the operation's result may be returned asynchronously 31 | */ 32 | NO_RESULT 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/jniLibs/arm64-v8a/libimagemagick.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/jniLibs/arm64-v8a/libimagemagick.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/armeabi-v7a/libimagemagick.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/jniLibs/armeabi-v7a/libimagemagick.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/armeabi/libimagemagick.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/jniLibs/armeabi/libimagemagick.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/mips/libimagemagick.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/jniLibs/mips/libimagemagick.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/mips64/libimagemagick.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/jniLibs/mips64/libimagemagick.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/x86/libimagemagick.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/jniLibs/x86/libimagemagick.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/x86_64/libimagemagick.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/jniLibs/x86_64/libimagemagick.so -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_down.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_in_left.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_in_right.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_out_left.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_out_right.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_up.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/color/main_bottomnavigationbar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/info_adafruit_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable-hdpi/info_adafruit_logo.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/info_adafruit_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable-mdpi/info_adafruit_logo.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/info_adafruit_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable-xhdpi/info_adafruit_logo.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/pad_arrow_button_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable-xhdpi/pad_arrow_button_down.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/pad_arrow_button_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable-xhdpi/pad_arrow_button_left.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/pad_arrow_button_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable-xhdpi/pad_arrow_button_right.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/pad_arrow_button_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable-xhdpi/pad_arrow_button_up.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/pad_button_numbers_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable-xhdpi/pad_button_numbers_1.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/pad_button_numbers_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable-xhdpi/pad_button_numbers_2.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/pad_button_numbers_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable-xhdpi/pad_button_numbers_3.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/pad_button_numbers_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable-xhdpi/pad_button_numbers_4.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/scanner_adaflower.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable-xhdpi/scanner_adaflower.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/batterylevel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable-xxhdpi/batterylevel.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/imagetransfer_default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable-xxhdpi/imagetransfer_default.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/imagetransfer_rotate_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable-xxhdpi/imagetransfer_rotate_left.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/imagetransfer_rotate_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable-xxhdpi/imagetransfer_rotate_right.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/imagetransfer_test1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable-xxhdpi/imagetransfer_test1.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/imagetransfer_test2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable-xxhdpi/imagetransfer_test2.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/mqtt_connected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable-xxhdpi/mqtt_connected.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/mqtt_connecting1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable-xxhdpi/mqtt_connecting1.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/mqtt_connecting2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable-xxhdpi/mqtt_connecting2.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/mqtt_connecting3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable-xxhdpi/mqtt_connecting3.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/mqtt_disconnected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable-xxhdpi/mqtt_disconnected.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/tab_calibration_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable-xxhdpi/tab_calibration_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/tab_circuitpython_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable-xxhdpi/tab_circuitpython_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/tab_controller_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable-xxhdpi/tab_controller_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/tab_dfu_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable-xxhdpi/tab_dfu_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/tab_imagetransfer_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable-xxhdpi/tab_imagetransfer_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/tab_info_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable-xxhdpi/tab_info_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/tab_neopixel_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable-xxhdpi/tab_neopixel_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/tab_pinio_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable-xxhdpi/tab_pinio_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/tab_plotter_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable-xxhdpi/tab_plotter_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/tab_thermalcamera_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable-xxhdpi/tab_thermalcamera_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/tab_uart_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable-xxhdpi/tab_uart_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/disclosure_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable-xxxhdpi/disclosure_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/about_message_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/border_gray.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/border_white.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_cancel_black_18dp.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_expand_more_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_info_outline_white_24dp.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_more_vert_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_notifications_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_pie_chart_outlined_white_24dp.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_rotate_right_white_36dp.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_select_all_white_36dp.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_settings_white_24dp.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_speaker_phone_white_24dp.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_tap_and_play_white_24dp.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/neopixel_colorpicker_border_black.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/neopixel_led.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/neopixel_palettecolor.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/neopixel_palettecolor_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/roundedborders_blue.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/roundedborders_border_black.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/roundedborders_gray.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/roundedbutton.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/scanresult_advertisementbackground.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/signalstrength0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable/signalstrength0.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/signalstrength1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable/signalstrength1.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/signalstrength2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable/signalstrength2.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/signalstrength3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable/signalstrength3.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/signalstrength4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Bluefruit_LE_Connect_Android_V2/442501b2b418baa80033df006b82e53df6a01369/app/src/main/res/drawable/signalstrength4.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/simpledivideritemdecoration.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/splash_screen.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | 11 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/layout/dialog_imagetransfer_chooseresolution.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 16 | 17 | 21 | 22 | 26 | 27 | 28 | 29 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_about.xml: -------------------------------------------------------------------------------- 1 | 13 | 14 | 18 | 19 | 23 | 24 | 30 | 31 | 38 | 39 | 40 | 53 | 54 | 61 | 62 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_commonhelp.xml: -------------------------------------------------------------------------------- 1 | 13 | 14 | 20 | 21 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_controller.xml: -------------------------------------------------------------------------------- 1 | 11 | 12 | 21 | 22 | 28 | 29 | 37 | 38 | 39 | 47 | 48 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_deviceinformationservice.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_dfu.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 14 | 15 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_imagecrop.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 23 | 24 |