feat:参照研听的基础工程
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
# To get started with Dependabot version updates, you'll need to specify which
|
||||
# package ecosystems to update and where the package manifests are located.
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
|
||||
- package-ecosystem: "pub"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
ignore:
|
||||
- dependency-name: "*"
|
||||
update-types: ["version-update:semver-minor", "version-update:semver-patch"]
|
||||
|
||||
- package-ecosystem: "pub"
|
||||
directory: "example"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
ignore:
|
||||
- dependency-name: "*"
|
||||
update-types: ["version-update:semver-minor", "version-update:semver-patch"]
|
||||
|
||||
- package-ecosystem: "gradle"
|
||||
directory: "android"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
|
||||
- package-ecosystem: "gradle"
|
||||
directory: "example/android"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
@@ -0,0 +1,34 @@
|
||||
name: Flutter build example
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
build_android:
|
||||
name: Build example for Android
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.head_ref }}
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '17'
|
||||
- name: Install Flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
- name: Disable analytics
|
||||
run: flutter config --no-analytics
|
||||
- name: Flutter pub get
|
||||
run: flutter pub get
|
||||
- name: Flutter build appbundle
|
||||
run: |
|
||||
cd example
|
||||
flutter build appbundle --release
|
||||
@@ -0,0 +1,101 @@
|
||||
name: Flutter checks
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
check_pub_dependencies:
|
||||
name: Check dependencies
|
||||
timeout-minutes: 10
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.head_ref }}
|
||||
- name: Install Flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
- name: Disable analytics
|
||||
run: flutter config --no-analytics
|
||||
- name: Flutter pub get
|
||||
run: flutter pub get
|
||||
|
||||
check_formatting:
|
||||
name: Check formatting
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.head_ref }}
|
||||
- name: Install Flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
- name: Disable analytics
|
||||
run: flutter config --no-analytics
|
||||
- name: Flutter pub get
|
||||
run: flutter pub get
|
||||
- name: Check Dart formatting
|
||||
run: dart format --line-length 80 --set-exit-if-changed .
|
||||
|
||||
analyze:
|
||||
name: Dart analyze
|
||||
timeout-minutes: 10
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.head_ref }}
|
||||
- name: Install Flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
- name: Disable analytics
|
||||
run: flutter config --no-analytics
|
||||
- name: Flutter pub get
|
||||
run: flutter pub get
|
||||
- name: Run Dart analyze
|
||||
uses: invertase/github-action-dart-analyzer@v3.0.0
|
||||
|
||||
test:
|
||||
name: Flutter test
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.head_ref }}
|
||||
- name: Install Flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
- name: Disable analytics
|
||||
run: flutter config --no-analytics
|
||||
- name: Flutter pub get
|
||||
run: flutter pub get
|
||||
- name: Flutter test
|
||||
run: flutter test
|
||||
|
||||
test_example:
|
||||
name: Flutter test example
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.head_ref }}
|
||||
- name: Install Flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
- name: Disable analytics
|
||||
run: flutter config --no-analytics
|
||||
- name: Flutter pub get
|
||||
run: |
|
||||
cd example
|
||||
flutter pub get
|
||||
- name: Flutter test example
|
||||
run: |
|
||||
cd example
|
||||
flutter test
|
||||
@@ -0,0 +1,18 @@
|
||||
name: Pub publish
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
name: Pub publish
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.head_ref }}
|
||||
- name: Publish
|
||||
uses: k-paxian/dart-package-publisher@v1.6
|
||||
with:
|
||||
credentialJson: ${{ secrets.CREDENTIALS }}
|
||||
@@ -0,0 +1,21 @@
|
||||
name: Pub publish dry run
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
publish-dry-run:
|
||||
name: Pub publish dry run
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.head_ref }}
|
||||
- name: Publish dry run
|
||||
uses: k-paxian/dart-package-publisher@v1.6
|
||||
with:
|
||||
credentialJson: 'MockCredentialJson'
|
||||
dryRunOnly: true
|
||||
@@ -0,0 +1,32 @@
|
||||
name: Check pub score
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
check-score:
|
||||
name: Check pub score
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.head_ref }}
|
||||
- uses: axel-op/dart-package-analyzer@v3
|
||||
id: workflow
|
||||
with:
|
||||
githubToken: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Check score
|
||||
env:
|
||||
TOTAL: ${{ steps.workflow.outputs.total }}
|
||||
TOTAL_MAX: ${{ steps.workflow.outputs.total_max }}
|
||||
run: |
|
||||
MISSING_POINTS=$(( $TOTAL_MAX - $TOTAL ))
|
||||
if (( MISSING_POINTS > 0 ))
|
||||
then
|
||||
echo Score can be improved!
|
||||
exit 1
|
||||
fi
|
||||
@@ -0,0 +1,26 @@
|
||||
# Miscellaneous
|
||||
*.class
|
||||
*.log
|
||||
*.pyc
|
||||
*.swp
|
||||
.DS_Store
|
||||
.atom/
|
||||
.buildlog/
|
||||
.history
|
||||
.svn/
|
||||
migrate_working_dir/
|
||||
|
||||
# IntelliJ related
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
.idea/
|
||||
.vscode/
|
||||
|
||||
# Flutter/Dart/Pub related
|
||||
# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
|
||||
/pubspec.lock
|
||||
**/doc/api/
|
||||
.dart_tool/
|
||||
.packages
|
||||
build/
|
||||
@@ -0,0 +1,30 @@
|
||||
# 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: "a14f74ff3a1cbd521163c5f03d68113d50af93d3"
|
||||
channel: "stable"
|
||||
|
||||
project_type: plugin
|
||||
|
||||
# Tracks metadata for the flutter migrate command
|
||||
migration:
|
||||
platforms:
|
||||
- platform: root
|
||||
create_revision: a14f74ff3a1cbd521163c5f03d68113d50af93d3
|
||||
base_revision: a14f74ff3a1cbd521163c5f03d68113d50af93d3
|
||||
- platform: android
|
||||
create_revision: a14f74ff3a1cbd521163c5f03d68113d50af93d3
|
||||
base_revision: a14f74ff3a1cbd521163c5f03d68113d50af93d3
|
||||
|
||||
# User provided section
|
||||
|
||||
# List of Local paths (relative to this file) that should be
|
||||
# ignored by the migrate tool.
|
||||
#
|
||||
# Files that are not part of the templates will be ignored by default.
|
||||
unmanaged_files:
|
||||
- 'lib/main.dart'
|
||||
- 'ios/Runner.xcodeproj/project.pbxproj'
|
||||
@@ -0,0 +1,103 @@
|
||||
## 0.4.0
|
||||
|
||||
* Upgrade Android dependencies (Gradle, AGP, Java, Kotlin)
|
||||
* Widen `flutter_lints` constraints
|
||||
|
||||
## 0.3.6
|
||||
|
||||
* Return `null` on platforms other than Android, instead of throwing an exception
|
||||
|
||||
## 0.3.5
|
||||
|
||||
* Maintenance release
|
||||
* Update `kotlin` and `gradle`
|
||||
|
||||
## 0.3.4
|
||||
|
||||
* Refactor native code
|
||||
|
||||
## 0.3.3
|
||||
|
||||
* Add topics to pubspec.yaml
|
||||
|
||||
## 0.3.2
|
||||
|
||||
* Improve `namespace` fix for `Android Gradle Plugin` versions < 7
|
||||
|
||||
## 0.3.1
|
||||
|
||||
* Fix `namespace` for `Android Gradle Plugin` versions < 7
|
||||
|
||||
## 0.3.0
|
||||
|
||||
* Add `namespace` for compatibility with `Android Gradle Plugin 8`
|
||||
* Update `Gradle` version
|
||||
|
||||
## 0.2.0
|
||||
|
||||
* Update `Gradle` version
|
||||
* Update `Android Gradle plugin` version
|
||||
* Update `Kotlin` version
|
||||
* Add Gradle wrapper files
|
||||
* Update `pubspec.lock` of example (`url: "https://pub.dev"`)
|
||||
|
||||
## 0.1.3+1
|
||||
|
||||
* Improve readme: Add explanation for connection of `Android ID` and signing key
|
||||
|
||||
## 0.1.3
|
||||
|
||||
* Add building of example app to GitHub workflows
|
||||
* Remove unneeded code
|
||||
|
||||
## 0.1.2
|
||||
|
||||
* Add `Flutter test` for example app to workflows
|
||||
|
||||
## 0.1.1+1
|
||||
|
||||
* Update readme
|
||||
|
||||
## 0.1.1
|
||||
|
||||
* Update example app dependencies
|
||||
|
||||
## 0.1.0
|
||||
|
||||
* Rename Android `applicationId`
|
||||
* Recreate `android` folder from template
|
||||
|
||||
## 0.0.8
|
||||
|
||||
* Add more GitHub Actions for checking code quality
|
||||
* Update kotlin_version from 1.6.10 to 1.7.20
|
||||
* Update gradle from 7.1.2 to 7.3.1
|
||||
* Add dependabot
|
||||
|
||||
## 0.0.7
|
||||
|
||||
* Add Google Play information to README.
|
||||
|
||||
## 0.0.6
|
||||
|
||||
* Lower minimal sdk version to `2.12.0`.
|
||||
|
||||
## 0.0.5
|
||||
|
||||
* Documentation typo fix.
|
||||
|
||||
## 0.0.4
|
||||
|
||||
* Small improvements.
|
||||
|
||||
## 0.0.3
|
||||
|
||||
* Improve example.
|
||||
|
||||
## 0.0.2
|
||||
|
||||
* Enhance description to get full pub.dev score.
|
||||
|
||||
## 0.0.1
|
||||
|
||||
* Initial release.
|
||||
@@ -0,0 +1,29 @@
|
||||
BSD 3-Clause License
|
||||
|
||||
Copyright (c) 2022, Joachim Nohl
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -0,0 +1,47 @@
|
||||
# android_id
|
||||
|
||||
[](https://github.com/fluttercommunity/community)
|
||||
|
||||

|
||||
|
||||
A Flutter plugin for retrieving the Android ID.
|
||||
|
||||
## Getting started
|
||||
|
||||
* Add plugin to pubspec.yaml
|
||||
* Use it in your code (see examples of all methods below)
|
||||
|
||||
## Usage
|
||||
|
||||
```dart
|
||||
const _androidIdPlugin = AndroidId();
|
||||
|
||||
final String? androidId = await _androidIdPlugin.getId();
|
||||
```
|
||||
|
||||
## Important
|
||||
|
||||
Please note that on `Android 8` and above, the `Android ID` is not unique per device, but also per signing key the app was built with:
|
||||
|
||||
<blockquote>
|
||||
On Android 8.0 (API level 26) and higher versions of the platform, a 64-bit number (expressed as a hexadecimal string), <b>unique to each combination of app-signing key, user, and device.</b>
|
||||
|
||||
The value may change if a factory reset is performed on the device or if an APK signing key changes.
|
||||
</blockquote>
|
||||
|
||||
[Android API reference](https://developer.android.com/reference/android/provider/Settings.Secure#ANDROID_ID)
|
||||
|
||||
[Stack Overflow explanation](https://stackoverflow.com/a/43393373)
|
||||
|
||||
|
||||
## Google Play
|
||||
|
||||
Before using this plugin in your app, make sure to follow Google Play guidelines.
|
||||
For example [here](https://support.google.com/googleplay/android-developer/answer/6048248#zippy=%2Cpersistent-identifiers-including-android-id):
|
||||
|
||||
<blockquote>
|
||||
<b>Persistent identifiers, including Android ID</b>
|
||||
|
||||
Use for non-advertising purposes<br>
|
||||
You can use persistent identifiers as long as you have a [privacy policy](https://support.google.com/googleplay/android-developer/answer/9859455) and handle the data in accordance with the [Developer Distribution Agreement](https://play.google.com/about/developer-distribution-agreement.html#use) and all applicable privacy laws in the areas where you make your app available.
|
||||
</blockquote>
|
||||
@@ -0,0 +1 @@
|
||||
include: package:flutter_lints/flutter.yaml
|
||||
@@ -0,0 +1,9 @@
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/workspace.xml
|
||||
/.idea/libraries
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
.cxx
|
||||
@@ -0,0 +1,74 @@
|
||||
group = "dev.fluttercommunity.android_id"
|
||||
version = "1.0-SNAPSHOT"
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = "2.0.0"
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
maven{url'https://repo1.maven.org/maven2/'}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath("com.android.tools.build:gradle:8.1.4")
|
||||
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version")
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
maven{url'https://repo1.maven.org/maven2/'}
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: "com.android.library"
|
||||
apply plugin: "kotlin-android"
|
||||
|
||||
android {
|
||||
if (project.android.hasProperty("namespace")) {
|
||||
namespace = "dev.fluttercommunity.android_id"
|
||||
}
|
||||
|
||||
compileSdk = 34
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = "17"
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main.java.srcDirs += "src/main/kotlin"
|
||||
test.java.srcDirs += "src/test/kotlin"
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
minSdk = 21
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation("org.jetbrains.kotlin:kotlin-test")
|
||||
testImplementation("org.mockito:mockito-core:5.12.0")
|
||||
}
|
||||
|
||||
testOptions {
|
||||
unitTests.all {
|
||||
useJUnitPlatform()
|
||||
|
||||
testLogging {
|
||||
events "passed", "skipped", "failed", "standardOut", "standardError"
|
||||
outputs.upToDateWhen {false}
|
||||
showStandardStreams = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
// implementation 'com.umeng.umsdk:common:9.7.7'// 必选
|
||||
// implementation 'com.umeng.umsdk:asms:1.8.3'// 必选
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
rootProject.name = 'android_id'
|
||||
@@ -0,0 +1,8 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="dev.fluttercommunity.android_id">
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
|
||||
<uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"
|
||||
tools:ignore="ProtectedPermissions" />
|
||||
</manifest>
|
||||
+279
@@ -0,0 +1,279 @@
|
||||
package dev.fluttercommunity.android_id
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.ContentResolver
|
||||
import android.provider.Settings
|
||||
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 android.content.Context
|
||||
import android.net.wifi.WifiInfo
|
||||
import android.net.wifi.WifiManager
|
||||
import android.os.Build
|
||||
import android.text.TextUtils
|
||||
import androidx.core.app.ActivityCompat
|
||||
|
||||
import java.io.IOException
|
||||
import java.io.InputStreamReader
|
||||
import java.io.LineNumberReader
|
||||
import java.net.NetworkInterface
|
||||
import java.util.Collections
|
||||
import java.util.List
|
||||
import java.util.ArrayList
|
||||
import java.util.Locale
|
||||
import android.content.pm.PackageManager
|
||||
import android.telephony.TelephonyManager
|
||||
//import com.umeng.commonsdk.UMConfigure
|
||||
|
||||
/** AndroidIdPlugin */
|
||||
class AndroidIdPlugin : 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 contentResolver: ContentResolver
|
||||
|
||||
private lateinit var context: Context
|
||||
|
||||
override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
|
||||
contentResolver = flutterPluginBinding.applicationContext.contentResolver
|
||||
channel = MethodChannel(flutterPluginBinding.binaryMessenger, "android_id")
|
||||
channel.setMethodCallHandler(this)
|
||||
context = flutterPluginBinding.getApplicationContext()
|
||||
}
|
||||
|
||||
override fun onMethodCall(call: MethodCall, result: Result) {
|
||||
when (call.method) {
|
||||
"getId" -> {
|
||||
try {
|
||||
result.success(getAndroidId())
|
||||
} catch (e: Exception) {
|
||||
result.success("")
|
||||
// result.error("ERROR_GETTING_ID", "Failed to get Android ID", e.localizedMessage)
|
||||
}
|
||||
}
|
||||
|
||||
"getImei" -> {
|
||||
try {
|
||||
result.success(getImei())
|
||||
} catch (e: Exception) {
|
||||
result.success("")
|
||||
// result.error("ERROR_GETTING_ID", "Failed to get Imei ", e.localizedMessage)
|
||||
}
|
||||
}
|
||||
|
||||
"getMacAddress" -> {
|
||||
try {
|
||||
result.success(getMacAddress())
|
||||
} catch (e: Exception) {
|
||||
result.success("")
|
||||
// result.error("ERROR_GETTING_ID", "Failed to get MacAddress", e.localizedMessage)
|
||||
}
|
||||
}
|
||||
|
||||
// "getOaid" -> {
|
||||
// try {
|
||||
// UMConfigure.getOaid(context) { p0 ->
|
||||
// if (p0 != null) {
|
||||
// result.success(p0)
|
||||
// } else {
|
||||
// result.success("")
|
||||
// }
|
||||
// }
|
||||
// } catch (e: Exception) {
|
||||
// result.success("")
|
||||
//// result.error("ERROR_GETTING_ID", "Failed to get MacAddress", e.localizedMessage)
|
||||
// }
|
||||
// }
|
||||
|
||||
"checkRoot" -> {
|
||||
try {
|
||||
result.success(checkRoot())
|
||||
} catch (e: Exception) {
|
||||
result.success(false)
|
||||
// result.error("ERROR_GETTING_ID", "Failed to get MacAddress", e.localizedMessage)
|
||||
}
|
||||
}
|
||||
"checkIsEmulator" -> {
|
||||
try {
|
||||
result.success(checkIsEmulator())
|
||||
} catch (e: Exception) {
|
||||
result.success(false)
|
||||
// result.error("ERROR_GETTING_ID", "Failed to get MacAddress", e.localizedMessage)
|
||||
}
|
||||
}
|
||||
|
||||
else -> result.notImplemented()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
|
||||
channel.setMethodCallHandler(null)
|
||||
}
|
||||
|
||||
// Fetch the Android ID while suppressing lint warning about hardware IDs
|
||||
@SuppressLint("HardwareIds")
|
||||
private fun getAndroidId(): String {
|
||||
return Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID)
|
||||
}
|
||||
|
||||
private fun getImei(): String? {
|
||||
val tm: TelephonyManager =
|
||||
context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
|
||||
var IMEIStr = ""
|
||||
if (ActivityCompat.checkSelfPermission(
|
||||
context,
|
||||
android.Manifest.permission.READ_PHONE_STATE
|
||||
) !== PackageManager.PERMISSION_GRANTED
|
||||
) {
|
||||
} else {
|
||||
try {
|
||||
IMEIStr = tm.getDeviceId()
|
||||
if (TextUtils.isEmpty(IMEIStr)) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
IMEIStr = tm.getImei()
|
||||
}
|
||||
}
|
||||
} catch (e: java.lang.Exception) {
|
||||
}
|
||||
}
|
||||
return IMEIStr
|
||||
}
|
||||
|
||||
private fun getMacAddress(): String? {
|
||||
var macNo = MacUtil().getMac(context)
|
||||
return macNo
|
||||
}
|
||||
|
||||
|
||||
private fun checkRoot(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
private fun checkIsEmulator(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class MacUtil {
|
||||
/**
|
||||
* Android 6.0 之前(不包括6.0)获取mac地址
|
||||
* 必须的权限 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
|
||||
*
|
||||
* @param context * @return
|
||||
*/
|
||||
@SuppressLint("MissingPermission")
|
||||
fun getMacDefault(context: Context?): String? {
|
||||
var mac = ""
|
||||
if (context == null) {
|
||||
return mac
|
||||
}
|
||||
val wifi: WifiManager =
|
||||
context.getApplicationContext().getSystemService(Context.WIFI_SERVICE) as WifiManager
|
||||
var info: WifiInfo? = null
|
||||
try {
|
||||
info = wifi.getConnectionInfo()
|
||||
} catch (e: java.lang.Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
if (info == null) {
|
||||
return null
|
||||
}
|
||||
mac = info.getMacAddress()
|
||||
if (!TextUtils.isEmpty(mac)) {
|
||||
mac = mac.uppercase()
|
||||
}
|
||||
return mac
|
||||
}
|
||||
|
||||
val macAddress: String?
|
||||
/**
|
||||
* Android 6.0-Android 7.0 获取mac地址
|
||||
*/
|
||||
get() {
|
||||
var macSerial: String? = null
|
||||
var str = ""
|
||||
|
||||
try {
|
||||
val pp: java.lang.Process =
|
||||
java.lang.Runtime.getRuntime().exec("cat/sys/class/net/wlan0/address")
|
||||
val ir: InputStreamReader = InputStreamReader(pp.getInputStream())
|
||||
val input: LineNumberReader = LineNumberReader(ir)
|
||||
|
||||
while (null != str) {
|
||||
str = input.readLine()
|
||||
if (str != null) {
|
||||
macSerial = str.trim { it <= ' ' } //去空格
|
||||
break
|
||||
}
|
||||
}
|
||||
} catch (ex: IOException) {
|
||||
// 赋予默认值
|
||||
ex.printStackTrace()
|
||||
}
|
||||
|
||||
return macSerial
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取mac地址(适配所有Android版本)
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
fun getMac(context: Context?): String? {
|
||||
var mac: String? = ""
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
||||
mac = getMacDefault(context)
|
||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
|
||||
mac = macAddress
|
||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
mac = macFromHardware
|
||||
}
|
||||
return mac
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val macFromHardware: String?
|
||||
/**
|
||||
* Android 7.0之后获取Mac地址
|
||||
* 遍历循环所有的网络接口,找到接口是 wlan0
|
||||
* 必须的权限 <uses-permission android:name="android.permission.INTERNET"></uses-permission>
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
get() {
|
||||
try {
|
||||
val all: ArrayList<NetworkInterface> =
|
||||
Collections.list<NetworkInterface>(NetworkInterface.getNetworkInterfaces())
|
||||
for (nif in all) {
|
||||
if (!nif.getName().equals("wlan0", ignoreCase = true)) {
|
||||
continue
|
||||
}
|
||||
|
||||
val macBytes: ByteArray = nif.getHardwareAddress() ?: return null
|
||||
|
||||
val res1: java.lang.StringBuilder = java.lang.StringBuilder()
|
||||
for (b in macBytes) {
|
||||
res1.append(String.format("%02X:", b))
|
||||
}
|
||||
|
||||
if (res1.length > 0) {
|
||||
res1.deleteCharAt(res1.length - 1)
|
||||
}
|
||||
return res1.toString()
|
||||
}
|
||||
} catch (e: java.lang.Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
/// The plugin class for retrieving the Android ID.
|
||||
class AndroidId {
|
||||
const AndroidId();
|
||||
|
||||
/// The method channel used to interact with the native platform.
|
||||
static const _methodChannel = MethodChannel('android_id');
|
||||
|
||||
/// Calls the native method to retrieve the Android ID.
|
||||
Future<String?> getId() async {
|
||||
final isAndroid =
|
||||
!kIsWeb && defaultTargetPlatform == TargetPlatform.android;
|
||||
if (!isAndroid) return null;
|
||||
|
||||
return _methodChannel.invokeMethod<String?>('getId');
|
||||
}
|
||||
|
||||
Future<String?> getImei() async {
|
||||
final isAndroid =
|
||||
!kIsWeb && defaultTargetPlatform == TargetPlatform.android;
|
||||
if (!isAndroid) return null;
|
||||
|
||||
return _methodChannel.invokeMethod<String?>('getImei');
|
||||
}
|
||||
|
||||
Future<String?> getMaAddress() async {
|
||||
final isAndroid =
|
||||
!kIsWeb && defaultTargetPlatform == TargetPlatform.android;
|
||||
if (!isAndroid) return null;
|
||||
|
||||
return _methodChannel.invokeMethod<String?>('getMacAddress');
|
||||
}
|
||||
// Future<String?> getOaid() async {
|
||||
// final isAndroid =
|
||||
// !kIsWeb && defaultTargetPlatform == TargetPlatform.android;
|
||||
// if (!isAndroid) return null;
|
||||
//
|
||||
// return _methodChannel.invokeMethod<String?>('getOaid');
|
||||
// }
|
||||
|
||||
Future<bool?> isRoot() async {
|
||||
final isAndroid =
|
||||
!kIsWeb && defaultTargetPlatform == TargetPlatform.android;
|
||||
if (!isAndroid) return null;
|
||||
|
||||
return _methodChannel.invokeMethod<bool?>('checkRoot');
|
||||
}
|
||||
|
||||
Future<bool?> isEmulator() async {
|
||||
final isAndroid =
|
||||
!kIsWeb && defaultTargetPlatform == TargetPlatform.android;
|
||||
if (!isAndroid) return null;
|
||||
|
||||
return _methodChannel.invokeMethod<bool?>('checkIsEmulator');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
name: android_id
|
||||
description: A Flutter plugin for getting the Android ID. Only for Android.
|
||||
|
||||
repository: https://github.com/fluttercommunity/android_id
|
||||
issue_tracker: https://github.com/fluttercommunity/android_id/issues
|
||||
|
||||
maintainer: Joachim Nohl (@nohli)
|
||||
|
||||
topics:
|
||||
- androidid
|
||||
- device
|
||||
- identifier
|
||||
- android
|
||||
- native
|
||||
|
||||
version: 0.4.0
|
||||
|
||||
environment:
|
||||
sdk: '>=2.12.0 <4.0.0'
|
||||
flutter: '>=2.0.0'
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
|
||||
dev_dependencies:
|
||||
flutter_lints: '>=2.0.0 <4.0.0'
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
|
||||
flutter:
|
||||
plugin:
|
||||
platforms:
|
||||
android:
|
||||
package: dev.fluttercommunity.android_id
|
||||
pluginClass: AndroidIdPlugin
|
||||
@@ -0,0 +1,26 @@
|
||||
import 'package:android_id/android_id.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
const plugin = AndroidId();
|
||||
const channel = MethodChannel('android_id');
|
||||
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
debugDefaultTargetPlatformOverride = TargetPlatform.android;
|
||||
|
||||
setUp(() {
|
||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
||||
.setMockMethodCallHandler(channel, (methodCall) async => '42');
|
||||
});
|
||||
|
||||
tearDown(() {
|
||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
||||
.setMockMethodCallHandler(channel, null);
|
||||
});
|
||||
|
||||
test('getAndroidId', () async {
|
||||
expect(await plugin.getId(), '42');
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user