From 398d353be9d2a62afaea36315d500d6b7cfe31c5 Mon Sep 17 00:00:00 2001 From: tongtongstudio Date: Mon, 10 Feb 2025 17:05:54 +0800 Subject: [PATCH] =?UTF-8?q?version:1.4.8=20fix:=E4=BF=AE=E5=A4=8D=E4=B8=80?= =?UTF-8?q?=E9=94=AE=E6=8B=A8=E5=8F=B7=20update:=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E8=81=94=E7=B3=BB=E4=BA=BA=E9=97=B9=E9=92=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 4 +- .../activity/alarm/add/AlarmAddActivity.java | 4 +- .../alarm/edit/AlarmEditActivity.java | 4 +- .../alarm/list/AlarmListActivity.java | 4 +- .../activity/contact/AddContactActivity.java | 16 +- .../activity/contact/AddContactViewModel.java | 42 +- .../activity/contact/ContactListActivity.java | 9 +- .../contact/ContactListViewModel.java | 86 +--- .../activity/contact/EditContactActivity.java | 35 +- .../contact/EditContactViewModel.java | 6 +- .../activity/emergency/EmergencyActivity.java | 1 - .../emergency/EmergencyViewModel.java | 89 +--- .../xxpatx/os/activity/main/MainActivity.java | 15 +- .../os/activity/noti/NoticeActivity.java | 4 +- .../os/activity/noti/NoticeInfoActivity.java | 19 +- .../screenlock/ScreenLockActivity.java | 17 +- .../os/activity/setting/SettingsActivity.java | 53 --- .../xxpatx/os/adapter/DailyAppAdapter.java | 2 +- .../java/com/xxpatx/os/alarm/AlarmUtils.java | 8 +- .../main/java/com/xxpatx/os/bean/Contact.java | 9 + .../java/com/xxpatx/os/bean/ContactId.java | 1 + .../xxpatx/os/disklrucache/CacheHelper.java | 8 +- .../os/fragment/app/AppListFragment.java | 2 +- .../os/fragment/contact/ContactFragment.java | 237 +--------- .../os/fragment/contact/ContactViewModel.java | 105 ++--- .../os/fragment/control/ControlFragment.java | 8 +- .../os/fragment/control/ControlViewModel.java | 6 +- .../phone/contact/ContactFragment.java | 64 +-- .../phone/contact/ContactViewModel.java | 77 +--- .../fragment/phone/dialer/DialerFragment.java | 39 +- .../os/network/NetInterfaceManager.java | 93 ++-- .../com/xxpatx/os/network/UrlAddress.java | 1 + .../api/uiui/{ => contact}/GetMailList.java | 2 +- .../os/receiver/InstallResultReceiver.java | 4 +- .../os/service/WeAccessibilityService.java | 219 ++++++++-- .../xxpatx/os/service/main/MainService.java | 80 +++- .../java/com/xxpatx/os/utils/ApkUtils.java | 2 +- .../com/xxpatx/os/utils/ContactsUtils.java | 403 ++++++++++++++---- .../xxpatx/os/utils/ForegroundAppUtil.java | 14 +- .../java/com/xxpatx/os/utils/ScreenUtil.java | 21 - .../main/java/com/xxpatx/os/utils/Utils.java | 2 +- .../java/com/xxpatx/os/view/ToggleButton.java | 2 +- ...d_contact.xml => activity_contact_add.xml} | 2 + ...d_contact.xml => activity_contact_add.xml} | 36 +- ..._contact.xml => activity_contact_edit.xml} | 37 +- .../main/res/layout/fragment_contact_home.xml | 171 +------- ...gment_control.xml => fragment_control.xml} | 0 app/src/main/res/layout/fragment_home.xml | 5 +- app/src/main/res/layout/item_contact.xml | 9 +- app/src/main/res/layout/settings_activity.xml | 16 - .../res/xml/accessibility_service_config.xml | 6 +- 51 files changed, 993 insertions(+), 1106 deletions(-) delete mode 100644 app/src/main/java/com/xxpatx/os/activity/setting/SettingsActivity.java rename app/src/main/java/com/xxpatx/os/network/api/uiui/{ => contact}/GetMailList.java (89%) delete mode 100644 app/src/main/java/com/xxpatx/os/utils/ScreenUtil.java rename app/src/main/res/layout-sw700dp/{activity_add_contact.xml => activity_contact_add.xml} (99%) rename app/src/main/res/layout/{activity_add_contact.xml => activity_contact_add.xml} (91%) rename app/src/main/res/layout/{activity_edit_contact.xml => activity_contact_edit.xml} (90%) rename app/src/main/res/layout/{phone_fragment_control.xml => fragment_control.xml} (100%) delete mode 100644 app/src/main/res/layout/settings_activity.xml diff --git a/app/build.gradle b/app/build.gradle index eb6a7cf..7c029f4 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,8 +15,8 @@ android { applicationId "com.xxpatx.os" minSdkVersion 24 targetSdkVersion 29 - versionCode 1042 - versionName "1.4.2" + versionCode 1048 + versionName "1.4.8" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/app/src/main/java/com/xxpatx/os/activity/alarm/add/AlarmAddActivity.java b/app/src/main/java/com/xxpatx/os/activity/alarm/add/AlarmAddActivity.java index d12e121..c6f1d8e 100644 --- a/app/src/main/java/com/xxpatx/os/activity/alarm/add/AlarmAddActivity.java +++ b/app/src/main/java/com/xxpatx/os/activity/alarm/add/AlarmAddActivity.java @@ -28,7 +28,7 @@ import com.xxpatx.os.databinding.ActivityAlarmAddBinding; import com.xxpatx.os.service.main.MainService; import com.xxpatx.os.utils.FFmpegUtils; import com.xxpatx.os.utils.FileUtil; -import com.xxpatx.os.utils.ScreenUtil; +import com.xxpatx.os.utils.ScreenUtils; import com.xxpatx.os.utils.TimeUtils; import java.io.File; @@ -162,7 +162,7 @@ public class AlarmAddActivity extends BaseMvvmActivity { +public class AddContactActivity extends BaseMvvmActivity { private static final String TAG = "AddContactActivity"; private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); @@ -64,7 +64,7 @@ public class AddContactActivity extends BaseMvvmActivity() { @Override public void onResourceReady(@androidx.annotation.NonNull Bitmap resource, @Nullable Transition transition) { @@ -207,7 +207,7 @@ public class AddContactActivity extends BaseMvvmActivity { +public class AddContactViewModel extends BaseViewModel { private static final String TAG = "AddContactViewModel"; @Override - public ActivityAddContactBinding getVDBinding() { + public ActivityContactAddBinding getVDBinding() { return binding; } @@ -69,12 +70,25 @@ public class AddContactViewModel extends BaseViewModel params = new HashMap<>(); - params.put("sn", Utils.getSerial()); params.put("name", name); params.put("mobile", phone); params.put("tag", tag); params.put("is_urgent", String.valueOf(binding.toggleButton.isToggleOn())); + params.put("show_desktop", String.valueOf(binding.tbShow.isToggleOn())); + + Contact contact = new Contact(); + ThreadLocalRandom random = ThreadLocalRandom.current(); + int fakeId = random.nextInt(Integer.MAX_VALUE); + Log.e(TAG, "checkContent: fakeId = " + fakeId); + contact.setId(fakeId); + contact.setMobile(phone); + contact.setName(name); + contact.setTag(tag); + contact.setIs_urgent(binding.toggleButton.isToggleOn()); + contact.setAvatar(avatarFilePath); + ContactsUtils.saveContactPhone(getCtx(), contact); + NetInterfaceManager.getInstance() .getMailListAddObservable(params, body) .compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY)) @@ -91,16 +105,6 @@ public class AddContactViewModel extends BaseViewModel> mContactListData = new MutableLiveData<>(); - - public MutableLiveData> getContactListData() { - return mContactListData; - } - - public void getCacheContact() { - String jsonString = mMMKV.getString(UrlAddress.GET_MAIL_LIST, null); - Gson gson = new Gson(); - Type type = new TypeToken>() { - }.getType(); - if (!TextUtils.isEmpty(jsonString)) { - List contacts = gson.fromJson(jsonString, type); - if (contacts != null) { - mContactListData.setValue(contacts); - } - } - getContact(); - } + public MutableLiveData> mContactListData = new MutableLiveData<>(); public void getContact() { + NetInterfaceManager.getInstance().getContactListObserverCache(UrlAddress.GET_MAIL_LIST, new NetInterfaceManager.ContactCallback() { + @Override + public void setContact(List contactList) { + mContactListData.setValue(contactList); + } + + @Override + public void onComplete() { + + } + }); + NetInterfaceManager.getInstance() - .getContactListObservable() - .compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY)) - .subscribe(new Observer>>() { + .getContactList(getLifecycle(), new NetInterfaceManager.ContactCallback() { @Override - public void onSubscribe(@NonNull Disposable d) { - Log.e("getContactList", "onSubscribe: "); - } - - @Override - public void onNext(@NonNull BaseResponse> listBaseResponse) { - Log.e("getContactList", "onNext: " + listBaseResponse); - if (listBaseResponse.code == 200) { - mMMKV.putString(UrlAddress.GET_MAIL_LIST, GsonUtils.toJSONString(listBaseResponse.data)); - mContactListData.setValue(listBaseResponse.data); - } else { - mMMKV.putString(UrlAddress.GET_MAIL_LIST, ""); - mContactListData.setValue(new ArrayList<>()); - } - } - - @Override - public void onError(@NonNull Throwable e) { - Log.e("getContactList", "onError: " + e.getMessage()); - String jsonString = mMMKV.getString(UrlAddress.GET_MAIL_LIST, null); - Gson gson = new Gson(); - Type type = new TypeToken>() { - }.getType(); - List contacts = gson.fromJson(jsonString, type); - if (contacts == null) { - mContactListData.setValue(new ArrayList<>()); - } else { - mContactListData.setValue(contacts); - } - onComplete(); + public void setContact(List contactList) { + mContactListData.setValue(contactList); } @Override public void onComplete() { - Log.e("getContactList", "onComplete: "); + } }); } - private MutableLiveData mDeleteData = new MutableLiveData<>(); - - public MutableLiveData getDeleteData() { - return mDeleteData; - } + public MutableLiveData mDeleteData = new MutableLiveData<>(); public void deleteContact(Contact contact) { Log.e(TAG, "deleteContact: " + contact.getId()); @@ -125,6 +80,9 @@ public class ContactListViewModel extends BaseViewModel { +public class EditContactActivity extends BaseMvvmActivity { private static final String TAG = "EditContactActivity"; private LoadingDialog mLoadingDialog; private String mPictrueFilePath; private Contact mContact; + @Override + public boolean setNightMode() { + return true; + } + @Override public boolean setfitWindow() { return true; @@ -55,7 +62,7 @@ public class EditContactActivity extends BaseMvvmActivity() { @Override public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition transition) { @@ -133,7 +146,7 @@ public class EditContactActivity extends BaseMvvmActivity> listBaseResponse) { - Log.e("getContactList", "onNext: " + listBaseResponse); - if (listBaseResponse.code == 200) { - List contactList = listBaseResponse.data; - if (contactList != null && !contactList.isEmpty()) { - List emergencyConcacts = contactList.stream().filter(new Predicate() { - @Override - public boolean test(Contact contact) { - return contact.getIs_urgent() == 1; - } - }).collect(Collectors.toList()); - mMMKV.putString(CommonConfig.EMERGENCY_CONTACT_LIST_KEY, GsonUtils.toJSONString(emergencyConcacts)); - mContactListData.setValue(emergencyConcacts); - } - } else { - mMMKV.putString(CommonConfig.EMERGENCY_CONTACT_LIST_KEY, ""); - mContactListData.setValue(new ArrayList<>()); - } - } - - @Override - public void onError(@NonNull Throwable e) { - Log.e("getContactList", "onError: " + e.getMessage()); - String jsonString = mMMKV.getString(CommonConfig.EMERGENCY_CONTACT_LIST_KEY, null); - Gson gson = new Gson(); - Type type = new TypeToken>() { - }.getType(); - List contacts = gson.fromJson(jsonString, type); - if (contacts == null) { - mContactListData.setValue(new ArrayList<>()); - } else { - mContactListData.setValue(contacts); - } - onComplete(); + public void setContact(List contactList) { + List emergencyConcacts = contactList.stream().filter(contact -> contact.getIs_urgent() == 1).collect(Collectors.toList()); + mContactListData.setValue(emergencyConcacts); } @Override public void onComplete() { - Log.e("getContactList", "onComplete: "); + } }); } diff --git a/app/src/main/java/com/xxpatx/os/activity/main/MainActivity.java b/app/src/main/java/com/xxpatx/os/activity/main/MainActivity.java index e0824c7..1ed3fa7 100644 --- a/app/src/main/java/com/xxpatx/os/activity/main/MainActivity.java +++ b/app/src/main/java/com/xxpatx/os/activity/main/MainActivity.java @@ -11,6 +11,7 @@ import android.content.IntentFilter; import android.content.ServiceConnection; import android.content.pm.PackageManager; import android.content.res.Configuration; +import android.content.res.Resources; import android.database.Cursor; import android.hardware.camera2.CameraAccessException; import android.hardware.camera2.CameraCharacteristics; @@ -93,6 +94,9 @@ import java.util.Date; import java.util.List; import java.util.Locale; +import me.jessyan.autosize.AutoSizeCompat; +import me.jessyan.autosize.AutoSizeConfig; + import static com.arialyy.aria.core.inf.IEntity.STATE_RUNNING; public class MainActivity extends BaseMvvmActivity implements NetworkUtils.OnNetworkStatusChangedListener, @@ -127,6 +131,15 @@ public class MainActivity extends BaseMvvmActivity height); + return super.getResources(); + } + @Override public void onDisconnected() { Log.e(TAG, "onDisconnected: "); @@ -177,7 +190,7 @@ public class MainActivity extends BaseMvvmActivity { private static final String TAG = "ContactFragment"; @@ -64,240 +50,57 @@ public class ContactFragment extends BaseMvvmFragment() { - @Override - public void onChanged(@Nullable MapBean mapBean) { - mViewDataBinding.tvLocation.setText(mapBean.getDistrict()); - } - }); - } else { - - } - } + private List mContacts = new ArrayList() {{ + this.add(new Contact("未设置")); + this.add(new Contact("未设置")); + this.add(new Contact("未设置")); + this.add(new Contact("未设置")); + this.add(new Contact("未设置")); + this.add(new Contact("未设置")); + }}; @Override protected void initData(Bundle savedInstanceState) { - LiveEventBus - .get("getWeatherNowKey", WeatherNowBean.NowBaseBean.class) - .observe(this, new Observer() { - @Override - public void onChanged(@Nullable WeatherNowBean.NowBaseBean nowBaseBean) { - mViewDataBinding.tvTemp.setText(nowBaseBean.getTemp() + "℃"); - if (DayUtils.isNight()) { -// mViewDataBinding.clWeather.setBackground(mContext.getDrawable(R.drawable.custom_bg_weather_night)); - } else { - switch (nowBaseBean.getIcon()) { - default: - case "100": - case "150": - //晴 -// mViewDataBinding.clWeather.setBackground(mContext.getDrawable(R.drawable.custom_bg_weather)); - break; - case "102": - case "152": - //少云 -// mViewDataBinding.clWeather.setBackground(mContext.getDrawable(R.drawable.custom_bg_weather_rain)); - break; - } - } -// mViewDataBinding.tvWeather.setText(nowBaseBean.getText()); - } - }); - -// LiveEventBus -// .get("getWeather24HourlyKey", WeatherHourlyBean.HourlyBean.class) -// .observe(this, new Observer() { -// @Override -// public void onChanged(@Nullable WeatherHourlyBean.HourlyBean hourlyBean) { -// String imageName = "he" + hourlyBean.getIcon(); -// Log.e(TAG, "onSuccess: " + imageName); -// if (isAdded()) { -// int resId = getResources().getIdentifier(imageName, "drawable", mContext.getPackageName()); -//// Log.e(TAG, "onSuccess: " + resId); -//// if (resId == 0) { -//// mViewDataBinding.ivPic.setImageDrawable(mContext.getDrawable(R.drawable.he100)); -//// } else { -//// mViewDataBinding.ivPic.setImageDrawable(mContext.getDrawable(resId)); -//// } -// mViewDataBinding.tvTemp.setText(hourlyBean.getTemp() + "℃"); -// } -// } -// }); -// -// LiveEventBus -// .get("getWeather7DKey", WeatherDailyBean.DailyBean.class) -// .observe(this, new Observer() { -// @Override -// public void onChanged(@Nullable WeatherDailyBean.DailyBean dailyBean) { -// mViewDataBinding.tvWeather.setText(dailyBean.getTempMin() + "℃ - " + dailyBean.getTempMax() + "℃"); -// } -// }); -// -// LiveEventBus -// .get("time", String.class) -// .observe(this, new Observer() { -// @Override -// public void onChanged(@Nullable String s) { -// mViewDataBinding.tvTime.setText(s); -// } -// }); -// -// LiveEventBus -// .get("date", String.class) -// .observe(this, new Observer() { -// @Override -// public void onChanged(@Nullable String s) { -// mViewDataBinding.tvData.setText(s); -// } -// }); -// -// LiveEventBus -// .get("week", String.class) -// .observe(this, new Observer() { -// @Override -// public void onChanged(@Nullable String s) { -// mViewDataBinding.tvWeek.setText(s); -// } -// }); - mViewModel.mContactListData.observe(this, new Observer>() { @Override public void onChanged(List contacts) { - if (contacts == null || contacts.size() == 0) { - contacts .add(new Contact("未设置")); - contacts .add(new Contact("未设置")); - contacts .add(new Contact("未设置")); - contacts .add(new Contact("未设置")); - contacts .add(new Contact("未设置")); - contacts .add(new Contact("未设置")); -// mViewDataBinding.clNodata.setVisibility(View.VISIBLE); -// mViewDataBinding.rvContact.setVisibility(View.GONE); + if (contacts == null || contacts.isEmpty()) { + mContactAdapter.setContactList(mContacts); } else { -// mViewDataBinding.clNodata.setVisibility(View.GONE); -// mViewDataBinding.rvContact.setVisibility(View.VISIBLE); -// List sim = getSIMContacts(); -// if (sim.size() != 0) { -// contacts.addAll(sim); -// } + List show = contacts.stream().filter(contact -> contact.getShow_desktop() == 1).collect(Collectors.toList()); + if (show.isEmpty()) { + mContactAdapter.setContactList(mContacts); + } else { + mContactAdapter.setContactList(show); + } } - mContactAdapter.setContactList(contacts); - } - }); - mViewModel.mDeleteData.observe(this, new Observer() { - @Override - public void onChanged(BaseResponse baseResponse) { - if (baseResponse.code == 200) { - Toaster.show("删除成功"); - } else { - Toaster.show("删除失败:" + baseResponse.msg); - } - mViewModel.getContact(); } }); + mViewModel.getContact(); } @Override public void fetchData() { Log.e(TAG, "fetchData: "); - mViewModel.getCacheContact(); + mViewModel.getContactNoSave(); } @Override public void onResume() { super.onResume(); - String district = mMMKV.decodeString(CommonConfig.MANUALLY_SELECT_LOCATION_DISTRICT, CommonConfig.DEFAULT_LOCATION_DISTRICT); - mViewDataBinding.tvLocation.setText(district); - } - - private EditContactDialog mEditContactDialog; - - private void showDialog(Contact contact) { - if (mEditContactDialog == null) { - mEditContactDialog = new EditContactDialog(getContext()); - } - mEditContactDialog - .setPhoneNumber(contact.getMobile()) - .setOnClickBottomListener(new EditContactDialog.OnClickBottomListener() { - @Override - public void onEditClick() { - Intent intent = new Intent(getContext(), EditContactActivity.class); - intent.putExtra("Contact", contact); - startActivity(intent); - mEditContactDialog.dismiss(); - } - - @Override - public void onDeleteClick() { - mViewModel.deleteContact(contact.getId()); - mEditContactDialog.dismiss(); - } - - @Override - public void onCancelClick() { - mEditContactDialog.dismiss(); - } - }); - Window window = mEditContactDialog.getWindow(); - window.setGravity(Gravity.BOTTOM); - mEditContactDialog.show(); - } - - public static final String NAME = "name"; - public static final String NUMBER = "number"; - - private List getSIMContacts() { - List contactList = new ArrayList<>(); - ContentResolver resolver = mContext.getContentResolver(); - // 获取Sims卡联系人 - Uri uri = Uri.parse("content://icc/adn"); - Cursor phoneCursor = resolver.query(uri, null, null, null, null); - if (phoneCursor != null) { - final int colName = phoneCursor.getColumnIndex(NAME); - final int colNumber = phoneCursor.getColumnIndex(NUMBER); - while (phoneCursor.moveToNext()) { - String number = phoneCursor.getString(colNumber); - // 当手机号码为空的或者为空字段 跳过当前循环 - String username = phoneCursor.getString(colName); - Log.e(TAG, "getSIMContacts: number = " + number + " username = " + username); - Contact contact = new Contact(username, number, true); - contactList.add(contact); - } - phoneCursor.close(); - } - return contactList; + mViewModel.getContactNoSave(); } public class BtnClick { - public void toAdd(View view) { Intent intent = new Intent(getContext(), AddContactActivity.class); startActivity(intent); diff --git a/app/src/main/java/com/xxpatx/os/fragment/contact/ContactViewModel.java b/app/src/main/java/com/xxpatx/os/fragment/contact/ContactViewModel.java index c4f0e00..47b38d9 100644 --- a/app/src/main/java/com/xxpatx/os/fragment/contact/ContactViewModel.java +++ b/app/src/main/java/com/xxpatx/os/fragment/contact/ContactViewModel.java @@ -1,12 +1,9 @@ package com.xxpatx.os.fragment.contact; -import android.text.TextUtils; import android.util.Log; import androidx.lifecycle.MutableLiveData; -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; import com.tencent.mmkv.MMKV; import com.trello.rxlifecycle4.RxLifecycle; import com.trello.rxlifecycle4.android.FragmentEvent; @@ -15,14 +12,10 @@ import com.xxpatx.os.bean.BaseResponse; import com.xxpatx.os.bean.Contact; import com.xxpatx.os.config.CommonConfig; import com.xxpatx.os.databinding.FragmentContactHomeBinding; -import com.xxpatx.os.db.ContactCacheUtils; import com.xxpatx.os.gson.GsonUtils; import com.xxpatx.os.network.NetInterfaceManager; import com.xxpatx.os.network.UrlAddress; -import com.xxpatx.os.utils.ContactsUtils; -import java.lang.reflect.Type; -import java.util.ArrayList; import java.util.List; import io.reactivex.rxjava3.annotations.NonNull; @@ -45,98 +38,62 @@ public class ContactViewModel extends BaseViewModel> mContactListData = new MutableLiveData<>(); - public void getCacheContact() { - String jsonString = mMMKV.getString(UrlAddress.GET_MAIL_LIST, null); - Gson gson = new Gson(); - Type type = new TypeToken>() { - }.getType(); - if (!TextUtils.isEmpty(jsonString)) { - List contacts = gson.fromJson(jsonString, type); - if (contacts != null) { - contacts.addAll(ContactCacheUtils.getInstance().getDatabaseContact()); - mContactListData.setValue(contacts); + public void getContact() { + NetInterfaceManager.getInstance().getContactListObserverCache(UrlAddress.GET_MAIL_LIST, new NetInterfaceManager.ContactCallback() { + @Override + public void setContact(List contactList) { + mContactListData.setValue(contactList); + } + + @Override + public void onComplete() { } - } - getContact(); + }); + + NetInterfaceManager.getInstance() + .getContactListFragment(getLifecycle(), new NetInterfaceManager.ContactCallback() { + @Override + public void setContact(List contactList) { + mContactListData.setValue(contactList); + } + + @Override + public void onComplete() { + + } + }); } - public void getContact() { - NetInterfaceManager.getInstance() - .getContactListObservable() + public void getContactNoSave() { + NetInterfaceManager.getInstance().getContactListObservable() .compose(RxLifecycle.bindUntilEvent(getLifecycle(), FragmentEvent.DESTROY)) .subscribe(new Observer>>() { @Override public void onSubscribe(@NonNull Disposable d) { - Log.e("getContactList", "onSubscribe: "); + Log.e("getContactNoSave", "onSubscribe: "); } @Override public void onNext(@NonNull BaseResponse> listBaseResponse) { - Log.e("getContactList", "onNext: " + listBaseResponse); + Log.e("getContactNoSave", "onNext: "); if (listBaseResponse.code == 200) { List contactList = listBaseResponse.data; - String oldCache = mMMKV.getString(UrlAddress.GET_MAIL_LIST, ""); - if (!oldCache.equals(GsonUtils.toJSONString(listBaseResponse.data))) { - ContactsUtils.saveContactPhone(getCtx(), contactList); - } + mMMKV.putString(UrlAddress.GET_MAIL_LIST, GsonUtils.toJSONString(contactList)); mContactListData.setValue(contactList); - mMMKV.putString(UrlAddress.GET_MAIL_LIST, GsonUtils.toJSONString(listBaseResponse.data)); } else { - mMMKV.putString(UrlAddress.GET_MAIL_LIST, ""); - mContactListData.setValue(new ArrayList<>()); + mMMKV.remove(UrlAddress.GET_MAIL_LIST); } } @Override public void onError(@NonNull Throwable e) { - Log.e("getContactList", "onError: " + e.getMessage()); - String jsonString = mMMKV.getString(UrlAddress.GET_MAIL_LIST, null); - Gson gson = new Gson(); - Type type = new TypeToken>() { - }.getType(); - List contacts = gson.fromJson(jsonString, type); - if (contacts == null) { - mContactListData.setValue(ContactCacheUtils.getInstance().getDatabaseContact()); - } else { - contacts.addAll(ContactCacheUtils.getInstance().getDatabaseContact()); - mContactListData.setValue(contacts); - } - onComplete(); + Log.e("getContactNoSave", "onError: "); } @Override public void onComplete() { - Log.e("getContactList", "onComplete: "); - } - }); - } - - public MutableLiveData mDeleteData = new MutableLiveData<>(); - - public void deleteContact(long id) { - NetInterfaceManager.getInstance().getMailListDeleteObservable(id) - .compose(RxLifecycle.bindUntilEvent(getLifecycle(), FragmentEvent.DESTROY)) - .subscribe(new Observer() { - @Override - public void onSubscribe(@NonNull Disposable d) { - Log.e("deleteContact", "onSubscribe: "); - } - - @Override - public void onNext(@NonNull BaseResponse baseResponse) { - Log.e("deleteContact", "onNext: " + baseResponse); - mDeleteData.setValue(baseResponse); - } - - @Override - public void onError(@NonNull Throwable e) { - Log.e("deleteContact", "onError: " + e.getMessage()); - } - - @Override - public void onComplete() { - Log.e("deleteContact", "onComplete: "); + Log.e("getContactNoSave", "onComplete: "); } }); } diff --git a/app/src/main/java/com/xxpatx/os/fragment/control/ControlFragment.java b/app/src/main/java/com/xxpatx/os/fragment/control/ControlFragment.java index 6d166ef..781d290 100644 --- a/app/src/main/java/com/xxpatx/os/fragment/control/ControlFragment.java +++ b/app/src/main/java/com/xxpatx/os/fragment/control/ControlFragment.java @@ -27,8 +27,6 @@ import android.provider.Settings; import android.text.TextUtils; import android.util.Log; import android.view.View; -import android.view.Window; -import android.view.WindowManager; import android.widget.SeekBar; import androidx.annotation.NonNull; @@ -41,7 +39,7 @@ import com.xxpatx.os.activity.setting.SettingActivity; import com.xxpatx.os.base.mvvm.fragment.BaseMvvmFragment; import com.xxpatx.os.bean.FamilyAddress; import com.xxpatx.os.config.CommonConfig; -import com.xxpatx.os.databinding.PhoneFragmentControlBinding; +import com.xxpatx.os.databinding.FragmentControlBinding; import com.xxpatx.os.manager.AmapManager; import com.xxpatx.os.utils.BrightnessUtils; @@ -57,7 +55,7 @@ import java.util.Set; * Use the {@link ControlFragment#newInstance} factory method to * create an instance of this fragment. */ -public class ControlFragment extends BaseMvvmFragment { +public class ControlFragment extends BaseMvvmFragment { private static final String TAG = "ControlFragment"; private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); @@ -133,7 +131,7 @@ public class ControlFragment extends BaseMvvmFragment { +public class ControlViewModel extends BaseViewModel { private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); @Override - public PhoneFragmentControlBinding getVDBinding() { + public FragmentControlBinding getVDBinding() { return binding; } diff --git a/app/src/main/java/com/xxpatx/os/fragment/phone/contact/ContactFragment.java b/app/src/main/java/com/xxpatx/os/fragment/phone/contact/ContactFragment.java index c0fb9ed..a2e9121 100644 --- a/app/src/main/java/com/xxpatx/os/fragment/phone/contact/ContactFragment.java +++ b/app/src/main/java/com/xxpatx/os/fragment/phone/contact/ContactFragment.java @@ -30,7 +30,6 @@ import com.xxpatx.os.config.CommonConfig; import com.xxpatx.os.databinding.FragmentContactBinding; import com.xxpatx.os.dialog.EditContactDialog; -import java.util.ArrayList; import java.util.List; /** @@ -90,11 +89,6 @@ public class ContactFragment extends BaseMvvmFragment>() { @Override public void onChanged(List contacts) { -// List sim = getSIMContacts(); - mViewDataBinding.tvPeople.setText(contacts.size() + "人"); -// if (sim.size() != 0) { -// contacts.addAll(sim); -// } + if (contacts != null) { + mViewDataBinding.tvPeople.setText(contacts.size() + "人"); + } mContactAdapter.setContactList(contacts); } }); @@ -123,63 +115,19 @@ public class ContactFragment extends BaseMvvmFragment getSIMContacts() { - getAll(); - List contactList = new ArrayList<>(); - ContentResolver resolver = mContext.getContentResolver(); - // 获取Sims卡联系人 - Uri uri = Uri.parse("content://icc/adn"); - Cursor phoneCursor = resolver.query(uri, null, null, null, null); - if (phoneCursor != null) { - int colName = phoneCursor.getColumnIndex(NAME); - int colNumber = phoneCursor.getColumnIndex(NUMBER); - while (phoneCursor.moveToNext()) { - String number = phoneCursor.getString(colNumber); - // 当手机号码为空的或者为空字段 跳过当前循环 - String username = phoneCursor.getString(colName); - long id = phoneCursor.getLong(phoneCursor.getColumnIndex("_id")); - Log.e(TAG, "getSIMContacts: number = " + number + " username = " + username + " _id = " + id); - Contact contact = new Contact(username, number, true); - contact.setId(id); - contactList.add(contact); - } - phoneCursor.close(); - } - return contactList; - } - - private void getAll() { - ContentResolver resolver = mContext.getContentResolver(); - Cursor adnCursor = resolver.query(Uri.parse("content://icc/adn/subId/0"), null, null, null, null); - for (String columnName : adnCursor.getColumnNames()) { - Log.d("CursorFields: adnCursor ", columnName); - } - Cursor rawContactsCursor = resolver.query(Uri.parse("content://com.android.contacts/raw_contacts"), null, null, null, null); - for (String columnName : rawContactsCursor.getColumnNames()) { - Log.d("CursorFields: rawContactsCursor ", columnName); - } - Cursor dataCursor = resolver.query(Uri.parse("content://com.android.contacts/data"), null, null, null, null); - for (String columnName : dataCursor.getColumnNames()) { - Log.d("CursorFields: dataCursor ", columnName); - } } private EditContactDialog mEditContactDialog; diff --git a/app/src/main/java/com/xxpatx/os/fragment/phone/contact/ContactViewModel.java b/app/src/main/java/com/xxpatx/os/fragment/phone/contact/ContactViewModel.java index 24fd77a..f3391ec 100644 --- a/app/src/main/java/com/xxpatx/os/fragment/phone/contact/ContactViewModel.java +++ b/app/src/main/java/com/xxpatx/os/fragment/phone/contact/ContactViewModel.java @@ -9,13 +9,10 @@ import android.net.Uri; import android.provider.ContactsContract; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; -import android.text.TextUtils; import android.util.Log; import androidx.lifecycle.MutableLiveData; -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; import com.tencent.mmkv.MMKV; import com.trello.rxlifecycle4.RxLifecycle; import com.trello.rxlifecycle4.android.FragmentEvent; @@ -24,12 +21,10 @@ import com.xxpatx.os.bean.BaseResponse; import com.xxpatx.os.bean.Contact; import com.xxpatx.os.config.CommonConfig; import com.xxpatx.os.databinding.FragmentContactBinding; -import com.xxpatx.os.gson.GsonUtils; import com.xxpatx.os.network.NetInterfaceManager; import com.xxpatx.os.network.UrlAddress; import com.xxpatx.os.utils.ContactsUtils; -import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -56,66 +51,29 @@ public class ContactViewModel extends BaseViewModel> mContactListData = new MutableLiveData<>(); - public void getCacheContact() { - String jsonString = mMMKV.getString(UrlAddress.GET_MAIL_LIST, null); - Gson gson = new Gson(); - Type type = new TypeToken>() { - }.getType(); - if (!TextUtils.isEmpty(jsonString)) { - List contacts = gson.fromJson(jsonString, type); - if (contacts != null) { - mContactListData.setValue(contacts); - } - } - getContact(); - } - public void getContact() { + NetInterfaceManager.getInstance().getContactListObserverCache(UrlAddress.GET_MAIL_LIST, new NetInterfaceManager.ContactCallback() { + @Override + public void setContact(List contactList) { + mContactListData.setValue(contactList); + } + + @Override + public void onComplete() { + + } + }); + NetInterfaceManager.getInstance() - .getContactListObservable() - .compose(RxLifecycle.bindUntilEvent(getLifecycle(), FragmentEvent.DESTROY)) - .subscribe(new Observer>>() { + .getContactListFragment(getLifecycle(), new NetInterfaceManager.ContactCallback() { @Override - public void onSubscribe(@NonNull Disposable d) { - Log.e("getContactList", "onSubscribe: "); - } - - @Override - public void onNext(@NonNull BaseResponse> listBaseResponse) { - Log.e("getContactList", "onNext: " + listBaseResponse); - if (listBaseResponse.code == 200) { - List contactList = listBaseResponse.data; - String oldCache = mMMKV.getString(UrlAddress.GET_MAIL_LIST, ""); - if (!oldCache.equals(GsonUtils.toJSONString(contactList))) { - ContactsUtils.saveContactPhone(getCtx(), contactList); - } - mContactListData.setValue(contactList); - mMMKV.putString(UrlAddress.GET_MAIL_LIST, GsonUtils.toJSONString(contactList)); - } else { - mMMKV.putString(UrlAddress.GET_MAIL_LIST, ""); - mContactListData.setValue(new ArrayList<>()); - } - } - - @Override - public void onError(@NonNull Throwable e) { - Log.e("getContactList", "onError: " + e.getMessage()); - String jsonString = mMMKV.getString(UrlAddress.GET_MAIL_LIST, null); - Gson gson = new Gson(); - Type type = new TypeToken>() { - }.getType(); - List contacts = gson.fromJson(jsonString, type); - if (contacts == null) { - mContactListData.setValue(new ArrayList<>()); - } else { - mContactListData.setValue(contacts); - } - onComplete(); + public void setContact(List contactList) { + mContactListData.setValue(contactList); } @Override public void onComplete() { - Log.e("getContactList", "onComplete: "); + } }); } @@ -135,6 +93,9 @@ public class ContactViewModel extends BaseViewModel soundMap = new HashMap<>(); public DialerFragment() { @@ -67,23 +67,23 @@ public class DialerFragment extends BaseMvvmFragment contactList); - - void setEmergencyContact(List emergencyContact); - - void setEmpty(); - - void onComplete(); - } - // public void getSystemSettings(boolean refresh, BehaviorSubject lifecycle, ContactCallback callback) { // ConnectMode connectMode = ConnectMode.ONE_MINUTE; // if (refresh) { @@ -1176,7 +1170,7 @@ public class NetInterfaceManager { String s = systemSettings.getSetting_sos(); } else { mCacheHelper.put(UrlAddress.GET_SETTINGS, ""); - if (callback != null) callback.setEmpty(); + if (callback != null) callback.setContact(null); } } @@ -1186,14 +1180,14 @@ public class NetInterfaceManager { String jsonString = mCacheHelper.getAsString(UrlAddress.GET_SETTINGS); //为 "" 是已经请求成功的 if (jsonString == null) { - if (callback != null) callback.setEmpty(); + if (callback != null) callback.setContact(null); } else { Gson gson = new Gson(); Type type = new TypeToken>() { }.getType(); List setting_sos = gson.fromJson(jsonString, type); if (setting_sos == null || setting_sos.size() == 0) { - if (callback != null) callback.setEmpty(); + if (callback != null) callback.setContact(null); } else { if (callback != null) callback.setContact(setting_sos); } @@ -1210,32 +1204,10 @@ public class NetInterfaceManager { }; } + public interface ContactCallback { + void setContact(List contactList); - public void getContactList(boolean refresh, BehaviorSubject lifecycle, ContactCallback callback) { - ConnectMode connectMode = ConnectMode.ONE_MINUTE; - if (refresh) { - connectMode = ConnectMode.DEFAULT; - } - if (ConnectManager.getInstance().isNeedConnect(UrlAddress.GET_MAIL_LIST, connectMode)) { - getContactList(lifecycle, callback); - } else { - String jsonString = mCacheHelper.getAsString(UrlAddress.GET_MAIL_LIST); - //为 "" 是已经请求成功的 - if (jsonString == null) { - getContactList(lifecycle, callback); - } else { - Gson gson = new Gson(); - Type type = new TypeToken>() { - }.getType(); - List setting_sos = gson.fromJson(jsonString, type); - if (setting_sos == null || setting_sos.size() == 0) { - if (callback != null) callback.setEmpty(); - } else { - if (callback != null) callback.setContact(setting_sos); - } - if (callback != null) callback.onComplete(); - } - } + void onComplete(); } public void getContactList(BehaviorSubject lifecycle, ContactCallback callback) { @@ -1244,16 +1216,12 @@ public class NetInterfaceManager { .subscribe(getContactListObserver(callback)); } - public void getContactList(ContactCallback callback) { + public void getContactListFragment(BehaviorSubject lifecycle, ContactCallback callback) { getContactListObservable() + .compose(RxLifecycle.bindUntilEvent(lifecycle, FragmentEvent.DESTROY)) .subscribe(getContactListObserver(callback)); } - public void getContactList() { - getContactListObservable() - .subscribe(getContactListObserver(null)); - } - public Observer>> getContactListObserver(ContactCallback callback) { return new Observer>>() { @Override @@ -1267,25 +1235,27 @@ public class NetInterfaceManager { if (listBaseResponse.code == 200) { List contactList = listBaseResponse.data; if (contactList == null || contactList.size() == 0) { - mCacheHelper.put(UrlAddress.GET_MAIL_LIST, ""); - if (callback != null) callback.setEmpty(); + mMMKV.remove(UrlAddress.GET_MAIL_LIST); + if (callback != null) callback.setContact(new ArrayList<>()); } else { - mCacheHelper.put(UrlAddress.GET_MAIL_LIST, GsonUtils.toJSONString(contactList)); - List emergencyContact = contactList.stream().filter(contact -> contact.getIs_urgent() == 1).collect(Collectors.toList()); + mMMKV.putString(UrlAddress.GET_MAIL_LIST, GsonUtils.toJSONString(contactList)); + ContactsUtils.saveContactPhone(mContext, contactList); + List emergencyConcacts = contactList.stream().filter(contact -> contact.getIs_urgent() == 1).collect(Collectors.toList()); + mMMKV.putString(CommonConfig.EMERGENCY_CONTACT_LIST_KEY, GsonUtils.toJSONString(emergencyConcacts)); if (callback != null) { callback.setContact(contactList); - callback.setEmergencyContact(emergencyContact); } } } else { - mCacheHelper.put(UrlAddress.GET_MAIL_LIST, ""); - if (callback != null) callback.setEmpty(); + mMMKV.remove(UrlAddress.GET_MAIL_LIST); + if (callback != null) callback.setContact(new ArrayList<>()); } } @Override public void onError(@NonNull Throwable e) { Log.e("getContactList", "onError: " + e.getMessage()); + getContactListObserverCache(UrlAddress.GET_MAIL_LIST, callback); onComplete(); } @@ -1298,6 +1268,25 @@ public class NetInterfaceManager { }; } + public void getContactListObserverCache(String tag, ContactCallback callback) { + String jsonString = mMMKV.getString(tag, null); + Gson gson = new Gson(); + Type type = new TypeToken>() { + }.getType(); + try { + List contacts = gson.fromJson(jsonString, type); + if (contacts != null) { + if (callback != null) callback.setContact(contacts); + } else { + if (callback != null) callback.setContact(new ArrayList<>()); + } + } catch (Exception e) { + Log.e(TAG, "getContactListObserverCache: " + e.getMessage()); + if (callback != null) callback.setContact(new ArrayList<>()); + } + } + + @Deprecated public void getAdminSnSetting(boolean refresh, BehaviorSubject lifecycle, onCompleteCallback callback) { ConnectMode connectMode = ConnectMode.ONE_MINUTE; if (refresh) { diff --git a/app/src/main/java/com/xxpatx/os/network/UrlAddress.java b/app/src/main/java/com/xxpatx/os/network/UrlAddress.java index 4dc4fca..5d7cb4a 100644 --- a/app/src/main/java/com/xxpatx/os/network/UrlAddress.java +++ b/app/src/main/java/com/xxpatx/os/network/UrlAddress.java @@ -58,6 +58,7 @@ public class UrlAddress { public static final String GET_ADMIN_SN_SETTING = "getAdminSnSetting"; /*更新app隐藏或者显示状态*/ public static final String APP_ICON_UPDATE = "Control/appIconUpdate"; + /*获取联系人*/ public static final String GET_MAIL_LIST = "Control/getMailList"; /*添加联系人*/ diff --git a/app/src/main/java/com/xxpatx/os/network/api/uiui/GetMailList.java b/app/src/main/java/com/xxpatx/os/network/api/uiui/contact/GetMailList.java similarity index 89% rename from app/src/main/java/com/xxpatx/os/network/api/uiui/GetMailList.java rename to app/src/main/java/com/xxpatx/os/network/api/uiui/contact/GetMailList.java index cb32918..03faa36 100644 --- a/app/src/main/java/com/xxpatx/os/network/api/uiui/GetMailList.java +++ b/app/src/main/java/com/xxpatx/os/network/api/uiui/contact/GetMailList.java @@ -1,4 +1,4 @@ -package com.xxpatx.os.network.api.uiui; +package com.xxpatx.os.network.api.uiui.contact; import com.xxpatx.os.bean.BaseResponse; import com.xxpatx.os.bean.Contact; diff --git a/app/src/main/java/com/xxpatx/os/receiver/InstallResultReceiver.java b/app/src/main/java/com/xxpatx/os/receiver/InstallResultReceiver.java index fff320c..2a1d9e0 100644 --- a/app/src/main/java/com/xxpatx/os/receiver/InstallResultReceiver.java +++ b/app/src/main/java/com/xxpatx/os/receiver/InstallResultReceiver.java @@ -39,11 +39,11 @@ public class InstallResultReceiver extends BroadcastReceiver { // while (iterator.hasNext()) { // Log.d("KEY", iterator.next()); // } - String STATUS = intent.getStringExtra(PackageInstaller.EXTRA_STATUS); +// String STATUS = intent.getStringExtra(PackageInstaller.EXTRA_STATUS); String PACKAGE_NAME = intent.getStringExtra(PackageInstaller.EXTRA_PACKAGE_NAME); String SESSION_ID = intent.getStringExtra(PackageInstaller.EXTRA_SESSION_ID); String STATUS_MESSAGE = intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE); - String LEGACY_STATUS = intent.getStringExtra("android.content.pm.extra.LEGACY_STATUS"); +// String LEGACY_STATUS = intent.getStringExtra("android.content.pm.extra.LEGACY_STATUS"); // Log.e("fht", STATUS); // Log.e("fht", PACKAGE_NAME); // Log.e("fht", SESSION_ID); diff --git a/app/src/main/java/com/xxpatx/os/service/WeAccessibilityService.java b/app/src/main/java/com/xxpatx/os/service/WeAccessibilityService.java index 82873ec..b423bc5 100644 --- a/app/src/main/java/com/xxpatx/os/service/WeAccessibilityService.java +++ b/app/src/main/java/com/xxpatx/os/service/WeAccessibilityService.java @@ -17,14 +17,20 @@ import android.util.Log; import android.view.WindowManager; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; +import android.view.accessibility.AccessibilityWindowInfo; import android.widget.Toast; +import com.hjq.toast.Toaster; import com.tencent.mmkv.MMKV; import com.xxpatx.os.bean.Contact; import com.xxpatx.os.config.CommonConfig; +import com.xxpatx.os.utils.ForegroundAppUtil; + +import java.util.List; /** * 通过微信标签最高支持8.0.49,8.0.50 获取不到数据 + * 通过 {@link android.accessibilityservice.AccessibilityService#getWindows}和修改accessibility-service 配置能遍历屏幕元素 */ public class WeAccessibilityService extends AccessibilityService { private static final String TAG = "WeAccessibilityService"; @@ -132,10 +138,30 @@ public class WeAccessibilityService extends AccessibilityService { Log.e(TAG, "_onAccessibilityEvent: " + mCurrentStep); switch (mCurrentStep) { case WAITING: - if (!mAutoAccept) return; + break; + default: + if (!TextUtils.isEmpty(event.getClassName())) { + if ("com.tencent.mm.ui.LauncherUI".contentEquals(event.getClassName())) { + if (mCurrentStep != Step.FIND_CONTACT) { + mCurrentStep = Step.CLICK_CONTACT; + } + } else if ("com.tencent.mm.plugin.label.ui.ContactLabelManagerUI".contentEquals(event.getClassName())) { + + } + } + } + switch (mCurrentStep) { + case WAITING: + mAutoAccept = mMMKV.decodeBool(CommonConfig.WECHAT_CALL_AUTO_ACCEPT, false); + Log.e(TAG, "_onAccessibilityEvent: mAutoAccept = " + mAutoAccept); + if (!mAutoAccept) { + return; + } if (stepAnswer(Property.DESCRIPTION, RECEIVE_DESCRIPTION)) { mCurrentStep = Step.WAITING; Toast.makeText(this, "已自动接听视频/语音", Toast.LENGTH_LONG).show(); + } else { +// clickAnswer(); } break; case CLICK_HOME://主页能找到直接点击进去更多 @@ -149,10 +175,15 @@ public class WeAccessibilityService extends AccessibilityService { break; case CLICK_CONTACT://进入通讯录界面 - step(Property.TEXT, CONTACT_TEXT, Step.FIND_TAG); + if (stepHome(Property.TEXT, CONTACT_TEXT, Step.FIND_TAG)) { + Log.e(TAG, "_onAccessibilityEvent: enter contact"); + } else { + touchContact(); + } break; case FIND_CONTACT://模拟滑动找到联系人 findContact(Property.TEXT, mName, Step.CLICK_NAME); + break; case FIND_TAG: step(Property.TEXT, TAG_TEXT, Step.CLICK_TAG); break; @@ -210,9 +241,32 @@ public class WeAccessibilityService extends AccessibilityService { } } + @Deprecated + private void clickAnswer() { + String className = ForegroundAppUtil.getForegroundActivityName(WeAccessibilityService.this); + Log.e(TAG, "clickAnswer: " + className); + if (!TextUtils.isEmpty(className)) { + if ("com.tencent.mm.plugin.voip.ui.VideoActivity".contentEquals(className)) { + boolean successful = clickByPoint(595, 1376); + Log.e(TAG, "clickAnswer: " + successful); + if (successful) { + Toast.makeText(this, "已自动接听视频/语音", Toast.LENGTH_LONG).show(); + } + } else { + Log.e(TAG, "clickAnswer: Not in the answering interface"); + } + } + } + private boolean step(Property type, String text, Step nextStep) { AccessibilityNodeInfo node = findNode(getRootInActiveWindow(), type, text); if (node != null) { + Rect rect = new Rect(); + node.getBoundsInScreen(rect); + Log.e(TAG, "step: rect = " + rect); + if (rect.left < 0 || rect.top < 0 || rect.right < 0 || rect.bottom < 0) { + return false; + } clickNode(node); Log.e(TAG, "step: mCurrentStep: " + mCurrentStep + " done"); mCurrentStep = nextStep; @@ -223,6 +277,61 @@ public class WeAccessibilityService extends AccessibilityService { } } + // TODO: 2025/2/8 先把通讯录点击的换成node + private boolean stepHome(Property type, String text, Step nextStep) { + AccessibilityNodeInfo node = findNode(getWindows(), type, text); + if (node != null) { + Rect rect = new Rect(); + node.getBoundsInScreen(rect); + Log.e(TAG, "step: rect = " + rect); + if (rect.left < 0 || rect.top < 0 || rect.right < 0 || rect.bottom < 0) { + return false; + } + clickNode(node); + Log.e(TAG, "step: mCurrentStep: " + mCurrentStep + " done"); + mCurrentStep = nextStep; + Log.e(TAG, "step: next: " + mCurrentStep); + return true; + } else { + return false; + } + } + + @Deprecated + private void touchContact() { + boolean successful = clickByPoint(268, 1440); + if (successful) { + mCurrentStep = Step.FIND_TAG; + } else { + mCurrentStep = Step.WAITING; + Toaster.show("点击失败,请重试"); + } + } + + private List findNodesByViewId(String id) { + List accessibilityNodeInfos = getRootInActiveWindow().findAccessibilityNodeInfosByViewId(id); + return accessibilityNodeInfos; + } + + private AccessibilityNodeInfo findNodeByText(AccessibilityNodeInfo root, String text) { + if (root == null) return null; + Log.e(TAG, "findNodeByText: getText = " + root.getText()); + Log.e(TAG, "findNodeByText: getContentDescription = " + root.getContentDescription()); + boolean found = root.getText() != null && text.contentEquals(root.getText()); + if (found) { + return root; + } else { + for (int i = 0; i < root.getChildCount(); i++) { + AccessibilityNodeInfo result = findNodeByText(root.getChild(i), text); + if (result != null) { + return result; + } + } + } + root.recycle(); + return null; + } + private boolean stepCallDialog(Property type, String text, Step nextStep) { AccessibilityNodeInfo node = findNode(getRootInActiveWindow(), type, text); if (node != null) { @@ -234,12 +343,23 @@ public class WeAccessibilityService extends AccessibilityService { Log.e(TAG, "stepCallDialog: next: " + mCurrentStep); return true; } else { - scrolDown(); + scrollDown(); return false; } } else { - scrolDown(); - return false; + if (mFindCount == mMaxCount) { + Log.e("stepCallDialog", "mCurrentStep: max"); + Toast.makeText(this, "没有找到联系人", Toast.LENGTH_LONG).show(); + mCurrentStep = Step.WAITING; + mFindCount = 0; + return false; + } else { + Log.e("stepCallDialog", "mCurrentStep: not found"); + mFindCount++; + Log.e("stepCallDialog", "mCurrentStep: mFindCount = " + mFindCount); + scrollDown(); + return false; + } } } @@ -281,7 +401,7 @@ public class WeAccessibilityService extends AccessibilityService { Log.e("findContact", "mCurrentStep: not found"); mFindCount++; Log.e("findContact", "mCurrentStep: mFindCount = " + mFindCount); - scrolDown(); + scrollDown(); return false; } } @@ -321,35 +441,52 @@ public class WeAccessibilityService extends AccessibilityService { return null; } + private AccessibilityNodeInfo findNode(List windows, Property type, String text) { + for (AccessibilityWindowInfo accessibilityWindowInfo : windows) { + AccessibilityNodeInfo nodeInfo = findNode(accessibilityWindowInfo.getRoot(), type, text); + if (nodeInfo != null) { + return nodeInfo; + } + } + Log.e(TAG, "findNode windows: not found"); + return null; + } + + private void clickNode(AccessibilityNodeInfo node) { try { Log.e(TAG, "clickNode: getText = " + node.getText()); + Log.e(TAG, "clickNode: isClickable = " + node.isClickable()); } catch (Exception e) { Log.e(TAG, "clickNode: e = " + e.getMessage()); } - Log.e(TAG, "clickNode: isClickable = " + node.isClickable()); if (node.isClickable()) { boolean performAction = node.performAction(AccessibilityNodeInfo.ACTION_CLICK); Log.e(TAG, "clickNode: performAction = " + performAction); if (!performAction) { Rect rect = new Rect(); node.getBoundsInScreen(rect); - int x = rect.left; - int y = rect.top; - Log.e(TAG, "clickNode: x = " + x); - Log.e(TAG, "clickNode: y = " + y); - int width = rect.width(); - int height = rect.height(); - Log.e(TAG, "clickNode: width = " + width); - Log.e(TAG, "clickNode: height = " + height); - Log.e(TAG, "clickNode: clickByNode = " + clickByNode(x + width / 2, y + height / 2)); + Log.e(TAG, "clickNode: rect = " + rect); + // 点击节点的中心位置 + int centerX = (rect.left + rect.right) / 2; + int centerY = (rect.top + rect.bottom) / 2; + Log.e(TAG, "clickNode: clickByNode = " + clickByPoint(centerX, centerY)); } node.recycle(); } else { - AccessibilityNodeInfo parent = node.getParent(); - node.recycle(); - clickNode(parent); + Rect rect = new Rect(); + node.getBoundsInScreen(rect); + Log.e(TAG, "clickNode: rect = " + rect); + // 点击节点的中心位置 + int centerX = (rect.left + rect.right) / 2; + int centerY = (rect.top + rect.bottom) / 2; + Log.e(TAG, "clickNode: clickByNode = " + clickByPoint(centerX, centerY)); } +// else { +// AccessibilityNodeInfo parent = node.getParent(); +// node.recycle(); +// clickNode(parent); +// } } private boolean stepCall(Property type, String text) { @@ -357,7 +494,7 @@ public class WeAccessibilityService extends AccessibilityService { if (node != null) { Point point = getPointtByNode(node); Log.e(TAG, "stepCall: " + point); - clickByNode(point.x, point.y + 30); + clickByPoint(point.x, point.y + 30); // clickNode(node); Log.e(TAG, "stepCall: mCurrentStep " + mCurrentStep + " done"); mCurrentStep = Step.CLICK_CALL; @@ -370,12 +507,12 @@ public class WeAccessibilityService extends AccessibilityService { } private boolean stepAnswer(Property type, String text) { - AccessibilityNodeInfo node = findNode(getRootInActiveWindow(), type, text); + AccessibilityNodeInfo node = findNode(getWindows(), type, text); if (node != null) { Point point = getPointtByNode(node); Log.e(TAG, "stepAnswer: " + point); - clickByNode(point.x, point.y - 50); - clickByNode(point.x, point.y); + clickByPoint(point.x, point.y - 50); + clickByPoint(point.x, point.y); // clickNode(node); Log.e(TAG, "stepAnswer: mCurrentStep " + mCurrentStep + " done"); mCurrentStep = Step.WAITING; @@ -399,14 +536,16 @@ public class WeAccessibilityService extends AccessibilityService { } //实现对(x,y)坐标进行点击操作。 - private boolean clickByNode(int x, int y) { + private boolean clickByPoint(int x, int y) { + Log.e(TAG, "clickByNode: x = " + x); + Log.e(TAG, "clickByNode: y = " + y); Point point = new Point(x, y); Path path = new Path(); path.moveTo(point.x, point.y); GestureDescription.Builder builder = new GestureDescription.Builder(); builder.addStroke(new GestureDescription.StrokeDescription(path, 0, 200)); GestureDescription gesture = builder.build(); - boolean isDispatched = dispatchGesture(gesture, new GestureResultCallback() { + boolean dispatched = dispatchGesture(gesture, new GestureResultCallback() { @Override public void onCompleted(GestureDescription gestureDescription) { super.onCompleted(gestureDescription); @@ -419,10 +558,10 @@ public class WeAccessibilityService extends AccessibilityService { Log.e("clickByNode", "onCompleted: "); } }, null); - return isDispatched; + return dispatched; } - private boolean scrolDown() { + private boolean scrollScreen(double startY, double endY) { WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE); DisplayMetrics dm = new DisplayMetrics(); wm.getDefaultDisplay().getRealMetrics(dm); @@ -433,34 +572,40 @@ public class WeAccessibilityService extends AccessibilityService { // 屏幕宽度算法:屏幕宽度(像素)/屏幕密度 // int screenWidth = (int) (width / density); // 屏幕宽度(dp) // int screenHeight = (int) (height / density);// 屏幕高度(dp) - Log.e(TAG, "scrolDown: screenWidth = " + width); - Log.e(TAG, "scrolDown: screenHeight = " + height); + Log.e(TAG, "scrollScreen: screenWidth = " + width); + Log.e(TAG, "scrollScreen: screenHeight = " + height); int center_X = width / 2; int center_Y = height / 2; - Log.e("scrolDown", "center position:" + "(" + center_X + "," + center_Y + ")"); + Log.e("scrollScreen", "center position:" + "(" + center_X + "," + center_Y + ")"); Path path = new Path(); - path.moveTo(center_X, (int) (center_Y * 1.5)); //起点坐标。 - path.lineTo(center_X, (int) (center_Y * 0.5)); //终点坐标。 + path.moveTo(center_X, (int) (center_Y * startY)); //起点坐标。 + path.lineTo(center_X, (int) (center_Y * endY)); //终点坐标。 GestureDescription.Builder builder = new GestureDescription.Builder(); GestureDescription gestureDescription = builder.addStroke(new GestureDescription.StrokeDescription(path, 0, 200)).build(); - boolean isDispatched = dispatchGesture(gestureDescription, new GestureResultCallback() { + boolean dispatched = dispatchGesture(gestureDescription, new GestureResultCallback() { @Override public void onCompleted(GestureDescription gestureDescription) { super.onCompleted(gestureDescription); - Log.d("scrolDown", "dispatchGesture ScrollUp onCompleted."); + Log.d("scrollScreen", "dispatchGesture ScrollUp onCompleted."); path.close(); } @Override public void onCancelled(GestureDescription gestureDescription) { super.onCancelled(gestureDescription); - Log.d("scrolDown", "dispatchGesture ScrollUp cancel."); + Log.d("scrollScreen", "dispatchGesture ScrollUp cancel."); } }, null); - - return isDispatched; + return dispatched; } + private boolean scrollDown() { + return scrollScreen(1.5, 0.5); + } + + private boolean scrollUp() { + return scrollScreen(0.5, 1.5); + } private enum Step { WAITING, diff --git a/app/src/main/java/com/xxpatx/os/service/main/MainService.java b/app/src/main/java/com/xxpatx/os/service/main/MainService.java index 726106b..2637069 100644 --- a/app/src/main/java/com/xxpatx/os/service/main/MainService.java +++ b/app/src/main/java/com/xxpatx/os/service/main/MainService.java @@ -28,6 +28,8 @@ import com.google.gson.reflect.TypeToken; import com.hjq.toast.Toaster; import com.shehuan.niv.NiceImageView; import com.tencent.mmkv.MMKV; +import com.trello.rxlifecycle4.RxLifecycle; +import com.trello.rxlifecycle4.android.ActivityEvent; import com.xxpatx.os.BuildConfig; import com.xxpatx.os.R; import com.xxpatx.os.activity.main.MainActivity; @@ -55,8 +57,10 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.concurrent.TimeUnit; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.annotations.NonNull; import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.core.ObservableEmitter; import io.reactivex.rxjava3.core.ObservableOnSubscribe; @@ -222,6 +226,38 @@ public class MainService extends BaseRxService implements MainSContact.MainSView registerOperateAlarmClockReceiver(); registerScreenLockReceiver(); registerSmsReceiver(); + + Observable.create(new ObservableOnSubscribe() { + @Override + public void subscribe(@NonNull ObservableEmitter emitter) throws Throwable { + mTimeSignalCallback = emitter::onNext; + } + }).throttleFirst(1, TimeUnit.MINUTES) + .compose(RxLifecycle.bindUntilEvent(lifecycleSubject, ActivityEvent.DESTROY)) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("mTimeSignalCallback", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull Integer hour) { + Log.e("mTimeSignalCallback", "onNext: "); + mSoundPool.play(soundMap.get(hour), 1, 1, 0, 0, 1); + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("mTimeSignalCallback", "onError: "); + } + + @Override + public void onComplete() { + Log.e("mTimeSignalCallback", "onComplete: "); + } + }); } @Override @@ -281,6 +317,11 @@ public class MainService extends BaseRxService implements MainSContact.MainSView if (mSmsReceiver != null) { unregisterReceiver(mSmsReceiver); } + + if (mSoundPool != null) { + mSoundPool.release(); + mSoundPool = null; + } } public boolean isScreenOn() { @@ -387,6 +428,12 @@ public class MainService extends BaseRxService implements MainSContact.MainSView } } + private interface TimeSignalCallback { + void timeTick(int hour); + } + + private TimeSignalCallback mTimeSignalCallback; + private void hourlyTimeSignal() { boolean hourly_time = mMMKV.decodeBool(CommonConfig.HOURLY_TIME_SIGNAL_KEY, false); if (hourly_time) { @@ -396,10 +443,10 @@ public class MainService extends BaseRxService implements MainSContact.MainSView int min = cal.get(Calendar.MINUTE); Log.e(TAG, "hourlyTimeSignal: min = " + min); if (min == 0) { - mSoundPool.play(soundMap.get(hour), 1, 1, 0, 0, 1); + mTimeSignalCallback.timeTick(hour); } } else { - Log.e(TAG, "hourlyTimeSignal: not enable hourly time signal"); + Log.e(TAG, "hourlyTimeSignal: disable hourly time signal"); } } @@ -409,12 +456,15 @@ public class MainService extends BaseRxService implements MainSContact.MainSView } IntentFilter filter = new IntentFilter(); filter.addAction(HOURLY_TIME_SIGNAL_KEY); + filter.addAction(WECHAT_AUTO_ACCEPT); registerReceiver(mTimeSignalReceiver, filter); } private TimeSignalReceiver mTimeSignalReceiver; private static final String HOURLY_TIME_SIGNAL_KEY = "hourly_time_signal"; + private static final String WECHAT_AUTO_ACCEPT = "wechat_auto_accept"; + private class TimeSignalReceiver extends BroadcastReceiver { @@ -422,12 +472,23 @@ public class MainService extends BaseRxService implements MainSContact.MainSView public void onReceive(Context context, Intent intent) { String action = intent.getAction(); Log.e("TimeSignalReceiver", "onReceive: " + action); - if (HOURLY_TIME_SIGNAL_KEY.equals(action)) { - int hour_notify = intent.getIntExtra("hour_notify", 0); - Log.e("TimeSignalReceiver", "onReceive: hour_notify = " + hour_notify); - mMMKV.encode(CommonConfig.HOURLY_TIME_SIGNAL_KEY, hour_notify == 1); - + if (TextUtils.isEmpty(action)) { + return; } + switch (action) { + case HOURLY_TIME_SIGNAL_KEY: + int hour_notify = intent.getIntExtra("hour_notify", 0); + Log.e("TimeSignalReceiver", "onReceive: hour_notify = " + hour_notify); + mMMKV.encode(CommonConfig.HOURLY_TIME_SIGNAL_KEY, hour_notify == 1); + break; + case WECHAT_AUTO_ACCEPT: + int wechat_auto_accept = intent.getIntExtra("wechat_auto_accept", 0); + Log.e("TimeSignalReceiver", "onReceive: wechat_auto_accept = " + wechat_auto_accept); + mMMKV.encode(CommonConfig.WECHAT_CALL_AUTO_ACCEPT, wechat_auto_accept == 1); + break; + default: + } + } } @@ -695,7 +756,7 @@ public class MainService extends BaseRxService implements MainSContact.MainSView @SuppressWarnings("WrongConstant") public void showPopupWindow() { if (!mFloatWindowEnable) { - Log.e(TAG, "showPopupWindow: not enable"); + Log.e(TAG, "showPopupWindow: disable"); return; } if (isBallShown) { @@ -756,7 +817,8 @@ public class MainService extends BaseRxService implements MainSContact.MainSView } killBackgroundProcesses(pkg); } - Toaster.show(String.format(getString(R.string.clear_app_size), pkgList.size())); +// Toaster.show(String.format(getString(R.string.clear_app_size), pkgList.size())); + Toaster.show("后台进程已清理"); } private void killBackgroundProcesses(String packageName) { diff --git a/app/src/main/java/com/xxpatx/os/utils/ApkUtils.java b/app/src/main/java/com/xxpatx/os/utils/ApkUtils.java index 3875d2e..c39f12b 100644 --- a/app/src/main/java/com/xxpatx/os/utils/ApkUtils.java +++ b/app/src/main/java/com/xxpatx/os/utils/ApkUtils.java @@ -81,7 +81,7 @@ public class ApkUtils { this.add("com.uiui.aios"); this.add("com.uiui.videoplayer"); // this.add("com.uiui.health"); - this.add("com.tencent.android.qqdownloader"); +// this.add("com.tencent.android.qqdownloader"); // this.add("com.xxpatx.store"); this.add("com.joytv.live"); this.add("com.xxpatx.store"); diff --git a/app/src/main/java/com/xxpatx/os/utils/ContactsUtils.java b/app/src/main/java/com/xxpatx/os/utils/ContactsUtils.java index 2d56683..bd0315a 100644 --- a/app/src/main/java/com/xxpatx/os/utils/ContactsUtils.java +++ b/app/src/main/java/com/xxpatx/os/utils/ContactsUtils.java @@ -1,5 +1,7 @@ package com.xxpatx.os.utils; +import android.content.ContentProviderOperation; +import android.content.ContentProviderResult; import android.content.ContentResolver; import android.content.ContentUris; import android.content.ContentValues; @@ -12,11 +14,7 @@ import android.provider.ContactsContract; import android.text.TextUtils; import android.util.Log; -import androidx.annotation.Nullable; - import com.bumptech.glide.Glide; -import com.bumptech.glide.request.target.SimpleTarget; -import com.bumptech.glide.request.transition.Transition; import com.xxpatx.os.R; import com.xxpatx.os.bean.Contact; import com.xxpatx.os.bean.ContactId; @@ -29,7 +27,6 @@ import java.util.List; import java.util.function.Predicate; import java.util.stream.Collectors; -import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; import io.reactivex.rxjava3.annotations.NonNull; import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.core.ObservableEmitter; @@ -41,83 +38,31 @@ import io.reactivex.rxjava3.schedulers.Schedulers; public class ContactsUtils { private static final String TAG = "ContactsUtils"; - - public static void saveContactPhone(Context context, List contactList) { - Log.e(TAG, "saveContactPhone: "); -// List contactIdList = ContactsUtils.getLocalContacts(context); + public static void saveContactPhone(Context context, Contact contact) { Observable.create(new ObservableOnSubscribe() { @Override public void subscribe(@NonNull ObservableEmitter emitter) throws Throwable { - for (Contact contact : contactList) { - if (TextUtils.isEmpty(contact.getMobile())) { - continue; - } + long time = System.currentTimeMillis(); + Log.e(TAG, "saveContactPhone: " + contact.getMobile() + " isExist = " + ContactsUtils.isExist(context, contact.getMobile())); + if (TextUtils.isEmpty(contact.getAvatar())) { + Bitmap bitmap = Glide.with(context).asBitmap().load(R.drawable.default_avatar).override(200, 200).submit().get(); if (ContactsUtils.isExist(context, contact.getMobile())) { - long rawContactId = ContactsUtils.getContactId(context, contact.getMobile()); - Glide.with(context).asBitmap().load(contact.getAvatar()).override(200, 200).into(new SimpleTarget() { - @Override - public void onResourceReady(@androidx.annotation.NonNull Bitmap resource, @Nullable Transition transition) { - ContentResolver resolver = context.getContentResolver(); - ContentValues nameValues = new ContentValues(); - //add Name - nameValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId); - nameValues.put(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/name"); - nameValues.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, contact.getName()); - resolver.update(ContactsContract.Data.CONTENT_URI, nameValues, "raw_contact_id=?" + rawContactId, new String[]{ContactsContract.Data.CONTACT_ID}); - - ContentValues photoValues = new ContentValues(); - photoValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - resource.compress(Bitmap.CompressFormat.PNG, 100, out); - photoValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE); - photoValues.put(ContactsContract.CommonDataKinds.Photo.PHOTO, out.toByteArray()); - resolver.update(ContactsContract.Data.CONTENT_URI, photoValues, "raw_contact_id=?" + rawContactId, new String[]{ContactsContract.Data.CONTACT_ID}); - - ContentValues phoneValues = new ContentValues(); - phoneValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId); - phoneValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE); - phoneValues.put(ContactsContract.CommonDataKinds.Phone.NUMBER, contact.getMobile()); - phoneValues.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE); - resolver.update(ContactsContract.Data.CONTENT_URI, phoneValues, "raw_contact_id=?" + rawContactId, new String[]{ContactsContract.Data.CONTACT_ID}); - } - }); + updateContactPhone(context, contact, bitmap); } else { - ContentValues values = new ContentValues(); - long rawContactId = ContentUris.parseId(context.getContentResolver().insert(ContactsContract.RawContacts.CONTENT_URI, values)); - Glide.with(context).asBitmap().load(contact.getAvatar()).override(200, 200).into(new SimpleTarget() { - @Override - public void onResourceReady(@androidx.annotation.NonNull Bitmap resource, @Nullable Transition transition) { - ContentResolver resolver = context.getContentResolver(); - ContentValues nameValues = new ContentValues(); - //add Name - nameValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId); - nameValues.put(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/name"); - nameValues.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, contact.getName()); - resolver.insert(ContactsContract.Data.CONTENT_URI, nameValues); - - ContentValues photoValues = new ContentValues(); - photoValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - resource.compress(Bitmap.CompressFormat.PNG, 100, out); - photoValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE); - photoValues.put(ContactsContract.CommonDataKinds.Photo.PHOTO, out.toByteArray()); - resolver.insert(ContactsContract.Data.CONTENT_URI, photoValues); - - ContentValues phoneValues = new ContentValues(); - phoneValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId); - phoneValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE); - phoneValues.put(ContactsContract.CommonDataKinds.Phone.NUMBER, contact.getMobile()); - phoneValues.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE); - resolver.insert(ContactsContract.Data.CONTENT_URI, phoneValues); - } - }); + insertContactPhone(context, contact, bitmap); + } + } else { + Bitmap bitmap = Glide.with(context).asBitmap().load(contact.getAvatar()).override(200, 200).error(R.drawable.default_avatar).submit().get(); + if (ContactsUtils.isExist(context, contact.getMobile())) { + updateContactPhone(context, contact, bitmap); + } else { + insertContactPhone(context, contact, bitmap); } } - emitter.onNext(1L); + emitter.onNext(System.currentTimeMillis() - time); } - }) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) + }).subscribeOn(Schedulers.io()) + .observeOn(Schedulers.newThread()) .subscribe(new Observer() { @Override public void onSubscribe(@NonNull Disposable d) { @@ -141,6 +86,313 @@ public class ContactsUtils { }); } + public static void saveContactPhone(Context context, List contactList) { + Log.e(TAG, "saveContactPhone: "); +// List contactIdList = ContactsUtils.getLocalContacts(context); + Observable.create(new ObservableOnSubscribe() { + @Override + public void subscribe(@NonNull ObservableEmitter emitter) throws Throwable { + long time = System.currentTimeMillis(); + for (Contact contact : contactList) { + if (TextUtils.isEmpty(contact.getMobile())) { + continue; + } + Log.e(TAG, "saveContactPhone: " + contact.getMobile() + " isExist = " + ContactsUtils.isExist(context, contact.getMobile())); + if (TextUtils.isEmpty(contact.getAvatar())) { + Bitmap bitmap = Glide.with(context).asBitmap().load(R.drawable.default_avatar).override(200, 200).submit().get(); + if (ContactsUtils.isExist(context, contact.getMobile())) { + updateContactPhone(context, contact, bitmap); + } else { + insertContactPhone(context, contact, bitmap); + } + } else { + Bitmap bitmap = Glide.with(context).asBitmap().load(contact.getAvatar()).override(200, 200).error(R.drawable.default_avatar).submit().get(); + if (ContactsUtils.isExist(context, contact.getMobile())) { + updateContactPhone(context, contact, bitmap); + } else { + insertContactPhone(context, contact, bitmap); + } + } + + } + emitter.onNext(System.currentTimeMillis() - time); + } + }).subscribeOn(Schedulers.io()) + .observeOn(Schedulers.newThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("saveContactPhone", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull Long aLong) { + Log.e("saveContactPhone", "onNext: " + aLong); + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("saveContactPhone", "onError: " + e.getMessage()); + } + + @Override + public void onComplete() { + Log.e("saveContactPhone", "onComplete: "); + } + }); + } + + public static void insertContactPhone(Context context, Contact contact, Bitmap bitmap) { + ContentValues values = new ContentValues(); + long rawContactId = ContentUris.parseId(context.getContentResolver().insert(ContactsContract.RawContacts.CONTENT_URI, values)); + Log.e(TAG, "insertContactPhone: rawContactId = " + rawContactId); + ContentResolver resolver = context.getContentResolver(); + + values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId); + values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE); + values.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, contact.getName()); + resolver.insert(ContactsContract.Data.CONTENT_URI, values); + values.clear(); + + values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + bitmap.compress(Bitmap.CompressFormat.PNG, 100, out); + values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE); + values.put(ContactsContract.CommonDataKinds.Photo.PHOTO, out.toByteArray()); + resolver.insert(ContactsContract.Data.CONTENT_URI, values); + values.clear(); + + values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId); + values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE); + values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, contact.getMobile()); + values.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE); + resolver.insert(ContactsContract.Data.CONTENT_URI, values); + } + + public static void insertContactPhone(Context context, Contact contact) { + ContentValues values = new ContentValues(); + long rawContactId = ContentUris.parseId(context.getContentResolver().insert(ContactsContract.RawContacts.CONTENT_URI, values)); + Log.e(TAG, "insertContactPhone: rawContactId = " + rawContactId); + ContentResolver resolver = context.getContentResolver(); + + values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId); + values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE); + values.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, contact.getName()); + resolver.insert(ContactsContract.Data.CONTENT_URI, values); + values.clear(); + + values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId); + values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE); + values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, contact.getMobile()); + values.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE); + resolver.insert(ContactsContract.Data.CONTENT_URI, values); + } + + public static void updateContactPhone(Context context, Contact contact, Bitmap bitmap) { + long rawContactId = ContactsUtils.getRawContactId(context, contact.getMobile()); + Log.e(TAG, "updateContactPhone: rawContactId = " + rawContactId); + ContentResolver resolver = context.getContentResolver(); + + ContentValues values = new ContentValues(); + values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId); + values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE); + values.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, contact.getName()); + resolver.insert(ContactsContract.Data.CONTENT_URI, values); + + values.clear(); + + values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + bitmap.compress(Bitmap.CompressFormat.PNG, 100, out); + values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE); + values.put(ContactsContract.CommonDataKinds.Photo.PHOTO, out.toByteArray()); + resolver.insert(ContactsContract.Data.CONTENT_URI, values); + + values.clear(); + +// values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId); +// values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE); +// values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, contact.getMobile()); +// values.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE); +// resolver.insert(ContactsContract.Data.CONTENT_URI, values); + +// Log.e(TAG, "updateContactPhone: phoneValues = " + +// resolver.update(ContactsContract.Data.CONTENT_URI, values, ContactsContract.Data.RAW_CONTACT_ID + "='" + rawContactId+"'", null)); + +// String selection = ContactsContract.Data.CONTACT_ID + "=" + contacts.getContactId() + " AND " + Data.MIMETYPE + "='" + StructuredName.CONTENT_ITEM_TYPE + "'"; +// ContentValues values = new ContentValues(); +// values.put(StructuredName.DISPLAY_NAME, contacts.getName()); // make sure getName() returns a String!!! +// getContentResolver().update(Data.CONTENT_URI, values, selection, null); + +// ContentValues values = new ContentValues(); +// values.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, name); +// values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phone); +// Log.d("updateContact", "values已经产生"); +// int result = resolver.update(ContactsContract.Data.CONTENT_URI, values, ContactsContract.Data.RAW_CONTACT_ID + "=?", new String[]{String.valueOf(bean.getId())}); + } + + public static void updateContactPhone(Context context, Contact contact) { + long rawContactId = ContactsUtils.getRawContactId(context, contact.getMobile()); + Log.e(TAG, "updateContactPhone: rawContactId = " + rawContactId); + ContentResolver resolver = context.getContentResolver(); + + ContentValues values = new ContentValues(); + values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId); + values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE); + values.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, contact.getName()); + resolver.insert(ContactsContract.Data.CONTENT_URI, values); + } + + public static void update(Context context, Contact contact, Bitmap bitmap) { + long rawContactId = ContactsUtils.getRawContactId(context, contact.getMobile()); + + ArrayList ops = new ArrayList(); + ContentProviderOperation op1 = ContentProviderOperation + .newUpdate(ContactsContract.Data.CONTENT_URI) + .withSelection( + ContactsContract.Data.RAW_CONTACT_ID + "=? and " + + ContactsContract.Data.MIMETYPE + "=?", + new String[]{ + String.valueOf(rawContactId), + ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE}) + .withValue( + ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME,// 对应data表中的data1字段 + contact.getName()).build(); + ops.add(op1); + + ContentProviderOperation op2 = ContentProviderOperation + .newUpdate(ContactsContract.Data.CONTENT_URI) + .withSelection( + ContactsContract.Data.RAW_CONTACT_ID + "=? and " + + ContactsContract.Data.MIMETYPE + "=?", + new String[]{String.valueOf(rawContactId), + ContactsContract.CommonDataKinds.Phone.MIMETYPE}) + .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER,// 对应data表中的data1字段 + contact.getMobile()).build(); + ops.add(op2); + +// ContentProviderOperation op3 = ContentProviderOperation +// .newUpdate(ContactsContract.Data.CONTENT_URI) +// .withSelection( +// ContactsContract.Data.RAW_CONTACT_ID + "=? and " +// + ContactsContract.Data.MIMETYPE + "=?", +// new String[]{String.valueOf(rawContactId), +// ContactsContract.CommonDataKinds.Phone.MIMETYPE}) +// .withValue(ContactsContract.CommonDataKinds.Email.ADDRESS,// 对应data表中的data1字段 +// "test@email.com").build(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + bitmap.compress(Bitmap.CompressFormat.PNG, 100, out); + ContentProviderOperation op3 = ContentProviderOperation + .newUpdate(ContactsContract.Data.CONTENT_URI) + .withSelection( + ContactsContract.Data.RAW_CONTACT_ID + "=? and " + + ContactsContract.Data.MIMETYPE + "=?", + new String[]{String.valueOf(rawContactId), + ContactsContract.CommonDataKinds.Photo.MIMETYPE}) + .withValue(ContactsContract.CommonDataKinds.Photo.PHOTO,// 对应data表中的data1字段 + out.toByteArray()).build(); + ops.add(op3); + + try { + ContentProviderResult[] contentProviderResults = context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops); + Log.e(TAG, "update: " + Arrays.toString(contentProviderResults)); + } catch (Exception e) { + e.printStackTrace(); + Log.e(TAG, "update: " + e.getMessage()); + } + } + + public static void deleteContactPhone(Context context, Contact contact) { + Observable.create(new ObservableOnSubscribe() { + @Override + public void subscribe(@NonNull ObservableEmitter emitter) throws Throwable { + deleteRawContact(context, contact.getMobile()); + emitter.onNext(0L); + } + }) + .subscribeOn(Schedulers.io()) + .observeOn(Schedulers.newThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("deleteContactPhone", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull Long aLong) { + Log.e("deleteContactPhone", "onNext: " + aLong); + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("deleteContactPhone", "onError: " + e.getMessage()); + } + + @Override + public void onComplete() { + Log.e("deleteContactPhone", "onComplete: "); + } + }); + } + + public static void deleteRawContact(Context context, String phoneNum) { + ContentResolver resolver = context.getContentResolver(); + Cursor cursor = null; + try { + cursor = resolver.query(ContactsContract.Data.CONTENT_URI, + new String[]{ContactsContract.Data.RAW_CONTACT_ID, ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME}, + ContactsContract.CommonDataKinds.Phone.NUMBER + "=?", new String[]{phoneNum}, null); + if (cursor.moveToFirst()) { + long rawContactId = cursor.getLong(cursor.getColumnIndexOrThrow(ContactsContract.Data.RAW_CONTACT_ID)); + Log.e(TAG, "deleteRawContact: rawContactId = " + rawContactId); +// int idCode = resolver.delete(ContactsContract.Contacts.CONTENT_URI, ContactsContract.Contacts._ID + " =?", new String[]{String.valueOf(rawContactId)}); +// Log.e(TAG, "deleteRawContact: idCode = " + idCode); +// int phoneCode = resolver.delete(ContactsContract.Data.CONTENT_URI, ContactsContract.CommonDataKinds.Phone.NUMBER + "=?", new String[]{phoneNum}); +// Log.e(TAG, "deleteRawContact: phoneCode = " + phoneCode); +// int contactIdCode = resolver.delete(ContactsContract.RawContacts.CONTENT_URI, ContactsContract.RawContacts.CONTACT_ID + " =?", new String[]{String.valueOf(rawContactId)}); +// Log.e(TAG, "deleteRawContact: contactIdCode = " + contactIdCode); +// String name +// int nameCode = resolver.delete(ContactsContract.RawContacts.CONTENT_URI, "display_name=?", new String[]{name}); +// Log.e(TAG, "deleteRawContact: nameCode = " + nameCode); + + int result = resolver.delete(ContactsContract.RawContacts.CONTENT_URI, + ContactsContract.RawContacts._ID + "=?", + new String[]{String.valueOf(rawContactId)}); + Log.e(TAG, "deleteRawContact: result = " + result); + } + } catch (Exception e) { + e.printStackTrace(); + Log.e(TAG, "deleteRawContact: " + e.getMessage()); + } finally { + if (cursor != null) { + cursor.close(); + } + } + } + + public static long getRawContactId(Context context, String phoneNum) { + ContentResolver resolver = context.getContentResolver(); + Cursor cursor = null; + try { + cursor = resolver.query(ContactsContract.Data.CONTENT_URI, + new String[]{ContactsContract.Data.RAW_CONTACT_ID, ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME}, + ContactsContract.CommonDataKinds.Phone.NUMBER + "=?", new String[]{phoneNum}, null); + if (cursor.moveToFirst()) { + long rawContactId = cursor.getLong(cursor.getColumnIndexOrThrow(ContactsContract.Data.RAW_CONTACT_ID)); + Log.e(TAG, "getRawContactId: rawContactId = " + rawContactId); + return rawContactId; + } + } catch (Exception e) { + e.printStackTrace(); + Log.e(TAG, "deleteRawContact: " + e.getMessage()); + } finally { + if (cursor != null) { + cursor.close(); + } + } + return -1; + } + /** * 添加联系人信息 */ @@ -156,7 +408,7 @@ public class ContactsUtils { //插入data表 //add Name nameValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId); - nameValues.put(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/name"); + nameValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE); nameValues.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, name); resolver.insert(ContactsContract.Data.CONTENT_URI, nameValues); @@ -305,6 +557,7 @@ public class ContactsUtils { // cursor.close(); } + @Deprecated public static List getLocalContacts(Context context) { ContentResolver resolver = context.getContentResolver(); Uri uri = ContactsContract.Contacts.CONTENT_URI; diff --git a/app/src/main/java/com/xxpatx/os/utils/ForegroundAppUtil.java b/app/src/main/java/com/xxpatx/os/utils/ForegroundAppUtil.java index bb72824..d66c73b 100644 --- a/app/src/main/java/com/xxpatx/os/utils/ForegroundAppUtil.java +++ b/app/src/main/java/com/xxpatx/os/utils/ForegroundAppUtil.java @@ -31,16 +31,8 @@ public class ForegroundAppUtil { * 获取栈顶的应用包名 */ public static String getForegroundActivityName(Context context) { - String currentClassName = ""; - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { - ActivityManager manager = (ActivityManager) context.getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE); - currentClassName = manager.getRunningTasks(1).get(0).topActivity.getPackageName(); - } else { - UsageStats initStat = getForegroundUsageStats(context, START_TIME, END_TIME); - if (initStat != null) { - currentClassName = initStat.getPackageName(); - } - } + ActivityManager manager = (ActivityManager) context.getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE); + String currentClassName = manager.getRunningTasks(1).get(0).topActivity.getClassName(); return currentClassName; } @@ -48,7 +40,7 @@ public class ForegroundAppUtil { * 判断当前应用是否在前台 */ public static boolean isForegroundApp(Context context) { - return TextUtils.equals(getForegroundActivityName(context), context.getPackageName()); + return TextUtils.equals(getForegroundPackageName(context), context.getPackageName()); } /** diff --git a/app/src/main/java/com/xxpatx/os/utils/ScreenUtil.java b/app/src/main/java/com/xxpatx/os/utils/ScreenUtil.java deleted file mode 100644 index 6768174..0000000 --- a/app/src/main/java/com/xxpatx/os/utils/ScreenUtil.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.xxpatx.os.utils; - -import android.content.Context; - -public class ScreenUtil { - /** - * 根据手机的分辨率从 dp 的单位 转成为 px(像素) - */ - public static int dip2px(Context context, float dpValue) { - final float scale = context.getResources().getDisplayMetrics().density; - return (int) (dpValue * scale + 0.5f); - } - - /** - * 根据手机的分辨率从 px(像素) 的单位 转成为 dp - */ - public static int px2dip(Context context, float pxValue) { - final float scale = context.getResources().getDisplayMetrics().density; - return (int) (pxValue / scale + 0.5f); - } -} diff --git a/app/src/main/java/com/xxpatx/os/utils/Utils.java b/app/src/main/java/com/xxpatx/os/utils/Utils.java index a3252f2..c9d41c3 100644 --- a/app/src/main/java/com/xxpatx/os/utils/Utils.java +++ b/app/src/main/java/com/xxpatx/os/utils/Utils.java @@ -66,7 +66,7 @@ public class Utils { Log.e("e", "读取设备序列号异常:" + e.toString()); } if (BuildConfig.DEBUG) { -// return "QNG2DKB00463"; +// return "TYZ185P5250101467"; } return serial; } diff --git a/app/src/main/java/com/xxpatx/os/view/ToggleButton.java b/app/src/main/java/com/xxpatx/os/view/ToggleButton.java index 80765f4..c55f231 100644 --- a/app/src/main/java/com/xxpatx/os/view/ToggleButton.java +++ b/app/src/main/java/com/xxpatx/os/view/ToggleButton.java @@ -34,7 +34,7 @@ public class ToggleButton extends View { /** * 关闭颜色 */ - private int offBorderColor = Color.parseColor("#f62626"); + private int offBorderColor = Color.parseColor("#626E82"); /** * 灰色带颜色 */ diff --git a/app/src/main/res/layout-sw700dp/activity_add_contact.xml b/app/src/main/res/layout-sw700dp/activity_contact_add.xml similarity index 99% rename from app/src/main/res/layout-sw700dp/activity_add_contact.xml rename to app/src/main/res/layout-sw700dp/activity_contact_add.xml index 239913d..a483c0b 100644 --- a/app/src/main/res/layout-sw700dp/activity_add_contact.xml +++ b/app/src/main/res/layout-sw700dp/activity_contact_add.xml @@ -77,7 +77,9 @@ android:layout_gravity="center" android:layout_marginTop="16dp" android:layout_marginBottom="16dp" + android:adjustViewBounds="true" android:onClick="@{click::selectPic}" + android:scaleType="centerCrop" android:src="@drawable/default_avatar" app:is_circle="true" app:layout_constraintBottom_toBottomOf="parent" diff --git a/app/src/main/res/layout/activity_add_contact.xml b/app/src/main/res/layout/activity_contact_add.xml similarity index 91% rename from app/src/main/res/layout/activity_add_contact.xml rename to app/src/main/res/layout/activity_contact_add.xml index d8d2058..c82ca03 100644 --- a/app/src/main/res/layout/activity_add_contact.xml +++ b/app/src/main/res/layout/activity_contact_add.xml @@ -78,6 +78,8 @@ android:layout_marginTop="32dp" android:layout_marginBottom="32dp" android:onClick="@{click::selectPic}" + android:adjustViewBounds="true" + android:scaleType="centerCrop" android:src="@drawable/default_avatar" app:is_circle="true" app:layout_constraintBottom_toBottomOf="parent" @@ -278,8 +280,37 @@ + + + + + + + + - @@ -99,6 +97,8 @@ android:layout_gravity="center" android:layout_marginTop="32dp" android:layout_marginBottom="32dp" + android:adjustViewBounds="true" + android:scaleType="centerCrop" android:onClick="@{click::selectPic}" android:src="@drawable/default_avatar" app:error="@{@drawable/default_avatar}" @@ -304,8 +304,36 @@ + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintStart_toStartOf="parent" /> - - - - - - - diff --git a/app/src/main/res/layout/phone_fragment_control.xml b/app/src/main/res/layout/fragment_control.xml similarity index 100% rename from app/src/main/res/layout/phone_fragment_control.xml rename to app/src/main/res/layout/fragment_control.xml diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index 404f17d..116a518 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -143,12 +143,15 @@ android:layout_height="wrap_content" android:layout_marginStart="4dp" android:text="--" + android:maxLines="1" + android:singleLine="true" + android:maxEms="3" android:textColor="@color/white" android:textSize="20sp" app:layout_constraintBottom_toBottomOf="@+id/imageView11" app:layout_constraintStart_toEndOf="@+id/imageView11" app:layout_constraintTop_toTopOf="@+id/imageView11" - tools:text="位置" /> + tools:text="城市" /> diff --git a/app/src/main/res/layout/item_contact.xml b/app/src/main/res/layout/item_contact.xml index 7362384..b51cce4 100644 --- a/app/src/main/res/layout/item_contact.xml +++ b/app/src/main/res/layout/item_contact.xml @@ -83,16 +83,15 @@ + app:layout_constraintTop_toTopOf="parent" /> diff --git a/app/src/main/res/layout/settings_activity.xml b/app/src/main/res/layout/settings_activity.xml deleted file mode 100644 index a0300d3..0000000 --- a/app/src/main/res/layout/settings_activity.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/xml/accessibility_service_config.xml b/app/src/main/res/xml/accessibility_service_config.xml index b45611f..143597b 100644 --- a/app/src/main/res/xml/accessibility_service_config.xml +++ b/app/src/main/res/xml/accessibility_service_config.xml @@ -1,7 +1,7 @@