diff --git a/src/dianhua/.gitignore b/src/dianhua/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/src/dianhua/.gitignore @@ -0,0 +1,14 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx diff --git a/src/dianhua/.idea/.name b/src/dianhua/.idea/.name new file mode 100644 index 0000000..87a4b73 --- /dev/null +++ b/src/dianhua/.idea/.name @@ -0,0 +1 @@ +luyin \ No newline at end of file diff --git a/src/dianhua/.idea/codeStyles/Project.xml b/src/dianhua/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..fb22c1d --- /dev/null +++ b/src/dianhua/.idea/codeStyles/Project.xml @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/src/dianhua/.idea/compiler.xml b/src/dianhua/.idea/compiler.xml new file mode 100644 index 0000000..61a9130 --- /dev/null +++ b/src/dianhua/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/dianhua/.idea/dbnavigator.xml b/src/dianhua/.idea/dbnavigator.xml new file mode 100644 index 0000000..46f942c --- /dev/null +++ b/src/dianhua/.idea/dbnavigator.xml @@ -0,0 +1,458 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/dianhua/.idea/gradle.xml b/src/dianhua/.idea/gradle.xml new file mode 100644 index 0000000..b617266 --- /dev/null +++ b/src/dianhua/.idea/gradle.xml @@ -0,0 +1,23 @@ + + + + + + + \ No newline at end of file diff --git a/src/dianhua/.idea/jarRepositories.xml b/src/dianhua/.idea/jarRepositories.xml new file mode 100644 index 0000000..e21670a --- /dev/null +++ b/src/dianhua/.idea/jarRepositories.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/dianhua/.idea/misc.xml b/src/dianhua/.idea/misc.xml new file mode 100644 index 0000000..d5d35ec --- /dev/null +++ b/src/dianhua/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/src/dianhua/.idea/runConfigurations.xml b/src/dianhua/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/src/dianhua/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/src/dianhua/.idea/vcs.xml b/src/dianhua/.idea/vcs.xml new file mode 100644 index 0000000..b2bdec2 --- /dev/null +++ b/src/dianhua/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/dianhua/app/.gitignore b/src/dianhua/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/src/dianhua/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/src/dianhua/app/build.gradle b/src/dianhua/app/build.gradle new file mode 100644 index 0000000..c526a87 --- /dev/null +++ b/src/dianhua/app/build.gradle @@ -0,0 +1,56 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + useLibrary 'org.apache.http.legacy' + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + defaultConfig { + applicationId "com.example.luyin" + minSdkVersion 23 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } +} + + + +dependencies { + implementation fileTree(dir: "libs", include: ["*.jar"]) + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'androidx.constraintlayout:constraintlayout:2.0.4' + implementation files('src/main/jniLibs/Msc.jar') + compileOnly files('src/main/jniLibs/Android_Map3D_SDK_V7.8.0_20201231.jar') + compileOnly files('src/main/jniLibs/AMap_Location_V5.2.0_20200915.jar') + implementation files('src/main/jniLibs/AMap_Search_V7.7.0_20201027.jar') + compileOnly files('src/main/jniLibs/android-support-v4.jar') + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.2' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' + + implementation 'cn.bmob.android:bmob-sdk:3.7.8' + implementation "io.reactivex.rxjava2:rxjava:2.2.8" + implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' + implementation 'com.squareup.okhttp3:okhttp:3.14.1' + implementation 'com.squareup.okio:okio:2.2.2' + implementation 'com.google.code.gson:gson:2.8.5' + + implementation 'com.amap.api:location:latest.integration' + + implementation 'com.yayandroid:LocationManager:2.0.4' + +} \ No newline at end of file diff --git a/src/dianhua/app/proguard-rules.pro b/src/dianhua/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/src/dianhua/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/src/dianhua/app/release/app-release.aab b/src/dianhua/app/release/app-release.aab new file mode 100644 index 0000000..2c9e443 Binary files /dev/null and b/src/dianhua/app/release/app-release.aab differ diff --git a/src/dianhua/app/src/androidTest/java/com/example/luyin/ExampleInstrumentedTest.java b/src/dianhua/app/src/androidTest/java/com/example/luyin/ExampleInstrumentedTest.java new file mode 100644 index 0000000..aba565d --- /dev/null +++ b/src/dianhua/app/src/androidTest/java/com/example/luyin/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.example.luyin; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + assertEquals("com.example.luyin", appContext.getPackageName()); + } +} \ No newline at end of file diff --git a/src/dianhua/app/src/main/AndroidManifest.xml b/src/dianhua/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..6cee14d --- /dev/null +++ b/src/dianhua/app/src/main/AndroidManifest.xml @@ -0,0 +1,181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/dianhua/app/src/main/ic_launcher-playstore.png b/src/dianhua/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000..27c436d Binary files /dev/null and b/src/dianhua/app/src/main/ic_launcher-playstore.png differ diff --git a/src/dianhua/app/src/main/java/com/example/luyin/activities/CheckPermissionsActivity.java b/src/dianhua/app/src/main/java/com/example/luyin/activities/CheckPermissionsActivity.java new file mode 100644 index 0000000..f5555e9 --- /dev/null +++ b/src/dianhua/app/src/main/java/com/example/luyin/activities/CheckPermissionsActivity.java @@ -0,0 +1,216 @@ + +package com.example.luyin.activities; + +import android.Manifest; +import android.annotation.TargetApi; +import android.app.Activity; +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.provider.Settings; +import android.view.KeyEvent; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +import com.example.luyin.R; + +/** + * 继承了Activity,实现Android6.0的运行时权限检测 + * 需要进行运行时权限检测的Activity可以继承这个类 + * + */ +public class CheckPermissionsActivity extends Activity { + //是否需要检测后台定位权限,设置为true时,如果用户没有给予后台定位权限会弹窗提示 + private boolean needCheckBackLocation = false; + //如果设置了target > 28,需要增加这个权限,否则不会弹出"始终允许"这个选择框 + private static String BACKGROUND_LOCATION_PERMISSION = "android.permission.ACCESS_BACKGROUND_LOCATION"; + /** + * 需要进行检测的权限数组 + */ + protected String[] needPermissions = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.READ_PHONE_STATE + }; + + private static final int PERMISSON_REQUESTCODE = 0; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if(Build.VERSION.SDK_INT > 28 + && getApplicationContext().getApplicationInfo().targetSdkVersion > 28) { + needPermissions = new String[] { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.READ_PHONE_STATE, + BACKGROUND_LOCATION_PERMISSION + }; + } + } + + /** + * 判断是否需要检测,防止不停的弹框 + */ + private boolean isNeedCheck = true; + + @Override + protected void onResume() { + super.onResume(); + if (Build.VERSION.SDK_INT >= 23 + && getApplicationInfo().targetSdkVersion >= 23) { + if (isNeedCheck) { + checkPermissions(needPermissions); + } + } + } + + /** + * + * @param permissions + * @since 2.5.0 + * + */ + private void checkPermissions(String... permissions) { + try { + if (Build.VERSION.SDK_INT >= 23 + && getApplicationInfo().targetSdkVersion >= 23) { + List needRequestPermissonList = findDeniedPermissions(permissions); + if (null != needRequestPermissonList + && needRequestPermissonList.size() > 0) { + String[] array = needRequestPermissonList.toArray(new String[needRequestPermissonList.size()]); + Method method = getClass().getMethod("requestPermissions", new Class[]{String[].class, + int.class}); + + method.invoke(this, array, PERMISSON_REQUESTCODE); + } + } + } catch (Throwable e) { + } + } + + /** + * 获取权限集中需要申请权限的列表 + * + * @param permissions + * @return + * @since 2.5.0 + * + */ + private List findDeniedPermissions(String[] permissions) { + List needRequestPermissonList = new ArrayList(); + if (Build.VERSION.SDK_INT >= 23 + && getApplicationInfo().targetSdkVersion >= 23){ + try { + for (String perm : permissions) { + Method checkSelfMethod = getClass().getMethod("checkSelfPermission", String.class); + Method shouldShowRequestPermissionRationaleMethod = getClass().getMethod("shouldShowRequestPermissionRationale", + String.class); + if ((Integer)checkSelfMethod.invoke(this, perm) != PackageManager.PERMISSION_GRANTED + || (Boolean)shouldShowRequestPermissionRationaleMethod.invoke(this, perm)) { + if(!needCheckBackLocation + && BACKGROUND_LOCATION_PERMISSION.equals(perm)) { + continue; + } + needRequestPermissonList.add(perm); + } + } + } catch (Throwable e) { + + } + } + return needRequestPermissonList; + } + + /** + * 检测是否所有的权限都已经授权 + * @param grantResults + * @return + * @since 2.5.0 + * + */ + private boolean verifyPermissions(int[] grantResults) { + for (int result : grantResults) { + if (result != PackageManager.PERMISSION_GRANTED) { + return false; + } + } + return true; + } + + @TargetApi(23) + public void onRequestPermissionsResult(int requestCode, + String[] permissions, int[] paramArrayOfInt) { + if (requestCode == PERMISSON_REQUESTCODE) { + if (!verifyPermissions(paramArrayOfInt)) { + showMissingPermissionDialog(); + isNeedCheck = false; + } + } + } + + /** + * 显示提示信息 + * + * @since 2.5.0 + * + */ + private void showMissingPermissionDialog() { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(R.string.notifyTitle); + builder.setMessage(R.string.notifyMsg); + + // 拒绝, 退出应用 + builder.setNegativeButton(R.string.cancel, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + finish(); + } + }); + + builder.setPositiveButton(R.string.setting, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + startAppSettings(); + } + }); + + builder.setCancelable(false); + + builder.show(); + } + + /** + * 启动应用的设置 + * + * @since 2.5.0 + * + */ + private void startAppSettings() { + Intent intent = new Intent( + Settings.ACTION_APPLICATION_DETAILS_SETTINGS); + intent.setData(Uri.parse("package:" + getPackageName())); + startActivity(intent); + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if(keyCode == KeyEvent.KEYCODE_BACK){ + this.finish(); + return true; + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/src/dianhua/app/src/main/java/com/example/luyin/activities/Contact.java b/src/dianhua/app/src/main/java/com/example/luyin/activities/Contact.java new file mode 100644 index 0000000..0312848 --- /dev/null +++ b/src/dianhua/app/src/main/java/com/example/luyin/activities/Contact.java @@ -0,0 +1,54 @@ +package com.example.luyin.activities; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.EditText; +import android.widget.Toast; +import com.example.luyin.services.EmergencyPeople; +import com.example.luyin.R; +import cn.bmob.v3.exception.BmobException; +import cn.bmob.v3.listener.SaveListener; + +public class Contact extends Activity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_contact); + //Toast.makeText(Contact.this, "短信发送完成", Toast.LENGTH_LONG).show(); + } + + public void confirm(View view){ + EditText phoneNumber1=(EditText)findViewById(R.id.phonenumber); + String phoneNumber2=phoneNumber1.getText().toString(); + EmergencyPeople people = new EmergencyPeople(); + people.setPhoneNumber(phoneNumber2); + EditText name1=(EditText)findViewById(R.id.contact); + String name2=name1.getText().toString(); + EmergencyPeople people1 = new EmergencyPeople(); + people1.setPhoneNumber(phoneNumber2); + people1.setName(name2); + Log.e("ss", "confirm: "+ people1.getName() ); + Log.e("bb", "confirm: "+people1.getPhoneNumber()); + people1.save(new SaveListener() { + @Override + public void done(String s, BmobException e) { + if(e==null){ + Toast.makeText(getApplicationContext(),"添加联系人成功",Toast.LENGTH_LONG).show(); + }else{ + Toast.makeText(getApplicationContext(),"添加失败",Toast.LENGTH_LONG).show(); + } + } + }); +// Toast.makeText(Contact.this, "已添加紧急联系人",Toast.LENGTH_SHORT).show(); + + Intent intent = new Intent(Contact.this,MainActivity.class); + startActivity(intent); + + + } + +} diff --git a/src/dianhua/app/src/main/java/com/example/luyin/activities/Location_Activity.java b/src/dianhua/app/src/main/java/com/example/luyin/activities/Location_Activity.java new file mode 100644 index 0000000..ff0e880 --- /dev/null +++ b/src/dianhua/app/src/main/java/com/example/luyin/activities/Location_Activity.java @@ -0,0 +1,384 @@ +package com.example.luyin.activities; + +import android.content.Intent; +import android.os.Bundle; +import android.text.TextUtils; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.RadioGroup; +import android.widget.RadioGroup.OnCheckedChangeListener; +import android.widget.TextView; + +import com.amap.api.location.AMapLocation; +import com.amap.api.location.AMapLocationClient; +import com.amap.api.location.AMapLocationClientOption; +import com.amap.api.location.AMapLocationClientOption.AMapLocationMode; +import com.amap.api.location.AMapLocationClientOption.AMapLocationProtocol; +import com.amap.api.location.AMapLocationListener; +import com.amap.api.location.AMapLocationQualityReport; + +import com.example.luyin.utils.Utils; +import com.example.luyin.R; + +// 高精度定位模式 + +public class Location_Activity extends CheckPermissionsActivity + implements + OnCheckedChangeListener, + OnClickListener { + private RadioGroup rgLocationMode; + private EditText etInterval; + private EditText etHttpTimeout; + private CheckBox cbOnceLocation; + private CheckBox cbAddress; + private CheckBox cbGpsFirst; + private CheckBox cbCacheAble; + private CheckBox cbOnceLastest; + private CheckBox cbSensorAble; + private TextView tvResult; + private Button btLocation; + private RadioGroup rgGeoLanguage; + + private AMapLocationClient locationClient = null; + private AMapLocationClientOption locationOption = null; + //储存位置 + public static String Location = null; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_location); + setTitle(R.string.title_location); + + initView(); + + //初始化定位 + initLocation(); + } + + //初始化控件 + private void initView(){ + rgLocationMode = (RadioGroup) findViewById(R.id.rg_locationMode); + + etInterval = (EditText) findViewById(R.id.et_interval); + etHttpTimeout = (EditText) findViewById(R.id.et_httpTimeout); + + cbOnceLocation = (CheckBox)findViewById(R.id.cb_onceLocation); + cbGpsFirst = (CheckBox) findViewById(R.id.cb_gpsFirst); + cbAddress = (CheckBox) findViewById(R.id.cb_needAddress); + cbCacheAble = (CheckBox) findViewById(R.id.cb_cacheAble); + cbOnceLastest = (CheckBox) findViewById(R.id.cb_onceLastest); + cbSensorAble = (CheckBox)findViewById(R.id.cb_sensorAble); + + tvResult = (TextView) findViewById(R.id.tv_result); + btLocation = (Button) findViewById(R.id.bt_location); + + rgGeoLanguage = (RadioGroup) findViewById(R.id.rg_language); + + rgLocationMode.setOnCheckedChangeListener(this); + btLocation.setOnClickListener(this); + rgGeoLanguage.setOnCheckedChangeListener(this); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + destroyLocation(); + } + + @Override + public void onCheckedChanged(RadioGroup group, int checkedId) { + if (null == locationOption) { + locationOption = new AMapLocationClientOption(); + } + if(group == rgLocationMode) { + switch (checkedId) { + case R.id.rb_batterySaving: + locationOption.setLocationMode(AMapLocationMode.Battery_Saving); + break; + case R.id.rb_deviceSensors: + locationOption.setLocationMode(AMapLocationMode.Device_Sensors); + break; + case R.id.rb_hightAccuracy: + locationOption.setLocationMode(AMapLocationMode.Hight_Accuracy); + break; + default: + break; + } + } + if(group == rgGeoLanguage){ + switch (checkedId){ + case R.id.rb_languageDefault: + locationOption.setGeoLanguage(AMapLocationClientOption.GeoLanguage.DEFAULT); + break; + case R.id.rb_languageEN: + locationOption.setGeoLanguage(AMapLocationClientOption.GeoLanguage.EN); + break; + case R.id.rb_languageZH: + locationOption.setGeoLanguage(AMapLocationClientOption.GeoLanguage.ZH); + break; + } + } + + } + + /** + * 设置控件的可用状态 + */ + private void setViewEnable(boolean isEnable) { + for(int i=0; i= 26) { + //Android O上对Notification进行了修改,如果设置的targetSDKVersion>=26建议使用此种方式创建通知栏 + if (null == notificationManager) { + notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + } + String channelId = getPackageName(); + if(!isCreateChannel) { + NotificationChannel notificationChannel = new NotificationChannel(channelId, + NOTIFICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT); + notificationChannel.enableLights(true);//是否在桌面icon右上角展示小圆点 + notificationChannel.setLightColor(Color.WHITE); //小圆点颜色 + notificationChannel.setShowBadge(true); //是否在久按桌面图标时显示此渠道的通知 + notificationManager.createNotificationChannel(notificationChannel); + isCreateChannel = true; + } + builder = new Notification.Builder(getApplicationContext(), channelId); + } else { + builder = new Notification.Builder(getApplicationContext()); + } + builder.setSmallIcon(R.drawable.locate) + .setContentTitle(Utils.getAppName(this)) + .setContentText("正在后台运行") + .setWhen(System.currentTimeMillis()); + + if (android.os.Build.VERSION.SDK_INT >= 16) { + notification = builder.build(); + } else { + return builder.getNotification(); + } + return notification; + } + +} diff --git a/src/dianhua/app/src/main/java/com/example/luyin/activities/MainActivity.java b/src/dianhua/app/src/main/java/com/example/luyin/activities/MainActivity.java new file mode 100644 index 0000000..144d83d --- /dev/null +++ b/src/dianhua/app/src/main/java/com/example/luyin/activities/MainActivity.java @@ -0,0 +1,729 @@ +package com.example.luyin.activities; + +import android.Manifest; +import android.annotation.SuppressLint; +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; +import android.media.MediaPlayer; +import android.media.MediaRecorder; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.os.Environment; +import android.os.Handler; +import android.os.Message; +import android.os.Vibrator; +import android.telephony.SmsManager; +import android.text.TextUtils; +import android.view.KeyEvent; +import android.view.View; +import android.widget.Button; +import android.widget.TextView; +import android.widget.Toast; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.telephony.SmsManager; +import android.telephony.SmsMessage; +import android.util.Log; + + + +import android.graphics.Color; + +import android.widget.CompoundButton; +import com.amap.api.location.AMapLocation; +import com.amap.api.location.AMapLocationClient; +import com.amap.api.location.AMapLocationClientOption; +import com.amap.api.location.AMapLocationListener; +import com.example.luyin.services.Location; +import com.example.luyin.speech.setting.TtsSettings; +import com.iflytek.cloud.ErrorCode; +import com.iflytek.cloud.InitListener; +import com.iflytek.cloud.SpeechConstant; +import com.iflytek.cloud.SpeechError; +import com.iflytek.cloud.SpeechEvent; +import com.iflytek.cloud.SpeechSynthesizer; +import com.iflytek.cloud.SpeechUtility; +import com.iflytek.cloud.SynthesizerListener; +import com.iflytek.cloud.util.ResourceUtil; +import com.example.luyin.utils.Utils; +import com.example.luyin.R; + + +import java.util.ArrayList; +import java.util.Calendar; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.atomic.AtomicLong; + + +import cn.bmob.v3.Bmob; +import cn.bmob.v3.exception.BmobException; +import cn.bmob.v3.listener.SaveListener; + + +public class MainActivity extends Activity implements SensorEventListener { + private static String TAG = MainActivity.class.getSimpleName(); + private static final String TAG_EXIT = "程序退出"; + private static final String ACTION = "android.provider.Telephony.SMS_RECEIVED"; + private static final String NOTIFICATION_CHANNEL_NAME = "BackgroundLocation"; + private final String TAGS = "SMSBroadcastReceiver"; + + private AMapLocationClient locationClient = null; //声明mLocationOption对象 + private AMapLocationClientOption locationOption = null; + + public String LocationLLLL = null; + public long lastTime = 0; + public long timeDifference = 1000; + + private NotificationManager notificationManager = null; + private SensorManager sensorManager; //sensor管理器 + private Vibrator mVibrator; //震动 + private TextView start; + private TextView mOffTextView; + private Handler mOffHandler; + private Timer mOffTime; + private Dialog mDialog; + private Button button = null; //按钮 + private boolean mIsExit; + private boolean isCreateChannel = false; + + private Toast mToast; + private SpeechSynthesizer mTts; + private int mPercentForBuffering = 0; + private int mPercentForPlaying = 0; + private String mEngineType = SpeechConstant.TYPE_CLOUD; + // 默认云端发音人 + public static String voicerCloud="xiaoyan"; + // 默认本地发音人 + public static String voicerLocal="xiaoyan"; + + public static String voicerXtts="xiaoyan"; + + private SharedPreferences mSharedPreferences; + + + + @Override + protected void onCreate(Bundle savedInstanceState) { + + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + button = (Button)findViewById(R.id.getLocation); + button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent intent = new Intent(); + intent.setClass(MainActivity.this,Location_Activity.class); + startActivity(intent); + } + }); + start=(TextView) findViewById(R.id.start); + + sensorManager=(SensorManager) getSystemService(SENSOR_SERVICE); + + mVibrator=(Vibrator) getSystemService(VIBRATOR_SERVICE); + initLocation(); + if(null == locationClient){ + locationClient = new AMapLocationClient(this); + } + boolean isCreateChannel = false; + locationClient.enableBackgroundLocation(2001, buildNotification()); + locationClient.startLocation(); + +// getCurrentLocationLatLng(); + Bmob.initialize(this,"f7635857d1eedd1e8949b0ca0d5324de"); //添加bmob数据库 +//初始化语音 + StringBuffer param = new StringBuffer(); + param.append("appid="+getString(R.string.app_id)); + param.append(","); + // 设置使用v5+ + param.append(SpeechConstant.ENGINE_MODE+"="+ SpeechConstant.MODE_MSC); + SpeechUtility.createUtility(MainActivity.this, param.toString()); + + mTts = SpeechSynthesizer.createSynthesizer(this, mTtsInitListener); + mSharedPreferences = getSharedPreferences(TtsSettings.PREFER_NAME, Activity.MODE_PRIVATE); + + } + + + public void stop(View view) { + Toast.makeText(MainActivity.this, "程序已结束", Toast.LENGTH_SHORT).show(); + finish(); + } + + public void getLocation(View view){ + + } + + public void play(View view) { + Toast.makeText(MainActivity.this, "程序开始", Toast.LENGTH_SHORT).show(); + sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_UI); + } + + public void contact(View view) { + Intent intent = new Intent(MainActivity.this, Contact.class); + startActivity(intent); + //finish(); + } + + public void voice(View view) { + Intent intent = new Intent(MainActivity.this, VoiceActivity.class); + startActivity(intent); + //finish(); + //Toast.makeText(MainActivity.this, "cnm", Toast.LENGTH_LONG).show(); + } + + public void backLocate(View view){ + Intent intent = new Intent(MainActivity.this, Location_BackGround_Activity.class); + startActivity(intent); + } + + public void wechat(View view) { + Intent intent = new Intent(MainActivity.this, Wechat.class); + startActivity(intent); + //finish(); + } + + private void showToast(String msg) { + Toast.makeText(MainActivity.this, msg, Toast.LENGTH_LONG).show(); + } + + private void showTip(final String str){ + runOnUiThread(new Runnable() { + @Override + public void run() { + mToast.setText(str); + mToast.show(); + } + }); + } + + + @Override + protected void onResume() { + // TODO Auto-generated method stub + super.onResume(); //传感器的绑定 + } + + @Override + protected void onStop() { + // TODO Auto-generated method stub + sensorManager.unregisterListener(this); //传感器的解除绑定 + super.onStop(); + } + + + + @SuppressLint("HandlerLeak") + @Override + + public void onSensorChanged(SensorEvent event) { + + // TODO Auto-generated method stub + + String phonenum = "18577348433"; + if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { + if (Math.abs(event.values[0]) > 20 || Math.abs(event.values[1]) > 20 || Math.abs(event.values[2]) > 20) { + + AtomicLong currentTime = new AtomicLong(Calendar.getInstance().getTimeInMillis()); + if ((currentTime.get() - lastTime) > timeDifference) { + lastTime = currentTime.get(); + //mVibrator.vibrate(100); + + //获得Vibrator实例 + final Vibrator vibrator = (Vibrator)this.getSystemService(this.VIBRATOR_SERVICE); + //暂停1秒,震动2秒,暂停1秒,震动2秒 + long[] patter = {1000, 2000, 1000, 2000}; + //设置为持续震动 + vibrator.vibrate(patter, 0); + //showToast("开始震动"); + setParam(); + int code = mTts.startSpeaking(getString(R.string.crash), mTtsListener); + mOffTextView = new TextView(this); + mDialog = new AlertDialog.Builder(this) + .setTitle(getString(R.string.crash)) + .setCancelable(false) + .setView(mOffTextView) + .setPositiveButton("确定", new DialogInterface.OnClickListener() { + //点击确定后的操作 + public void onClick(DialogInterface dialog, int id) { + mOffTime.cancel(); + mTts.stopSpeaking(); + vibrator.cancel(); + sendMessage(); + } + + }) + + .setNegativeButton("取消", new DialogInterface.OnClickListener() { + //点击取消后的操作 + public void onClick(DialogInterface dialog, int id) { + dialog.cancel(); + mOffTime.cancel(); + showToast("没有报警"); + //震动停止 + vibrator.cancel(); + mTts.stopSpeaking(); + } + }) + .create(); + mDialog.show(); + mDialog.setCanceledOnTouchOutside(false); + + mOffHandler = new Handler() { + public void handleMessage(Message msg) { + + if (msg.what > 0) { + + //动态显示倒计时 + mOffTextView.setText("\n" + + " 倒计时:" + msg.what); + + } else { + + //倒计时结束自己主动关闭 + if (mDialog != null) { + mDialog.dismiss(); + } + + //callPhone(phonenum); + showToast("您未点击取消,已报警"); + //关闭后的操作 + mOffTime.cancel(); + //震动停止 + vibrator.cancel(); + } + super.handleMessage(msg); + } + + }; + + //////倒计时 + mOffTime = new Timer(true); + TimerTask tt = new TimerTask() { + int countTime = 30; + + public void run() { + if (countTime > 0) { + countTime--; + } + Message msg = new Message(); + msg.what = countTime; + mOffHandler.sendMessage(msg); + } + }; + mOffTime.schedule(tt, 1000, 1000); + } + } + } + } + + @Override + public void onAccuracyChanged(Sensor sensor, int accuracy) { + // TODO Auto-generated method stub + } + + public void callPhone(String phoneNum) { + //android6版本获取动态权限 + if (Build.VERSION.SDK_INT >= 23) { + int REQUEST_CODE_CONTACT = 101; + String[] permissions = {Manifest.permission.CALL_PHONE}; + //验证是否许可权限 + for (String str : permissions) { + if (this.checkSelfPermission(str) != PackageManager.PERMISSION_GRANTED) { + //申请权限 + this.requestPermissions(permissions, REQUEST_CODE_CONTACT); + return; + } + } + } + //如果需要手动拨号将Intent.ACTION_CALL改为Intent.ACTION_DIAL(跳转到拨号界面,用户手动点击拨打) + Intent intent = new Intent(Intent.ACTION_CALL); + Uri data = Uri.parse("tel:" + phoneNum); + intent.setData(data); + startActivity(intent); + } + + public void sendMessage() { +// Intent intent = getIntent(); +// String content = intent.getStringExtra("location"); + String content = LocationLLLL; + String number = "18577348433"; + + if (TextUtils.isEmpty(number)) { + showToast("请输入手机号"); + return; + } + if (TextUtils.isEmpty(content)) { + showToast("请输入内容"); + return; + } + + ArrayList messages = SmsManager.getDefault().divideMessage(content); + for (String text : messages) { + SmsManager.getDefault().sendTextMessage(number, null, text, null, null); + setParam(); + int code = mTts.startSpeaking("救命!我出车祸了!"+text, mTtsListener); + } + showToast("短信已发送"); + Location loca1 = new Location(); + loca1.setAddress(LocationLLLL); + loca1.setName("ouxiaolan"); + loca1.save(new SaveListener() { + @Override + public void done(String s, BmobException e) { + if(e==null){ + Toast.makeText(getApplicationContext(),"添加数据成功,返回objectID"+s,Toast.LENGTH_LONG).show(); + }else{ + Toast.makeText(getApplicationContext(),"创建数据失败"+e.getMessage(),Toast.LENGTH_LONG).show(); + } + } + }); + + } + + private void initLocation(){ + //初始化client + locationClient = new AMapLocationClient(this.getApplicationContext()); + locationOption = getDefaultOption(); + //设置定位参数 + locationClient.setLocationOption(locationOption); + // 设置定位监听 + locationClient.setLocationListener(locationListener); + } + + private Notification buildNotification() { + Notification.Builder builder = null; + Notification notification = null; + if(android.os.Build.VERSION.SDK_INT >= 26) { + //Android O上对Notification进行了修改,如果设置的targetSDKVersion>=26建议使用此种方式创建通知栏 + if (null == notificationManager) { + notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + } + String channelId = getPackageName(); + if(!isCreateChannel) { + NotificationChannel notificationChannel = new NotificationChannel(channelId, + NOTIFICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT); + notificationChannel.enableLights(true);//是否在桌面icon右上角展示小圆点 + notificationChannel.setLightColor(Color.WHITE); //小圆点颜色 + notificationChannel.setShowBadge(true); //是否在久按桌面图标时显示此渠道的通知 + notificationManager.createNotificationChannel(notificationChannel); + isCreateChannel = true; + } + builder = new Notification.Builder(getApplicationContext(), channelId); + } else { + builder = new Notification.Builder(getApplicationContext()); + } + builder.setSmallIcon(R.drawable.locate) + .setContentTitle(Utils.getAppName(this)) + .setContentText("正在后台运行") + .setWhen(System.currentTimeMillis()); + + if (android.os.Build.VERSION.SDK_INT >= 16) { + notification = builder.build(); + } else { + return builder.getNotification(); + } + return notification; + } + + private AMapLocationClientOption getDefaultOption(){ + AMapLocationClientOption mOption = new AMapLocationClientOption(); + mOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);//可选,设置定位模式,可选的模式有高精度、仅设备、仅网络。默认为高精度模式 + mOption.setGpsFirst(false);//可选,设置是否gps优先,只在高精度模式下有效。默认关闭 + mOption.setHttpTimeOut(30000);//可选,设置网络请求超时时间。默认为30秒。在仅设备模式下无效 + mOption.setInterval(2000);//可选,设置定位间隔。默认为2秒 + mOption.setNeedAddress(true);//可选,设置是否返回逆地理地址信息。默认是true + mOption.setOnceLocation(false);//可选,设置是否单次定位。默认是false + mOption.setOnceLocationLatest(false);//可选,设置是否等待wifi刷新,默认为false.如果设置为true,会自动变为单次定位,持续定位时不要使用 + AMapLocationClientOption.setLocationProtocol(AMapLocationClientOption.AMapLocationProtocol.HTTP);//可选, 设置网络请求的协议。可选HTTP或者HTTPS。默认为HTTP + mOption.setSensorEnable(false);//可选,设置是否使用传感器。默认是false + mOption.setWifiScan(true); //可选,设置是否开启wifi扫描。默认为true,如果设置为false会同时停止主动刷新,停止以后完全依赖于系统刷新,定位位置可能存在误差 + mOption.setLocationCacheEnable(true); //可选,设置是否使用缓存定位,默认为true + return mOption; + } + + AMapLocationListener locationListener = new AMapLocationListener() { + @Override + public void onLocationChanged(AMapLocation location) { + if (null != location) { + + StringBuffer sb = new StringBuffer(); + //errCode等于0代表定位成功,其他的为定位失败,具体的可以参照官网定位错误码说明 + if(location.getErrorCode() == 0){ + sb.append("定位成功" + "\n"); + sb.append("定位类型: " + location.getLocationType() + "\n"); + sb.append("经 度 : " + location.getLongitude() + "\n"); + sb.append("纬 度 : " + location.getLatitude() + "\n"); + sb.append("精 度 : " + location.getAccuracy() + "米" + "\n"); + sb.append("提供者 : " + location.getProvider() + "\n"); + + sb.append("速 度 : " + location.getSpeed() + "米/秒" + "\n"); + sb.append("角 度 : " + location.getBearing() + "\n"); + // 获取当前提供定位服务的卫星个数 + sb.append("星 数 : " + location.getSatellites() + "\n"); + sb.append("国 家 : " + location.getCountry() + "\n"); + sb.append("省 : " + location.getProvince() + "\n"); + sb.append("市 : " + location.getCity() + "\n"); + sb.append("城市编码 : " + location.getCityCode() + "\n"); + sb.append("区 : " + location.getDistrict() + "\n"); + sb.append("区域 码 : " + location.getAdCode() + "\n"); + sb.append("地 址 : " + location.getAddress() + "\n"); + sb.append("兴趣点 : " + location.getPoiName() + "\n"); + //定位完成的时间 + sb.append("定位时间: " + Utils.formatUTC(location.getTime(), "yyyy-MM-dd HH:mm:ss") + "\n"); + } else { + //定位失败 + sb.append("定位失败" + "\n"); + sb.append("错误码:" + location.getErrorCode() + "\n"); + sb.append("错误信息:" + location.getErrorInfo() + "\n"); + sb.append("错误描述:" + location.getLocationDetail() + "\n"); + } + sb.append("***定位质量报告***").append("\n"); + sb.append("* WIFI开关:").append(location.getLocationQualityReport().isWifiAble() ? "开启":"关闭").append("\n"); +// sb.append("* GPS状态:").append(getGPSStatusString(location.getLocationQualityReport().getGPSStatus())).append("\n"); + sb.append("* GPS星数:").append(location.getLocationQualityReport().getGPSSatellites()).append("\n"); + sb.append("* 网络类型:" + location.getLocationQualityReport().getNetworkType()).append("\n"); + sb.append("* 网络耗时:" + location.getLocationQualityReport().getNetUseTime()).append("\n"); + sb.append("****************").append("\n"); + //定位之后的回调时间 + sb.append("回调时间: " + Utils.formatUTC(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss") + "\n"); + + //解析定位结果, + String result = sb.toString(); +// Log.i(TAG, "onLocationChanged: "+"1111111111111111111111111111"); + LocationLLLL = "请速来救援"+"\n"+"地点在国防科技大学三号宿舍楼,具体经纬度为:"+location.getProvince() + location.getCity()+location.getDistrict() + +location.getAddress()+location.getStreet()+location.getStreetNum() + +"\n"+"北纬"+location.getLatitude()+"度"+"东经"+location.getLongitude()+"度"; + +// Intent intent = new Intent(); +// intent.putExtra("location",result); +//// startActivity(intent); +// sendBroadcast(intent); +// tvResult.setText(result); + } else { +// tvResult.setText("定位失败,loc is null"); + Toast.makeText(MainActivity.this,"定位失败",Toast.LENGTH_SHORT).show(); + } + } + }; + + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + if (intent != null) { + boolean isExit = intent.getBooleanExtra(TAG_EXIT, false); + if (isExit) { + this.finish(); + } + } + } + + /** + * 双击返回键退出 + */ + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (mIsExit) { + this.finish(); + + } else { + Toast.makeText(this, "再按一次退出", Toast.LENGTH_SHORT).show(); + mIsExit = true; + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + mIsExit = false; + } + }, 2000); + } + return true; + } + return super.onKeyDown(keyCode, event); + } + + /** + * 初始化监听。 + */ + private InitListener mTtsInitListener = new InitListener() { + @Override + public void onInit(int code) { + Log.d(TAG, "InitListener init() code = " + code); + if (code != ErrorCode.SUCCESS) { + showTip("初始化失败,错误码:"+code+",请点击网址https://www.xfyun.cn/document/error-code查询解决方案"); + + } else { + // 初始化成功,之后可以调用startSpeaking方法 + // 注:有的开发者在onCreate方法中创建完合成对象之后马上就调用startSpeaking进行合成, + // 正确的做法是将onCreate中的startSpeaking调用移至这里 + } + } + }; + + /** + * 合成回调监听。 + */ + private SynthesizerListener mTtsListener = new SynthesizerListener() { + + @Override + public void onSpeakBegin() { + //showTip("开始播放"); + Log.d(MainActivity.TAG,"开始播放:"+ System.currentTimeMillis()); + } + + @Override + public void onSpeakPaused() { + showTip("暂停播放"); + } + + @Override + public void onSpeakResumed() { + showTip("继续播放"); + } + + @Override + public void onBufferProgress(int percent, int beginPos, int endPos, + String info) { + // 合成进度 + mPercentForBuffering = percent; + showTip(String.format(getString(R.string.tts_toast_format), + mPercentForBuffering, mPercentForPlaying)); + } + + @Override + public void onSpeakProgress(int percent, int beginPos, int endPos) { + // 播放进度 + mPercentForPlaying = percent; + showTip(String.format(getString(R.string.tts_toast_format), + mPercentForBuffering, mPercentForPlaying)); + } + + @Override + public void onCompleted(SpeechError error) { + if (error == null) { + showTip("播放完成"); + } else if (error != null) { + showTip(error.getPlainDescription(true)); + } + } + + @Override + public void onEvent(int eventType, int arg1, int arg2, Bundle obj) { + // 以下代码用于获取与云端的会话id,当业务出错时将会话id提供给技术支持人员,可用于查询会话日志,定位出错原因 + // 若使用本地能力,会话id为null + if (SpeechEvent.EVENT_SESSION_ID == eventType) { + String sid = obj.getString(SpeechEvent.KEY_EVENT_AUDIO_URL); + Log.d(TAGS, "session id =" + sid); + } + + //实时音频流输出参考 + /*if (SpeechEvent.EVENT_TTS_BUFFER == eventType) { + byte[] buf = obj.getByteArray(SpeechEvent.KEY_EVENT_TTS_BUFFER); + Log.e("MscSpeechLog", "buf is =" + buf); + }*/ + } + }; + + /** + * 参数设置 + */ + private void setParam(){ + // 清空参数 + mTts.setParameter(SpeechConstant.PARAMS, null); + //设置合成 + if(mEngineType.equals(SpeechConstant.TYPE_CLOUD)) + { + //设置使用云端引擎 + mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD); + //设置发音人 + mTts.setParameter(SpeechConstant.VOICE_NAME,voicerCloud); + + }else if(mEngineType.equals(SpeechConstant.TYPE_LOCAL)){ + //设置使用本地引擎 + mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_LOCAL); + //设置发音人资源路径 + mTts.setParameter(ResourceUtil.TTS_RES_PATH,getResourcePath()); + //设置发音人 + mTts.setParameter(SpeechConstant.VOICE_NAME,voicerLocal); + }else{ + mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_XTTS); + //设置发音人资源路径 + mTts.setParameter(ResourceUtil.TTS_RES_PATH,getResourcePath()); + //设置发音人 + mTts.setParameter(SpeechConstant.VOICE_NAME,voicerXtts); + } + //mTts.setParameter(SpeechConstant.TTS_DATA_NOTIFY,"1");//支持实时音频流抛出,仅在synthesizeToUri条件下支持 + //设置合成语速 + mTts.setParameter(SpeechConstant.SPEED, mSharedPreferences.getString("speed_preference", "50")); + //设置合成音调 + mTts.setParameter(SpeechConstant.PITCH, mSharedPreferences.getString("pitch_preference", "50")); + //设置合成音量 + mTts.setParameter(SpeechConstant.VOLUME, mSharedPreferences.getString("volume_preference", "50")); + //设置播放器音频流类型 + mTts.setParameter(SpeechConstant.STREAM_TYPE, mSharedPreferences.getString("stream_preference", "3")); + // mTts.setParameter(SpeechConstant.STREAM_TYPE, AudioManager.STREAM_MUSIC+""); + + // 设置播放合成音频打断音乐播放,默认为true + mTts.setParameter(SpeechConstant.KEY_REQUEST_FOCUS, "true"); + + // 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限 + mTts.setParameter(SpeechConstant.AUDIO_FORMAT, "wav"); + + mTts.setParameter(SpeechConstant.TTS_AUDIO_PATH, Environment.getExternalStorageDirectory()+"/msc/tts.wav"); + + + } + + //获取发音人资源路径 + private String getResourcePath(){ + StringBuffer tempBuffer = new StringBuffer(); + String type= "tts"; + if(mEngineType.equals(SpeechConstant.TYPE_XTTS)){ + type="xtts"; + } + //合成通用资源 + tempBuffer.append(ResourceUtil.generateResourcePath(this, ResourceUtil.RESOURCE_TYPE.assets, type+"/common.jet")); + tempBuffer.append(";"); + //发音人资源 + if(mEngineType.equals(SpeechConstant.TYPE_XTTS)){ + tempBuffer.append(ResourceUtil.generateResourcePath(this, ResourceUtil.RESOURCE_TYPE.assets, type+"/"+ TtsDemo.voicerXtts+".jet")); + }else { + tempBuffer.append(ResourceUtil.generateResourcePath(this, ResourceUtil.RESOURCE_TYPE.assets, type + "/" + TtsDemo.voicerLocal + ".jet")); + } + + return tempBuffer.toString(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + + if( null != mTts ){ + mTts.stopSpeaking(); + // 退出时释放连接 + mTts.destroy(); + } + } +} diff --git a/src/dianhua/app/src/main/java/com/example/luyin/activities/MyApplication.java b/src/dianhua/app/src/main/java/com/example/luyin/activities/MyApplication.java new file mode 100644 index 0000000..cf029cf --- /dev/null +++ b/src/dianhua/app/src/main/java/com/example/luyin/activities/MyApplication.java @@ -0,0 +1,61 @@ +package com.example.luyin.activities; + +import android.app.Activity; +import android.app.Application; +import android.os.Bundle; + + +public class MyApplication extends Application { + private int count = 0; + + @Override + public void onCreate() { + super.onCreate(); + registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() { + @Override + public void onActivityCreated(Activity activity, Bundle savedInstanceState) { + } + + @Override + public void onActivityStarted(Activity activity) { + count ++; + } + + @Override + public void onActivityResumed(Activity activity) { + } + + @Override + public void onActivityPaused(Activity activity) { + } + + @Override + public void onActivityStopped(Activity activity) { + if(count > 0) { + count--; + } + } + + @Override + public void onActivitySaveInstanceState(Activity activity, Bundle outState) { + + } + + @Override + public void onActivityDestroyed(Activity activity) { + } + }); + } + + /** + * 判断app是否在后台 + * @return + */ + public boolean isBackground(){ + if(count <= 0){ + return true; + } else { + return false; + } + } +} diff --git a/src/dianhua/app/src/main/java/com/example/luyin/activities/SMS.java b/src/dianhua/app/src/main/java/com/example/luyin/activities/SMS.java new file mode 100644 index 0000000..f5d683f --- /dev/null +++ b/src/dianhua/app/src/main/java/com/example/luyin/activities/SMS.java @@ -0,0 +1,60 @@ +package com.example.luyin.activities; + +import java.util.ArrayList; + +import android.app.Activity; +import android.os.Bundle; +import android.telephony.SmsManager; +import android.text.TextUtils; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.EditText; +import android.widget.Toast; + +import com.example.luyin.R; + +public class SMS extends Activity { + + private EditText mNumberText; + private EditText mContentText; + + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setTitle(getString(R.string.app_name)); + setContentView(R.layout.activity_sms); + + mNumberText = (EditText)this.findViewById(R.id.number);//找到number + mContentText = (EditText)this.findViewById(R.id.msg_content); + + } + + + public void SEND(View view) { + + + //String content = mContentText.getText().toString(); + //String number = mNumberText.getText().toString(); + String content = "尼玛1111111111111111"; + String number = "18577348433"; + + if(TextUtils.isEmpty(number)){ + showToast("请输入手机号"); + return; + } + if(TextUtils.isEmpty(content)){ + showToast("请输入内容"); + return; + } + + ArrayList messages = SmsManager.getDefault().divideMessage(content); + for(String text : messages){ + SmsManager.getDefault().sendTextMessage(number, null, text, null, null); + } + showToast("success"); + } + + private void showToast(String msg) { + Toast.makeText(SMS.this, msg, Toast.LENGTH_LONG).show(); + } + +} \ No newline at end of file diff --git a/src/dianhua/app/src/main/java/com/example/luyin/activities/TtsDemo.java b/src/dianhua/app/src/main/java/com/example/luyin/activities/TtsDemo.java new file mode 100644 index 0000000..acffee3 --- /dev/null +++ b/src/dianhua/app/src/main/java/com/example/luyin/activities/TtsDemo.java @@ -0,0 +1,431 @@ +package com.example.luyin.activities; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.os.Environment; +import android.util.Log; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.Window; +import android.widget.EditText; +import android.widget.RadioGroup; +import android.widget.RadioGroup.OnCheckedChangeListener; +import android.widget.Toast; + +import com.example.luyin.speech.setting.TtsSettings; +import com.iflytek.cloud.ErrorCode; +import com.iflytek.cloud.InitListener; +import com.iflytek.cloud.SpeechConstant; +import com.iflytek.cloud.SpeechError; +import com.iflytek.cloud.SpeechEvent; +import com.iflytek.cloud.SpeechSynthesizer; +import com.iflytek.cloud.SynthesizerListener; +import com.iflytek.cloud.util.ResourceUtil; +import com.iflytek.cloud.util.ResourceUtil.RESOURCE_TYPE; +import com.example.luyin.R; + +//import com.iflytek.cloud.param.MscKeys; + +public class TtsDemo extends Activity implements OnClickListener { + private static String TAG = TtsDemo.class.getSimpleName(); + // 语音合成对象 + private SpeechSynthesizer mTts; + + // 默认云端发音人 + public static String voicerCloud="xiaoyan"; + // 默认本地发音人 + public static String voicerLocal="xiaoyan"; + + public static String voicerXtts="xiaoyan"; + // 云端发音人列表 + private String[] cloudVoicersEntries; + private String[] cloudVoicersValue ; + + // 本地发音人列表 + private String[] localVoicersEntries; + private String[] localVoicersValue ; + + // 增强版发音人列表 + private String[] xttsVoicersEntries; + private String[] xttsVoicersValue; + + //缓冲进度 + private int mPercentForBuffering = 0; + //播放进度 + private int mPercentForPlaying = 0; + + // 云端/本地选择按钮 + private RadioGroup mRadioGroup; + // 引擎类型 + private String mEngineType = SpeechConstant.TYPE_CLOUD; + + private Toast mToast; + private SharedPreferences mSharedPreferences; + + @SuppressLint("ShowToast") + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + this.requestWindowFeature(Window.FEATURE_NO_TITLE); + setContentView(R.layout.ttsdemo); + initLayout(); + + // 初始化合成对象 + mTts = SpeechSynthesizer.createSynthesizer(this, mTtsInitListener); + + // 云端发音人名称列表 + cloudVoicersEntries = getResources().getStringArray(R.array.voicer_cloud_entries); + cloudVoicersValue = getResources().getStringArray(R.array.voicer_cloud_values); + + // 本地发音人名称列表 + localVoicersEntries = getResources().getStringArray(R.array.voicer_local_entries); + localVoicersValue = getResources().getStringArray(R.array.voicer_local_values); + + // 增强版发音人名称列表 + xttsVoicersEntries = getResources().getStringArray(R.array.voicer_xtts_entries); + xttsVoicersValue = getResources().getStringArray(R.array.voicer_xtts_values); + + mSharedPreferences = getSharedPreferences(TtsSettings.PREFER_NAME, Activity.MODE_PRIVATE); + mToast = Toast.makeText(this,"",Toast.LENGTH_SHORT); + } + + /** + * 初始化Layout。 + */ + private void initLayout() { + findViewById(R.id.tts_play).setOnClickListener(this); + + findViewById(R.id.tts_cancel).setOnClickListener(this); + findViewById(R.id.tts_pause).setOnClickListener(this); + findViewById(R.id.tts_resume).setOnClickListener(this); + findViewById(R.id.image_tts_set).setOnClickListener(this); + + findViewById(R.id.tts_btn_person_select).setOnClickListener(this); + + mRadioGroup=((RadioGroup) findViewById(R.id.tts_rediogroup)); + mRadioGroup.setOnCheckedChangeListener(new OnCheckedChangeListener() { + + @Override + public void onCheckedChanged(RadioGroup group, int checkedId) { + switch (checkedId) { + case R.id.tts_radioCloud: + mEngineType = SpeechConstant.TYPE_CLOUD; + break; + case R.id.tts_radioLocal: + mEngineType = SpeechConstant.TYPE_LOCAL; + break; + case R.id.tts_radioXtts: + mEngineType = SpeechConstant.TYPE_XTTS; + break; + default: + break; + } + } + } ); + } + + @Override + public void onClick(View view) { + if( null == mTts ){ + // 创建单例失败,与 21001 错误为同样原因,参考 http://bbs.xfyun.cn/forum.php?mod=viewthread&tid=9688 + this.showTip( "创建对象失败,请确认 libmsc.so 放置正确,\n 且有调用 createUtility 进行初始化" ); + return; + } + + switch(view.getId()) { + case R.id.image_tts_set: + Intent intent = new Intent(TtsDemo.this, TtsSettings.class); + startActivity(intent); + break; + // 开始合成 + // 收到onCompleted 回调时,合成结束、生成合成音频 + // 合成的音频格式:只支持pcm格式 + case R.id.tts_play: + //会话内容在这修改 + //String text = ((EditText) findViewById(R.id.tts_text)).getText().toString(); + String text = ((EditText) findViewById(R.id.tts_text)).getText().toString(); + // 设置参数 + setParam(); + Log.d(TAG,"准备点击: "+ System.currentTimeMillis()); + int code = mTts.startSpeaking(text, mTtsListener); +// /** +// * 只保存音频不进行播放接口,调用此接口请注释startSpeaking接口 +// * text:要合成的文本,uri:需要保存的音频全路径,listener:回调接口 +// */ +// String path = Environment.getExternalStorageDirectory()+"/tts.pcm"; +// int code = mTts.synthesizeToUri(text, path, mTtsListener); + + if (code != ErrorCode.SUCCESS) { + showTip("语音合成失败,错误码: " + code+",请点击网址https://www.xfyun.cn/document/error-code查询解决方案"); + } + break; + // 取消合成 + case R.id.tts_cancel: + mTts.stopSpeaking(); + break; + // 暂停播放 + case R.id.tts_pause: + mTts.pauseSpeaking(); + break; + // 继续播放 + case R.id.tts_resume: + mTts.resumeSpeaking(); + break; + // 选择发音人 + case R.id.tts_btn_person_select: + showPresonSelectDialog(); + break; + } + } + + + private static int selectedNumCloud=0; + private static int selectedNumLocal=0; + /** + * 发音人选择。 + */ + private void showPresonSelectDialog() { + switch (mRadioGroup.getCheckedRadioButtonId()) { + // 选择在线合成 + case R.id.tts_radioCloud: + new AlertDialog.Builder(this).setTitle("在线合成发音人选项") + .setSingleChoiceItems(cloudVoicersEntries, // 单选框有几项,各是什么名字 + selectedNumCloud, // 默认的选项 + new DialogInterface.OnClickListener() { // 点击单选框后的处理 + public void onClick(DialogInterface dialog, + int which) { // 点击了哪一项 + voicerCloud = cloudVoicersValue[which]; + + if ("catherine".equals(voicerCloud) || "henry".equals(voicerCloud) || "vimary".equals(voicerCloud)) { + ((EditText) findViewById(R.id.tts_text)).setText(R.string.text_tts_source_en); + }else { + ((EditText) findViewById(R.id.tts_text)).setText(R.string.text_tts_source); + } + selectedNumCloud = which; + dialog.dismiss(); + } + }).show(); + break; + + // 选择本地合成 + case R.id.tts_radioLocal: + new AlertDialog.Builder(this).setTitle("本地合成发音人选项") + .setSingleChoiceItems(localVoicersEntries, // 单选框有几项,各是什么名字 + selectedNumLocal, // 默认的选项 + new DialogInterface.OnClickListener() { // 点击单选框后的处理 + public void onClick(DialogInterface dialog, + int which) { // 点击了哪一项 + voicerLocal = localVoicersValue[which]; + if ("catherine".equals(voicerLocal) || "henry".equals(voicerLocal) || "vimary".equals(voicerLocal)) { + ((EditText) findViewById(R.id.tts_text)).setText(R.string.text_tts_source_en); + }else { + ((EditText) findViewById(R.id.tts_text)).setText(R.string.text_tts_source); + } + selectedNumLocal = which; + dialog.dismiss(); + } + }).show(); + break; + case R.id.tts_radioXtts: + new AlertDialog.Builder(this).setTitle("增强版合成发音人选项") + .setSingleChoiceItems(xttsVoicersEntries, // 单选框有几项,各是什么名字 + selectedNumLocal, // 默认的选项 + new DialogInterface.OnClickListener() { // 点击单选框后的处理 + public void onClick(DialogInterface dialog, + int which) { // 点击了哪一项 + voicerXtts = xttsVoicersValue[which]; + //Toast.makeText(this,voicerXtts,Toast.LENGTH_LONG); + System.out.println("sssssss:"+voicerXtts); + if ("catherine".equals(voicerXtts) || "henry".equals(voicerXtts) || "vimary".equals(voicerXtts)) { + ((EditText) findViewById(R.id.tts_text)).setText(R.string.text_tts_source_en); + }else { + ((EditText) findViewById(R.id.tts_text)).setText(R.string.text_tts_source); + } + selectedNumLocal = which; + dialog.dismiss(); + } + }).show(); + break; + + default: + break; + } + } + + /** + * 初始化监听。 + */ + private InitListener mTtsInitListener = new InitListener() { + @Override + public void onInit(int code) { + Log.d(TAG, "InitListener init() code = " + code); + if (code != ErrorCode.SUCCESS) { + showTip("初始化失败,错误码:"+code+",请点击网址https://www.xfyun.cn/document/error-code查询解决方案"); + + } else { + // 初始化成功,之后可以调用startSpeaking方法 + // 注:有的开发者在onCreate方法中创建完合成对象之后马上就调用startSpeaking进行合成, + // 正确的做法是将onCreate中的startSpeaking调用移至这里 + } + } + }; + + /** + * 合成回调监听。 + */ + private SynthesizerListener mTtsListener = new SynthesizerListener() { + + @Override + public void onSpeakBegin() { + //showTip("开始播放"); + Log.d(TtsDemo.TAG,"开始播放:"+ System.currentTimeMillis()); + } + + @Override + public void onSpeakPaused() { + showTip("暂停播放"); + } + + @Override + public void onSpeakResumed() { + showTip("继续播放"); + } + + @Override + public void onBufferProgress(int percent, int beginPos, int endPos, + String info) { + // 合成进度 + mPercentForBuffering = percent; + showTip(String.format(getString(R.string.tts_toast_format), + mPercentForBuffering, mPercentForPlaying)); + } + + @Override + public void onSpeakProgress(int percent, int beginPos, int endPos) { + // 播放进度 + mPercentForPlaying = percent; + showTip(String.format(getString(R.string.tts_toast_format), + mPercentForBuffering, mPercentForPlaying)); + } + + @Override + public void onCompleted(SpeechError error) { + if (error == null) { + showTip("播放完成"); + } else if (error != null) { + showTip(error.getPlainDescription(true)); + } + } + + @Override + public void onEvent(int eventType, int arg1, int arg2, Bundle obj) { + // 以下代码用于获取与云端的会话id,当业务出错时将会话id提供给技术支持人员,可用于查询会话日志,定位出错原因 + // 若使用本地能力,会话id为null + if (SpeechEvent.EVENT_SESSION_ID == eventType) { + String sid = obj.getString(SpeechEvent.KEY_EVENT_AUDIO_URL); + Log.d(TAG, "session id =" + sid); + } + + //实时音频流输出参考 + /*if (SpeechEvent.EVENT_TTS_BUFFER == eventType) { + byte[] buf = obj.getByteArray(SpeechEvent.KEY_EVENT_TTS_BUFFER); + Log.e("MscSpeechLog", "buf is =" + buf); + }*/ + } + }; + + private void showTip(final String str){ + runOnUiThread(new Runnable() { + @Override + public void run() { + mToast.setText(str); + mToast.show(); + } + }); + } + + /** + * 参数设置 + */ + private void setParam(){ + // 清空参数 + mTts.setParameter(SpeechConstant.PARAMS, null); + //设置合成 + if(mEngineType.equals(SpeechConstant.TYPE_CLOUD)) + { + //设置使用云端引擎 + mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD); + //设置发音人 + mTts.setParameter(SpeechConstant.VOICE_NAME,voicerCloud); + + }else if(mEngineType.equals(SpeechConstant.TYPE_LOCAL)){ + //设置使用本地引擎 + mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_LOCAL); + //设置发音人资源路径 + mTts.setParameter(ResourceUtil.TTS_RES_PATH,getResourcePath()); + //设置发音人 + mTts.setParameter(SpeechConstant.VOICE_NAME,voicerLocal); + }else{ + mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_XTTS); + //设置发音人资源路径 + mTts.setParameter(ResourceUtil.TTS_RES_PATH,getResourcePath()); + //设置发音人 + mTts.setParameter(SpeechConstant.VOICE_NAME,voicerXtts); + } + //mTts.setParameter(SpeechConstant.TTS_DATA_NOTIFY,"1");//支持实时音频流抛出,仅在synthesizeToUri条件下支持 + //设置合成语速 + mTts.setParameter(SpeechConstant.SPEED, mSharedPreferences.getString("speed_preference", "50")); + //设置合成音调 + mTts.setParameter(SpeechConstant.PITCH, mSharedPreferences.getString("pitch_preference", "50")); + //设置合成音量 + mTts.setParameter(SpeechConstant.VOLUME, mSharedPreferences.getString("volume_preference", "50")); + //设置播放器音频流类型 + mTts.setParameter(SpeechConstant.STREAM_TYPE, mSharedPreferences.getString("stream_preference", "3")); + // mTts.setParameter(SpeechConstant.STREAM_TYPE, AudioManager.STREAM_MUSIC+""); + + // 设置播放合成音频打断音乐播放,默认为true + mTts.setParameter(SpeechConstant.KEY_REQUEST_FOCUS, "true"); + + // 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限 + mTts.setParameter(SpeechConstant.AUDIO_FORMAT, "wav"); + + mTts.setParameter(SpeechConstant.TTS_AUDIO_PATH, Environment.getExternalStorageDirectory()+"/msc/tts.wav"); + + + } + + //获取发音人资源路径 + private String getResourcePath(){ + StringBuffer tempBuffer = new StringBuffer(); + String type= "tts"; + if(mEngineType.equals(SpeechConstant.TYPE_XTTS)){ + type="xtts"; + } + //合成通用资源 + tempBuffer.append(ResourceUtil.generateResourcePath(this, RESOURCE_TYPE.assets, type+"/common.jet")); + tempBuffer.append(";"); + //发音人资源 + if(mEngineType.equals(SpeechConstant.TYPE_XTTS)){ + tempBuffer.append(ResourceUtil.generateResourcePath(this, RESOURCE_TYPE.assets, type+"/"+ TtsDemo.voicerXtts+".jet")); + }else { + tempBuffer.append(ResourceUtil.generateResourcePath(this, RESOURCE_TYPE.assets, type + "/" + TtsDemo.voicerLocal + ".jet")); + } + + return tempBuffer.toString(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + + if( null != mTts ){ + mTts.stopSpeaking(); + // 退出时释放连接 + mTts.destroy(); + } + } +} diff --git a/src/dianhua/app/src/main/java/com/example/luyin/activities/VoiceActivity.java b/src/dianhua/app/src/main/java/com/example/luyin/activities/VoiceActivity.java new file mode 100644 index 0000000..6c7d486 --- /dev/null +++ b/src/dianhua/app/src/main/java/com/example/luyin/activities/VoiceActivity.java @@ -0,0 +1,155 @@ +package com.example.luyin.activities; + +import android.Manifest; +import android.annotation.SuppressLint; +import android.app.Activity; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.os.Build; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup; +import android.view.Window; +import android.widget.BaseAdapter; +import android.widget.Button; +import android.widget.ListView; +import android.widget.Toast; + +import androidx.core.app.ActivityCompat; + +import com.example.luyin.R; +import com.example.luyin.activities.TtsDemo; +import com.iflytek.cloud.SpeechConstant; +import com.iflytek.cloud.SpeechUtility; + + +public class VoiceActivity extends Activity implements OnClickListener{ + + private Toast mToast; + @SuppressLint("ShowToast") + public void onCreate(Bundle savedInstanceState){ + super.onCreate(savedInstanceState); + // 设置标题栏(无标题) + this.requestWindowFeature(Window.FEATURE_NO_TITLE); + setContentView(R.layout.main); + requestPermissions(); + mToast = Toast.makeText(this,"",Toast.LENGTH_SHORT); + SimpleAdapter listitemAdapter = new SimpleAdapter(); + ((ListView)findViewById(R.id.listview_main)).setAdapter(listitemAdapter); + + StringBuffer param = new StringBuffer(); + param.append("appid="+getString(R.string.app_id)); + param.append(","); + // 设置使用v5+ + param.append(SpeechConstant.ENGINE_MODE+"="+ SpeechConstant.MODE_MSC); + SpeechUtility.createUtility(VoiceActivity.this, param.toString()); + } + @Override + public void onClick(View view) { + int tag = Integer.parseInt(view.getTag().toString()); + Intent intent = null; + switch (tag) { + case 0: + // 语音听写 + showTip("这个功能写不出来!"); + break; + case 1: + // 语法识别 + showTip("这个功能写不出来!"); + break; + case 2: + // 语义理解 + showTip("这个功能写不出来!"); + break; + case 3 : + case 4: + // 合成(包括增强版) + intent = new Intent(this, TtsDemo.class); + break; + + case 5: + // 唤醒 + showTip("这个功能写不出来!"); + break; + case 6: + // 声纹 + showTip("这个功能写不出来!"); + break; + default: + showTip("这个功能写不出来!"); + break; + } + if (intent != null) { + startActivity(intent); + } + } + + + //Menu 列表 + String items[] = {"立刻体验语音听写","立刻体验语法识别","立刻体验语义理解","立刻体验语音合成","立即体验增强版语音合成","立刻体验语音唤醒","立刻体验声纹密码"}; + private class SimpleAdapter extends BaseAdapter{ + public View getView(int position, View convertView, ViewGroup parent) + { + if(null == convertView){ + LayoutInflater factory = LayoutInflater.from(VoiceActivity.this); + View mView = factory.inflate(R.layout.list_items, null); + convertView = mView; + } + Button btn = (Button)convertView.findViewById(R.id.btn); + btn.setOnClickListener(VoiceActivity.this); + btn.setTag(position); + btn.setText(items[position]); + return convertView; + } + @Override + public int getCount() { + return items.length; + } + + @Override + public Object getItem(int position) { + return null; + } + + @Override + public long getItemId(int position) { + return 0; + } + } + private void showTip(final String str) + { + runOnUiThread(new Runnable() { + @Override + public void run() { + mToast.setText(str); + mToast.show(); + } + }); + } + + + private void requestPermissions(){ + try { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + int permission = ActivityCompat.checkSelfPermission(this, + Manifest.permission.WRITE_EXTERNAL_STORAGE); + if(permission!= PackageManager.PERMISSION_GRANTED) { + ActivityCompat.requestPermissions(this,new String[] { + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.LOCATION_HARDWARE,Manifest.permission.READ_PHONE_STATE, + Manifest.permission.WRITE_SETTINGS,Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO,Manifest.permission.READ_CONTACTS},0x0010); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + } +} diff --git a/src/dianhua/app/src/main/java/com/example/luyin/activities/Wechat.java b/src/dianhua/app/src/main/java/com/example/luyin/activities/Wechat.java new file mode 100644 index 0000000..f0e6a5e --- /dev/null +++ b/src/dianhua/app/src/main/java/com/example/luyin/activities/Wechat.java @@ -0,0 +1,426 @@ +package com.example.luyin.activities; + +import androidx.appcompat.app.AppCompatActivity; + +import android.accessibilityservice.AccessibilityService; +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.hardware.Sensor; +import android.hardware.SensorEventListener; +import android.os.Bundle; +import android.os.Vibrator; +import android.provider.Settings; +import android.text.TextUtils; +import android.util.DisplayMetrics; +import android.util.Log; +import android.view.KeyEvent; +import android.view.View; +import android.view.WindowManager; +import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityManager; +import android.widget.Adapter; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.CompoundButton; +import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.Spinner; +import android.widget.Switch; +import android.widget.TextView; + +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; +import android.widget.Toast; + +import com.example.luyin.wechat.Constants; +import com.example.luyin.R; +import com.example.luyin.wechat.service.utils.SendMessage; +import com.example.luyin.wechat.service.RedEnvelopeService; +import com.example.luyin.wechat.utils.AccessibilityUtil; +import com.example.luyin.wechat.utils.AppUtil; + +import java.util.Calendar; + +public class Wechat extends AppCompatActivity implements View.OnClickListener, AdapterView.OnItemSelectedListener, SensorEventListener { + public static Context AppContext; + public static Context WeChatContext; + public static int Width; + public static int Height; + private static AccessibilityService CurrentService; + public long lastTime = 0; + public long timeDifference = 1000; + + private Switch OpenService; + private Switch AutoWeChat; + private Switch AutoSendMsg; + private LinearLayout SendMsgDetail; + private TextView VersionView; + + + private EditText ToWho; + private EditText WhatMsg; + private Button SendMsgBtn; + + private Button InitFriend; + //下拉列表 + private Spinner FriendList; + //传感器 + private SensorManager sensorManager; + //震动 + private Vibrator mVibrator; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.autowechat); + init(); + initWeChatVersion(); + +// if(OpenService.isChecked()){ +// System.out.println("click"); +// SendMessage.NAME = ToWho.getText().toString(); +// SendMessage.CONTENT = WhatMsg.getText().toString(); +// Constants.CurrentTask = Constants.AutoSendMsgType; +// gotoWeChat(); +// } else{ +// AppUtil.makeToast("请先打开辅助功能"); +// openAccessibility(); +// } + + + } + + @Override + protected void onStart() { + super.onStart(); + freshOpenServiceSwitch(RedEnvelopeService.class, OpenService); + initList(); + } + + private void initWeChatVersion(){ + Context weChat = AppUtil.getContext(this, Constants.WeChatInfo.WECHAT_PACKAGE); + WeChatContext = weChat; + if(weChat != null){ + String weChatVersion = AppUtil.getAppVersion(weChat); + System.out.println(weChatVersion); + Constants.setArgs(weChatVersion); + + } + } + + + private void init(){ + AppContext = this; + initScreen(); + //initVersion(); + SendMsgDetail = findViewById(R.id.send_msg_detail); + SendMsgDetail.clearAnimation(); + OpenService = findViewById(R.id.open_accessibility); + setOpenServiceListener(RedEnvelopeService.class, OpenService); +// AutoWeChat = findViewById(R.id.open_we_chat); +// setSwitchListener(AutoWeChat); + AutoSendMsg = findViewById(R.id.auto_send_msg); + setSwitchListener(AutoSendMsg); + //freshOpenServiceSwitch(RedEnvelopeService.class, OpenService); + + ToWho = findViewById(R.id.send_name); + WhatMsg = findViewById(R.id.send_msg); + SendMsgBtn = findViewById(R.id.send_WeChat); + SendMsgBtn.setOnClickListener(this); + + InitFriend = findViewById(R.id.init_friend_btn); + InitFriend.setOnClickListener(this); + FriendList = findViewById(R.id.friend_list); + + sensorManager=(SensorManager) getSystemService(SENSOR_SERVICE); + sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), + SensorManager.SENSOR_DELAY_UI); + + mVibrator=(Vibrator) getSystemService(VIBRATOR_SERVICE); + } + @Override + public void onSensorChanged(SensorEvent event) { + + if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { + if (Math.abs(event.values[0]) > 20|| Math.abs(event.values[1]) > 20 || Math.abs(event.values[2]) > 20) { + long currentTime = Calendar.getInstance().getTimeInMillis(); + if (currentTime - lastTime > timeDifference) { + lastTime = currentTime; + //mVibrator.vibrate(100); + //callPhone(phonenum); + Toast.makeText(Wechat.this,"123",Toast.LENGTH_LONG).show(); + if(OpenService.isChecked()){ + System.out.println("click"); + SendMessage.NAME = ToWho.getText().toString(); + SendMessage.CONTENT = WhatMsg.getText().toString(); + Constants.CurrentTask = Constants.AutoSendMsgType; + gotoWeChat(); + } else{ + AppUtil.makeToast("请先打开辅助功能"); + openAccessibility(); + } + + } + + } + } + } + + @Override + public void onClick(View v) { + switch (v.getId()){ + case R.id.send_WeChat: + if(OpenService.isChecked()){ + System.out.println("click"); + SendMessage.NAME = ToWho.getText().toString(); + SendMessage.CONTENT = WhatMsg.getText().toString(); + Constants.CurrentTask = Constants.AutoSendMsgType; + gotoWeChat(); + } else{ + AppUtil.makeToast("请先打开辅助功能"); + openAccessibility(); + } + break; + case R.id.init_friend_btn: + if(OpenService.isChecked()){ + Constants.CurrentTask = Constants.InitFriendList; + gotoWeChat(); + }else { + AppUtil.makeToast("请先打开辅助功能"); + openAccessibility(); + } + break; + } + } + + private void gotoWeChat(){ + Intent intent = new Intent(); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.setClassName(Constants.WeChatInfo.WECHAT_PACKAGE, Constants.WeChatInfo.WECHAT_LAUNCHER_UI); + startActivity(intent); + } + + public static void performHome(AccessibilityService service) { + if (service == null) { + return; + } + service.performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK); + } + + + private void initList(){ + if(Constants.FriendList == null) return; + System.out.println(Constants.FriendList); + FriendList.setAdapter(new ArrayAdapter<>(this, R.layout.spinner_item, Constants.FriendList)); + FriendList.setOnItemSelectedListener(this); + } + + + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + System.out.println(Constants.FriendList.get(position)); + ToWho.setText(Constants.FriendList.get(position)); + } + + @Override + public void onNothingSelected(AdapterView parent) { + + } + + private void setOpenServiceListener(final Class clazz, Switch s){ + s.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + Log.i(Constants.TAG, "onCheckedChanged: " + isChecked); + if(isChecked){ + if(!isAccessibilitySettingOn(clazz.getCanonicalName(), AppContext)){ + openAccessibility(); + } + }else { + if(isAccessibilitySettingOn(clazz.getCanonicalName(), AppContext)){ + openAccessibility(); + } + } + } + }); + } + + private void setSwitchListener(final Switch s){ + s.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if(isChecked){ + freshSwitch(s); + }else { + freshSwitch(s); + } + } + }); + } + + // private void initVersion(){ +// VersionView = findViewById(R.id.app_version); +// String version = AppUtil.getAppVersion(this); +// VersionView.setText(version); +// } + //重置服务按钮 + private void freshOpenServiceSwitch(Class clazz, Switch s){ + if(isAccessibilitySettingOn(clazz.getCanonicalName(), Wechat.this)){ + s.setChecked(true); + switch (s.getId()){ + case R.id.open_accessibility: + //freshSwitch(AutoWeChat); + freshSwitch(AutoSendMsg); + } + }else { + s.setChecked(false); + switch (s.getId()){ + case R.id.open_accessibility: + AutoSendMsg.setChecked(true); + //AutoWeChat.setChecked(false); + } + } + SendMsgDetail.setVisibility(View.VISIBLE); + } + //点击自动发送消息按钮,弹出详细发送界面,需要先点击开启辅助功能,否则打不开 + private void freshSwitch(Switch s){ + //if(OpenService.isChecked()) { + if(Constants.CurrentTask == Constants.InitFriendList){ + Constants.CurrentTask = -1; + } + switch (s.getId()){ +// case R.id.open_we_chat: +// if(s.isChecked()){ +// if(Constants.IsOver){ +// s.setChecked(false); +// Constants.IsOver = false; +// break; +// }else if(AutoSendMsg.isChecked()){ +// AutoSendMsg.setChecked(false); +// SendMsgDetail.setVisibility(View.GONE); +// } +// Constants.CurrentTask = Constants.RedEnvelopeType; +// }else { +// Constants.CurrentTask = -1; +// } +// break; + case R.id.auto_send_msg: + //if(OpenService.isChecked()) { + if (s.isChecked()) { + if (Constants.IsOver) { + s.setChecked(false); + Constants.IsOver = false; + break; + } + //}else if(AutoWeChat.isChecked()){ + //AutoWeChat.setChecked(false); + //} + if (s.isChecked()) { + SendMsgDetail.setVisibility(View.VISIBLE); + } + } else { + SendMsgDetail.setVisibility(View.GONE); + Constants.CurrentTask = -1; + } + // } + break; + default: + break; + } +// }else { +// AppUtil.makeToast("请先打开辅助功能"); +// // s.setChecked(false); +// } + } + + private boolean isAccessibilitySettingOn(String accessibilityServiceName, Context context){ + int enable = 0; + String serviceName = context.getPackageName() + "/" + accessibilityServiceName; + Log.i(Constants.TAG, "isAccessibilitySettingOn: " + serviceName); + try { + enable = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.ACCESSIBILITY_ENABLED, 0); + } catch (Exception e) { + e.printStackTrace(); + } + if(enable == 1){ + TextUtils.SimpleStringSplitter stringSplitter = new TextUtils.SimpleStringSplitter(':'); + String settingVal = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES); + if(settingVal != null){ + stringSplitter.setString(settingVal); + while(stringSplitter.hasNext()){ + String accessibilityService = stringSplitter.next(); + if(accessibilityService.equals(serviceName)){ + return true; + } + } + } + } + return false; + } + //打开系统设置 + private void openAccessibility(){ + DialogInterface.OnClickListener clickListener = new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS); + startActivity(intent); + } + }; + DialogInterface.OnClickListener cancelListener = new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + freshOpenServiceSwitch(RedEnvelopeService.class, OpenService); + } + }; + DialogInterface.OnCancelListener cancel = new DialogInterface.OnCancelListener() { + @Override + public void onCancel(DialogInterface dialog) { + freshOpenServiceSwitch(RedEnvelopeService.class, OpenService); + } + }; + AlertDialog dialog = new AlertDialog.Builder(this) + .setMessage(R.string.tips) + .setOnCancelListener(cancel) + .setNegativeButton("取消", cancelListener) + .setPositiveButton("确定", clickListener) + .create(); + dialog.show(); + } + + private void initScreen(){ + WindowManager manager = this.getWindowManager(); + DisplayMetrics metrics = new DisplayMetrics(); + manager.getDefaultDisplay().getMetrics(metrics); + Width = metrics.widthPixels; + Height = metrics.heightPixels; + } + +// @Override +// public boolean onKeyDown(int keyCode, KeyEvent event) { +// if(keyCode == KeyEvent.KEYCODE_BACK){ +// moveTaskToBack(true); +// return true; +// } +// return super.onKeyDown(keyCode, event); +// } + +// @Override +// public void onBackPressed() { +// moveTaskToBack(true); +// } + + @Override + + public void onAccuracyChanged(Sensor sensor, int accuracy) { + + // TODO Auto-generated method stub + + } + +} + + diff --git a/src/dianhua/app/src/main/java/com/example/luyin/services/EmergencyPeople.java b/src/dianhua/app/src/main/java/com/example/luyin/services/EmergencyPeople.java new file mode 100644 index 0000000..dc74554 --- /dev/null +++ b/src/dianhua/app/src/main/java/com/example/luyin/services/EmergencyPeople.java @@ -0,0 +1,22 @@ +package com.example.luyin.services; + +import cn.bmob.v3.BmobObject; + +public class EmergencyPeople extends BmobObject { + + private String name; + private String phoneNumber; + + public String getName(){ + return name; + } + public void setName(String name) { + this.name = name; + } + public String getPhoneNumber() { + return phoneNumber; + } + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber=phoneNumber; + } +} diff --git a/src/dianhua/app/src/main/java/com/example/luyin/services/Location.java b/src/dianhua/app/src/main/java/com/example/luyin/services/Location.java new file mode 100644 index 0000000..d45c478 --- /dev/null +++ b/src/dianhua/app/src/main/java/com/example/luyin/services/Location.java @@ -0,0 +1,21 @@ +package com.example.luyin.services; + +import cn.bmob.v3.BmobObject; + +public class Location extends BmobObject{ + private String name; + private String address; + + public String getName(){ + return name; + } + public void setName(String name) { + this.name = name; + } + public String getAddress() { + return address; + } + public void setAddress(String address) { + this.address = address; + } +} diff --git a/src/dianhua/app/src/main/java/com/example/luyin/speech/setting/IatSettings.java b/src/dianhua/app/src/main/java/com/example/luyin/speech/setting/IatSettings.java new file mode 100644 index 0000000..7106bef --- /dev/null +++ b/src/dianhua/app/src/main/java/com/example/luyin/speech/setting/IatSettings.java @@ -0,0 +1,39 @@ +package com.example.luyin.speech.setting; + +import android.os.Bundle; +import android.preference.EditTextPreference; +import android.preference.Preference; +import android.preference.Preference.OnPreferenceChangeListener; +import android.preference.PreferenceActivity; +import android.view.Window; + +import com.example.luyin.R; +import com.example.luyin.speech.util.SettingTextWatcher; + +/** + * 听写设置界面 + */ +public class IatSettings extends PreferenceActivity implements OnPreferenceChangeListener { + + public static final String PREFER_NAME = "com.iflytek.setting"; + private EditTextPreference mVadbosPreference; + private EditTextPreference mVadeosPreference; + + @SuppressWarnings("deprecation") + public void onCreate(Bundle savedInstanceState) { + requestWindowFeature(Window.FEATURE_NO_TITLE); + super.onCreate(savedInstanceState); + getPreferenceManager().setSharedPreferencesName(PREFER_NAME); + addPreferencesFromResource(R.xml.iat_setting); + + mVadbosPreference = (EditTextPreference)findPreference("iat_vadbos_preference"); + mVadbosPreference.getEditText().addTextChangedListener(new SettingTextWatcher(IatSettings.this,mVadbosPreference,0,10000)); + + mVadeosPreference = (EditTextPreference)findPreference("iat_vadeos_preference"); + mVadeosPreference.getEditText().addTextChangedListener(new SettingTextWatcher(IatSettings.this,mVadeosPreference,0,10000)); + } + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + return true; + } +} diff --git a/src/dianhua/app/src/main/java/com/example/luyin/speech/setting/TtsSettings.java b/src/dianhua/app/src/main/java/com/example/luyin/speech/setting/TtsSettings.java new file mode 100644 index 0000000..6489469 --- /dev/null +++ b/src/dianhua/app/src/main/java/com/example/luyin/speech/setting/TtsSettings.java @@ -0,0 +1,49 @@ +package com.example.luyin.speech.setting; + +import android.os.Bundle; +import android.preference.EditTextPreference; +import android.preference.Preference; +import android.preference.Preference.OnPreferenceChangeListener; +import android.preference.PreferenceActivity; +import android.view.Window; + +import com.example.luyin.R; +import com.example.luyin.speech.util.SettingTextWatcher; + + +/** + * 合成设置界面 + */ +public class TtsSettings extends PreferenceActivity implements OnPreferenceChangeListener { + + public static final String PREFER_NAME = "com.iflytek.setting"; + private EditTextPreference mSpeedPreference; + private EditTextPreference mPitchPreference; + private EditTextPreference mVolumePreference; + + @SuppressWarnings("deprecation") + @Override + public void onCreate(Bundle savedInstanceState) { + requestWindowFeature(Window.FEATURE_NO_TITLE); + super.onCreate(savedInstanceState); + // 指定保存文件名字 + getPreferenceManager().setSharedPreferencesName(PREFER_NAME); + addPreferencesFromResource(R.xml.tts_setting); + mSpeedPreference = (EditTextPreference)findPreference("speed_preference"); + mSpeedPreference.getEditText().addTextChangedListener(new SettingTextWatcher(TtsSettings.this,mSpeedPreference,0,200)); + + mPitchPreference = (EditTextPreference)findPreference("pitch_preference"); + mPitchPreference.getEditText().addTextChangedListener(new SettingTextWatcher(TtsSettings.this,mPitchPreference,0,100)); + + mVolumePreference = (EditTextPreference)findPreference("volume_preference"); + mVolumePreference.getEditText().addTextChangedListener(new SettingTextWatcher(TtsSettings.this,mVolumePreference,0,100)); + + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + return true; + } + + +} \ No newline at end of file diff --git a/src/dianhua/app/src/main/java/com/example/luyin/speech/util/FucUtil.java b/src/dianhua/app/src/main/java/com/example/luyin/speech/util/FucUtil.java new file mode 100644 index 0000000..20ec1a4 --- /dev/null +++ b/src/dianhua/app/src/main/java/com/example/luyin/speech/util/FucUtil.java @@ -0,0 +1,56 @@ +package com.example.luyin.speech.util; + +import android.content.Context; + +import java.io.IOException; +import java.io.InputStream; + +/** + * 功能性函数扩展类 + */ +public class FucUtil { + /** + * 读取asset目录下文件。 + * @return content + */ + public static String readFile(Context mContext,String file,String code) + { + int len = 0; + byte []buf = null; + String result = ""; + try { + InputStream in = mContext.getAssets().open(file); + len = in.available(); + buf = new byte[len]; + in.read(buf, 0, len); + + result = new String(buf,code); + } catch (Exception e) { + e.printStackTrace(); + } + return result; + } + + /** + * 读取asset目录下音频文件。 + * + * @return 二进制文件数据 + */ + public static byte[] readAudioFile(Context context, String filename) { + try { + InputStream ins = context.getAssets().open(filename); + byte[] data = new byte[ins.available()]; + + ins.read(data); + ins.close(); + + return data; + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + return null; + } + +} diff --git a/src/dianhua/app/src/main/java/com/example/luyin/speech/util/JsonParser.java b/src/dianhua/app/src/main/java/com/example/luyin/speech/util/JsonParser.java new file mode 100644 index 0000000..a50f9ea --- /dev/null +++ b/src/dianhua/app/src/main/java/com/example/luyin/speech/util/JsonParser.java @@ -0,0 +1,147 @@ +package com.example.luyin.speech.util; + +import org.json.JSONArray; +import org.json.JSONObject; +import org.json.JSONTokener; + +/** + * Json结果解析类 + */ +public class JsonParser { + + public static String parseIatResult(String json) { + StringBuffer ret = new StringBuffer(); + try { + JSONTokener tokener = new JSONTokener(json); + JSONObject joResult = new JSONObject(tokener); + + JSONArray words = joResult.getJSONArray("ws"); + for (int i = 0; i < words.length(); i++) { + // 转写结果词,默认使用第一个结果 + JSONArray items = words.getJSONObject(i).getJSONArray("cw"); + JSONObject obj = items.getJSONObject(0); + ret.append(obj.getString("w")); +// 如果需要多候选结果,解析数组其他字段 +// for(int j = 0; j < items.length(); j++) +// { +// JSONObject obj = items.getJSONObject(j); +// ret.append(obj.getString("w")); +// } + } + } catch (Exception e) { + e.printStackTrace(); + } + return ret.toString(); + } + + public static String parseGrammarResult(String json, String engType) { + StringBuffer ret = new StringBuffer(); + try { + JSONTokener tokener = new JSONTokener(json); + JSONObject joResult = new JSONObject(tokener); + + JSONArray words = joResult.getJSONArray("ws"); + // 云端和本地结果分情况解析 + if ("cloud".equals(engType)) { + for (int i = 0; i < words.length(); i++) { + JSONArray items = words.getJSONObject(i).getJSONArray("cw"); + for(int j = 0; j < items.length(); j++) + { + JSONObject obj = items.getJSONObject(j); + if(obj.getString("w").contains("nomatch")) + { + ret.append("没有匹配结果."); + return ret.toString(); + } + ret.append("【结果】" + obj.getString("w")); + ret.append("【置信度】" + obj.getInt("sc")); + ret.append("\n"); + } + } + } else if ("local".equals(engType)) { + ret.append("【结果】"); + for (int i = 0; i < words.length(); i++) { + JSONObject wsItem = words.getJSONObject(i); + JSONArray items = wsItem.getJSONArray("cw"); + if ("".equals(wsItem.getString("slot"))) { + // 可能会有多个联系人供选择,用中括号括起来,这些候选项具有相同的置信度 + ret.append("【"); + for(int j = 0; j < items.length(); j++) + { + JSONObject obj = items.getJSONObject(j); + if(obj.getString("w").contains("nomatch")) + { + ret.append("没有匹配结果."); + return ret.toString(); + } + ret.append(obj.getString("w")).append("|"); + } + ret.setCharAt(ret.length() - 1, '】'); + } else { + //本地多候选按照置信度高低排序,一般选取第一个结果即可 + JSONObject obj = items.getJSONObject(0); + if(obj.getString("w").contains("nomatch")) + { + ret.append("没有匹配结果."); + return ret.toString(); + } + ret.append(obj.getString("w")); + } + } + ret.append("【置信度】" + joResult.getInt("sc")); + ret.append("\n"); + } + + } catch (Exception e) { + e.printStackTrace(); + ret.append("没有匹配结果."); + } + return ret.toString(); + } + + public static String parseGrammarResult(String json) { + StringBuffer ret = new StringBuffer(); + try { + JSONTokener tokener = new JSONTokener(json); + JSONObject joResult = new JSONObject(tokener); + + JSONArray words = joResult.getJSONArray("ws"); + for (int i = 0; i < words.length(); i++) { + JSONArray items = words.getJSONObject(i).getJSONArray("cw"); + for(int j = 0; j < items.length(); j++) + { + JSONObject obj = items.getJSONObject(j); + if(obj.getString("w").contains("nomatch")) + { + ret.append("没有匹配结果."); + return ret.toString(); + } + ret.append("【结果】" + obj.getString("w")); + ret.append("【置信度】" + obj.getInt("sc")); + ret.append("\n"); + } + } + } catch (Exception e) { + e.printStackTrace(); + ret.append("没有匹配结果."); + } + return ret.toString(); + } + + public static String parseTransResult(String json,String key) { + StringBuffer ret = new StringBuffer(); + try { + JSONTokener tokener = new JSONTokener(json); + JSONObject joResult = new JSONObject(tokener); + String errorCode = joResult.optString("ret"); + if(!errorCode.equals("0")) { + return joResult.optString("errmsg"); + } + JSONObject transResult = joResult.optJSONObject("trans_result"); + ret.append(transResult.optString(key)); + } catch (Exception e) { + e.printStackTrace(); + } + return ret.toString(); + } +} diff --git a/src/dianhua/app/src/main/java/com/example/luyin/speech/util/SettingTextWatcher.java b/src/dianhua/app/src/main/java/com/example/luyin/speech/util/SettingTextWatcher.java new file mode 100644 index 0000000..ac65676 --- /dev/null +++ b/src/dianhua/app/src/main/java/com/example/luyin/speech/util/SettingTextWatcher.java @@ -0,0 +1,71 @@ +package com.example.luyin.speech.util; + +import android.content.Context; +import android.preference.EditTextPreference; +import android.text.Editable; +import android.text.TextUtils; +import android.text.TextWatcher; +import android.widget.Toast; + +import java.util.regex.Pattern; + +/** + * 输入框输入范围控制 + */ +public class SettingTextWatcher implements TextWatcher { + private int editStart ; + private int editCount ; + private EditTextPreference mEditTextPreference; + int minValue;//最小值 + int maxValue;//最大值 + private Context mContext; + + public SettingTextWatcher(Context context,EditTextPreference e,int min, int max) { + mContext = context; + mEditTextPreference = e; + minValue = min; + maxValue = max; + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { +// Log.e("demo", "onTextChanged start:"+start+" count:"+count+" before:"+before); + editStart = start; + editCount = count; + } + + @Override + public void beforeTextChanged(CharSequence s, int start, int count,int after) { +// Log.e("demo", "beforeTextChanged start:"+start+" count:"+count+" after:"+after); + } + + @Override + public void afterTextChanged(Editable s) { + if (TextUtils.isEmpty(s)) { + return; + } + String content = s.toString(); +// Log.e("demo", "content:"+content); + if (isNumeric(content)) { + int num = Integer.parseInt(content); + if (num > maxValue || num < minValue) { + s.delete(editStart, editStart+editCount); + mEditTextPreference.getEditText().setText(s); + Toast.makeText(mContext, "超出有效值范围", Toast.LENGTH_SHORT).show(); + } + }else { + s.delete(editStart, editStart+editCount); + mEditTextPreference.getEditText().setText(s); + Toast.makeText(mContext, "只能输入数字哦", Toast.LENGTH_SHORT).show(); + } + } + + /** + * 正则表达式-判断是否为数字 + */ + public static boolean isNumeric(String str){ + Pattern pattern = Pattern.compile("[0-9]*"); + return pattern.matcher(str).matches(); + } + +}; diff --git a/src/dianhua/app/src/main/java/com/example/luyin/speech/util/XmlParser.java b/src/dianhua/app/src/main/java/com/example/luyin/speech/util/XmlParser.java new file mode 100644 index 0000000..829f3f1 --- /dev/null +++ b/src/dianhua/app/src/main/java/com/example/luyin/speech/util/XmlParser.java @@ -0,0 +1,58 @@ +package com.example.luyin.speech.util; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +/** + * Xml结果解析类 + */ +public class XmlParser { + + public static String parseNluResult(String xml) + { + StringBuffer buffer = new StringBuffer(); + try + { + // DOM builder + DocumentBuilder domBuilder = null; + // DOM doc + Document domDoc = null; + + // init DOM + DocumentBuilderFactory domFact = DocumentBuilderFactory.newInstance(); + domBuilder = domFact.newDocumentBuilder(); + InputStream is = new ByteArrayInputStream(xml.getBytes()); + domDoc = domBuilder.parse(is); + + // 获取根节点 + Element root = (Element) domDoc.getDocumentElement(); + + Element raw = (Element)root.getElementsByTagName("rawtext").item(0); + buffer.append("【识别结果】" + raw.getFirstChild().getNodeValue()); + buffer.append("\n"); + + Element e = (Element)root.getElementsByTagName("result").item(0); + + Element focus = (Element)e.getElementsByTagName("focus").item(0); + buffer.append("【FOCUS】" + focus.getFirstChild().getNodeValue()); + buffer.append("\n"); + + Element action = (Element)e.getElementsByTagName("action").item(0); + Element operation = (Element)action.getElementsByTagName("operation").item(0); + buffer.append("【ACTION】" + operation.getFirstChild().getNodeValue()); + buffer.append("\n"); + + + }catch(Exception e){ + e.printStackTrace(); + }; + buffer.append("【ALL】" + xml); + return buffer.toString(); + } +} diff --git a/src/dianhua/app/src/main/java/com/example/luyin/utils/Utils.java b/src/dianhua/app/src/main/java/com/example/luyin/utils/Utils.java new file mode 100644 index 0000000..b54c6a6 --- /dev/null +++ b/src/dianhua/app/src/main/java/com/example/luyin/utils/Utils.java @@ -0,0 +1,115 @@ +/** + * + */ +package com.example.luyin.utils; + +import android.content.Context; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.text.TextUtils; + +import com.amap.api.location.AMapLocation; + +import java.text.SimpleDateFormat; +import java.util.Locale; + +/** + * 辅助工具类 + + */ +public class Utils { + /** + * 开始定位 + */ + public final static int MSG_LOCATION_START = 0; + /** + * 定位完成 + */ + public final static int MSG_LOCATION_FINISH = 1; + /** + * 停止定位 + */ + public final static int MSG_LOCATION_STOP= 2; + + public final static String KEY_URL = "URL"; + public final static String URL_H5LOCATION = "file:///android_asset/sdkLoc.html"; + /** + * 根据定位结果返回定位信息的字符串 + * @param location + * @return + */ + public synchronized static String getLocationStr(AMapLocation location){ + if(null == location){ + return null; + } + StringBuffer sb = new StringBuffer(); + //errCode等于0代表定位成功,其他的为定位失败,具体的可以参照官网定位错误码说明 + if(location.getErrorCode() == 0){ + sb.append("定位成功" + "\n"); + sb.append("定位类型: " + location.getLocationType() + "\n"); + sb.append("经 度 : " + location.getLongitude() + "\n"); + sb.append("纬 度 : " + location.getLatitude() + "\n"); + sb.append("精 度 : " + location.getAccuracy() + "米" + "\n"); + sb.append("提供者 : " + location.getProvider() + "\n"); + + sb.append("速 度 : " + location.getSpeed() + "米/秒" + "\n"); + sb.append("角 度 : " + location.getBearing() + "\n"); + // 获取当前提供定位服务的卫星个数 + sb.append("星 数 : " + location.getSatellites() + "\n"); + sb.append("国 家 : " + location.getCountry() + "\n"); + sb.append("省 : " + location.getProvince() + "\n"); + sb.append("市 : " + location.getCity() + "\n"); + sb.append("城市编码 : " + location.getCityCode() + "\n"); + sb.append("区 : " + location.getDistrict() + "\n"); + sb.append("区域 码 : " + location.getAdCode() + "\n"); + sb.append("地 址 : " + location.getAddress() + "\n"); + sb.append("兴趣点 : " + location.getPoiName() + "\n"); + //定位完成的时间 + sb.append("定位时间: " + formatUTC(location.getTime(), "yyyy-MM-dd HH:mm:ss") + "\n"); + } else { + //定位失败 + sb.append("定位失败" + "\n"); + sb.append("错误码:" + location.getErrorCode() + "\n"); + sb.append("错误信息:" + location.getErrorInfo() + "\n"); + sb.append("错误描述:" + location.getLocationDetail() + "\n"); + } + //定位之后的回调时间 + sb.append("回调时间: " + formatUTC(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss") + "\n"); + return sb.toString(); + } + + private static SimpleDateFormat sdf = null; + public static String formatUTC(long l, String strPattern) { + if (TextUtils.isEmpty(strPattern)) { + strPattern = "yyyy-MM-dd HH:mm:ss"; + } + if (sdf == null) { + try { + sdf = new SimpleDateFormat(strPattern, Locale.CHINA); + } catch (Throwable e) { + } + } else { + sdf.applyPattern(strPattern); + } + return sdf == null ? "NULL" : sdf.format(l); + } + + /** + * 获取app的名称 + * @param context + * @return + */ + public static String getAppName(Context context) { + String appName = ""; + try { + PackageManager packageManager = context.getPackageManager(); + PackageInfo packageInfo = packageManager.getPackageInfo( + context.getPackageName(), 0); + int labelRes = packageInfo.applicationInfo.labelRes; + appName = context.getResources().getString(labelRes); + } catch (Throwable e) { + e.printStackTrace(); + } + return appName; + } +} diff --git a/src/dianhua/app/src/main/java/com/example/luyin/wechat/Constants.java b/src/dianhua/app/src/main/java/com/example/luyin/wechat/Constants.java new file mode 100644 index 0000000..bc5e431 --- /dev/null +++ b/src/dianhua/app/src/main/java/com/example/luyin/wechat/Constants.java @@ -0,0 +1,81 @@ +package com.example.luyin.wechat; + + +import com.example.luyin.wechat.utils.AppUtil; + +import java.util.List; + +public class Constants { + public static String Version = ""; + public static boolean IsOver = false; + public static int CurrentTask = -1; + public static final int RedEnvelopeType = 1000; + public static final int AutoSendMsgType = 1001; + public static final int InitFriendList = 1002; + public static List FriendList; + public static final String TAG = "Accessibility"; + + public static class WeChatInfo{ + public static final String WECHAT_PACKAGE = "com.tencent.mm"; + //首页 + public static final String WECHAT_LAUNCHER_UI = "com.tencent.mm.ui.LauncherUI"; + //红包界面 + public static final String LUCKY_MONEY_UI = "com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyNotHookReceiveUI"; + //聊天界面 + public static final String TALKING_UI = "com.tencent.mm.ui.chatting.ChattingUI"; + //微信联系人页面 + public static final String WECHAT_CLASS_CONTACT_INFO_UI = "com.tencent.mm.plugin.profile.ui.ContactInfoUI"; + + /** + * 聊天界面 + */ + //聊天框左上角名字id + public static String ID_CHATTING_NAME; + //聊天语音切换按钮id + public static String ID_VOICE_BTN; + //聊天界面输入框id + public static String ID_EDIT_VIEW; + //发送按钮 + public static String ID_SEND_BTN; + + /** + * 联系人界面 + */ + //通讯录listViewId + public static String ID_CONTACT_LIST; + //联系人textViewID + public static String ID_CONTACTOR_TEXT; + + + } + + public static void setArgs(String version){ + switch (version){ + case "7.0.6": + WeChatInfo.ID_CHATTING_NAME = "com.tencent.mm:id/l5"; + WeChatInfo.ID_VOICE_BTN = "com.tencent.mm:id/aok"; + WeChatInfo.ID_EDIT_VIEW = "com.tencent.mm:id/aom"; + WeChatInfo.ID_CONTACT_LIST = "com.tencent.mm:id/nn"; + WeChatInfo.ID_CONTACTOR_TEXT = "com.tencent.mm:id/ol"; + WeChatInfo.ID_SEND_BTN = "com.tencent.mm:id/aot"; + break; + case "7.0.10": + WeChatInfo.ID_CHATTING_NAME = "com.tencent.mm:id/lt"; + WeChatInfo.ID_VOICE_BTN = "com.tencent.mm:id/aqc"; + WeChatInfo.ID_EDIT_VIEW = "com.tencent.mm:id/aqe"; + WeChatInfo.ID_CONTACT_LIST = "com.tencent.mm:id/oc"; + WeChatInfo.ID_CONTACTOR_TEXT = "com.tencent.mm:id/pa"; + WeChatInfo.ID_SEND_BTN = "com.tencent.mm:id/aql"; + break; + default: + AppUtil.makeToast( "初始化版本失败"); + } + } + + public static void init(String version){ + switch (version){ + case "7.0.10": + + } + } +} diff --git a/src/dianhua/app/src/main/java/com/example/luyin/wechat/service/RedEnvelopeService.java b/src/dianhua/app/src/main/java/com/example/luyin/wechat/service/RedEnvelopeService.java new file mode 100644 index 0000000..33e15d0 --- /dev/null +++ b/src/dianhua/app/src/main/java/com/example/luyin/wechat/service/RedEnvelopeService.java @@ -0,0 +1,54 @@ +package com.example.luyin.wechat.service; + +import android.accessibilityservice.AccessibilityService; +import android.os.Build; +import android.util.Log; +import android.view.accessibility.AccessibilityEvent; + +import androidx.annotation.RequiresApi; + +import com.example.luyin.wechat.Constants; +import com.example.luyin.wechat.service.utils.AutoRedEnvelope; +import com.example.luyin.wechat.service.utils.InitFriendList; +import com.example.luyin.wechat.service.utils.SendMessage; +import com.example.luyin.wechat.utils.AccessibilityUtil; +import com.example.luyin.wechat.utils.AppUtil; + + + +public class RedEnvelopeService extends AccessibilityService { + + @Override + protected void onServiceConnected() { + AppUtil.makeToast("初始化成功"); + } + + + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + @Override + public void onAccessibilityEvent(AccessibilityEvent event) { + if(event == null || event.getPackageName() == null){ + return; + } + if(event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED || event.getEventType() == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED){ + switch (Constants.CurrentTask){ + case Constants.RedEnvelopeType: + AutoRedEnvelope.getInstance(this).startEnvelope(event); + break; + case Constants.AutoSendMsgType: + SendMessage.getInstance(this).startSedMessage(event); + break; + case Constants.InitFriendList: + InitFriendList.getInstance(this).initList(event); + break; + } + } + } + + @Override + public void onInterrupt() { + Log.i(Constants.TAG, "onInterrupt"); + } + + +} diff --git a/src/dianhua/app/src/main/java/com/example/luyin/wechat/service/utils/AutoRedEnvelope.java b/src/dianhua/app/src/main/java/com/example/luyin/wechat/service/utils/AutoRedEnvelope.java new file mode 100644 index 0000000..01a0527 --- /dev/null +++ b/src/dianhua/app/src/main/java/com/example/luyin/wechat/service/utils/AutoRedEnvelope.java @@ -0,0 +1,86 @@ +package com.example.luyin.wechat.service.utils; + +import android.accessibilityservice.AccessibilityService; +import android.os.SystemClock; +import android.util.Log; +import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityNodeInfo; + +import com.example.luyin.wechat.Constants; +import com.example.luyin.activities.Wechat; +import com.example.luyin.wechat.utils.AccessibilityUtil; +import com.example.luyin.wechat.utils.AppUtil; + +import java.util.List; + +import static com.example.luyin.wechat.utils.AppUtil.weakUpScreen; + +public class AutoRedEnvelope { + private static AutoRedEnvelope autoRedEnvelope; + private static AccessibilityService Service; + + private AutoRedEnvelope(AccessibilityService service){ + Service = service; + } + + public static AutoRedEnvelope getInstance(AccessibilityService service){ + if(autoRedEnvelope == null){ + synchronized (AutoRedEnvelope.class){ + if(autoRedEnvelope == null){ + autoRedEnvelope = new AutoRedEnvelope(service); + } + } + } + return autoRedEnvelope; + } + + public void startEnvelope(AccessibilityEvent event){ + switch (event.getEventType()){ + case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED: + Log.i(Constants.TAG, "CurrentPackage: " + event.getPackageName().toString()); + List texts = event.getText(); + for(CharSequence ch : texts){ + Log.i(Constants.TAG, "NotificationContent: " + ch.toString()); + AppUtil.makeToast("Msg: " + ch.toString()); + if(ch.toString().contains("[微信红包]")){ + weakUpScreen(); + AccessibilityUtil.gotoApp(event); + Log.i(Constants.TAG, "Get Red Envelope!"); + } + } + break; + case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED : + String className = event.getClassName().toString(); + if(className.equals(Constants.WeChatInfo.WECHAT_LAUNCHER_UI)){ + AccessibilityNodeInfo nodeInfo = event.getSource(); + List list = nodeInfo.findAccessibilityNodeInfosByText("微信红包"); + if(list != null && list.size() > 0){ + AccessibilityUtil.performClick(list.get(list.size() - 1)); + } + + }else if(className.equals(Constants.WeChatInfo.LUCKY_MONEY_UI)){ + openRedEnvelope(event.getSource()); + } + break; + default: + break; + } + } + + //开启红包 + private void openRedEnvelope(AccessibilityNodeInfo node){ + if(node == null) { + Log.i(Constants.TAG, "node = null"); + } + SystemClock.sleep(50); + Log.i(Constants.TAG, "openRedEnvelope: fakeClick"); + float x = Wechat.Width / 2.0F; + float y = Wechat.Height * 2 / 3.0F; + for(int i = 0; i < 10; i++){ + SystemClock.sleep(17); + AccessibilityUtil.performXYClick(Service, x, y); + } + SystemClock.sleep(500); + AccessibilityUtil.globalGoHome(Service); + } +} diff --git a/src/dianhua/app/src/main/java/com/example/luyin/wechat/service/utils/InitFriendList.java b/src/dianhua/app/src/main/java/com/example/luyin/wechat/service/utils/InitFriendList.java new file mode 100644 index 0000000..36f61be --- /dev/null +++ b/src/dianhua/app/src/main/java/com/example/luyin/wechat/service/utils/InitFriendList.java @@ -0,0 +1,105 @@ +package com.example.luyin.wechat.service.utils; + +import android.accessibilityservice.AccessibilityService; +import android.app.ActivityManager; +import android.content.Context; +import android.os.SystemClock; +import android.util.Log; +import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityNodeInfo; + +import com.example.luyin.wechat.Constants; +import com.example.luyin.wechat.utils.AccessibilityUtil; +import com.example.luyin.wechat.utils.AppUtil; + +import java.util.ArrayList; +import java.util.List; + +public class InitFriendList { + + private static AccessibilityService CurrentService; + private static InitFriendList mInstance; + + private InitFriendList(AccessibilityService service){ + CurrentService = service; + } + + public static InitFriendList getInstance(AccessibilityService service){ + if(mInstance == null){ + synchronized (InitFriendList.class){ + if(mInstance == null){ + mInstance = new InitFriendList(service); + } + } + } + return mInstance; + } + + public void initList(AccessibilityEvent event){ + String currentActivity = event.getClassName().toString(); + Log.i(Constants.TAG, "initList: " + currentActivity); + switch (currentActivity){ + case Constants.WeChatInfo.WECHAT_LAUNCHER_UI: + headToContactUI(); + break; + default: + AppUtil.makeToast("请回到主界面"); + } + } + // + private void headToContactUI(){ + if(!AccessibilityUtil.findTextAndClick(CurrentService,"通讯录")) { + AccessibilityUtil.globalGoBack(CurrentService); + } + freshContactUI(); + getList(); + resetApp(); + } + //找到通讯录UI界面并点击 + private void freshContactUI(){ + AccessibilityUtil.findTextAndClick(CurrentService,"通讯录"); + SystemClock.sleep(500); + AccessibilityUtil.findTextAndClick(CurrentService,"通讯录"); + } + + private void getList(){ + AccessibilityNodeInfo nodeInfo = CurrentService.getRootInActiveWindow(); + List list = nodeInfo.findAccessibilityNodeInfosByViewId(Constants.WeChatInfo.ID_CONTACT_LIST); + if(list != null && !list.isEmpty()){ + List userList = new ArrayList<>(); + while (true){ + List users = nodeInfo.findAccessibilityNodeInfosByViewId(Constants.WeChatInfo.ID_CONTACTOR_TEXT); + if(users != null && !users.isEmpty()){ + for(int i = 0; i < users.size(); i++){ + AccessibilityNodeInfo node = users.get(i); + String name = node.getText().toString(); + if(!userList.contains(name)){ + userList.add(name); + }else{ + if(i == users.size() - 1){ + AppUtil.makeToast("扫描完毕"); + Constants.FriendList = userList; + return; + } + } + } + list.get(0).performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD); + SystemClock.sleep(500); + } + } + + } + } + + + public void resetApp(){ + ActivityManager manager = (ActivityManager) CurrentService.getSystemService(Context.ACTIVITY_SERVICE); + List taskInfos = manager.getRunningTasks(3); + for(ActivityManager.RunningTaskInfo info : taskInfos){ + if(CurrentService.getPackageName().equals(info.topActivity.getPackageName())){ + manager.moveTaskToFront(info.id, ActivityManager.MOVE_TASK_WITH_HOME); + } + } + } + +} diff --git a/src/dianhua/app/src/main/java/com/example/luyin/wechat/service/utils/SendMessage.java b/src/dianhua/app/src/main/java/com/example/luyin/wechat/service/utils/SendMessage.java new file mode 100644 index 0000000..8a75934 --- /dev/null +++ b/src/dianhua/app/src/main/java/com/example/luyin/wechat/service/utils/SendMessage.java @@ -0,0 +1,144 @@ +package com.example.luyin.wechat.service.utils; + +import android.accessibilityservice.AccessibilityService; +import android.app.ActivityManager; +import android.content.Context; +import android.os.SystemClock; +import android.util.Log; +import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityNodeInfo; + +import com.example.luyin.wechat.Constants; +import com.example.luyin.wechat.utils.AccessibilityUtil; +import com.example.luyin.wechat.utils.AppUtil; + +import java.util.ArrayList; +import java.util.List; + +public class SendMessage { + public static String NAME; + public static String CONTENT; + private static AccessibilityService CurrentService; + private static SendMessage mInstance; + + private SendMessage(AccessibilityService service){ + CurrentService = service; + } + + public static SendMessage getInstance(AccessibilityService service){ + if(mInstance == null){ + synchronized (SendMessage.class){ + if(mInstance == null){ + mInstance = new SendMessage(service); + } + } + } + return mInstance; + } + + public void startSedMessage(AccessibilityEvent event){ + String currentActivity = event.getClassName().toString(); + Log.i(Constants.TAG, "startSedMessage: " + currentActivity); + switch (currentActivity){ + case Constants.WeChatInfo.WECHAT_LAUNCHER_UI://首页 + headToContactUI(); + break; + case "android.widget.LinearLayout": + case Constants.WeChatInfo.TALKING_UI://聊天界面 + sendMsg(); + break; + case Constants.WeChatInfo.WECHAT_CLASS_CONTACT_INFO_UI://联系人界面 + headToChattingUi(); + break; + default: + AppUtil.makeToast("请回到主界面"); + } + } + + private void headToContactUI(){ + if(!AccessibilityUtil.findTextAndClick(CurrentService,"通讯录")){ + String talker = AccessibilityUtil.findTextById(CurrentService, Constants.WeChatInfo.ID_CHATTING_NAME); + if(talker.equals(NAME)){ + sendMsg(); + }else { + AccessibilityUtil.globalGoBack(CurrentService); + freshContactUI(); + } + }else { + freshContactUI(); + } + } + + private void freshContactUI(){ + AccessibilityUtil.findTextAndClick(CurrentService,"通讯录"); + SystemClock.sleep(300); + AccessibilityUtil.findTextAndClick(CurrentService,"通讯录"); + SystemClock.sleep(300); + AccessibilityNodeInfo node = findTalker(); + if(node != null){ + AccessibilityUtil.performClick(node); + } + } + + private void headToChattingUi(){ + AccessibilityUtil.findTextAndClick(CurrentService, "发消息"); + } + + private AccessibilityNodeInfo findTalker(){ + AccessibilityNodeInfo nodeInfo = CurrentService.getRootInActiveWindow(); + List list = nodeInfo.findAccessibilityNodeInfosByViewId(Constants.WeChatInfo.ID_CONTACT_LIST); + if(list != null && !list.isEmpty()){ + List userList = new ArrayList<>(); + while (true){ + List users = nodeInfo.findAccessibilityNodeInfosByViewId(Constants.WeChatInfo.ID_CONTACTOR_TEXT); + if(users != null && !users.isEmpty()){ + for(int i = 0; i < users.size(); i++){ + AccessibilityNodeInfo node = users.get(i); + String name = node.getText().toString(); + if(name.equals(NAME)) return node; + if(!userList.contains(name)){ + userList.add(name); + }else{ + if(i == users.size() - 1){ + AppUtil.makeToast("未找到联系人"); + return null; + } + } + } + list.get(0).performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD); + SystemClock.sleep(300); + } + } + + } + return null; + } + + private void sendMsg(){ + String talker = AccessibilityUtil.findTextById(CurrentService, Constants.WeChatInfo.ID_CHATTING_NAME); + if(talker != null && talker.equals(NAME)){ + if(!AccessibilityUtil.findIdAndWrite(CurrentService, Constants.WeChatInfo.ID_EDIT_VIEW, CONTENT)){ + AccessibilityUtil.findAndClickById(CurrentService, Constants.WeChatInfo.ID_VOICE_BTN); + AccessibilityUtil.findIdAndWrite(CurrentService, Constants.WeChatInfo.ID_EDIT_VIEW, CONTENT); + } + AccessibilityUtil.findAndClickById(CurrentService, Constants.WeChatInfo.ID_SEND_BTN); + resetApp(); + Constants.CurrentTask = -1; + Constants.IsOver = true; + }else { + AccessibilityUtil.globalGoBack(CurrentService); + freshContactUI(); + } + } + + public void resetApp(){ + ActivityManager manager = (ActivityManager) CurrentService.getSystemService(Context.ACTIVITY_SERVICE); + List taskInfos = manager.getRunningTasks(3); + for(ActivityManager.RunningTaskInfo info : taskInfos){ + if(CurrentService.getPackageName().equals(info.topActivity.getPackageName())){ + manager.moveTaskToFront(info.id, ActivityManager.MOVE_TASK_WITH_HOME); + } + } + } + +} diff --git a/src/dianhua/app/src/main/java/com/example/luyin/wechat/utils/AccessibilityUtil.java b/src/dianhua/app/src/main/java/com/example/luyin/wechat/utils/AccessibilityUtil.java new file mode 100644 index 0000000..475c0e2 --- /dev/null +++ b/src/dianhua/app/src/main/java/com/example/luyin/wechat/utils/AccessibilityUtil.java @@ -0,0 +1,136 @@ +package com.example.luyin.wechat.utils; + + +import android.accessibilityservice.AccessibilityService; +import android.accessibilityservice.GestureDescription; +import android.annotation.TargetApi; +import android.app.Notification; +import android.app.PendingIntent; +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.Context; +import android.graphics.Path; +import android.os.Parcelable; +import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityNodeInfo; + +import com.example.luyin.activities.Wechat; + +import java.util.List; + +import static android.accessibilityservice.AccessibilityService.GLOBAL_ACTION_BACK; +import static android.accessibilityservice.AccessibilityService.GLOBAL_ACTION_HOME; + +public class AccessibilityUtil { + + + //点击文字所属按钮事件 + public static boolean findTextAndClick(AccessibilityService service, String text){ + AccessibilityNodeInfo nodeInfo = service.getRootInActiveWindow(); + if(nodeInfo == null) return false; + List nodeInfoList = nodeInfo.findAccessibilityNodeInfosByText(text); + if(nodeInfoList != null && !nodeInfoList.isEmpty()){ + for(AccessibilityNodeInfo info : nodeInfoList){ + if(info != null && (text.equals(info.getText())) || text.equals(info.getContentDescription())){ + performClick(info); + return true; + } + } + } + return false; + } + + //点击id所属按钮文字 + public static void findAndClickById(AccessibilityService service, String id){ + AccessibilityNodeInfo nodeInfo = service.getRootInActiveWindow(); + if(nodeInfo == null) return; + List nodeInfoList = nodeInfo.findAccessibilityNodeInfosByViewId(id); + if(nodeInfoList != null && nodeInfoList.size() > 0){ + performClick(nodeInfoList.get(0)); + } + } + + //获取id所属按钮文字 + public static String findTextById(AccessibilityService service, String id){ + AccessibilityNodeInfo nodeInfo = service.getRootInActiveWindow(); + if(nodeInfo == null) return null; + List nodeInfoList = nodeInfo.findAccessibilityNodeInfosByViewId(id); + if(nodeInfoList != null && nodeInfoList.size() > 0){ + return nodeInfoList.get(0).getText().toString(); + } + return null; + } + + //编辑EditView + public static boolean findIdAndWrite(AccessibilityService service, String id, String text){ + AccessibilityNodeInfo nodeInfo = service.getRootInActiveWindow(); + List edit = nodeInfo.findAccessibilityNodeInfosByViewId(id); + if(edit != null && !edit.isEmpty()){ + AccessibilityNodeInfo node = edit.get(0); + ClipboardManager clipboardManager = (ClipboardManager) Wechat.AppContext.getSystemService(Context.CLIPBOARD_SERVICE); + ClipData clipData = ClipData.newPlainText("text", text); + clipboardManager.setPrimaryClip(clipData); + node.performAction(AccessibilityNodeInfo.ACTION_FOCUS); + node.performAction(AccessibilityNodeInfo.ACTION_PASTE); + return true; + } + return false; + } + + //输入x, y坐标模拟点击事件 + @TargetApi(android.os.Build.VERSION_CODES.N) + public static void performXYClick(AccessibilityService service, float x, float y){ + Path path = new Path(); + path.moveTo(x, y); + GestureDescription.Builder builder = new GestureDescription.Builder(); + builder.addStroke(new GestureDescription.StrokeDescription(path, 0, 1)); + GestureDescription gestureDescription = builder.build(); + service.dispatchGesture(gestureDescription, new AccessibilityService.GestureResultCallback() { + @Override + public void onCompleted(GestureDescription gestureDescription) { + super.onCompleted(gestureDescription); + //Log.i(Constants.TAG, "onCompleted: completed"); + } + @Override + public void onCancelled(GestureDescription gestureDescription) { + super.onCancelled(gestureDescription); + //Log.i(Constants.TAG, "onCancelled: cancelled"); + } + }, null); + } + + //对某个节点进行点击 + public static void performClick(AccessibilityNodeInfo nodeInfo){ + if(nodeInfo == null) return; + while (nodeInfo != null){ + if(nodeInfo.isClickable()){ + nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK); + break; + } + nodeInfo = nodeInfo.getParent(); + } + } + + + //通知栏事件进入应用 + public static void gotoApp(AccessibilityEvent event){ + Parcelable data = event.getParcelableData(); + if(data != null && data instanceof Notification){ + Notification notification = (Notification) data; + PendingIntent intent = notification.contentIntent; + try { + intent.send(); + } catch (PendingIntent.CanceledException e) { + e.printStackTrace(); + } + } + } + //模拟点击返回键 + public static void globalGoBack(AccessibilityService service){ + service.performGlobalAction(GLOBAL_ACTION_BACK); + } + //模拟点击Home键 + public static void globalGoHome(AccessibilityService service){ + service.performGlobalAction(GLOBAL_ACTION_HOME); + } +} diff --git a/src/dianhua/app/src/main/java/com/example/luyin/wechat/utils/AppUtil.java b/src/dianhua/app/src/main/java/com/example/luyin/wechat/utils/AppUtil.java new file mode 100644 index 0000000..ce77ed6 --- /dev/null +++ b/src/dianhua/app/src/main/java/com/example/luyin/wechat/utils/AppUtil.java @@ -0,0 +1,64 @@ +package com.example.luyin.wechat.utils; + +import android.annotation.SuppressLint; +import android.app.KeyguardManager; +import android.content.Context; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.os.PowerManager; +import android.widget.Toast; + +import com.example.luyin.activities.Wechat; + +public class AppUtil { + + + public static String getVersion(Context context, String packageName){ + try { + return context.getPackageManager().getPackageInfo(packageName, 0).versionName; + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + return ""; + } + + @SuppressLint("InvalidWakeLockTag") + public static void weakUpScreen(){ + PowerManager pm = (PowerManager)Wechat.AppContext.getSystemService(Context.POWER_SERVICE); + PowerManager.WakeLock wakeLock = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "WakeLock"); + wakeLock.acquire(); + wakeLock.release(); + + KeyguardManager km = (KeyguardManager) Wechat.AppContext.getSystemService(Context.KEYGUARD_SERVICE); + KeyguardManager.KeyguardLock lock = km.newKeyguardLock("unlock"); + lock.disableKeyguard(); + } + + public static void makeToast(String text){ + Toast.makeText(Wechat.AppContext, text, Toast.LENGTH_SHORT).show(); + } + + //获取版本号 + public static String getAppVersion(Context context){ + PackageManager packageManager = context.getPackageManager(); + PackageInfo info = null; + try { + info = packageManager.getPackageInfo(context.getPackageName(), 0); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + return info.versionName; + } + + //创建context + public static Context getContext(Context t, String packageName){ + Context context = null; + try { + context = t.createPackageContext(packageName, Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + return context; + } + +} diff --git a/src/dianhua/app/src/main/jnLibs/BmobSDK_3.7.4_20190523.jar b/src/dianhua/app/src/main/jnLibs/BmobSDK_3.7.4_20190523.jar new file mode 100644 index 0000000..7df79f7 Binary files /dev/null and b/src/dianhua/app/src/main/jnLibs/BmobSDK_3.7.4_20190523.jar differ diff --git a/src/dianhua/app/src/main/jnLibs/androidx-core-1.0.0.jar b/src/dianhua/app/src/main/jnLibs/androidx-core-1.0.0.jar new file mode 100644 index 0000000..f1f7e72 Binary files /dev/null and b/src/dianhua/app/src/main/jnLibs/androidx-core-1.0.0.jar differ diff --git a/src/dianhua/app/src/main/jnLibs/arm64-v8a/libbmob.so b/src/dianhua/app/src/main/jnLibs/arm64-v8a/libbmob.so new file mode 100644 index 0000000..0eac711 Binary files /dev/null and b/src/dianhua/app/src/main/jnLibs/arm64-v8a/libbmob.so differ diff --git a/src/dianhua/app/src/main/jnLibs/armeabi-v7a/libbmob.so b/src/dianhua/app/src/main/jnLibs/armeabi-v7a/libbmob.so new file mode 100644 index 0000000..e5d5fb8 Binary files /dev/null and b/src/dianhua/app/src/main/jnLibs/armeabi-v7a/libbmob.so differ diff --git a/src/dianhua/app/src/main/jnLibs/armeabi/libbmob.so b/src/dianhua/app/src/main/jnLibs/armeabi/libbmob.so new file mode 100644 index 0000000..e6c7f74 Binary files /dev/null and b/src/dianhua/app/src/main/jnLibs/armeabi/libbmob.so differ diff --git a/src/dianhua/app/src/main/jnLibs/gson-2.8.5.jar b/src/dianhua/app/src/main/jnLibs/gson-2.8.5.jar new file mode 100644 index 0000000..0d5baf3 Binary files /dev/null and b/src/dianhua/app/src/main/jnLibs/gson-2.8.5.jar differ diff --git a/src/dianhua/app/src/main/jnLibs/mips/libbmob.so b/src/dianhua/app/src/main/jnLibs/mips/libbmob.so new file mode 100644 index 0000000..2a65318 Binary files /dev/null and b/src/dianhua/app/src/main/jnLibs/mips/libbmob.so differ diff --git a/src/dianhua/app/src/main/jnLibs/mips64/libbmob.so b/src/dianhua/app/src/main/jnLibs/mips64/libbmob.so new file mode 100644 index 0000000..a7bea9e Binary files /dev/null and b/src/dianhua/app/src/main/jnLibs/mips64/libbmob.so differ diff --git a/src/dianhua/app/src/main/jnLibs/okio-2.1.0.jar b/src/dianhua/app/src/main/jnLibs/okio-2.1.0.jar new file mode 100644 index 0000000..256a550 Binary files /dev/null and b/src/dianhua/app/src/main/jnLibs/okio-2.1.0.jar differ diff --git a/src/dianhua/app/src/main/jnLibs/rxandroid-2.1.0.jar b/src/dianhua/app/src/main/jnLibs/rxandroid-2.1.0.jar new file mode 100644 index 0000000..ee0b4a6 Binary files /dev/null and b/src/dianhua/app/src/main/jnLibs/rxandroid-2.1.0.jar differ diff --git a/src/dianhua/app/src/main/jnLibs/rxjava-2.2.2.jar b/src/dianhua/app/src/main/jnLibs/rxjava-2.2.2.jar new file mode 100644 index 0000000..18959b2 Binary files /dev/null and b/src/dianhua/app/src/main/jnLibs/rxjava-2.2.2.jar differ diff --git a/src/dianhua/app/src/main/jnLibs/x86/libbmob.so b/src/dianhua/app/src/main/jnLibs/x86/libbmob.so new file mode 100644 index 0000000..0382437 Binary files /dev/null and b/src/dianhua/app/src/main/jnLibs/x86/libbmob.so differ diff --git a/src/dianhua/app/src/main/jnLibs/x86_64/libbmob.so b/src/dianhua/app/src/main/jnLibs/x86_64/libbmob.so new file mode 100644 index 0000000..e0c6bcb Binary files /dev/null and b/src/dianhua/app/src/main/jnLibs/x86_64/libbmob.so differ diff --git a/src/dianhua/app/src/main/jniLibs/AMap_Location_V5.2.0_20200915.jar b/src/dianhua/app/src/main/jniLibs/AMap_Location_V5.2.0_20200915.jar new file mode 100644 index 0000000..28c3dae Binary files /dev/null and b/src/dianhua/app/src/main/jniLibs/AMap_Location_V5.2.0_20200915.jar differ diff --git a/src/dianhua/app/src/main/jniLibs/AMap_Search_V7.7.0_20201027.jar b/src/dianhua/app/src/main/jniLibs/AMap_Search_V7.7.0_20201027.jar new file mode 100644 index 0000000..ac189a6 Binary files /dev/null and b/src/dianhua/app/src/main/jniLibs/AMap_Search_V7.7.0_20201027.jar differ diff --git a/src/dianhua/app/src/main/jniLibs/Android_Map3D_SDK_V7.8.0_20201231.jar b/src/dianhua/app/src/main/jniLibs/Android_Map3D_SDK_V7.8.0_20201231.jar new file mode 100644 index 0000000..fd1c594 Binary files /dev/null and b/src/dianhua/app/src/main/jniLibs/Android_Map3D_SDK_V7.8.0_20201231.jar differ diff --git a/src/dianhua/app/src/main/jniLibs/Msc.jar b/src/dianhua/app/src/main/jniLibs/Msc.jar new file mode 100644 index 0000000..e4ed582 Binary files /dev/null and b/src/dianhua/app/src/main/jniLibs/Msc.jar differ diff --git a/src/dianhua/app/src/main/jniLibs/android-support-v4.jar b/src/dianhua/app/src/main/jniLibs/android-support-v4.jar new file mode 100644 index 0000000..2ff47f4 Binary files /dev/null and b/src/dianhua/app/src/main/jniLibs/android-support-v4.jar differ diff --git a/src/dianhua/app/src/main/jniLibs/arm64-v8a/libAMapSDK_MAP_v7_8_0.so b/src/dianhua/app/src/main/jniLibs/arm64-v8a/libAMapSDK_MAP_v7_8_0.so new file mode 100644 index 0000000..51b2207 Binary files /dev/null and b/src/dianhua/app/src/main/jniLibs/arm64-v8a/libAMapSDK_MAP_v7_8_0.so differ diff --git a/src/dianhua/app/src/main/jniLibs/arm64-v8a/libmsc.so b/src/dianhua/app/src/main/jniLibs/arm64-v8a/libmsc.so new file mode 100644 index 0000000..bd927c3 Binary files /dev/null and b/src/dianhua/app/src/main/jniLibs/arm64-v8a/libmsc.so differ diff --git a/src/dianhua/app/src/main/jniLibs/armeabi-v7a/libAMapSDK_MAP_v7_8_0.so b/src/dianhua/app/src/main/jniLibs/armeabi-v7a/libAMapSDK_MAP_v7_8_0.so new file mode 100644 index 0000000..2273bbd Binary files /dev/null and b/src/dianhua/app/src/main/jniLibs/armeabi-v7a/libAMapSDK_MAP_v7_8_0.so differ diff --git a/src/dianhua/app/src/main/jniLibs/armeabi-v7a/libmsc.so b/src/dianhua/app/src/main/jniLibs/armeabi-v7a/libmsc.so new file mode 100644 index 0000000..27c5f36 Binary files /dev/null and b/src/dianhua/app/src/main/jniLibs/armeabi-v7a/libmsc.so differ diff --git a/src/dianhua/app/src/main/jniLibs/armeabi/libAMapSDK_MAP_v7_8_0.so b/src/dianhua/app/src/main/jniLibs/armeabi/libAMapSDK_MAP_v7_8_0.so new file mode 100644 index 0000000..2273bbd Binary files /dev/null and b/src/dianhua/app/src/main/jniLibs/armeabi/libAMapSDK_MAP_v7_8_0.so differ diff --git a/src/dianhua/app/src/main/jniLibs/x86/libAMapSDK_MAP_v7_8_0.so b/src/dianhua/app/src/main/jniLibs/x86/libAMapSDK_MAP_v7_8_0.so new file mode 100644 index 0000000..aeab878 Binary files /dev/null and b/src/dianhua/app/src/main/jniLibs/x86/libAMapSDK_MAP_v7_8_0.so differ diff --git a/src/dianhua/app/src/main/jniLibs/x86_64/libAMapSDK_MAP_v7_8_0.so b/src/dianhua/app/src/main/jniLibs/x86_64/libAMapSDK_MAP_v7_8_0.so new file mode 100644 index 0000000..b2f0561 Binary files /dev/null and b/src/dianhua/app/src/main/jniLibs/x86_64/libAMapSDK_MAP_v7_8_0.so differ diff --git a/src/dianhua/app/src/main/res/drawable-hdpi/bg.png b/src/dianhua/app/src/main/res/drawable-hdpi/bg.png new file mode 100644 index 0000000..ebcc253 Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable-hdpi/bg.png differ diff --git a/src/dianhua/app/src/main/res/drawable-hdpi/btn_left.xml b/src/dianhua/app/src/main/res/drawable-hdpi/btn_left.xml new file mode 100644 index 0000000..42d1efa --- /dev/null +++ b/src/dianhua/app/src/main/res/drawable-hdpi/btn_left.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/src/dianhua/app/src/main/res/drawable-hdpi/btn_left_f.9.png b/src/dianhua/app/src/main/res/drawable-hdpi/btn_left_f.9.png new file mode 100644 index 0000000..7350c23 Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable-hdpi/btn_left_f.9.png differ diff --git a/src/dianhua/app/src/main/res/drawable-hdpi/btn_left_n.9.png b/src/dianhua/app/src/main/res/drawable-hdpi/btn_left_n.9.png new file mode 100644 index 0000000..af63253 Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable-hdpi/btn_left_n.9.png differ diff --git a/src/dianhua/app/src/main/res/drawable-hdpi/btn_left_p.9.png b/src/dianhua/app/src/main/res/drawable-hdpi/btn_left_p.9.png new file mode 100644 index 0000000..ae6e24c Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable-hdpi/btn_left_p.9.png differ diff --git a/src/dianhua/app/src/main/res/drawable-hdpi/btn_right.xml b/src/dianhua/app/src/main/res/drawable-hdpi/btn_right.xml new file mode 100644 index 0000000..198532e --- /dev/null +++ b/src/dianhua/app/src/main/res/drawable-hdpi/btn_right.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/src/dianhua/app/src/main/res/drawable-hdpi/btn_right_f.9.png b/src/dianhua/app/src/main/res/drawable-hdpi/btn_right_f.9.png new file mode 100644 index 0000000..ad645cf Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable-hdpi/btn_right_f.9.png differ diff --git a/src/dianhua/app/src/main/res/drawable-hdpi/btn_right_n.9.png b/src/dianhua/app/src/main/res/drawable-hdpi/btn_right_n.9.png new file mode 100644 index 0000000..dd73748 Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable-hdpi/btn_right_n.9.png differ diff --git a/src/dianhua/app/src/main/res/drawable-hdpi/btn_right_p.9.png b/src/dianhua/app/src/main/res/drawable-hdpi/btn_right_p.9.png new file mode 100644 index 0000000..63a14ee Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable-hdpi/btn_right_p.9.png differ diff --git a/src/dianhua/app/src/main/res/drawable-hdpi/button_login.xml b/src/dianhua/app/src/main/res/drawable-hdpi/button_login.xml new file mode 100644 index 0000000..b1e89c8 --- /dev/null +++ b/src/dianhua/app/src/main/res/drawable-hdpi/button_login.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/src/dianhua/app/src/main/res/drawable-hdpi/cancel.9.png b/src/dianhua/app/src/main/res/drawable-hdpi/cancel.9.png new file mode 100644 index 0000000..e5bf5b8 Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable-hdpi/cancel.9.png differ diff --git a/src/dianhua/app/src/main/res/drawable-hdpi/cancel_p.9.png b/src/dianhua/app/src/main/res/drawable-hdpi/cancel_p.9.png new file mode 100644 index 0000000..277f33d Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable-hdpi/cancel_p.9.png differ diff --git a/src/dianhua/app/src/main/res/drawable-hdpi/editbox.9.png b/src/dianhua/app/src/main/res/drawable-hdpi/editbox.9.png new file mode 100644 index 0000000..4321a7c Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable-hdpi/editbox.9.png differ diff --git a/src/dianhua/app/src/main/res/drawable-hdpi/edittext_name.9.png b/src/dianhua/app/src/main/res/drawable-hdpi/edittext_name.9.png new file mode 100644 index 0000000..50b010b Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable-hdpi/edittext_name.9.png differ diff --git a/src/dianhua/app/src/main/res/drawable-hdpi/head.png b/src/dianhua/app/src/main/res/drawable-hdpi/head.png new file mode 100644 index 0000000..db4a8a1 Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable-hdpi/head.png differ diff --git a/src/dianhua/app/src/main/res/drawable-hdpi/icon.png b/src/dianhua/app/src/main/res/drawable-hdpi/icon.png new file mode 100644 index 0000000..cf0cb01 Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable-hdpi/icon.png differ diff --git a/src/dianhua/app/src/main/res/drawable-hdpi/login.png b/src/dianhua/app/src/main/res/drawable-hdpi/login.png new file mode 100644 index 0000000..c7bbfa3 Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable-hdpi/login.png differ diff --git a/src/dianhua/app/src/main/res/drawable-hdpi/login_p.png b/src/dianhua/app/src/main/res/drawable-hdpi/login_p.png new file mode 100644 index 0000000..315eac9 Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable-hdpi/login_p.png differ diff --git a/src/dianhua/app/src/main/res/drawable-hdpi/mic_0.png b/src/dianhua/app/src/main/res/drawable-hdpi/mic_0.png new file mode 100644 index 0000000..69073f9 Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable-hdpi/mic_0.png differ diff --git a/src/dianhua/app/src/main/res/drawable-hdpi/mic_1.png b/src/dianhua/app/src/main/res/drawable-hdpi/mic_1.png new file mode 100644 index 0000000..130d340 Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable-hdpi/mic_1.png differ diff --git a/src/dianhua/app/src/main/res/drawable-hdpi/mic_2.png b/src/dianhua/app/src/main/res/drawable-hdpi/mic_2.png new file mode 100644 index 0000000..3d22d49 Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable-hdpi/mic_2.png differ diff --git a/src/dianhua/app/src/main/res/drawable-hdpi/mic_3.png b/src/dianhua/app/src/main/res/drawable-hdpi/mic_3.png new file mode 100644 index 0000000..fea462c Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable-hdpi/mic_3.png differ diff --git a/src/dianhua/app/src/main/res/drawable-hdpi/name_left.png b/src/dianhua/app/src/main/res/drawable-hdpi/name_left.png new file mode 100644 index 0000000..6916dad Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable-hdpi/name_left.png differ diff --git a/src/dianhua/app/src/main/res/drawable-hdpi/name_right.png b/src/dianhua/app/src/main/res/drawable-hdpi/name_right.png new file mode 100644 index 0000000..c7f2be8 Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable-hdpi/name_right.png differ diff --git a/src/dianhua/app/src/main/res/drawable-hdpi/ok.9.png b/src/dianhua/app/src/main/res/drawable-hdpi/ok.9.png new file mode 100644 index 0000000..e53f2be Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable-hdpi/ok.9.png differ diff --git a/src/dianhua/app/src/main/res/drawable-hdpi/ok_d.9.png b/src/dianhua/app/src/main/res/drawable-hdpi/ok_d.9.png new file mode 100644 index 0000000..a94d1f6 Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable-hdpi/ok_d.9.png differ diff --git a/src/dianhua/app/src/main/res/drawable-hdpi/ok_p.9.png b/src/dianhua/app/src/main/res/drawable-hdpi/ok_p.9.png new file mode 100644 index 0000000..f1b6579 Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable-hdpi/ok_p.9.png differ diff --git a/src/dianhua/app/src/main/res/drawable-hdpi/pane_bg.9.png b/src/dianhua/app/src/main/res/drawable-hdpi/pane_bg.9.png new file mode 100644 index 0000000..8eefa0a Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable-hdpi/pane_bg.9.png differ diff --git a/src/dianhua/app/src/main/res/drawable-hdpi/superman.9.png b/src/dianhua/app/src/main/res/drawable-hdpi/superman.9.png new file mode 100644 index 0000000..be4a3c1 Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable-hdpi/superman.9.png differ diff --git a/src/dianhua/app/src/main/res/drawable-ldpi/icon.png b/src/dianhua/app/src/main/res/drawable-ldpi/icon.png new file mode 100644 index 0000000..d2dfdc6 Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable-ldpi/icon.png differ diff --git a/src/dianhua/app/src/main/res/drawable-mdpi/icon.png b/src/dianhua/app/src/main/res/drawable-mdpi/icon.png new file mode 100644 index 0000000..6a5697e Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable-mdpi/icon.png differ diff --git a/src/dianhua/app/src/main/res/drawable/addcontacts.png b/src/dianhua/app/src/main/res/drawable/addcontacts.png new file mode 100644 index 0000000..ff59c56 Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable/addcontacts.png differ diff --git a/src/dianhua/app/src/main/res/drawable/begin.png b/src/dianhua/app/src/main/res/drawable/begin.png new file mode 100644 index 0000000..67ddd22 Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable/begin.png differ diff --git a/src/dianhua/app/src/main/res/drawable/blue.xml b/src/dianhua/app/src/main/res/drawable/blue.xml new file mode 100644 index 0000000..de5cc30 --- /dev/null +++ b/src/dianhua/app/src/main/res/drawable/blue.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + diff --git a/src/dianhua/app/src/main/res/drawable/cancel_button.xml b/src/dianhua/app/src/main/res/drawable/cancel_button.xml new file mode 100644 index 0000000..f174e34 --- /dev/null +++ b/src/dianhua/app/src/main/res/drawable/cancel_button.xml @@ -0,0 +1,17 @@ + + + + + + + \ No newline at end of file diff --git a/src/dianhua/app/src/main/res/drawable/contacts.png b/src/dianhua/app/src/main/res/drawable/contacts.png new file mode 100644 index 0000000..1c07919 Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable/contacts.png differ diff --git a/src/dianhua/app/src/main/res/drawable/contacts2.png b/src/dianhua/app/src/main/res/drawable/contacts2.png new file mode 100644 index 0000000..42ee2bd Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable/contacts2.png differ diff --git a/src/dianhua/app/src/main/res/drawable/end.png b/src/dianhua/app/src/main/res/drawable/end.png new file mode 100644 index 0000000..7c095f0 Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable/end.png differ diff --git a/src/dianhua/app/src/main/res/drawable/gray.xml b/src/dianhua/app/src/main/res/drawable/gray.xml new file mode 100644 index 0000000..7ce8f25 --- /dev/null +++ b/src/dianhua/app/src/main/res/drawable/gray.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + diff --git a/src/dianhua/app/src/main/res/drawable/green.xml b/src/dianhua/app/src/main/res/drawable/green.xml new file mode 100644 index 0000000..7a3088d --- /dev/null +++ b/src/dianhua/app/src/main/res/drawable/green.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + diff --git a/src/dianhua/app/src/main/res/drawable/ic_launcher_background.xml b/src/dianhua/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/src/dianhua/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/dianhua/app/src/main/res/drawable/ic_launcher_foreground.xml b/src/dianhua/app/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/src/dianhua/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/dianhua/app/src/main/res/drawable/list_bg_color.xml b/src/dianhua/app/src/main/res/drawable/list_bg_color.xml new file mode 100644 index 0000000..bfc0d13 --- /dev/null +++ b/src/dianhua/app/src/main/res/drawable/list_bg_color.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/src/dianhua/app/src/main/res/drawable/locate.png b/src/dianhua/app/src/main/res/drawable/locate.png new file mode 100644 index 0000000..53fdfd8 Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable/locate.png differ diff --git a/src/dianhua/app/src/main/res/drawable/location.png b/src/dianhua/app/src/main/res/drawable/location.png new file mode 100644 index 0000000..794213c Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable/location.png differ diff --git a/src/dianhua/app/src/main/res/drawable/location2.png b/src/dianhua/app/src/main/res/drawable/location2.png new file mode 100644 index 0000000..f3b2544 Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable/location2.png differ diff --git a/src/dianhua/app/src/main/res/drawable/main_setting_btn_np.xml b/src/dianhua/app/src/main/res/drawable/main_setting_btn_np.xml new file mode 100644 index 0000000..2f4d36b --- /dev/null +++ b/src/dianhua/app/src/main/res/drawable/main_setting_btn_np.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/dianhua/app/src/main/res/drawable/message.png b/src/dianhua/app/src/main/res/drawable/message.png new file mode 100644 index 0000000..766d584 Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable/message.png differ diff --git a/src/dianhua/app/src/main/res/drawable/ok_button.xml b/src/dianhua/app/src/main/res/drawable/ok_button.xml new file mode 100644 index 0000000..ef12820 --- /dev/null +++ b/src/dianhua/app/src/main/res/drawable/ok_button.xml @@ -0,0 +1,21 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/dianhua/app/src/main/res/drawable/orange.xml b/src/dianhua/app/src/main/res/drawable/orange.xml new file mode 100644 index 0000000..e9c7e3f --- /dev/null +++ b/src/dianhua/app/src/main/res/drawable/orange.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + diff --git a/src/dianhua/app/src/main/res/drawable/out.png b/src/dianhua/app/src/main/res/drawable/out.png new file mode 100644 index 0000000..80b8e22 Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable/out.png differ diff --git a/src/dianhua/app/src/main/res/drawable/purple.xml b/src/dianhua/app/src/main/res/drawable/purple.xml new file mode 100644 index 0000000..74432e0 --- /dev/null +++ b/src/dianhua/app/src/main/res/drawable/purple.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + diff --git a/src/dianhua/app/src/main/res/drawable/red.xml b/src/dianhua/app/src/main/res/drawable/red.xml new file mode 100644 index 0000000..90ecc7b --- /dev/null +++ b/src/dianhua/app/src/main/res/drawable/red.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + diff --git a/src/dianhua/app/src/main/res/drawable/setting.png b/src/dianhua/app/src/main/res/drawable/setting.png new file mode 100644 index 0000000..437bc51 Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable/setting.png differ diff --git a/src/dianhua/app/src/main/res/drawable/setting_p.png b/src/dianhua/app/src/main/res/drawable/setting_p.png new file mode 100644 index 0000000..0da80e4 Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable/setting_p.png differ diff --git a/src/dianhua/app/src/main/res/drawable/voice.png b/src/dianhua/app/src/main/res/drawable/voice.png new file mode 100644 index 0000000..d30f4ba Binary files /dev/null and b/src/dianhua/app/src/main/res/drawable/voice.png differ diff --git a/src/dianhua/app/src/main/res/drawable/yellow.xml b/src/dianhua/app/src/main/res/drawable/yellow.xml new file mode 100644 index 0000000..135ffc7 --- /dev/null +++ b/src/dianhua/app/src/main/res/drawable/yellow.xml @@ -0,0 +1,16 @@ + + + + + + + + diff --git a/src/dianhua/app/src/main/res/layout/activity_contact.xml b/src/dianhua/app/src/main/res/layout/activity_contact.xml new file mode 100644 index 0000000..8237627 --- /dev/null +++ b/src/dianhua/app/src/main/res/layout/activity_contact.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + +