Application lock (Android)

This commit is contained in:
niuhuan 2022-05-15 02:04:54 +08:00
parent 5f3b73d12c
commit b1b020ed83
4 changed files with 115 additions and 51 deletions

View File

@ -7,6 +7,7 @@
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.USE_BIOMETRIC"/>
<queries> <queries>
<intent> <intent>

View File

@ -1,11 +1,12 @@
package niuhuan.pikapika package niuhuan.pikapika
import android.content.ContentValues import android.content.ContentValues
import android.content.DialogInterface
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.hardware.biometrics.BiometricPrompt
import android.os.* import android.os.*
import android.provider.MediaStore import android.provider.MediaStore
import android.util.DisplayMetrics
import android.util.Log import android.util.Log
import android.view.Display import android.view.Display
import android.view.KeyEvent import android.view.KeyEvent
@ -27,6 +28,8 @@ import java.io.FileInputStream
import java.io.FileOutputStream import java.io.FileOutputStream
import java.nio.file.Files import java.nio.file.Files
import java.util.concurrent.Executors import java.util.concurrent.Executors
import java.util.concurrent.LinkedBlockingQueue
import java.util.concurrent.TimeUnit
class MainActivity : FlutterActivity() { class MainActivity : FlutterActivity() {
@ -70,7 +73,10 @@ class MainActivity : FlutterActivity() {
super.configureFlutterEngine(flutterEngine) super.configureFlutterEngine(flutterEngine)
Mobile.initApplication(androidDataLocal()) Mobile.initApplication(androidDataLocal())
// Method Channel // Method Channel
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "method").setMethodCallHandler { call, result -> MethodChannel(
flutterEngine.dartExecutor.binaryMessenger,
"method"
).setMethodCallHandler { call, result ->
result.withCoroutine { result.withCoroutine {
when (call.method) { when (call.method) {
"flatInvoke" -> { "flatInvoke" -> {
@ -96,6 +102,7 @@ class MainActivity : FlutterActivity() {
// 获取可以迁移数据地址 // 获取可以迁移数据地址
"androidGetExtendDirs" -> androidGetExtendDirs() "androidGetExtendDirs" -> androidGetExtendDirs()
"androidSecureFlag" -> androidSecureFlag(call.argument("flag")!!) "androidSecureFlag" -> androidSecureFlag(call.argument("flag")!!)
"verifyAuthentication" -> auth()
else -> { else -> {
notImplementedToken notImplementedToken
} }
@ -239,7 +246,8 @@ class MainActivity : FlutterActivity() {
put(MediaStore.MediaColumns.IS_PENDING, 1) put(MediaStore.MediaColumns.IS_PENDING, 1)
} }
} }
contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)?.let { uri -> contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
?.let { uri ->
contentResolver.openOutputStream(uri)?.use { fos -> contentResolver.openOutputStream(uri)?.use { fos ->
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos) bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos)
} }
@ -339,20 +347,62 @@ class MainActivity : FlutterActivity() {
private fun androidSecureFlag(flag: Boolean) { private fun androidSecureFlag(flag: Boolean) {
uiThreadHandler.post { uiThreadHandler.post {
if (flag) { if (flag) {
window.setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE) window.setFlags(
WindowManager.LayoutParams.FLAG_SECURE,
WindowManager.LayoutParams.FLAG_SECURE
)
} else { } else {
window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE) window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
} }
} }
} }
private fun compressBitMap(bitmap: Bitmap): ByteArray { // withCoroutine -> queue
val bos = ByteArrayOutputStream() private fun auth(): Boolean {
bos.use { bos -> var queue = LinkedBlockingQueue<Boolean>()
Log.d("BITMAP", bitmap.width.toString()) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
bitmap.compress(Bitmap.CompressFormat.PNG, 100, bos) var mBiometricPrompt = BiometricPrompt.Builder(this)
.setTitle("验证身份")
.setDescription("需要验证您的身份")
.setNegativeButton(
"取消", mainExecutor
) { _, _ -> queue.add(false) }
.build()
var mCancellationSignal = CancellationSignal()
mCancellationSignal.setOnCancelListener {
queue.add(false)
} }
return bos.toByteArray()
var mAuthenticationCallback = object : BiometricPrompt.AuthenticationCallback() {
override fun onAuthenticationError(errorCode: Int, errString: CharSequence?) {
super.onAuthenticationError(errorCode, errString)
queue.add(false)
}
override fun onAuthenticationFailed() {
super.onAuthenticationFailed()
queue.add(false)
}
override fun onAuthenticationSucceeded(result1: BiometricPrompt.AuthenticationResult?) {
super.onAuthenticationSucceeded(result1)
queue.add(true)
}
}
mBiometricPrompt.authenticate(
mCancellationSignal,
mainExecutor,
mAuthenticationCallback
)
} else {
queue.add(false)
}
return queue.poll(5, TimeUnit.MINUTES) ?: false
} }

View File

@ -13,8 +13,7 @@ buildscript {
allprojects { allprojects {
repositories { repositories {
google() maven { url('https://maven.aliyun.com/repository/public') }
jcenter()
} }
} }

View File

@ -1,6 +1,7 @@
import 'dart:io'; import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:pikapika/basic/config/Platform.dart';
import '../Common.dart'; import '../Common.dart';
import '../Method.dart'; import '../Method.dart';
@ -30,9 +31,7 @@ Future<void> _chooseAuthentication(BuildContext context) async {
} }
Widget authenticationSetting() { Widget authenticationSetting() {
if (Platform.isIOS != true) { if (Platform.isIOS) {
return Container();
}
return StatefulBuilder( return StatefulBuilder(
builder: (BuildContext context, void Function(void Function()) setState) { builder: (BuildContext context, void Function(void Function()) setState) {
return ListTile( return ListTile(
@ -45,4 +44,19 @@ Widget authenticationSetting() {
); );
}, },
); );
} else if (androidVersion >= 29) {
return StatefulBuilder(
builder: (BuildContext context, void Function(void Function()) setState) {
return ListTile(
title: const Text("进入APP时验证指纹(如果系统已经录入)"),
subtitle: Text(_authentication ? "" : ""),
onTap: () async {
await _chooseAuthentication(context);
setState(() {});
},
);
},
);
}
return Container();
} }