Skip to content

flutter 3.32.2 tested on Android #49

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
include: package:pedantic/analysis_options.1.11.0.yaml
include: package:flutter_lints/flutter.yaml
analyzer:
errors:
constant_identifier_names: ignore
56 changes: 35 additions & 21 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,53 +4,71 @@ group 'com.michaeljperri.flutter_sequencer'
version '1.0-SNAPSHOT'

buildscript {
ext.kotlin_version = '1.5.21'
ext.kotlin_version = '1.9.10'
repositories {
google()
mavenCentral()
}

dependencies {
classpath 'com.android.tools.build:gradle:4.1.2'
classpath 'com.android.tools.build:gradle:8.6.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.eclipse.jgit:org.eclipse.jgit:5.12.0+"
classpath "org.eclipse.jgit:org.eclipse.jgit:7.0.0.202409031743-r"
}
}

rootProject.allprojects {
repositories {
google()
mavenCentral()
}
}

apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'

android {
compileSdkVersion 29
namespace "com.michaeljperri.flutter_sequencer"

compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_17.toString()
}

compileSdk = 35
ndkVersion = "27.0.12077973"

sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}

defaultConfig {
minSdkVersion 16
minSdk 23

externalNativeBuild {
cmake {
cppFlags '-std=c++17', '-frelaxed-template-template-args'
arguments "-DCMAKE_CXX_STANDARD=17", "-DCMAKE_CXX_STANDARD_REQUIRED=ON"
cppFlags '-frelaxed-template-template-args'
}
}

ndk {
abiFilters "arm64-v8a"
}
}
lintOptions {
disable 'InvalidPackage'
}
ndkVersion "22.1.7171670"

externalNativeBuild {
cmake {
version "3.18.1"
path "CMakeLists.txt"
}
}

}

void cloneThirdPartyRepo(String name, String uri, String commit) {
Expand All @@ -60,12 +78,12 @@ void cloneThirdPartyRepo(String name, String uri, String commit) {
if (!dir.exists()) {
dir.mkdirs()
def repo =
Git.cloneRepository()
.setDirectory(dir)
.setURI(uri)
.setRemote('origin')
.setCloneSubmodules(true)
.call()
Git.cloneRepository()
.setDirectory(dir)
.setURI(uri)
.setRemote('origin')
.setCloneSubmodules(true)
.call()

repo.checkout().setName(commit).call()
repo.submoduleUpdate()
Expand All @@ -74,13 +92,9 @@ void cloneThirdPartyRepo(String name, String uri, String commit) {
}

task cloneThirdPartyRepos {
cloneThirdPartyRepo('oboe', 'https://github.com/google/oboe', '06ec23e4f6bc00ba7eea9b84e299f9200a598838')
cloneThirdPartyRepo('TinySoundFont', 'https://github.com/schellingb/TinySoundFont.git', 'bf574519e601202c3a9d27a74f345921277eed39')
cloneThirdPartyRepo('sfizz', 'https://github.com/sfztools/sfizz.git', 'fc1f0451cebd8996992cbc4f983fcf76b03295c5')
cloneThirdPartyRepo('oboe', 'https://github.com/google/oboe', 'e40043061cc94df965fda802938b0989f201e86c')
cloneThirdPartyRepo('TinySoundFont', 'https://github.com/schellingb/TinySoundFont.git', '790a219810cb0fca5defa8cdbd88e2487e5efc7a')
cloneThirdPartyRepo('sfizz', 'https://github.com/PROGrand/sfizz.git', 'a5cacdb0abdcabfd3ff1d302d7a2e8784627e340')
}

preBuild.dependsOn cloneThirdPartyRepos

dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}
2 changes: 1 addition & 1 deletion android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-all.zip
3 changes: 1 addition & 2 deletions android/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.michaeljperri.flutter_sequencer">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
</manifest>
Original file line number Diff line number Diff line change
@@ -1,130 +1,109 @@
package com.michaeljperri.flutter_sequencer

import android.content.Context
import android.content.res.AssetManager;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat

import android.content.res.AssetManager
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
import io.flutter.plugin.common.PluginRegistry.Registrar
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.net.URLDecoder

const val flutterAssetRoot = "flutter_assets"

/** FlutterSequencerPlugin */
public class FlutterSequencerPlugin: FlutterPlugin, MethodCallHandler {
/// The MethodChannel that will the communication between Flutter and native Android
///
/// This local reference serves to register the plugin with the Flutter Engine and unregister it
/// when the Flutter Engine is detached from the Activity
private lateinit var channel : MethodChannel

override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
channel = MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), "flutter_sequencer")
channel.setMethodCallHandler(this);
context = flutterPluginBinding.applicationContext
}

