add nfc permission,add AccessibilityService
This commit is contained in:
@@ -1,8 +1,16 @@
|
|||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
|
def appName() {
|
||||||
|
return "TTStdElderlyAssistant"
|
||||||
|
}
|
||||||
|
|
||||||
|
def releaseTime() {
|
||||||
|
return new Date().format("yyyyMMdd_HHmmss", TimeZone.getDefault())
|
||||||
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 33
|
compileSdkVersion 33
|
||||||
buildToolsVersion "36.0.0"
|
buildToolsVersion "30.0.3"
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.ttstd.elderlyassistant"
|
applicationId "com.ttstd.elderlyassistant"
|
||||||
@@ -13,12 +21,68 @@ android {
|
|||||||
versionName "1.0"
|
versionName "1.0"
|
||||||
|
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
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 {
|
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 {
|
release {
|
||||||
minifyEnabled false
|
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 {
|
dependencies {
|
||||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
|
|
||||||
implementation 'androidx.appcompat:appcompat:1.7.1'
|
implementation 'androidx.appcompat:appcompat:1.3.1'
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:2.2.1'
|
implementation 'androidx.constraintlayout:constraintlayout:2.0.3'
|
||||||
|
|
||||||
testImplementation 'junit:junit:4.12'
|
testImplementation 'junit:junit:4.12'
|
||||||
androidTestImplementation 'androidx.test.ext:junit:1.2.1'
|
androidTestImplementation 'androidx.test.ext:junit:1.2.1'
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.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'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,13 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.ttstd.elderlyassistant">
|
package="com.ttstd.elderlyassistant">
|
||||||
|
|
||||||
|
<!--NFC权限-->
|
||||||
|
<uses-permission android:name="android.permission.NFC" />
|
||||||
|
<!--声明只有带NFC的手机才可以下载-->
|
||||||
|
<uses-feature android:name="android.hardware.nfc" android:required="true" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
@@ -9,13 +16,44 @@
|
|||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme">
|
android:theme="@style/AppTheme">
|
||||||
<activity android:name=".MainActivity">
|
<activity android:name=".activity.main.MainActivity">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
|
<activity android:name=".activity.nfc.NfcActivity">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<data android:mimeType="text/plain" />
|
||||||
|
</intent-filter>
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.nfc.action.TECH_DISCOVERED" />
|
||||||
|
</intent-filter>
|
||||||
|
<meta-data
|
||||||
|
android:name="android.nfc.action.TECH_DISCOVERED"
|
||||||
|
android:resource="@xml/nfc_tech_filter" />
|
||||||
|
</activity>
|
||||||
|
|
||||||
|
<service
|
||||||
|
android:name="com.google.android.accessibility.selecttospeak.SelectToSpeakService"
|
||||||
|
android:label="@string/accessibility_service_label"
|
||||||
|
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
|
||||||
|
|
||||||
|
<!-- android:priority="10000" 可提高服务在设置中的权重,排在前面 -->
|
||||||
|
<intent-filter android:priority="10000">
|
||||||
|
<action android:name="android.accessibilityservice.AccessibilityService" />
|
||||||
|
</intent-filter>
|
||||||
|
|
||||||
|
<meta-data
|
||||||
|
android:name="android.accessibilityservice"
|
||||||
|
android:resource="@xml/accessibility_service_config" />
|
||||||
|
</service>
|
||||||
|
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
@@ -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: ");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
package com.ttstd.elderlyassistant;
|
package com.ttstd.elderlyassistant.activity.main;
|
||||||
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import com.ttstd.elderlyassistant.R;
|
||||||
|
|
||||||
public class MainActivity extends AppCompatActivity {
|
public class MainActivity extends AppCompatActivity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package com.ttstd.elderlyassistant.config;
|
||||||
|
|
||||||
|
public class CommonConfig {
|
||||||
|
public static final String MMKV_ID = "InterProcessKV";
|
||||||
|
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context=".MainActivity">
|
tools:context=".activity.main.MainActivity">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
|||||||
9
app/src/main/res/layout/activity_nfc.xml
Normal file
9
app/src/main/res/layout/activity_nfc.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".activity.nfc.NfcActivity">
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
@@ -1,3 +1,7 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">ElderlyAssistant</string>
|
<string name="app_name">ElderlyAssistant</string>
|
||||||
|
|
||||||
|
<string name="accessibility_service_label">老人助理快捷服务</string>
|
||||||
|
<string name="accessibility_service_description">老人助理一键拨打视频</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
10
app/src/main/res/xml/accessibility_service_config.xml
Normal file
10
app/src/main/res/xml/accessibility_service_config.xml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:accessibilityEventTypes="typeAllMask|typeViewClicked|typeViewFocused|typeWindowStateChanged|typeWindowsChanged|typeContextClicked|typeWindowContentChanged"
|
||||||
|
android:accessibilityFeedbackType="feedbackAllMask|feedbackGeneric|feedbackSpoken"
|
||||||
|
android:accessibilityFlags="flagDefault|flagRetrieveInteractiveWindows|flagIncludeNotImportantViews|flagReportViewIds|flagRequestEnhancedWebAccessibility"
|
||||||
|
android:canPerformGestures="true"
|
||||||
|
android:canRequestEnhancedWebAccessibility="true"
|
||||||
|
android:canRetrieveWindowContent="true"
|
||||||
|
android:description="@string/accessibility_service_description"
|
||||||
|
android:notificationTimeout="100"
|
||||||
|
android:packageNames="com.tencent.mm,com.android.incallui" />
|
||||||
5
app/src/main/res/xml/nfc_tech_filter.xml
Normal file
5
app/src/main/res/xml/nfc_tech_filter.xml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
|
<tech-list>
|
||||||
|
<tech>android.nfc.tech.Ndef</tech>
|
||||||
|
</tech-list>
|
||||||
|
</resources>
|
||||||
20
build.gradle
20
build.gradle
@@ -4,8 +4,14 @@ buildscript {
|
|||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
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 {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:3.6.2'
|
classpath 'com.android.tools.build:gradle:3.6.2'
|
||||||
@@ -19,8 +25,14 @@ buildscript {
|
|||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
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' }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user