diff --git a/packages/package_info_plus/package_info_plus/CHANGELOG.md b/packages/package_info_plus/package_info_plus/CHANGELOG.md
index 1c6e213a5d..bdfbaba2e0 100644
--- a/packages/package_info_plus/package_info_plus/CHANGELOG.md
+++ b/packages/package_info_plus/package_info_plus/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 1.4.0
+
+- Android: Migrate to Kotlin
+- Android: Update dependencies, build config updates
+- Android: Fix project title
+
## 1.3.1
- Fix embedding issue in example
diff --git a/packages/package_info_plus/package_info_plus/README.md b/packages/package_info_plus/package_info_plus/README.md
index 2469310404..d1d0c2d6c1 100644
--- a/packages/package_info_plus/package_info_plus/README.md
+++ b/packages/package_info_plus/package_info_plus/README.md
@@ -2,11 +2,13 @@
[](https://github.com/fluttercommunity/community)
+[](https://github.com/fluttercommunity/plus_plugins/actions/workflows/package_info_plus.yaml)
[](https://pub.dev/packages/package_info_plus)
-
+
+
This Flutter plugin provides an API for querying information about an
application package.
@@ -24,7 +26,7 @@ application package. This works both on iOS and Android.
```dart
import 'package:package_info_plus/package_info_plus.dart';
-...
+...
// Be sure to add this line if `PackageInfo.fromPlatform()` is called before runApp()
WidgetsFlutterBinding.ensureInitialized();
@@ -54,5 +56,3 @@ Check out our documentation website to learn more. [Plus plugins documentation](
Calling to `PackageInfo.fromPlatform()` before the `runApp()` call will cause an exception.
See https://github.com/fluttercommunity/plus_plugins/issues/309
-
-**Important:** As of January 2021, the Flutter team is no longer accepting non-critical PRs for the original set of plugins in `flutter/plugins`, and instead they should be submitted in this project. [You can read more about this announcement here.](https://github.com/flutter/plugins/blob/master/CONTRIBUTING.md#important-note) as well as [in the Flutter 2 announcement blog post.](https://medium.com/flutter/whats-new-in-flutter-2-0-fe8e95ecc65)
diff --git a/packages/package_info_plus/package_info_plus/android/build.gradle b/packages/package_info_plus/package_info_plus/android/build.gradle
index 632f51b5c0..64cbb1e4ae 100644
--- a/packages/package_info_plus/package_info_plus/android/build.gradle
+++ b/packages/package_info_plus/package_info_plus/android/build.gradle
@@ -2,13 +2,16 @@ group 'io.flutter.plugins.packageinfo'
version '1.0-SNAPSHOT'
buildscript {
+ ext.kotlin_version = '1.6.10'
+
repositories {
google()
mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:7.0.2'
+ classpath 'com.android.tools.build:gradle:7.1.1'
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
@@ -20,6 +23,7 @@ rootProject.allprojects {
}
apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
android {
compileSdkVersion 31
@@ -31,4 +35,8 @@ android {
lintOptions {
disable 'InvalidPackage'
}
+
+ dependencies {
+ implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
+ }
}
diff --git a/packages/package_info_plus/package_info_plus/android/settings.gradle b/packages/package_info_plus/package_info_plus/android/settings.gradle
index a5683f94fc..50f50a6b45 100644
--- a/packages/package_info_plus/package_info_plus/android/settings.gradle
+++ b/packages/package_info_plus/package_info_plus/android/settings.gradle
@@ -1 +1 @@
-rootProject.name = 'package_info'
+rootProject.name = 'package_info_plus'
diff --git a/packages/package_info_plus/package_info_plus/android/src/main/java/dev/fluttercommunity/plus/packageinfo/PackageInfoPlugin.java b/packages/package_info_plus/package_info_plus/android/src/main/java/dev/fluttercommunity/plus/packageinfo/PackageInfoPlugin.java
deleted file mode 100644
index 317f363340..0000000000
--- a/packages/package_info_plus/package_info_plus/android/src/main/java/dev/fluttercommunity/plus/packageinfo/PackageInfoPlugin.java
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package dev.fluttercommunity.plus.packageinfo;
-
-import android.annotation.SuppressLint;
-import android.content.Context;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.os.Build;
-import androidx.annotation.NonNull;
-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 java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.HashMap;
-import java.util.Map;
-
-/** PackageInfoPlugin */
-public class PackageInfoPlugin implements MethodCallHandler, FlutterPlugin {
- private Context applicationContext;
- private MethodChannel methodChannel;
-
- @SuppressWarnings("deprecation")
- private static long getLongVersionCode(PackageInfo info) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
- return info.getLongVersionCode();
- }
- return info.versionCode;
- }
-
- /** Plugin registration. */
- @Override
- public void onAttachedToEngine(FlutterPluginBinding binding) {
- this.applicationContext = binding.getApplicationContext();
- methodChannel =
- new MethodChannel(binding.getBinaryMessenger(), "dev.fluttercommunity.plus/package_info");
- methodChannel.setMethodCallHandler(this);
- }
-
- @Override
- public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
- applicationContext = null;
- methodChannel.setMethodCallHandler(null);
- methodChannel = null;
- }
-
- @Override
- public void onMethodCall(MethodCall call, @NonNull Result result) {
- try {
- if (call.method.equals("getAll")) {
- PackageManager pm = applicationContext.getPackageManager();
- PackageInfo info = pm.getPackageInfo(applicationContext.getPackageName(), 0);
-
- String buildSignature = getBuildSignature(pm);
-
- Map map = new HashMap<>();
- map.put("appName", info.applicationInfo.loadLabel(pm).toString());
- map.put("packageName", applicationContext.getPackageName());
- map.put("version", info.versionName);
- map.put("buildNumber", String.valueOf(getLongVersionCode(info)));
- if (buildSignature != null) map.put("buildSignature", buildSignature);
-
- result.success(map);
- } else {
- result.notImplemented();
- }
- } catch (PackageManager.NameNotFoundException ex) {
- result.error("Name not found", ex.getMessage(), null);
- }
- }
-
- @SuppressWarnings("deprecation")
- private String getBuildSignature(PackageManager pm) {
- try {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
- PackageInfo packageInfo =
- pm.getPackageInfo(
- applicationContext.getPackageName(), PackageManager.GET_SIGNING_CERTIFICATES);
- if (packageInfo == null || packageInfo.signingInfo == null) {
- return null;
- }
- if (packageInfo.signingInfo.hasMultipleSigners()) {
- return signatureToSha1(packageInfo.signingInfo.getApkContentsSigners()[0].toByteArray());
- } else {
- return signatureToSha1(
- packageInfo.signingInfo.getSigningCertificateHistory()[0].toByteArray());
- }
- } else {
- @SuppressLint("PackageManagerGetSignatures")
- PackageInfo packageInfo =
- pm.getPackageInfo(applicationContext.getPackageName(), PackageManager.GET_SIGNATURES);
- if (packageInfo == null
- || packageInfo.signatures == null
- || packageInfo.signatures.length == 0
- || packageInfo.signatures[0] == null) {
- return null;
- }
- return signatureToSha1(packageInfo.signatures[0].toByteArray());
- }
- } catch (PackageManager.NameNotFoundException | NoSuchAlgorithmException e) {
- return null;
- }
- }
-
- // Credits https://gist.github.com/scottyab/b849701972d57cf9562e
- private String bytesToHex(byte[] bytes) {
- final char[] hexArray = {
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
- };
- char[] hexChars = new char[bytes.length * 2];
- int v;
- for (int j = 0; j < bytes.length; j++) {
- v = bytes[j] & 0xFF;
- hexChars[j * 2] = hexArray[v >>> 4];
- hexChars[j * 2 + 1] = hexArray[v & 0x0F];
- }
- return new String(hexChars);
- }
-
- // Credits https://gist.github.com/scottyab/b849701972d57cf9562e
- private String signatureToSha1(byte[] sig) throws NoSuchAlgorithmException {
- MessageDigest digest = MessageDigest.getInstance("SHA1");
- digest.update(sig);
- byte[] hashtext = digest.digest();
- return bytesToHex(hashtext);
- }
-}
diff --git a/packages/package_info_plus/package_info_plus/android/src/main/kotlin/dev/fluttercommunity/plus/packageinfo/PackageInfoPlugin.kt b/packages/package_info_plus/package_info_plus/android/src/main/kotlin/dev/fluttercommunity/plus/packageinfo/PackageInfoPlugin.kt
new file mode 100644
index 0000000000..34080ffd53
--- /dev/null
+++ b/packages/package_info_plus/package_info_plus/android/src/main/kotlin/dev/fluttercommunity/plus/packageinfo/PackageInfoPlugin.kt
@@ -0,0 +1,130 @@
+package dev.fluttercommunity.plus.packageinfo
+
+import android.content.Context
+import android.content.pm.PackageInfo
+import android.content.pm.PackageManager
+import android.os.Build
+import io.flutter.embedding.engine.plugins.FlutterPlugin
+import io.flutter.embedding.engine.plugins.FlutterPlugin.FlutterPluginBinding
+import io.flutter.plugin.common.MethodCall
+import io.flutter.plugin.common.MethodChannel
+import io.flutter.plugin.common.MethodChannel.MethodCallHandler
+import java.security.MessageDigest
+import java.security.NoSuchAlgorithmException
+
+/** PackageInfoPlugin */
+class PackageInfoPlugin : MethodCallHandler, FlutterPlugin {
+ private var applicationContext: Context? = null
+ private var methodChannel: MethodChannel? = null
+
+ /** Plugin registration. */
+ override fun onAttachedToEngine(binding: FlutterPluginBinding) {
+ applicationContext = binding.applicationContext
+ methodChannel = MethodChannel(binding.binaryMessenger, CHANNEL_NAME)
+ methodChannel!!.setMethodCallHandler(this)
+ }
+
+ override fun onDetachedFromEngine(binding: FlutterPluginBinding) {
+ applicationContext = null
+ methodChannel!!.setMethodCallHandler(null)
+ methodChannel = null
+ }
+
+ override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
+ try {
+ if (call.method == "getAll") {
+ val packageManager = applicationContext!!.packageManager
+ val info = packageManager.getPackageInfo(applicationContext!!.packageName, 0)
+
+ val buildSignature = getBuildSignature(packageManager)
+
+ val infoMap = HashMap()
+ infoMap.apply {
+ put("appName", info.applicationInfo.loadLabel(packageManager).toString())
+ put("packageName", applicationContext!!.packageName)
+ put("version", info.versionName)
+ put("buildNumber", getLongVersionCode(info).toString())
+ if (buildSignature != null) put("buildSignature", buildSignature)
+ }.also { resultingMap ->
+ result.success(resultingMap)
+ }
+ } else {
+ result.notImplemented()
+ }
+ } catch (ex: PackageManager.NameNotFoundException) {
+ result.error("Name not found", ex.message, null)
+ }
+ }
+
+ @Suppress("deprecation")
+ private fun getLongVersionCode(info: PackageInfo): Long {
+ return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+ info.longVersionCode
+ } else {
+ info.versionCode.toLong()
+ }
+ }
+
+ @Suppress("deprecation", "PackageManagerGetSignatures")
+ private fun getBuildSignature(pm: PackageManager): String? {
+ return try {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+ val packageInfo = pm.getPackageInfo(
+ applicationContext!!.packageName,
+ PackageManager.GET_SIGNING_CERTIFICATES
+ )
+ val signingInfo = packageInfo.signingInfo ?: return null
+
+ if (signingInfo.hasMultipleSigners()) {
+ signatureToSha1(signingInfo.apkContentsSigners.first().toByteArray())
+ } else {
+ signatureToSha1(signingInfo.signingCertificateHistory.first().toByteArray())
+ }
+ } else {
+ val packageInfo = pm.getPackageInfo(
+ applicationContext!!.packageName,
+ PackageManager.GET_SIGNATURES
+ )
+ val signatures = packageInfo.signatures
+
+ if (signatures.isNullOrEmpty() || packageInfo.signatures.first() == null) {
+ null
+ } else {
+ signatureToSha1(signatures.first().toByteArray())
+ }
+ }
+ } catch (e: PackageManager.NameNotFoundException) {
+ null
+ } catch (e: NoSuchAlgorithmException) {
+ null
+ }
+ }
+
+ // Credits https://gist.github.com/scottyab/b849701972d57cf9562e
+ @Throws(NoSuchAlgorithmException::class)
+ private fun signatureToSha1(sig: ByteArray): String {
+ val digest = MessageDigest.getInstance("SHA1")
+ digest.update(sig)
+ val hashText = digest.digest()
+ return bytesToHex(hashText)
+ }
+
+ // Credits https://gist.github.com/scottyab/b849701972d57cf9562e
+ private fun bytesToHex(bytes: ByteArray): String {
+ val hexArray = charArrayOf(
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
+ )
+ val hexChars = CharArray(bytes.size * 2)
+ var v: Int
+ for (j in bytes.indices) {
+ v = bytes[j].toInt() and 0xFF
+ hexChars[j * 2] = hexArray[v ushr 4]
+ hexChars[j * 2 + 1] = hexArray[v and 0x0F]
+ }
+ return String(hexChars)
+ }
+
+ companion object {
+ private const val CHANNEL_NAME = "dev.fluttercommunity.plus/package_info"
+ }
+}
diff --git a/packages/package_info_plus/package_info_plus/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/package_info_plus/package_info_plus/example/android/gradle/wrapper/gradle-wrapper.properties
index cb24abda10..7645e290ee 100644
--- a/packages/package_info_plus/package_info_plus/example/android/gradle/wrapper/gradle-wrapper.properties
+++ b/packages/package_info_plus/package_info_plus/example/android/gradle/wrapper/gradle-wrapper.properties
@@ -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-7.4-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
diff --git a/packages/package_info_plus/package_info_plus/pubspec.yaml b/packages/package_info_plus/package_info_plus/pubspec.yaml
index 1058fc6ac7..ec05afcfa0 100644
--- a/packages/package_info_plus/package_info_plus/pubspec.yaml
+++ b/packages/package_info_plus/package_info_plus/pubspec.yaml
@@ -1,6 +1,6 @@
name: package_info_plus
description: Flutter plugin for querying information about the application package, such as CFBundleVersion on iOS or versionCode on Android.
-version: 1.3.1
+version: 1.4.0
homepage: https://plus.fluttercommunity.dev/
repository: https://github.com/fluttercommunity/plus_plugins/tree/main/packages/