Page 7 Stage 4

This commit is contained in:
icewithcola 2024-07-28 18:03:12 +08:00
parent 71c168488b
commit ec813eda1b
6 changed files with 193 additions and 37 deletions

View file

@ -12,8 +12,8 @@ android {
applicationId = "uk.kagurach.android101" applicationId = "uk.kagurach.android101"
minSdk = 28 minSdk = 28
targetSdk = 34 targetSdk = 34
versionCode = 173 versionCode = 174
versionName = "1.7.3" versionName = "1.7.4"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
} }
@ -47,6 +47,9 @@ android {
buildFeatures { buildFeatures {
viewBinding = true viewBinding = true
} }
aaptOptions {
noCompress("tflite")
}
} }
dependencies { dependencies {
@ -95,4 +98,8 @@ dependencies {
implementation(libs.okhttp3) implementation(libs.okhttp3)
implementation(libs.ffmpeg.min) implementation(libs.ffmpeg.min)
implementation (libs.tensorflow.lite.task.vision)
// Import the GPU delegate plugin Library for GPU inference
implementation (libs.tensorflow.lite.gpu.delegate.plugin)
} }

View file

@ -47,9 +47,10 @@ public class MainActivity extends KaBaseActivity {
super.onResume(); super.onResume();
TextView tv = findViewById(R.id.tv_hello); TextView tv = findViewById(R.id.tv_hello);
textViewAppendString(tv, "Starting Initialize"); textViewAppendString(tv, "Starting Initialize\nChecking Permission...");
if (Build.VERSION.SDK_INT >= 33) { if (Build.VERSION.SDK_INT >= 33) {
textViewAppendString(tv, "Find api > 33, checking permission"); textViewAppendString(tv, "Find api > 33");
if (ContextCompat if (ContextCompat
.checkSelfPermission .checkSelfPermission
(MainActivity.this, Manifest.permission.POST_NOTIFICATIONS) (MainActivity.this, Manifest.permission.POST_NOTIFICATIONS)
@ -70,6 +71,8 @@ public class MainActivity extends KaBaseActivity {
new String[]{Manifest.permission.READ_MEDIA_AUDIO}, new String[]{Manifest.permission.READ_MEDIA_AUDIO},
102); 102);
} }
}
if (ContextCompat if (ContextCompat
.checkSelfPermission .checkSelfPermission
(MainActivity.this, Manifest.permission.CAMERA) (MainActivity.this, Manifest.permission.CAMERA)
@ -78,12 +81,12 @@ public class MainActivity extends KaBaseActivity {
ActivityCompat.requestPermissions ActivityCompat.requestPermissions
(MainActivity.this, (MainActivity.this,
new String[]{Manifest.permission.CAMERA}, new String[]{Manifest.permission.CAMERA},
102); 103);
} }
textViewAppendString(tv, "Check Finished"); textViewAppendString(tv, "Check Finished");
textViewAppendString(tv, "提示:常按有惊喜"); textViewAppendString(tv, "提示:常按有惊喜");
}
textViewAppendString(tv, "*************************\nfinished"); textViewAppendString(tv, "*************************\nFinished");
// Initialize Page Helper // Initialize Page Helper
pageHelper = new PageHelper(this, null, MainActivity2.class, this); pageHelper = new PageHelper(this, null, MainActivity2.class, this);

View file

@ -3,23 +3,26 @@ package uk.kagurach.android101
import android.app.Activity import android.app.Activity
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.graphics.BitmapFactory
import android.media.AudioAttributes import android.media.AudioAttributes
import android.media.MediaPlayer import android.media.MediaPlayer
import android.net.Uri import android.net.Uri
import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.provider.MediaStore import android.provider.MediaStore
import android.util.Log import android.util.Log
import android.view.View import android.view.View
import android.view.View.GONE import android.view.View.GONE
import android.view.View.OnClickListener import android.view.View.OnClickListener
import android.view.View.OnLongClickListener
import android.view.View.VISIBLE import android.view.View.VISIBLE
import android.widget.Button import android.widget.Button
import android.widget.EditText import android.widget.EditText
import android.widget.FrameLayout import android.widget.FrameLayout
import android.widget.ImageButton import android.widget.ImageButton
import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.annotation.RequiresApi
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
import androidx.datastore.preferences.core.edit import androidx.datastore.preferences.core.edit
@ -40,11 +43,19 @@ import okhttp3.Request
import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.asRequestBody
import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response import okhttp3.Response
import org.tensorflow.lite.support.image.TensorImage
import org.tensorflow.lite.task.core.BaseOptions
import org.tensorflow.lite.task.vision.classifier.Classifications
import org.tensorflow.lite.task.vision.classifier.ImageClassifier
import org.tensorflow.lite.task.vision.classifier.ImageClassifier.ImageClassifierOptions
import uk.kagurach.android101.additionalActivity.CameraXActivity import uk.kagurach.android101.additionalActivity.CameraXActivity
import uk.kagurach.android101.helper.ToastHelper import uk.kagurach.android101.helper.ToastHelper
import java.io.File import java.io.File
import java.io.FileInputStream
import java.io.IOException import java.io.IOException
import java.io.InputStream import java.io.InputStream
import java.nio.ByteBuffer
import java.nio.channels.FileChannel
val Context.tgDatastore by preferencesDataStore(name = "tg_settings") val Context.tgDatastore by preferencesDataStore(name = "tg_settings")
@ -53,6 +64,7 @@ val DefaultID = stringPreferencesKey("default_id")
class Page7 : KaBaseActivity() { class Page7 : KaBaseActivity() {
lateinit var storage: TGStorage lateinit var storage: TGStorage
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
enableEdgeToEdge() enableEdgeToEdge()
@ -64,23 +76,34 @@ class Page7 : KaBaseActivity() {
} }
storage = TGStorage(this) storage = TGStorage(this)
findViewById<Button>(R.id.P7SendMessageButton).setOnClickListener(ButtonHandler(this))
findViewById<Button>(R.id.P7SaveAndSetAPI).setOnClickListener(ButtonHandler(this))
findViewById<EditText>(R.id.Page7BotID).setText(runBlocking { storage.getDefaultAPI() }) findViewById<EditText>(R.id.Page7BotID).setText(runBlocking { storage.getDefaultAPI() })
findViewById<EditText>(R.id.Page7ChatID).setText(runBlocking { storage.getDefaultID() }) findViewById<EditText>(R.id.Page7ChatID).setText(runBlocking { storage.getDefaultID() })
findViewById<Button>(R.id.P7ShowResult).setOnClickListener(FrameButtonHandler()) // Message
findViewById<Button>(R.id.P7SetAPI).setOnClickListener(FrameButtonHandler()) findViewById<Button>(R.id.P7SendMessageButton).setOnClickListener(ButtonHandler(this))
findViewById<ImageButton>(R.id.P7CloseResultButton).setOnClickListener(FrameButtonHandler())
findViewById<ImageButton>(R.id.P7CloseAPIButton).setOnClickListener(FrameButtonHandler())
// Record Audio
findViewById<Button>(R.id.P7ListenAudio).setOnClickListener(RecordButtonHandler()) findViewById<Button>(R.id.P7ListenAudio).setOnClickListener(RecordButtonHandler())
findViewById<Button>(R.id.P7RecordAudio).setOnClickListener(RecordButtonHandler()) findViewById<Button>(R.id.P7RecordAudio).setOnClickListener(RecordButtonHandler())
findViewById<Button>(R.id.P7SendAudio).setOnClickListener(ButtonHandler(this)) findViewById<Button>(R.id.P7SendAudio).setOnClickListener(ButtonHandler(this))
// Photo
findViewById<Button>(R.id.P7ShotPhoto).setOnClickListener(PhotoButtonHandler(this)) findViewById<Button>(R.id.P7ShotPhoto).setOnClickListener(PhotoButtonHandler(this))
findViewById<Button>(R.id.P7SendPhoto).setOnClickListener(ButtonHandler(this)) findViewById<Button>(R.id.P7SendPhoto).setOnClickListener(ButtonHandler(this))
findViewById<Button>(R.id.P7ViewPhoto).setOnClickListener(FrameButtonHandler())
// Base Settings
findViewById<Button>(R.id.P7ShowResult).setOnClickListener(FrameButtonHandler())
findViewById<Button>(R.id.P7SetAPI).setOnClickListener(FrameButtonHandler())
// In frame
findViewById<Button>(R.id.P7SaveAndSetAPI).setOnClickListener(ButtonHandler(this))
findViewById<Button>(R.id.P7RecognizePic).setOnClickListener(RecognizePhoto(this))
// Close Frame
findViewById<ImageButton>(R.id.P7CloseResultButton).setOnClickListener(FrameButtonHandler())
findViewById<ImageButton>(R.id.P7CloseAPIButton).setOnClickListener(FrameButtonHandler())
findViewById<ImageButton>(R.id.P7CloseShowPicButton).setOnClickListener(FrameButtonHandler())
} }
inner class ButtonHandler(val activity: Activity) : OnClickListener { inner class ButtonHandler(val activity: Activity) : OnClickListener {
@ -105,6 +128,9 @@ class Page7 : KaBaseActivity() {
storage.setDefaultAPI(botAPI) storage.setDefaultAPI(botAPI)
storage.setDefaultID(chatID) storage.setDefaultID(chatID)
} }
runOnUiThread{
ToastHelper.ShowToast("OKAY",baseContext)
}
} }
runOnUiThread { runOnUiThread {
resultTextField.text = result resultTextField.text = result
@ -120,6 +146,11 @@ class Page7 : KaBaseActivity() {
return return
} }
tgHandler.postText(text) { result -> tgHandler.postText(text) { result ->
if (result.contains("\"ok\":true")) {
runOnUiThread{
ToastHelper.ShowToast("OKAY",baseContext)
}
}
runOnUiThread { runOnUiThread {
resultTextField.text = result resultTextField.text = result
} }
@ -131,6 +162,11 @@ class Page7 : KaBaseActivity() {
audioUri, audioUri,
baseContext, baseContext,
) { result -> ) { result ->
if (result.contains("\"ok\":true")) {
runOnUiThread{
ToastHelper.ShowToast("OKAY",baseContext)
}
}
runOnUiThread { runOnUiThread {
resultTextField.text = result resultTextField.text = result
} }
@ -139,6 +175,11 @@ class Page7 : KaBaseActivity() {
R.id.P7SendPhoto -> { // 发送照片 R.id.P7SendPhoto -> { // 发送照片
tgHandler.postImage(photoPath) { result -> tgHandler.postImage(photoPath) { result ->
if (result.contains("\"ok\":true")) {
runOnUiThread{
ToastHelper.ShowToast("OKAY",baseContext)
}
}
runOnUiThread { runOnUiThread {
resultTextField.text = result resultTextField.text = result
} }
@ -157,6 +198,7 @@ class Page7 : KaBaseActivity() {
when (v.id) { when (v.id) {
R.id.P7ShowResult, R.id.P7CloseResultButton -> R.id.P7ResultFrame R.id.P7ShowResult, R.id.P7CloseResultButton -> R.id.P7ResultFrame
R.id.P7SetAPI, R.id.P7CloseAPIButton -> R.id.P7SetAPIFrame R.id.P7SetAPI, R.id.P7CloseAPIButton -> R.id.P7SetAPIFrame
R.id.P7ViewPhoto, R.id.P7CloseShowPicButton -> R.id.P7ShowPicFrame
else -> throw RuntimeException("Invalid Button") else -> throw RuntimeException("Invalid Button")
} }
) )
@ -197,18 +239,43 @@ class Page7 : KaBaseActivity() {
} }
} }
inner class PhotoButtonHandler(val context: Context) : OnClickListener, OnLongClickListener { inner class PhotoButtonHandler(val context: Context) : OnClickListener {
override fun onClick(v: View) { override fun onClick(v: View) {
val myIntent = Intent(context, CameraXActivity::class.java) val myIntent = Intent(context, CameraXActivity::class.java)
startActivityForResult(myIntent, 1) startActivityForResult(myIntent, 1)
} }
}
override fun onLongClick(v: View): Boolean { inner class RecognizePhoto(val context: Context) : OnClickListener{
TODO("Not yet implemented") override fun onClick(v: View) {
// Initialization
val options =
ImageClassifierOptions.builder()
.setBaseOptions(BaseOptions.builder().build())
.setMaxResults(1)
.build()
// Copy model
val modelStream = assets.open("TFModels/mobilenet_v1.tflite")
val bytes = modelStream.readBytes()
val file = File(context.cacheDir.path + "/mobilenet_v1.tflite")
file.writeBytes(bytes)
// Run
val imageClassifier =
ImageClassifier.createFromFileAndOptions(file,options)
val results: List<Classifications> = imageClassifier.classify(
TensorImage.fromBitmap(BitmapFactory.decodeFile(photoPath))
)
val resultName = results.first().toString().split("\"")[1].split("\"").first()
val resultScore = results.first().toString().split("score=").last().split("index").first()
findViewById<TextView>(R.id.P7ViewPhotoRecognizeResult).text = "${resultName}:${resultScore}"
} }
} }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data) super.onActivityResult(requestCode, resultCode, data)
when (requestCode) { when (requestCode) {
@ -225,6 +292,8 @@ class Page7 : KaBaseActivity() {
photoPath = data.getStringExtra("result") ?: return photoPath = data.getStringExtra("result") ?: return
ToastHelper.ShowToast("Saved at ${photoPath}", this) ToastHelper.ShowToast("Saved at ${photoPath}", this)
findViewById<Button>(R.id.P7ViewPhoto).isEnabled = true findViewById<Button>(R.id.P7ViewPhoto).isEnabled = true
findViewById<ImageView>(R.id.P7ViewPhotoPic)
.setImageBitmap(BitmapFactory.decodeFile(photoPath))
} }
} }
} }

