Migrate android native code to plugin

This commit is contained in:
Ming Ming 2022-03-11 22:44:43 +08:00
parent a4dfe29e92
commit c94c2708db
31 changed files with 348 additions and 32 deletions

View file

@ -45,7 +45,7 @@
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:authorities="com.nkming.nc_photos.plugin.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data

View file

@ -2,9 +2,6 @@ package com.nkming.nc_photos
interface K {
companion object {
const val DOWNLOAD_NOTIFICATION_ID_MIN = 1000
const val DOWNLOAD_NOTIFICATION_ID_MAX = 2000
const val ACTION_DOWNLOAD_CANCEL = "com.nkming.nc_photos.ACTION_DOWNLOAD_CANCEL"
const val EXTRA_NOTIFICATION_ID = "com.nkming.nc_photos.EXTRA_NOTIFICATION_ID"

View file

@ -12,9 +12,6 @@ class MainActivity : FlutterActivity() {
MethodChannel(flutterEngine.dartExecutor.binaryMessenger,
MediaStoreChannelHandler.CHANNEL).setMethodCallHandler(
MediaStoreChannelHandler(this))
MethodChannel(flutterEngine.dartExecutor.binaryMessenger,
NotificationChannelHandler.CHANNEL).setMethodCallHandler(
NotificationChannelHandler(this))
MethodChannel(flutterEngine.dartExecutor.binaryMessenger,
SelfSignedCertChannelHandler.CHANNEL).setMethodCallHandler(
SelfSignedCertChannelHandler(this))

View file

@ -138,7 +138,7 @@ class MediaStoreChannelHandler(activity: Activity) :
val fileUri = Uri.fromFile(file)
triggerMediaScan(fileUri)
val contentUri = FileProvider.getUriForFile(
_context, "${BuildConfig.APPLICATION_ID}.fileprovider", file
_context, "com.nkming.nc_photos.plugin.fileprovider", file
)
result.success(contentUri.toString())
}

View file

@ -2,15 +2,6 @@
<resources>
<string name="app_name">Photos</string>
<string name="download_notification_channel_name">Download</string>
<string name="download_notification_channel_description">Download</string>
<string name="download_successful_notification_title">Download was successful</string>
<string name="download_successful_notification_text">Tap to view your downloaded item</string>
<string name="download_successful_notification_action_share">SHARE</string>
<string name="download_successful_notification_action_share_chooser">Share with:</string>
<string name="download_multiple_successful_notification_title">Downloaded %1$d items successfully</string>
<string name="download_progress_notification_text">Downloading %1$s</string>
<string name="download_progress_notification_untitled_text">Downloading</string>
<string name="log_save_successful_notification_title">Logs saved successfully</string>
<string name="log_save_successful_notification_text">Tap to view your saved logs</string>
</resources>

View file

@ -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<String> fileUris;
final List<String?> mimeTypes;
@ -26,7 +26,7 @@ class AndroidDownloadProgressNotification extends _AndroidNotification {
});
@override
doNotify() => Notification.notifyDownloadProgress(
doNotify() => plugin.Notification.notifyDownloadProgress(
progress, max, currentItemTitle, notificationId);
Future<void> 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!);
}
}

View file

@ -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:

View file

@ -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

46
plugin/.gitignore vendored Normal file
View file

@ -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*

10
plugin/.metadata Normal file
View file

@ -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

View file

@ -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

8
plugin/android/.gitignore vendored Normal file
View file

@ -0,0 +1,8 @@
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures

View file

@ -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"
}

View file

@ -0,0 +1,3 @@
org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true

View file

@ -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

View file

@ -0,0 +1 @@
rootProject.name = 'plugin'

View file

@ -0,0 +1,3 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.nkming.nc_photos.plugin">
</manifest>

View file

@ -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"
}
}

View file

@ -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
}

View file

@ -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<String>,
* mimeTypes: List<String>): 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
}

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="download_notification_channel_name">Download</string>
<string name="download_notification_channel_description">Download</string>
<string name="download_successful_notification_title">Download was successful</string>
<string name="download_successful_notification_text">Tap to view your downloaded item</string>
<string name="download_successful_notification_action_share">SHARE</string>
<string name="download_successful_notification_action_share_chooser">Share with:</string>
<string name="download_multiple_successful_notification_title">Downloaded %1$d items successfully</string>
<string name="download_progress_notification_text">Downloading %1$s</string>
<string name="download_progress_notification_untitled_text">Downloading</string>
<string name="log_save_successful_notification_title">Logs saved successfully</string>
<string name="log_save_successful_notification_text">Tap to view your saved logs</string>
</resources>

View file

@ -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");
}

65
plugin/pubspec.lock Normal file
View file

@ -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"

61
plugin/pubspec.yaml Normal file
View file

@ -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