// This static function is optional and equivalent to onAttachedToEngine. It supports the old
// pre-Flutter-1.12 Android projects. You are encouraged to continue supporting
// plugin registration via this function while apps migrate to use the new Android APIs
// post-flutter-1.12 via https://flutter.dev/go/android-project-migration.
//
// It is encouraged to share logic between onAttachedToEngine and registerWith to keep
// them functionally equivalent. Only one of onAttachedToEngine or registerWith will be called
// depending on the user's project. onAttachedToEngine or registerWith must both be defined
// in the same class.
companion object {
private lateinit var context : Context

@JvmStatic
fun registerWith(registrar: Registrar) {
val channel = MethodChannel(registrar.messenger(), "flutter_sequencer")
channel.setMethodCallHandler(FlutterSequencerPlugin())
context = registrar.context()
class FlutterSequencerPlugin : FlutterPlugin, MethodCallHandler {
/// The MethodChannel that will the communication between Flutter and native Android
///
/// This local reference serves to register the plugin with the Flutter Engine and unregister it
/// when the Flutter Engine is detached from the Activity
private lateinit var channel: MethodChannel

private lateinit var context: Context

override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
channel = MethodChannel(flutterPluginBinding.binaryMessenger, "flutter_sequencer")
channel.setMethodCallHandler(this)
context = flutterPluginBinding.applicationContext
}

init {
System.loadLibrary("flutter_sequencer")
companion object {
init {
System.loadLibrary("flutter_sequencer")
}
}
}

override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
if (call.method == "getPlatformVersion") {
result.success("Android ${android.os.Build.VERSION.RELEASE}")
} else if (call.method == "setupAssetManager") {
setupAssetManager(context.assets)
result.success(null)
} else if (call.method == "normalizeAssetDir") {
val assetDir = call.argument<String>("assetDir")!!
val filesDir = context.filesDir
val isSuccess = copyAssetDirOrFile(assetDir, filesDir)

if (isSuccess) {
val copiedDir = filesDir.resolve(assetDir).absolutePath
result.success(copiedDir)
} else {
result.success(null)
}
} else if (call.method == "listAudioUnits") {
result.success(emptyList<String>())
} else {
result.notImplemented()

override fun onMethodCall(call: MethodCall, result: Result) {
if (call.method == "getPlatformVersion") {
result.success("Android ${android.os.Build.VERSION.RELEASE}")
} else if (call.method == "setupAssetManager") {
setupAssetManager(context.assets)
result.success(null)
} else if (call.method == "normalizeAssetDir") {
val assetDir = call.argument<String>("assetDir")!!
val filesDir = context.filesDir
val isSuccess = copyAssetDirOrFile(assetDir, filesDir)

if (isSuccess) {
val copiedDir = filesDir.resolve(assetDir).absolutePath
result.success(copiedDir)
} else {
result.success(null)
}
} else if (call.method == "listAudioUnits") {
result.success(emptyList<String>())
} else {
result.notImplemented()
}
}
}

override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
channel.setMethodCallHandler(null)
}

private fun copyAssetFile(assetFilePath: String, outputDir: File): Boolean {
val inputStream = context.assets.open("$flutterAssetRoot/$assetFilePath")
val decodedAssetFilePath = URLDecoder.decode(assetFilePath, "UTF-8")
val outputFile = outputDir.resolve(decodedAssetFilePath)
var outputStream: FileOutputStream? = null

try {
outputFile.parentFile.mkdirs()
outputFile.createNewFile()

outputStream = FileOutputStream(outputFile)
inputStream.copyTo(outputStream, 1024)
} catch (e: SecurityException) {
return false;
} catch (e: java.io.IOException) {
return false;
} finally {
inputStream.close()
outputStream?.flush()
outputStream?.close()

override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
channel.setMethodCallHandler(null)
}

return true;
}

private fun copyAssetDirOrFile(assetPath: String, outputDir: File): Boolean {
val paths = context.assets.list("$flutterAssetRoot/$assetPath")!!
var isSuccess = true;

if (paths.isEmpty()) {
// It's a file.
isSuccess = isSuccess && copyAssetFile(assetPath, outputDir)
} else {
// It's a directory.
paths.forEach {
isSuccess = isSuccess && copyAssetDirOrFile("$assetPath/$it", outputDir)
}
private fun copyAssetFile(assetFilePath: String, outputDir: File): Boolean {
val inputStream = context.assets.open("$flutterAssetRoot/$assetFilePath")
val decodedAssetFilePath = URLDecoder.decode(assetFilePath, "UTF-8")
val outputFile = outputDir.resolve(decodedAssetFilePath)
var outputStream: FileOutputStream? = null

try {
outputFile.parentFile!!.mkdirs()
outputFile.createNewFile()

outputStream = FileOutputStream(outputFile)
inputStream.copyTo(outputStream, 1024)
} catch (e: SecurityException) {
return false
} catch (e: java.io.IOException) {
return false
} finally {
inputStream.close()
outputStream?.flush()
outputStream?.close()
}

return true
}

return isSuccess
}
private fun copyAssetDirOrFile(assetPath: String, outputDir: File): Boolean {
val paths = context.assets.list("$flutterAssetRoot/$assetPath")!!
var isSuccess = true

if (paths.isEmpty()) {
// It's a file.
isSuccess = isSuccess && copyAssetFile(assetPath, outputDir)
} else {
// It's a directory.
paths.forEach {
isSuccess = isSuccess && copyAssetDirOrFile("$assetPath/$it", outputDir)
}
}

return isSuccess
}

private external fun setupAssetManager(assetManager: AssetManager)
private external fun setupAssetManager(assetManager: AssetManager)
}
4 changes: 4 additions & 0 deletions example/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
include: package:flutter_lints/flutter.yaml
analyzer:
errors:
constant_identifier_names: ignore
Loading