From c94c2708db7de4981b1c29d25012e3cc4ce719b9 Mon Sep 17 00:00:00 2001 From: Ming Ming Date: Fri, 11 Mar 2022 22:44:43 +0800 Subject: [PATCH] Migrate android native code to plugin --- app/LICENSE => LICENSE | 0 app/README.md => README.md | 0 app/android/app/src/main/AndroidManifest.xml | 2 +- .../src/main/kotlin/com/nkming/nc_photos/K.kt | 3 - .../com/nkming/nc_photos/MainActivity.kt | 3 - .../nc_photos/MediaStoreChannelHandler.kt | 2 +- .../app/src/main/res/values/strings.xml | 9 --- app/lib/mobile/notification.dart | 12 ++-- app/pubspec.lock | 7 ++ app/pubspec.yaml | 2 + plugin/.gitignore | 46 +++++++++++++ plugin/.metadata | 10 +++ plugin/analysis_options.yaml | 4 ++ plugin/android/.gitignore | 8 +++ plugin/android/build.gradle | 58 ++++++++++++++++ plugin/android/gradle.properties | 3 + .../gradle/wrapper/gradle-wrapper.properties | 5 ++ plugin/android/settings.gradle | 1 + plugin/android/src/main/AndroidManifest.xml | 3 + .../kotlin/com/nkming/nc_photos/plugin/K.kt | 14 ++++ .../nkming/nc_photos/plugin/NcPhotosPlugin.kt | 29 ++++++++ .../plugin}/NotificationChannelHandler.kt | 14 ++-- .../baseline_download_white_18.png | Bin .../baseline_download_white_18.png | Bin .../baseline_download_white_18.png | Bin .../baseline_download_white_18.png | Bin .../baseline_download_white_18.png | Bin .../android/src/main/res/values/strings.xml | 14 ++++ .../lib/nc_photos_plugin.dart | 5 +- plugin/pubspec.lock | 65 ++++++++++++++++++ plugin/pubspec.yaml | 61 ++++++++++++++++ 31 files changed, 348 insertions(+), 32 deletions(-) rename app/LICENSE => LICENSE (100%) rename app/README.md => README.md (100%) create mode 100644 plugin/.gitignore create mode 100644 plugin/.metadata create mode 100644 plugin/analysis_options.yaml create mode 100644 plugin/android/.gitignore create mode 100644 plugin/android/build.gradle create mode 100644 plugin/android/gradle.properties create mode 100644 plugin/android/gradle/wrapper/gradle-wrapper.properties create mode 100644 plugin/android/settings.gradle create mode 100644 plugin/android/src/main/AndroidManifest.xml create mode 100644 plugin/android/src/main/kotlin/com/nkming/nc_photos/plugin/K.kt create mode 100644 plugin/android/src/main/kotlin/com/nkming/nc_photos/plugin/NcPhotosPlugin.kt rename {app/android/app/src/main/kotlin/com/nkming/nc_photos => plugin/android/src/main/kotlin/com/nkming/nc_photos/plugin}/NotificationChannelHandler.kt (96%) rename {app/android/app => plugin/android}/src/main/res/drawable-hdpi/baseline_download_white_18.png (100%) rename {app/android/app => plugin/android}/src/main/res/drawable-mdpi/baseline_download_white_18.png (100%) rename {app/android/app => plugin/android}/src/main/res/drawable-xhdpi/baseline_download_white_18.png (100%) rename {app/android/app => plugin/android}/src/main/res/drawable-xxhdpi/baseline_download_white_18.png (100%) rename {app/android/app => plugin/android}/src/main/res/drawable-xxxhdpi/baseline_download_white_18.png (100%) create mode 100644 plugin/android/src/main/res/values/strings.xml rename app/lib/mobile/android/notification.dart => plugin/lib/nc_photos_plugin.dart (90%) create mode 100644 plugin/pubspec.lock create mode 100644 plugin/pubspec.yaml diff --git a/app/LICENSE b/LICENSE similarity index 100% rename from app/LICENSE rename to LICENSE diff --git a/app/README.md b/README.md similarity index 100% rename from app/README.md rename to README.md diff --git a/app/android/app/src/main/AndroidManifest.xml b/app/android/app/src/main/AndroidManifest.xml index c53da564..8c12b50e 100644 --- a/app/android/app/src/main/AndroidManifest.xml +++ b/app/android/app/src/main/AndroidManifest.xml @@ -45,7 +45,7 @@ Photos - Download - Download - Download was successful - Tap to view your downloaded item SHARE Share with: - Downloaded %1$d items successfully - Downloading %1$s - Downloading - Logs saved successfully - Tap to view your saved logs diff --git a/app/lib/mobile/notification.dart b/app/lib/mobile/notification.dart index 8ca575b8..1e9d52a0 100644 --- a/app/lib/mobile/notification.dart +++ b/app/lib/mobile/notification.dart @@ -1,6 +1,6 @@ import 'package:flutter/foundation.dart'; -import 'package:nc_photos/mobile/android/notification.dart'; import 'package:nc_photos/platform/notification.dart' as itf; +import 'package:nc_photos_plugin/nc_photos_plugin.dart' as plugin; class AndroidDownloadSuccessfulNotification extends _AndroidNotification { AndroidDownloadSuccessfulNotification( @@ -10,8 +10,8 @@ class AndroidDownloadSuccessfulNotification extends _AndroidNotification { }) : replaceId = notificationId; @override - doNotify() => - Notification.notifyDownloadSuccessful(fileUris, mimeTypes, replaceId); + doNotify() => plugin.Notification.notifyDownloadSuccessful( + fileUris, mimeTypes, replaceId); final List fileUris; final List mimeTypes; @@ -26,7 +26,7 @@ class AndroidDownloadProgressNotification extends _AndroidNotification { }); @override - doNotify() => Notification.notifyDownloadProgress( + doNotify() => plugin.Notification.notifyDownloadProgress( progress, max, currentItemTitle, notificationId); Future update( @@ -47,7 +47,7 @@ class AndroidLogSaveSuccessfulNotification extends _AndroidNotification { AndroidLogSaveSuccessfulNotification(this.fileUri); @override - doNotify() => Notification.notifyLogSaveSuccessful(fileUri); + doNotify() => plugin.Notification.notifyLogSaveSuccessful(fileUri); final String fileUri; } @@ -61,7 +61,7 @@ abstract class _AndroidNotification extends itf.Notification { @override dismiss() async { if (notificationId != null) { - await Notification.dismiss(notificationId!); + await plugin.Notification.dismiss(notificationId!); } } diff --git a/app/pubspec.lock b/app/pubspec.lock index 91a4bffb..7fde0b69 100644 --- a/app/pubspec.lock +++ b/app/pubspec.lock @@ -582,6 +582,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.0" + nc_photos_plugin: + dependency: "direct main" + description: + path: "../plugin" + relative: true + source: path + version: "0.0.1" nested: dependency: transitive description: diff --git a/app/pubspec.yaml b/app/pubspec.yaml index 9c8a51ed..8dd07518 100644 --- a/app/pubspec.yaml +++ b/app/pubspec.yaml @@ -66,6 +66,8 @@ dependencies: logging: ^1.0.1 mutex: ^3.0.0 native_device_orientation: ^1.0.0 + nc_photos_plugin: + path: ../plugin page_view_indicators: ^2.0.0 path: ^1.8.0 path_provider: ^2.0.6 diff --git a/plugin/.gitignore b/plugin/.gitignore new file mode 100644 index 00000000..5ed1214c --- /dev/null +++ b/plugin/.gitignore @@ -0,0 +1,46 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +.vscode/ +*.code-workspace + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Web related +lib/generated_plugin_registrant.dart + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/free* +/android/app/paid* diff --git a/plugin/.metadata b/plugin/.metadata new file mode 100644 index 00000000..5bed5265 --- /dev/null +++ b/plugin/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: 18116933e77adc82f80866c928266a5b4f1ed645 + channel: stable + +project_type: plugin diff --git a/plugin/analysis_options.yaml b/plugin/analysis_options.yaml new file mode 100644 index 00000000..a5744c1c --- /dev/null +++ b/plugin/analysis_options.yaml @@ -0,0 +1,4 @@ +include: package:flutter_lints/flutter.yaml + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/plugin/android/.gitignore b/plugin/android/.gitignore new file mode 100644 index 00000000..c6cbe562 --- /dev/null +++ b/plugin/android/.gitignore @@ -0,0 +1,8 @@ +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures diff --git a/plugin/android/build.gradle b/plugin/android/build.gradle new file mode 100644 index 00000000..d3b8ae1a --- /dev/null +++ b/plugin/android/build.gradle @@ -0,0 +1,58 @@ +group 'com.nkming.nc_photos.plugin' +version '1.0-SNAPSHOT' + +buildscript { + ext.kotlin_version = '1.6.10' + repositories { + google() + mavenCentral() + } + + dependencies { + classpath 'com.android.tools.build:gradle:7.0.4' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +rootProject.allprojects { + repositories { + google() + mavenCentral() + } +} + +apply plugin: 'com.android.library' +apply plugin: 'kotlin-android' + +android { + compileSdkVersion 30 + + compileOptions { + coreLibraryDesugaringEnabled true + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + kotlinOptions { + jvmTarget = '1.8' + } + + lintOptions { + disable 'LongLogTag' + } + + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + } + + defaultConfig { + minSdkVersion 21 + } +} + +dependencies { + coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.1.5" + implementation "androidx.annotation:annotation:1.3.0" + implementation "androidx.core:core-ktx:1.7.0" + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" +} diff --git a/plugin/android/gradle.properties b/plugin/android/gradle.properties new file mode 100644 index 00000000..94adc3a3 --- /dev/null +++ b/plugin/android/gradle.properties @@ -0,0 +1,3 @@ +org.gradle.jvmargs=-Xmx1536M +android.useAndroidX=true +android.enableJetifier=true diff --git a/plugin/android/gradle/wrapper/gradle-wrapper.properties b/plugin/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..297f2fec --- /dev/null +++ b/plugin/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip diff --git a/plugin/android/settings.gradle b/plugin/android/settings.gradle new file mode 100644 index 00000000..b90f0d3f --- /dev/null +++ b/plugin/android/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'plugin' diff --git a/plugin/android/src/main/AndroidManifest.xml b/plugin/android/src/main/AndroidManifest.xml new file mode 100644 index 00000000..7b1d1a3b --- /dev/null +++ b/plugin/android/src/main/AndroidManifest.xml @@ -0,0 +1,3 @@ + + diff --git a/plugin/android/src/main/kotlin/com/nkming/nc_photos/plugin/K.kt b/plugin/android/src/main/kotlin/com/nkming/nc_photos/plugin/K.kt new file mode 100644 index 00000000..88f6f329 --- /dev/null +++ b/plugin/android/src/main/kotlin/com/nkming/nc_photos/plugin/K.kt @@ -0,0 +1,14 @@ +package com.nkming.nc_photos.plugin + +interface K { + companion object { + const val DOWNLOAD_NOTIFICATION_ID_MIN = 1000 + const val DOWNLOAD_NOTIFICATION_ID_MAX = 2000 + + const val LIB_ID = "com.nkming.nc_photos.plugin" + + const val ACTION_DOWNLOAD_CANCEL = "com.nkming.nc_photos.ACTION_DOWNLOAD_CANCEL" + + const val EXTRA_NOTIFICATION_ID = "com.nkming.nc_photos.EXTRA_NOTIFICATION_ID" + } +} diff --git a/plugin/android/src/main/kotlin/com/nkming/nc_photos/plugin/NcPhotosPlugin.kt b/plugin/android/src/main/kotlin/com/nkming/nc_photos/plugin/NcPhotosPlugin.kt new file mode 100644 index 00000000..f573bd27 --- /dev/null +++ b/plugin/android/src/main/kotlin/com/nkming/nc_photos/plugin/NcPhotosPlugin.kt @@ -0,0 +1,29 @@ +package com.nkming.nc_photos.plugin + +import androidx.annotation.NonNull +import io.flutter.embedding.engine.plugins.FlutterPlugin +import io.flutter.plugin.common.MethodChannel + +class NcPhotosPlugin : FlutterPlugin { + override fun onAttachedToEngine( + @NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding + ) { + notificationChannel = MethodChannel( + flutterPluginBinding.binaryMessenger, + NotificationChannelHandler.CHANNEL + ) + notificationChannel.setMethodCallHandler( + NotificationChannelHandler( + flutterPluginBinding.applicationContext + ) + ) + } + + override fun onDetachedFromEngine( + @NonNull binding: FlutterPlugin.FlutterPluginBinding + ) { + notificationChannel.setMethodCallHandler(null) + } + + private lateinit var notificationChannel: MethodChannel +} diff --git a/app/android/app/src/main/kotlin/com/nkming/nc_photos/NotificationChannelHandler.kt b/plugin/android/src/main/kotlin/com/nkming/nc_photos/plugin/NotificationChannelHandler.kt similarity index 96% rename from app/android/app/src/main/kotlin/com/nkming/nc_photos/NotificationChannelHandler.kt rename to plugin/android/src/main/kotlin/com/nkming/nc_photos/plugin/NotificationChannelHandler.kt index d5486389..fa6e09a7 100644 --- a/app/android/app/src/main/kotlin/com/nkming/nc_photos/NotificationChannelHandler.kt +++ b/plugin/android/src/main/kotlin/com/nkming/nc_photos/plugin/NotificationChannelHandler.kt @@ -1,6 +1,5 @@ -package com.nkming.nc_photos +package com.nkming.nc_photos.plugin -import android.app.Activity import android.app.NotificationChannel import android.app.NotificationManager import android.app.PendingIntent @@ -25,10 +24,10 @@ import kotlin.math.max * fun notifyItemsDownloadSuccessful(fileUris: List, * mimeTypes: List): Unit */ -class NotificationChannelHandler(activity: Activity) : +class NotificationChannelHandler(context: Context) : MethodChannel.MethodCallHandler { companion object { - const val CHANNEL = "com.nkming.nc_photos/notification" + const val CHANNEL = "${K.LIB_ID}/notification" fun getNextNotificationId(): Int { if (++notificationId >= K.DOWNLOAD_NOTIFICATION_ID_MAX) { @@ -42,7 +41,7 @@ class NotificationChannelHandler(activity: Activity) : } init { - createDownloadChannel(activity) + createDownloadChannel(context) } override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { @@ -217,7 +216,7 @@ class NotificationChannelHandler(activity: Activity) : } val cancelIntent = Intent().apply { - `package` = BuildConfig.APPLICATION_ID + `package` = _context.packageName action = K.ACTION_DOWNLOAD_CANCEL putExtra(K.EXTRA_NOTIFICATION_ID, id) } @@ -337,6 +336,5 @@ class NotificationChannelHandler(activity: Activity) : } } - private val _activity = activity - private val _context get() = _activity + private val _context = context } diff --git a/app/android/app/src/main/res/drawable-hdpi/baseline_download_white_18.png b/plugin/android/src/main/res/drawable-hdpi/baseline_download_white_18.png similarity index 100% rename from app/android/app/src/main/res/drawable-hdpi/baseline_download_white_18.png rename to plugin/android/src/main/res/drawable-hdpi/baseline_download_white_18.png diff --git a/app/android/app/src/main/res/drawable-mdpi/baseline_download_white_18.png b/plugin/android/src/main/res/drawable-mdpi/baseline_download_white_18.png similarity index 100% rename from app/android/app/src/main/res/drawable-mdpi/baseline_download_white_18.png rename to plugin/android/src/main/res/drawable-mdpi/baseline_download_white_18.png diff --git a/app/android/app/src/main/res/drawable-xhdpi/baseline_download_white_18.png b/plugin/android/src/main/res/drawable-xhdpi/baseline_download_white_18.png similarity index 100% rename from app/android/app/src/main/res/drawable-xhdpi/baseline_download_white_18.png rename to plugin/android/src/main/res/drawable-xhdpi/baseline_download_white_18.png diff --git a/app/android/app/src/main/res/drawable-xxhdpi/baseline_download_white_18.png b/plugin/android/src/main/res/drawable-xxhdpi/baseline_download_white_18.png similarity index 100% rename from app/android/app/src/main/res/drawable-xxhdpi/baseline_download_white_18.png rename to plugin/android/src/main/res/drawable-xxhdpi/baseline_download_white_18.png diff --git a/app/android/app/src/main/res/drawable-xxxhdpi/baseline_download_white_18.png b/plugin/android/src/main/res/drawable-xxxhdpi/baseline_download_white_18.png similarity index 100% rename from app/android/app/src/main/res/drawable-xxxhdpi/baseline_download_white_18.png rename to plugin/android/src/main/res/drawable-xxxhdpi/baseline_download_white_18.png diff --git a/plugin/android/src/main/res/values/strings.xml b/plugin/android/src/main/res/values/strings.xml new file mode 100644 index 00000000..7a9e31fa --- /dev/null +++ b/plugin/android/src/main/res/values/strings.xml @@ -0,0 +1,14 @@ + + + Download + Download + Download was successful + Tap to view your downloaded item + SHARE + Share with: + Downloaded %1$d items successfully + Downloading %1$s + Downloading + Logs saved successfully + Tap to view your saved logs + diff --git a/app/lib/mobile/android/notification.dart b/plugin/lib/nc_photos_plugin.dart similarity index 90% rename from app/lib/mobile/android/notification.dart rename to plugin/lib/nc_photos_plugin.dart index 099d654a..a023cf4c 100644 --- a/app/lib/mobile/android/notification.dart +++ b/plugin/lib/nc_photos_plugin.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:flutter/services.dart'; class Notification { @@ -28,5 +30,6 @@ class Notification { "notificationId": notificationId, }); - static const _channel = MethodChannel("com.nkming.nc_photos/notification"); + static const _channel = + MethodChannel("com.nkming.nc_photos.plugin/notification"); } diff --git a/plugin/pubspec.lock b/plugin/pubspec.lock new file mode 100644 index 00000000..21fac38b --- /dev/null +++ b/plugin/pubspec.lock @@ -0,0 +1,65 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + characters: + dependency: transitive + description: + name: characters + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + collection: + dependency: transitive + description: + name: collection + url: "https://pub.dartlang.org" + source: hosted + version: "1.15.0" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" + lints: + dependency: transitive + description: + name: lints + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" + meta: + dependency: transitive + description: + name: meta + url: "https://pub.dartlang.org" + source: hosted + version: "1.7.0" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.0" + vector_math: + dependency: transitive + description: + name: vector_math + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" +sdks: + dart: ">=2.14.0 <3.0.0" + flutter: ">=1.20.0" diff --git a/plugin/pubspec.yaml b/plugin/pubspec.yaml new file mode 100644 index 00000000..48d8becf --- /dev/null +++ b/plugin/pubspec.yaml @@ -0,0 +1,61 @@ +name: nc_photos_plugin +description: A new flutter plugin project. +version: 0.0.1 +homepage: + +environment: + sdk: ">=2.14.0 <3.0.0" + flutter: ">=1.20.0" + +dependencies: + flutter: + sdk: flutter + +dev_dependencies: + flutter_lints: ^1.0.0 + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + # This section identifies this Flutter project as a plugin project. + # The 'pluginClass' and Android 'package' identifiers should not ordinarily + # be modified. They are used by the tooling to maintain consistency when + # adding or updating assets for this project. + plugin: + platforms: + android: + package: com.nkming.nc_photos.plugin + pluginClass: NcPhotosPlugin + + # To add assets to your plugin package, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + # + # For details regarding assets in packages, see + # https://flutter.dev/assets-and-images/#from-packages + # + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # To add custom fonts to your plugin package, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts in packages, see + # https://flutter.dev/custom-fonts/#from-packages