From 89fbe4eb7b7676ca30dace4a1568a5de7120ca22 Mon Sep 17 00:00:00 2001 From: tongtongstudio Date: Tue, 24 Jun 2025 16:07:13 +0800 Subject: [PATCH] add nfc permission,add AccessibilityService --- app/build.gradle | 79 ++++++++++++++++++- app/src/main/AndroidManifest.xml | 40 +++++++++- .../selecttospeak/SelectToSpeakService.java | 54 +++++++++++++ .../{ => activity/main}/MainActivity.java | 4 +- .../activity/nfc/NfcActivity.java | 64 +++++++++++++++ .../elderlyassistant/config/CommonConfig.java | 6 ++ app/src/main/res/layout/activity_main.xml | 2 +- app/src/main/res/layout/activity_nfc.xml | 9 +++ app/src/main/res/values/strings.xml | 4 + .../res/xml/accessibility_service_config.xml | 10 +++ app/src/main/res/xml/nfc_tech_filter.xml | 5 ++ build.gradle | 20 ++++- 12 files changed, 286 insertions(+), 11 deletions(-) create mode 100644 app/src/main/java/com/google/android/accessibility/selecttospeak/SelectToSpeakService.java rename app/src/main/java/com/ttstd/elderlyassistant/{ => activity/main}/MainActivity.java (77%) create mode 100644 app/src/main/java/com/ttstd/elderlyassistant/activity/nfc/NfcActivity.java create mode 100644 app/src/main/java/com/ttstd/elderlyassistant/config/CommonConfig.java create mode 100644 app/src/main/res/layout/activity_nfc.xml create mode 100644 app/src/main/res/xml/accessibility_service_config.xml create mode 100644 app/src/main/res/xml/nfc_tech_filter.xml diff --git a/app/build.gradle b/app/build.gradle index 8a7085b..9fadb35 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,8 +1,16 @@ apply plugin: 'com.android.application' +def appName() { + return "TTStdElderlyAssistant" +} + +def releaseTime() { + return new Date().format("yyyyMMdd_HHmmss", TimeZone.getDefault()) +} + android { compileSdkVersion 33 - buildToolsVersion "36.0.0" + buildToolsVersion "30.0.3" defaultConfig { applicationId "com.ttstd.elderlyassistant" @@ -13,12 +21,68 @@ android { versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + + lintOptions { + checkReleaseBuilds false + // Or, if you prefer, you can continue to check for errors in release builds, + // but continue the build even when errors are found: + abortOnError false + } + + ndk { + //根据需要 自行选择添加的对应cpu类型的.so库。 + abiFilters 'arm64-v8a' + // 还可以添加 'armeabi','armeabi-v7a', 'x86', 'x86_64', 'mips', 'mips64' + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + dataBinding { + enabled true + } + + } buildTypes { + debug { + versionNameSuffix "_debug" + debuggable true + minifyEnabled false + //Zipalign优化 + zipAlignEnabled true +// signingConfig signingConfigs.tuixin + applicationVariants.all { variant -> + variant.outputs.each { output -> + if (outputFile != null) { + def fileName = "${appName()}_V${defaultConfig.versionName}_${releaseTime()}.apk" + output.outputFileName = fileName + } + } + } + } + release { minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + //Zipalign优化 + zipAlignEnabled true + //前一部分代表系统默认的android程序的混淆文件,该文件已经包含了基本的混淆声明,后一个文件是自己的定义混淆文件 + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + //签名 +// signingConfig signingConfigs.tuixin +// 将release版本的包名重命名,加上版本及日期 + applicationVariants.all { variant -> + variant.outputs.each { output -> + def outputFile = "" + if (outputFile != null) { + def fileName = "${appName()}_${variant.versionCode}_V${variant.versionName}_${releaseTime()}_${buildType.name}.apk" + output.outputFileName = new File(outputFile, fileName) + } + } + } } } @@ -27,9 +91,16 @@ android { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation 'androidx.appcompat:appcompat:1.7.1' - implementation 'androidx.constraintlayout:constraintlayout:2.2.1' + implementation 'androidx.appcompat:appcompat:1.3.1' + implementation 'androidx.constraintlayout:constraintlayout:2.0.3' + testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test.ext:junit:1.2.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1' + + //MMKV + implementation 'com.tencent:mmkv-static:1.2.14' + //bugly + implementation 'com.tencent.bugly:crashreport:4.1.9.2' + implementation 'com.iqiyi.xcrash:xcrash-android-lib:3.0.0' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7cf1bb5..e882106 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,6 +2,13 @@ + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/google/android/accessibility/selecttospeak/SelectToSpeakService.java b/app/src/main/java/com/google/android/accessibility/selecttospeak/SelectToSpeakService.java new file mode 100644 index 0000000..28f27e6 --- /dev/null +++ b/app/src/main/java/com/google/android/accessibility/selecttospeak/SelectToSpeakService.java @@ -0,0 +1,54 @@ +package com.google.android.accessibility.selecttospeak; + +import android.accessibilityservice.AccessibilityService; +import android.content.Intent; +import android.util.Log; +import android.view.accessibility.AccessibilityEvent; + +import com.tencent.mmkv.MMKV; +import com.ttstd.elderlyassistant.config.CommonConfig; + +public class SelectToSpeakService extends AccessibilityService { + private static final String TAG = "SelectToSpeakService"; + + private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); + + @Override + public void onCreate() { + super.onCreate(); + Log.e(TAG, "onCreate: "); + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + Log.e(TAG, "onStartCommand: "); + + return super.onStartCommand(intent, flags, startId); + } + + @Override + public void onDestroy() { + super.onDestroy(); + Log.e(TAG, "onDestroy: "); + + } + + @Override + public void onAccessibilityEvent(AccessibilityEvent event) { + Log.v(TAG, "onAccessibilityEvent: event = " + event.toString()); + + } + + @Override + public void onInterrupt() { + Log.e(TAG, "onInterrupt: "); + + } + + @Override + protected void onServiceConnected() { + super.onServiceConnected(); + Log.e(TAG, "onServiceConnected: "); + } + +} diff --git a/app/src/main/java/com/ttstd/elderlyassistant/MainActivity.java b/app/src/main/java/com/ttstd/elderlyassistant/activity/main/MainActivity.java similarity index 77% rename from app/src/main/java/com/ttstd/elderlyassistant/MainActivity.java rename to app/src/main/java/com/ttstd/elderlyassistant/activity/main/MainActivity.java index ea74787..b5425af 100644 --- a/app/src/main/java/com/ttstd/elderlyassistant/MainActivity.java +++ b/app/src/main/java/com/ttstd/elderlyassistant/activity/main/MainActivity.java @@ -1,9 +1,11 @@ -package com.ttstd.elderlyassistant; +package com.ttstd.elderlyassistant.activity.main; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; +import com.ttstd.elderlyassistant.R; + public class MainActivity extends AppCompatActivity { @Override diff --git a/app/src/main/java/com/ttstd/elderlyassistant/activity/nfc/NfcActivity.java b/app/src/main/java/com/ttstd/elderlyassistant/activity/nfc/NfcActivity.java new file mode 100644 index 0000000..3354edc --- /dev/null +++ b/app/src/main/java/com/ttstd/elderlyassistant/activity/nfc/NfcActivity.java @@ -0,0 +1,64 @@ +package com.ttstd.elderlyassistant.activity.nfc; + +import androidx.appcompat.app.AppCompatActivity; + +import android.content.Context; +import android.content.Intent; +import android.nfc.NdefMessage; +import android.nfc.NdefRecord; +import android.nfc.NfcAdapter; +import android.nfc.NfcManager; +import android.os.Bundle; +import android.os.Parcelable; +import android.widget.Toast; + +import com.ttstd.elderlyassistant.R; + +import java.util.Arrays; + +public class NfcActivity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_nfc); + + NfcManager manager = (NfcManager) getSystemService(Context.NFC_SERVICE); + NfcAdapter nfcAdapter = manager.getDefaultAdapter(); + + if (nfcAdapter == null) { + // 设备不支持 NFC + Toast.makeText(this, "设备不支持 NFC", Toast.LENGTH_SHORT).show(); + finish(); + } + + } + + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) { + Parcelable[] rawMessages = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES); + if (rawMessages != null) { + NdefMessage[] messages = new NdefMessage[rawMessages.length]; + for (int i = 0; i < rawMessages.length; i++) { + messages[i] = (NdefMessage) rawMessages[i]; + } + // 处理 NDEF 消息 + processNdefMessages(messages); + } + } + } + + private void processNdefMessages(NdefMessage[] messages) { + for (NdefMessage message : messages) { + for (NdefRecord record : message.getRecords()) { + if (record.getTnf() == NdefRecord.TNF_WELL_KNOWN && Arrays.equals(record.getType(), NdefRecord.RTD_TEXT)) { + // 处理文本记录 + String text = new String(record.getPayload()); + Toast.makeText(this, "NFC 数据: " + text, Toast.LENGTH_SHORT).show(); + } + } + } + } +} diff --git a/app/src/main/java/com/ttstd/elderlyassistant/config/CommonConfig.java b/app/src/main/java/com/ttstd/elderlyassistant/config/CommonConfig.java new file mode 100644 index 0000000..d95bf93 --- /dev/null +++ b/app/src/main/java/com/ttstd/elderlyassistant/config/CommonConfig.java @@ -0,0 +1,6 @@ +package com.ttstd.elderlyassistant.config; + +public class CommonConfig { + public static final String MMKV_ID = "InterProcessKV"; + +} diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 4fc2444..c2f34a7 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -4,7 +4,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".MainActivity"> + tools:context=".activity.main.MainActivity"> + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 070e68b..f35b995 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,3 +1,7 @@ ElderlyAssistant + + 老人助理快捷服务 + 老人助理一键拨打视频 + diff --git a/app/src/main/res/xml/accessibility_service_config.xml b/app/src/main/res/xml/accessibility_service_config.xml new file mode 100644 index 0000000..d99d41d --- /dev/null +++ b/app/src/main/res/xml/accessibility_service_config.xml @@ -0,0 +1,10 @@ + diff --git a/app/src/main/res/xml/nfc_tech_filter.xml b/app/src/main/res/xml/nfc_tech_filter.xml new file mode 100644 index 0000000..2424736 --- /dev/null +++ b/app/src/main/res/xml/nfc_tech_filter.xml @@ -0,0 +1,5 @@ + + + android.nfc.tech.Ndef + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index 659b03c..d6eeb1e 100644 --- a/build.gradle +++ b/build.gradle @@ -4,8 +4,14 @@ buildscript { repositories { google() - jcenter() - + mavenCentral() + maven { url "https://jitpack.io" } + maven { url 'https://developer.huawei.com/repo/' } + maven { url 'https://developer.hihonor.com/repo' } + maven { url 'https://maven.aliyun.com/repository/central' } + maven { url "https://maven.aliyun.com/repository/jcenter" } + maven { url 'https://maven.aliyun.com/repository/public' } + maven { url 'https://maven.aliyun.com/repository/google' } } dependencies { classpath 'com.android.tools.build:gradle:3.6.2' @@ -19,8 +25,14 @@ buildscript { allprojects { repositories { google() - jcenter() - + mavenCentral() + maven { url "https://jitpack.io" } + maven { url 'https://developer.huawei.com/repo/' } + maven { url 'https://developer.hihonor.com/repo' } + maven { url 'https://maven.aliyun.com/repository/central' } + maven { url "https://maven.aliyun.com/repository/jcenter" } + maven { url 'https://maven.aliyun.com/repository/public' } + maven { url 'https://maven.aliyun.com/repository/google' } } }