View file

@ -288,5 +288,78 @@
</LinearLayout> </LinearLayout>
</FrameLayout> </FrameLayout>
<FrameLayout
android:id="@+id/P7ShowPicFrame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="10dp"
android:layout_marginVertical="25dp"
android:background="@drawable/p7_result_layout"
android:visibility="invisible">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="55dp"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="15dp"
android:layout_weight="1"
android:text="@string/result"
android:textSize="40sp" />
<ImageButton
android:id="@+id/P7CloseShowPicButton"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_marginTop="5dp"
android:layout_marginEnd="5dp"
android:background="@drawable/close_24"
android:clickable="true"
android:contentDescription="@string/close" />
</LinearLayout>
<ImageView
android:id="@+id/P7ViewPhotoPic"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="10"
android:layout_marginHorizontal="5dp"
android:layout_marginTop="5dp"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:rotation="90" />
<TextView
android:id="@+id/P7ViewPhotoRecognizeResult"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_marginTop="5dp"
android:fontFamily="sans-serif"
android:textSize="15sp"
android:textAlignment="center"
/>
<Button
android:id="@+id/P7RecognizePic"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:textAllCaps="false"
android:text="Recognize"
/>
</LinearLayout>
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -21,3 +21,4 @@ kotlin.code.style=official
# resources declared in the library itself and none from the library's dependencies, # resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library # thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true android.nonTransitiveRClass=true
org.gradle.configuration-cache=true

View file

@ -27,6 +27,7 @@ moshiJson = "1.15.1"
ffmpegKit = "6.0-2" ffmpegKit = "6.0-2"
cameraX = "1.3.4" cameraX = "1.3.4"
cameraView = "1.3.4" cameraView = "1.3.4"
tensorFlow = "0.4.4"
[libraries] [libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
@ -56,16 +57,18 @@ androidx-annotation = { group = "androidx.annotation", name = "annotation", vers
androidx-lifecycle-livedata-ktx = { group = "androidx.lifecycle", name = "lifecycle-livedata-ktx", version.ref = "lifecycleLivedataKtx" } androidx-lifecycle-livedata-ktx = { group = "androidx.lifecycle", name = "lifecycle-livedata-ktx", version.ref = "lifecycleLivedataKtx" }
androidx-lifecycle-viewmodel-ktx = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "lifecycleViewmodelKtx" } androidx-lifecycle-viewmodel-ktx = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "lifecycleViewmodelKtx" }
androidx-datastore-rxjava3 = { group = "androidx.datastore", name = "datastore-rxjava3", version.ref = "datastoreRxjava3" } androidx-datastore-rxjava3 = { group = "androidx.datastore", name = "datastore-rxjava3", version.ref = "datastoreRxjava3" }
androidx-work = { group = "androidx.work", name="work-runtime", version.ref = "androidxWork" } androidx-work = { group = "androidx.work", name = "work-runtime", version.ref = "androidxWork" }
androidx-camera-core = { group = "androidx.camera",name = "camera-core",version.ref="cameraX"} androidx-camera-core = { group = "androidx.camera", name = "camera-core", version.ref = "cameraX" }
androidx-camera-camera2 = { group = "androidx.camera",name = "camera-camera2",version.ref="cameraX"} androidx-camera-camera2 = { group = "androidx.camera", name = "camera-camera2", version.ref = "cameraX" }
androidx-camera-lifecycle = { group = "androidx.camera",name = "camera-lifecycle",version.ref="cameraX"} androidx-camera-lifecycle = { group = "androidx.camera", name = "camera-lifecycle", version.ref = "cameraX" }
androidx-camera-view = { group = "androidx.camera",name="camera-view",version.ref="cameraView"} androidx-camera-view = { group = "androidx.camera", name = "camera-view", version.ref = "cameraView" }
okhttp3 = { group = "com.squareup.okhttp3", name="okhttp",version.ref="okHttp3"} okhttp3 = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okHttp3" }
moshi = {group="com.squareup.moshi",name="moshi-kotlin",version.ref="moshiJson"} moshi = { group = "com.squareup.moshi", name = "moshi-kotlin", version.ref = "moshiJson" }
ffmpeg-min = {group="com.arthenica",name="ffmpeg-kit-full",version.ref="ffmpegKit"} ffmpeg-min = { group = "com.arthenica", name = "ffmpeg-kit-full", version.ref = "ffmpegKit" }
tensorflow-lite-gpu-delegate-plugin = { group = "org.tensorflow", name = "tensorflow-lite-gpu-delegate-plugin", version.ref = "tensorFlow" }
tensorflow-lite-task-vision = { group = "org.tensorflow", name = "tensorflow-lite-task-vision", version.ref = "tensorFlow" }
[plugins] [plugins]
androidApplication = { id = "com.android.application", version.ref = "agp" } androidApplication = { id = "com.android.application", version.ref = "agp" }