version:1.4.8

fix:修复一键拨号
update:优化联系人闹钟
This commit is contained in:
2025-02-10 17:05:54 +08:00
parent 3f1216ad5c
commit 398d353be9
51 changed files with 993 additions and 1106 deletions

View File

@@ -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"

View File

@@ -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<AlarmAddViewModel, Activi
mPictrueFilePath = result.get(0).getRealPath();
File file = new File(mPictrueFilePath);
if (file.exists()) {
RequestOptions options = new RequestOptions().transform(new RoundedCorners(ScreenUtil.dip2px(AlarmAddActivity.this, 8F)));
RequestOptions options = new RequestOptions().transform(new RoundedCorners(ScreenUtils.dip2px(AlarmAddActivity.this, 8F)));
Glide.with(mViewDataBinding.nvPic).load(file).apply(options).into(mViewDataBinding.nvPic);
mViewDataBinding.nvPic.setVisibility(View.VISIBLE);
mViewDataBinding.clPic.setVisibility(View.GONE);

View File

@@ -33,7 +33,7 @@ import com.xxpatx.os.network.NetInterfaceManager;
import com.xxpatx.os.utils.FFmpegUtils;
import com.xxpatx.os.utils.FileUtil;
import com.xxpatx.os.utils.GlideLoadUtils;
import com.xxpatx.os.utils.ScreenUtil;
import com.xxpatx.os.utils.ScreenUtils;
import com.xxpatx.os.utils.TimeUtils;
import com.xxpatx.os.utils.Utils;
@@ -295,7 +295,7 @@ public class AlarmEditActivity extends BaseMvvmActivity<AlarmEditViewModel, Acti
mPictrueFilePath = result.get(0).getRealPath();
File file = new File(mPictrueFilePath);
if (file.exists()) {
RequestOptions options = new RequestOptions().transform(new RoundedCorners(ScreenUtil.dip2px(AlarmEditActivity.this, 8F)));
RequestOptions options = new RequestOptions().transform(new RoundedCorners(ScreenUtils.dip2px(AlarmEditActivity.this, 8F)));
Glide.with(mViewDataBinding.nvPic).load(file).apply(options).into(mViewDataBinding.nvPic);
mViewDataBinding.nvPic.setVisibility(View.VISIBLE);
mViewDataBinding.clPic.setVisibility(View.GONE);

View File

@@ -80,7 +80,7 @@ public class AlarmListActivity extends BaseMvvmActivity<AlarmListViewModel, Acti
@Override
public void onLongClick(AlarmClockData alarmClockData) {
boolean clockModify = mMMKV.decodeBool(CommonConfig.DISABLE_CLOCK_MODIFY, false);
int alarm_clock_ctrl = Settings.Global.getInt(getContentResolver(), CommonConfig.ALARM_CLOCK_CTRL, 0);
int alarm_clock_ctrl = Settings.Global.getInt(getContentResolver(), CommonConfig.ALARM_CLOCK_CTRL, 1);
if (clockModify || alarm_clock_ctrl == 0) {
Toaster.showLong("已禁用闹钟修改");
} else {
@@ -237,7 +237,7 @@ public class AlarmListActivity extends BaseMvvmActivity<AlarmListViewModel, Acti
public void add(View view) {
boolean clockModify = mMMKV.decodeBool(CommonConfig.DISABLE_CLOCK_MODIFY, false);
int alarm_clock_ctrl = Settings.Global.getInt(getContentResolver(), CommonConfig.ALARM_CLOCK_CTRL, 0);
int alarm_clock_ctrl = Settings.Global.getInt(getContentResolver(), CommonConfig.ALARM_CLOCK_CTRL, 1);
if (clockModify || alarm_clock_ctrl == 0) {
Toaster.showLong("已禁用闹钟修改");
} else {

View File

@@ -32,11 +32,11 @@ import com.xxpatx.os.base.mvvm.BaseMvvmActivity;
import com.xxpatx.os.bean.Contact;
import com.xxpatx.os.config.CommonConfig;
import com.xxpatx.os.custom.GlideEngine;
import com.xxpatx.os.databinding.ActivityAddContactBinding;
import com.xxpatx.os.databinding.ActivityContactAddBinding;
import com.xxpatx.os.db.ContactCacheUtils;
import com.xxpatx.os.utils.ContactsUtils;
import com.xxpatx.os.utils.LocalContactUtils;
import com.xxpatx.os.utils.ScreenUtil;
import com.xxpatx.os.utils.ScreenUtils;
import com.zackratos.ultimatebarx.ultimatebarx.UltimateBarXKt;
import com.zackratos.ultimatebarx.ultimatebarx.java.UltimateBarX;
@@ -45,7 +45,7 @@ import java.io.File;
import java.util.ArrayList;
import java.util.concurrent.ThreadLocalRandom;
public class AddContactActivity extends BaseMvvmActivity<AddContactViewModel, ActivityAddContactBinding> {
public class AddContactActivity extends BaseMvvmActivity<AddContactViewModel, ActivityContactAddBinding> {
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<AddContactViewModel, Ac
@Override
protected int getLayoutId() {
return R.layout.activity_add_contact;
return R.layout.activity_contact_add;
}
@Override
@@ -141,7 +141,7 @@ public class AddContactActivity extends BaseMvvmActivity<AddContactViewModel, Ac
mViewModel.avatarFilePath = result.get(0).getRealPath();
File file = new File(mViewModel.avatarFilePath);
if (file.exists()) {
RequestOptions options = new RequestOptions().transform(new RoundedCorners(ScreenUtil.dip2px(AddContactActivity.this, 8F)));
RequestOptions options = new RequestOptions().transform(new RoundedCorners(ScreenUtils.dip2px(AddContactActivity.this, 8F)));
Glide.with(mViewDataBinding.nvAvatar).load(file).apply(options).into(mViewDataBinding.nvAvatar);
} else {
mViewModel.avatarFilePath = "";
@@ -199,7 +199,7 @@ public class AddContactActivity extends BaseMvvmActivity<AddContactViewModel, Ac
LocalContactUtils.addLocalContact(contact);
if (ContactsUtils.isExist(AddContactActivity.this, contact.getMobile())) {
long rawContactId = ContactsUtils.getContactId(AddContactActivity.this, contact.getMobile());
long rawContactId = ContactsUtils.getRawContactId(AddContactActivity.this, contact.getMobile());
Glide.with(AddContactActivity.this).asBitmap().load(contact.getAvatar()).override(200, 200).into(new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(@androidx.annotation.NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
@@ -207,7 +207,7 @@ public class AddContactActivity extends BaseMvvmActivity<AddContactViewModel, Ac
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.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
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});
@@ -237,7 +237,7 @@ public class AddContactActivity extends BaseMvvmActivity<AddContactViewModel, Ac
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.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
nameValues.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, contact.getName());
resolver.insert(ContactsContract.Data.CONTENT_URI, nameValues);

View File

@@ -13,8 +13,9 @@ import com.xxpatx.os.R;
import com.xxpatx.os.base.mvvm.BaseViewModel;
import com.xxpatx.os.bean.BaseResponse;
import com.xxpatx.os.bean.Contact;
import com.xxpatx.os.databinding.ActivityAddContactBinding;
import com.xxpatx.os.databinding.ActivityContactAddBinding;
import com.xxpatx.os.network.NetInterfaceManager;
import com.xxpatx.os.utils.ContactsUtils;
import com.xxpatx.os.utils.FileUtil;
import com.xxpatx.os.utils.Utils;
@@ -30,11 +31,11 @@ import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
public class AddContactViewModel extends BaseViewModel<ActivityAddContactBinding, ActivityEvent> {
public class AddContactViewModel extends BaseViewModel<ActivityContactAddBinding, ActivityEvent> {
private static final String TAG = "AddContactViewModel";
@Override
public ActivityAddContactBinding getVDBinding() {
public ActivityContactAddBinding getVDBinding() {
return binding;
}
@@ -69,12 +70,25 @@ public class AddContactViewModel extends BaseViewModel<ActivityAddContactBinding
RequestBody requestBody = RequestBody.Companion.create(avatarFile, mediaType);
MultipartBody.Part body = MultipartBody.Part.createFormData("avatar", avatarFile.getName(), requestBody);
Map<String, String> 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<ActivityAddContactBinding
Toaster.show("已添加");
mAddData.setValue(true);
} else {
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);
mContactData.setValue(contact);
Toaster.show(baseResponse.msg);
mAddData.setValue(false);
@@ -110,16 +114,6 @@ public class AddContactViewModel extends BaseViewModel<ActivityAddContactBinding
@Override
public void onError(@NonNull Throwable e) {
Log.e("checkContact", "onError: " + e.getMessage());
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);
mContactData.setValue(contact);
mAddData.setValue(false);
}

View File

@@ -82,7 +82,7 @@ public class ContactListActivity extends BaseMvvmActivity<ContactListViewModel,
@Override
protected void initData() {
mViewModel.getContactListData().observe(this, new Observer<List<Contact>>() {
mViewModel.mContactListData.observe(this, new Observer<List<Contact>>() {
@Override
public void onChanged(List<Contact> contacts) {
// List<Contact> sim = getSIMContacts();
@@ -93,10 +93,11 @@ public class ContactListActivity extends BaseMvvmActivity<ContactListViewModel,
}
});
mViewModel.getDeleteData().observe(this, new Observer<BaseResponse>() {
mViewModel.mDeleteData.observe(this, new Observer<BaseResponse>() {
@Override
public void onChanged(BaseResponse baseResponse) {
if (baseResponse.code == 200) {
Toaster.show("删除成功");
} else {
Toaster.show("删除失败:" + baseResponse.msg);
@@ -104,14 +105,14 @@ public class ContactListActivity extends BaseMvvmActivity<ContactListViewModel,
mViewModel.getContact();
}
});
mViewModel.getCacheContact();
mViewModel.getContact();
}
@Override
public void onResume() {
super.onResume();
Log.e(TAG, "onResume: ");
mViewModel.getCacheContact();
mViewModel.getContact();
}

View File

@@ -1,12 +1,9 @@
package com.xxpatx.os.activity.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.ActivityEvent;
@@ -15,12 +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.ActivityContactListBinding;
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;
@@ -41,76 +36,36 @@ public class ContactListViewModel extends BaseViewModel<ActivityContactListBindi
}
private MutableLiveData<List<Contact>> mContactListData = new MutableLiveData<>();
public MutableLiveData<List<Contact>> getContactListData() {
return mContactListData;
}
public void getCacheContact() {
String jsonString = mMMKV.getString(UrlAddress.GET_MAIL_LIST, null);
Gson gson = new Gson();
Type type = new TypeToken<List<Contact>>() {
}.getType();
if (!TextUtils.isEmpty(jsonString)) {
List<Contact> contacts = gson.fromJson(jsonString, type);
if (contacts != null) {
mContactListData.setValue(contacts);
}
}
getContact();
}
public MutableLiveData<List<Contact>> mContactListData = new MutableLiveData<>();
public void getContact() {
NetInterfaceManager.getInstance()
.getContactListObservable()
.compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY))
.subscribe(new Observer<BaseResponse<List<Contact>>>() {
NetInterfaceManager.getInstance().getContactListObserverCache(UrlAddress.GET_MAIL_LIST, new NetInterfaceManager.ContactCallback() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e("getContactList", "onSubscribe: ");
}
@Override
public void onNext(@NonNull BaseResponse<List<Contact>> 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<List<Contact>>() {
}.getType();
List<Contact> contacts = gson.fromJson(jsonString, type);
if (contacts == null) {
mContactListData.setValue(new ArrayList<>());
} else {
mContactListData.setValue(contacts);
}
onComplete();
public void setContact(List<Contact> contactList) {
mContactListData.setValue(contactList);
}
@Override
public void onComplete() {
Log.e("getContactList", "onComplete: ");
}
});
NetInterfaceManager.getInstance()
.getContactList(getLifecycle(), new NetInterfaceManager.ContactCallback() {
@Override
public void setContact(List<Contact> contactList) {
mContactListData.setValue(contactList);
}
@Override
public void onComplete() {
}
});
}
private MutableLiveData<BaseResponse> mDeleteData = new MutableLiveData<>();
public MutableLiveData<BaseResponse> getDeleteData() {
return mDeleteData;
}
public MutableLiveData<BaseResponse> mDeleteData = new MutableLiveData<>();
public void deleteContact(Contact contact) {
Log.e(TAG, "deleteContact: " + contact.getId());
@@ -125,6 +80,9 @@ public class ContactListViewModel extends BaseViewModel<ActivityContactListBindi
@Override
public void onNext(@NonNull BaseResponse baseResponse) {
Log.e("deleteContact", "onNext: " + baseResponse);
if (baseResponse.code == 200) {
ContactsUtils.deleteRawContact(getCtx(), contact.getMobile());
}
mDeleteData.setValue(baseResponse);
}

View File

@@ -27,27 +27,34 @@ import com.xxpatx.os.base.mvvm.BaseMvvmActivity;
import com.xxpatx.os.bean.BaseResponse;
import com.xxpatx.os.bean.Contact;
import com.xxpatx.os.custom.GlideEngine;
import com.xxpatx.os.databinding.ActivityEditContactBinding;
import com.xxpatx.os.databinding.ActivityContactEditBinding;
import com.xxpatx.os.utils.ContactsUtils;
import com.xxpatx.os.utils.FileUtil;
import com.xxpatx.os.utils.ScreenUtil;
import com.xxpatx.os.utils.ScreenUtils;
import com.xxpatx.os.utils.Utils;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
public class EditContactActivity extends BaseMvvmActivity<EditContactViewModel, ActivityEditContactBinding> {
public class EditContactActivity extends BaseMvvmActivity<EditContactViewModel, ActivityContactEditBinding> {
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<EditContactViewModel,
@Override
protected int getLayoutId() {
return R.layout.activity_edit_contact;
return R.layout.activity_contact_edit;
}
@Override
@@ -112,6 +119,12 @@ public class EditContactActivity extends BaseMvvmActivity<EditContactViewModel,
} else {
mViewDataBinding.toggleButton.setToggleOff(false);
}
if (mContact.getShow_desktop() == 1) {
mViewDataBinding.tbShow.setToggleOn(false);
} else {
mViewDataBinding.tbShow.setToggleOff(false);
}
Glide.with(this).asBitmap().load(mContact.getAvatar()).error(R.drawable.default_avatar).into(new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
@@ -133,7 +146,7 @@ public class EditContactActivity extends BaseMvvmActivity<EditContactViewModel,
mPictrueFilePath = result.get(0).getRealPath();
File file = new File(mPictrueFilePath);
if (file.exists()) {
RequestOptions options = new RequestOptions().transform(new RoundedCorners(ScreenUtil.dip2px(EditContactActivity.this, 8F)));
RequestOptions options = new RequestOptions().transform(new RoundedCorners(ScreenUtils.dip2px(EditContactActivity.this, 8F)));
Glide.with(mViewDataBinding.nvAvatar).load(file).apply(options).into(mViewDataBinding.nvAvatar);
} else {
mPictrueFilePath = "";
@@ -181,6 +194,18 @@ public class EditContactActivity extends BaseMvvmActivity<EditContactViewModel,
params.put("mobile", phone);
params.put("tag", groupTag);
params.put("is_urgent", String.valueOf(mViewDataBinding.toggleButton.isToggleOn()));
params.put("show_desktop", String.valueOf(mViewDataBinding.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(groupTag);
contact.setIs_urgent(mViewDataBinding.toggleButton.isToggleOn());
contact.setAvatar(mPictrueFilePath);
ContactsUtils.saveContactPhone(EditContactActivity.this, contact);
mViewModel.editContact(params, body);
mLoadingDialog.show();
}

View File

@@ -8,7 +8,7 @@ import com.trello.rxlifecycle4.RxLifecycle;
import com.trello.rxlifecycle4.android.ActivityEvent;
import com.xxpatx.os.base.mvvm.BaseViewModel;
import com.xxpatx.os.bean.BaseResponse;
import com.xxpatx.os.databinding.ActivityEditContactBinding;
import com.xxpatx.os.databinding.ActivityContactEditBinding;
import com.xxpatx.os.network.NetInterfaceManager;
import java.util.Map;
@@ -18,10 +18,10 @@ import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.Disposable;
import okhttp3.MultipartBody;
public class EditContactViewModel extends BaseViewModel<ActivityEditContactBinding, ActivityEvent> {
public class EditContactViewModel extends BaseViewModel<ActivityContactEditBinding, ActivityEvent> {
@Override
public ActivityEditContactBinding getVDBinding() {
public ActivityContactEditBinding getVDBinding() {
return binding;
}

View File

@@ -162,7 +162,6 @@ public class EmergencyActivity extends BaseMvvmActivity<EmergencyViewModel, Acti
mEmergencyContactAdapter.setContactList(mContactList);
}
});
mViewModel.getCacheContact();
mViewModel.getContact();
}

View File

@@ -1,33 +1,18 @@
package com.xxpatx.os.activity.emergency;
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.ActivityEvent;
import com.xxpatx.os.base.mvvm.BaseViewModel;
import com.xxpatx.os.bean.BaseResponse;
import com.xxpatx.os.bean.Contact;
import com.xxpatx.os.config.CommonConfig;
import com.xxpatx.os.databinding.ActivityEmergencyBinding;
import com.xxpatx.os.gson.GsonUtils;
import com.xxpatx.os.network.NetInterfaceManager;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.Disposable;
public class EmergencyViewModel extends BaseViewModel<ActivityEmergencyBinding, ActivityEvent> {
private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE);
@@ -44,70 +29,30 @@ public class EmergencyViewModel extends BaseViewModel<ActivityEmergencyBinding,
public MutableLiveData<List<Contact>> mContactListData = new MutableLiveData<>();
public void getCacheContact() {
String jsonString = mMMKV.getString(CommonConfig.EMERGENCY_CONTACT_LIST_KEY, null);
Gson gson = new Gson();
Type type = new TypeToken<List<Contact>>() {
}.getType();
if (!TextUtils.isEmpty(jsonString)) {
List<Contact> contacts = gson.fromJson(jsonString, type);
if (contacts != null) {
mContactListData.setValue(contacts);
}
}
getContact();
}
public void getContact() {
NetInterfaceManager.getInstance()
.getContactListObservable()
.compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY))
.subscribe(new Observer<BaseResponse<List<Contact>>>() {
NetInterfaceManager.getInstance().getContactListObserverCache(CommonConfig.EMERGENCY_CONTACT_LIST_KEY, new NetInterfaceManager.ContactCallback() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e("getContactList", "onSubscribe: ");
}
@Override
public void onNext(@NonNull BaseResponse<List<Contact>> listBaseResponse) {
Log.e("getContactList", "onNext: " + listBaseResponse);
if (listBaseResponse.code == 200) {
List<Contact> contactList = listBaseResponse.data;
if (contactList != null && !contactList.isEmpty()) {
List<Contact> emergencyConcacts = contactList.stream().filter(new Predicate<Contact>() {
@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<List<Contact>>() {
}.getType();
List<Contact> contacts = gson.fromJson(jsonString, type);
if (contacts == null) {
mContactListData.setValue(new ArrayList<>());
} else {
mContactListData.setValue(contacts);
}
onComplete();
public void setContact(List<Contact> contactList) {
mContactListData.setValue(contactList);
}
@Override
public void onComplete() {
Log.e("getContactList", "onComplete: ");
}
});
NetInterfaceManager.getInstance()
.getContactList(getLifecycle(), new NetInterfaceManager.ContactCallback() {
@Override
public void setContact(List<Contact> contactList) {
List<Contact> emergencyConcacts = contactList.stream().filter(contact -> contact.getIs_urgent() == 1).collect(Collectors.toList());
mContactListData.setValue(emergencyConcacts);
}
@Override
public void onComplete() {
}
});
}

View File

@@ -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<MainViewModel, ActivityMainBinding> implements NetworkUtils.OnNetworkStatusChangedListener,
@@ -127,6 +131,15 @@ public class MainActivity extends BaseMvvmActivity<MainViewModel, ActivityMainBi
// private DockAppAdapter mDockAppAdapter;
private DockAppGridAdapter mDockAppGridAdapter;
@Override
public Resources getResources() {
//需要升级到 v1.1.2 及以上版本才能使用 AutoSizeCompat
int width = AutoSizeConfig.getInstance().getScreenWidth();
int height = AutoSizeConfig.getInstance().getScreenHeight();
AutoSizeCompat.autoConvertDensity(super.getResources(), 740, width > height);
return super.getResources();
}
@Override
public void onDisconnected() {
Log.e(TAG, "onDisconnected: ");
@@ -177,7 +190,7 @@ public class MainActivity extends BaseMvvmActivity<MainViewModel, ActivityMainBi
Log.e(TAG, "getContacts: " + ContactsUtils.isExist(MainActivity.this, "13220282310"));
Log.e(TAG, "getContacts: " + ContactsUtils.getContactId(MainActivity.this, "13220282310"));
Log.e(TAG, "getContacts: " + ContactsUtils.getRawContactId(MainActivity.this, "13220282310"));
ContactsUtils.isThePhoneExist(MainActivity.this, "13220282310");
// ContactsUtils.getContacts(MainActivity.this);
// ContactsUtils.getLocalContacts(MainActivity.this);

View File

@@ -57,10 +57,12 @@ public class NoticeActivity extends BaseDataBindingActivity {
mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
mWakeLock = mPowerManager.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_DIM_WAKE_LOCK, "WakeAndLock");
mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
mWakeLock.acquire(60 * 1000L);
mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
long[] pattern = {1000, 5000, 1000, 5000};
mVibrator.vibrate(pattern, 0);
WakeUpUtils.wakeUpAndUnlockScreen(this);
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);

View File

@@ -76,7 +76,6 @@ public class NoticeInfoActivity extends BaseMvvmActivity<NoticeInfoViewModel, Ac
mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
mWakeLock = mPowerManager.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_DIM_WAKE_LOCK, "WakeAndLock");
// mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
int maxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
@@ -179,6 +178,7 @@ public class NoticeInfoActivity extends BaseMvvmActivity<NoticeInfoViewModel, Ac
mViewDataBinding.clVoice.setVisibility(View.GONE);
}
String filePath = alarmClockData.getFile();
if (!TextUtils.isEmpty(filePath)) {
RequestOptions options = new RequestOptions().transform(new RoundedCorners(ScreenUtils.dip2px(this, 16F)));
String fileName = filePath.substring(filePath.lastIndexOf("/") + 1, filePath.length());
String realPath = Utils.getDownLoadPath(NoticeInfoActivity.this) + fileName;
@@ -189,6 +189,7 @@ public class NoticeInfoActivity extends BaseMvvmActivity<NoticeInfoViewModel, Ac
Glide.with(NoticeInfoActivity.this).load(filePath).apply(options).error(R.drawable.icon_nodata).into(mViewDataBinding.imageView);
}
}
}
private void showData(AlarmClockData alarmClockData) {

View File

@@ -24,8 +24,8 @@ public class ScreenLockActivity extends BaseMvvmActivity<ScreenLockViewModel, Ac
private static final String TAG = "ScreenLockActivity";
private SoundPool soundPool;
private int soundId;
private SoundPool mSoundPool;
private int mSoundId;
@Override
@@ -34,12 +34,12 @@ public class ScreenLockActivity extends BaseMvvmActivity<ScreenLockViewModel, Ac
getWindow().addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
AudioAttributes attr = new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_GAME) // 设置音效使用场景
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC).build(); // 设置音效的类型
soundPool = new SoundPool.Builder().setAudioAttributes(attr) // 设置音效池的属性
mSoundPool = new SoundPool.Builder().setAudioAttributes(attr) // 设置音效池的属性
.setMaxStreams(1) // 设置最多可容纳10个音频流
.build(); // ①
// load方法加载指定音频文件并返回所加载的音效ID
// 此处使用HashMap来管理这些音频流
soundId = soundPool.load(this, R.raw.click, 1);
mSoundId = mSoundPool.load(this, R.raw.click, 1);
}
@Override
@@ -145,6 +145,15 @@ public class ScreenLockActivity extends BaseMvvmActivity<ScreenLockViewModel, Ac
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mSoundPool != null) {
mSoundPool.release();
mSoundPool = null;
}
}
private void add(VerificationCodeView codeView, String text) {
Log.e(TAG, "add: text = " + text);
String oldText = codeView.getEditText().getText().toString();

View File

@@ -1,53 +0,0 @@
package com.xxpatx.os.activity.setting;
import android.os.Bundle;
import androidx.appcompat.app.ActionBar;
import androidx.preference.PreferenceFragmentCompat;
import com.xxpatx.os.R;
import com.xxpatx.os.base.mvvm.BaseMvvmActivity;
public class SettingsActivity extends BaseMvvmActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.settings_activity);
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.settings, new SettingsFragment())
.commit();
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
}
@Override
protected int getLayoutId() {
return 0;
}
@Override
protected void initDataBinding() {
}
@Override
protected void initView() {
}
@Override
protected void initData() {
}
public static class SettingsFragment extends PreferenceFragmentCompat {
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.root_preferences, rootKey);
}
}
}

View File

@@ -99,7 +99,7 @@ public class DailyAppAdapter extends RecyclerView.Adapter<DailyAppAdapter.Holder
private void showDialog(DailyAppBean dailyAppBean) {
int appLockCtrl = Settings.Global.getInt(mContext.getContentResolver(), CommonConfig.APP_LOCK_CTRL, 0);
int appLockCtrl = Settings.Global.getInt(mContext.getContentResolver(), CommonConfig.APP_LOCK_CTRL, 1);
if (appLockCtrl == 0) {
Toaster.showLong("已禁止桌面编辑");
return;

View File

@@ -697,10 +697,10 @@ public class AlarmUtils {
case ONCE:
if (!finished) {
if (timeStamp < System.currentTimeMillis()) {
Intent intent = new Intent(MainService.ALARMWAKEUP);
intent.putExtra("title", title);
intent.putExtra("id", id);
mContext.sendBroadcast(intent);
// Intent intent = new Intent(MainService.ALARMWAKEUP);
// intent.putExtra("title", title);
// intent.putExtra("id", id);
// mContext.sendBroadcast(intent);
} else {
setOnceAlarm(MainService.ALARMWAKEUP, title, id, timeStamp, local);
}

View File

@@ -18,6 +18,7 @@ public class Contact implements Serializable {
String mobile;//手机号
String avatar;//头像
String tag;//标签
int show_desktop;//是否在主页显示
boolean simContact;
public Contact() {
@@ -82,6 +83,14 @@ public class Contact implements Serializable {
this.tag = tag;
}
public int getShow_desktop() {
return show_desktop;
}
public void setShow_desktop(int show_desktop) {
this.show_desktop = show_desktop;
}
public boolean isSimContact() {
return simContact;
}

View File

@@ -7,6 +7,7 @@ import com.google.gson.JsonParser;
import java.io.Serializable;
@Deprecated
public class ContactId implements Serializable {
private static final long serialVersionUID = 6712547690395593591L;

View File

@@ -454,7 +454,13 @@ public class CacheHelper {
String cachePath;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
|| !Environment.isExternalStorageRemovable()) {
if (context.getExternalCacheDir() != null) {
cachePath = context.getExternalCacheDir().getPath();
} else if (context.getExternalFilesDir("cache") != null) {
cachePath = context.getExternalFilesDir("cache").getPath();
} else {
cachePath = context.getCacheDir().getPath();
}
} else {
cachePath = context.getCacheDir().getPath();
}

View File

@@ -411,7 +411,7 @@ public class AppListFragment extends BaseFragment {
}
private void showHideDialog(DesktopIcon desktopIcon) {
int appLockCtrl = Settings.Global.getInt(mContext.getContentResolver(), CommonConfig.APP_LOCK_CTRL, 0);
int appLockCtrl = Settings.Global.getInt(mContext.getContentResolver(), CommonConfig.APP_LOCK_CTRL, 1);
if (appLockCtrl == 0) {
Toaster.showLong("已禁止桌面编辑");
return;

View File

@@ -1,42 +1,28 @@
package com.xxpatx.os.fragment.contact;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.res.Configuration;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.Observer;
import androidx.recyclerview.widget.GridLayoutManager;
import com.hjq.toast.Toaster;
import com.jeremyliao.liveeventbus.LiveEventBus;
import com.qweather.sdk.bean.weather.WeatherNowBean;
import com.tencent.mmkv.MMKV;
import com.xxpatx.os.R;
import com.xxpatx.os.activity.contact.AddContactActivity;
import com.xxpatx.os.activity.contact.EditContactActivity;
import com.xxpatx.os.activity.weather.WeatherActivity;
import com.xxpatx.os.adapter.WechatContactAdapter;
import com.xxpatx.os.base.mvvm.fragment.BaseMvvmFragment;
import com.xxpatx.os.bean.BaseResponse;
import com.xxpatx.os.bean.Contact;
import com.xxpatx.os.bean.MapBean;
import com.xxpatx.os.config.CommonConfig;
import com.xxpatx.os.databinding.FragmentContactHomeBinding;
import com.xxpatx.os.dialog.EditContactDialog;
import com.xxpatx.os.utils.DayUtils;
import com.xxpatx.os.utils.TimeUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class ContactFragment extends BaseMvvmFragment<ContactViewModel, FragmentContactHomeBinding> {
private static final String TAG = "ContactFragment";
@@ -64,240 +50,57 @@ public class ContactFragment extends BaseMvvmFragment<ContactViewModel, Fragment
@Override
protected void initView(Bundle bundle) {
mContactAdapter = new WechatContactAdapter();
mContactAdapter.setOnLongClick(new WechatContactAdapter.OnLongClick() {
@Override
public void setOnLongClickListener(Contact contact) {
// showDialog(contact);
}
});
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
SPAN_COUNT = 3;
} else {
SPAN_COUNT = 2;
}
mViewDataBinding.rvContact.setLayoutManager(new GridLayoutManager(getContext(), SPAN_COUNT));
// EquallyDividedItemDecoration equallyDividedItemDecoration = new EquallyDividedItemDecoration(SPAN_COUNT, 2);
// mViewDataBinding.rvContact.addItemDecoration(equallyDividedItemDecoration);
mViewDataBinding.rvContact.setAdapter(mContactAdapter);
setTime();
initAmap();
}
private void setTime() {
mViewDataBinding.tvTime.setText(TimeUtils.getNowTime(mContext));
mViewDataBinding.tvData.setText(TimeUtils.getDateWeek());
mViewDataBinding.tvWeek.setText(DayUtils.getWeek());
}
private void initAmap() {
boolean manual = mMMKV.decodeBool(CommonConfig.MANUALLY_SELECT_LOCATION_KEY, false);
if (!manual) {
LiveEventBus.get(CommonConfig.AMAP_LOCATION_MAP_BEAN, MapBean.class)
.observe(this, new Observer<MapBean>() {
@Override
public void onChanged(@Nullable MapBean mapBean) {
mViewDataBinding.tvLocation.setText(mapBean.getDistrict());
}
});
} else {
}
}
private List<Contact> mContacts = new ArrayList<Contact>() {{
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<WeatherNowBean.NowBaseBean>() {
@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<WeatherHourlyBean.HourlyBean>() {
// @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<WeatherDailyBean.DailyBean>() {
// @Override
// public void onChanged(@Nullable WeatherDailyBean.DailyBean dailyBean) {
// mViewDataBinding.tvWeather.setText(dailyBean.getTempMin() + "℃ - " + dailyBean.getTempMax() + "℃");
// }
// });
//
// LiveEventBus
// .get("time", String.class)
// .observe(this, new Observer<String>() {
// @Override
// public void onChanged(@Nullable String s) {
// mViewDataBinding.tvTime.setText(s);
// }
// });
//
// LiveEventBus
// .get("date", String.class)
// .observe(this, new Observer<String>() {
// @Override
// public void onChanged(@Nullable String s) {
// mViewDataBinding.tvData.setText(s);
// }
// });
//
// LiveEventBus
// .get("week", String.class)
// .observe(this, new Observer<String>() {
// @Override
// public void onChanged(@Nullable String s) {
// mViewDataBinding.tvWeek.setText(s);
// }
// });
mViewModel.mContactListData.observe(this, new Observer<List<Contact>>() {
@Override
public void onChanged(List<Contact> 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<Contact> sim = getSIMContacts();
// if (sim.size() != 0) {
// contacts.addAll(sim);
// }
List<Contact> 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<BaseResponse>() {
@Override
public void onChanged(BaseResponse baseResponse) {
if (baseResponse.code == 200) {
Toaster.show("删除成功");
} else {
Toaster.show("删除失败:" + baseResponse.msg);
}
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<Contact> getSIMContacts() {
List<Contact> 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);

View File

@@ -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<FragmentContactHomeBinding,
public MutableLiveData<List<Contact>> mContactListData = new MutableLiveData<>();
public void getCacheContact() {
String jsonString = mMMKV.getString(UrlAddress.GET_MAIL_LIST, null);
Gson gson = new Gson();
Type type = new TypeToken<List<Contact>>() {
}.getType();
if (!TextUtils.isEmpty(jsonString)) {
List<Contact> contacts = gson.fromJson(jsonString, type);
if (contacts != null) {
contacts.addAll(ContactCacheUtils.getInstance().getDatabaseContact());
mContactListData.setValue(contacts);
}
}
getContact();
}
public void getContact() {
NetInterfaceManager.getInstance().getContactListObserverCache(UrlAddress.GET_MAIL_LIST, new NetInterfaceManager.ContactCallback() {
@Override
public void setContact(List<Contact> contactList) {
mContactListData.setValue(contactList);
}
@Override
public void onComplete() {
}
});
NetInterfaceManager.getInstance()
.getContactListObservable()
.getContactListFragment(getLifecycle(), new NetInterfaceManager.ContactCallback() {
@Override
public void setContact(List<Contact> contactList) {
mContactListData.setValue(contactList);
}
@Override
public void onComplete() {
}
});
}
public void getContactNoSave() {
NetInterfaceManager.getInstance().getContactListObservable()
.compose(RxLifecycle.bindUntilEvent(getLifecycle(), FragmentEvent.DESTROY))
.subscribe(new Observer<BaseResponse<List<Contact>>>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e("getContactList", "onSubscribe: ");
Log.e("getContactNoSave", "onSubscribe: ");
}
@Override
public void onNext(@NonNull BaseResponse<List<Contact>> listBaseResponse) {
Log.e("getContactList", "onNext: " + listBaseResponse);
Log.e("getContactNoSave", "onNext: ");
if (listBaseResponse.code == 200) {
List<Contact> 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<List<Contact>>() {
}.getType();
List<Contact> 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<BaseResponse> mDeleteData = new MutableLiveData<>();
public void deleteContact(long id) {
NetInterfaceManager.getInstance().getMailListDeleteObservable(id)
.compose(RxLifecycle.bindUntilEvent(getLifecycle(), FragmentEvent.DESTROY))
.subscribe(new Observer<BaseResponse>() {
@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: ");
}
});
}

View File

@@ -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<ControlViewModel, PhoneFragmentControlBinding> {
public class ControlFragment extends BaseMvvmFragment<ControlViewModel, FragmentControlBinding> {
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<ControlViewModel, PhoneFra
@Override
protected int getLayoutId() {
return R.layout.phone_fragment_control;
return R.layout.fragment_control;
}
@Override

View File

@@ -11,19 +11,19 @@ import com.xxpatx.os.base.mvvm.BaseViewModel;
import com.xxpatx.os.bean.BaseResponse;
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.network.NetInterfaceManager;
import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.Disposable;
public class ControlViewModel extends BaseViewModel<PhoneFragmentControlBinding, FragmentEvent> {
public class ControlViewModel extends BaseViewModel<FragmentControlBinding, FragmentEvent> {
private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE);
@Override
public PhoneFragmentControlBinding getVDBinding() {
public FragmentControlBinding getVDBinding() {
return binding;
}

View File

@@ -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<ContactViewModel, Fragment
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(mContext);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mViewDataBinding.rvContact.setLayoutManager(linearLayoutManager);
// if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
// mViewDataBinding.rvContact.setLayoutManager(new GridLayoutManager(mContext, 3));
// } else {
// mViewDataBinding.rvContact.setLayoutManager(new GridLayoutManager(mContext, 2));
// }
mViewDataBinding.rvContact.setAdapter(mContactAdapter);
}
@@ -103,11 +97,9 @@ public class ContactFragment extends BaseMvvmFragment<ContactViewModel, Fragment
mViewModel.mContactListData.observe(this, new Observer<List<Contact>>() {
@Override
public void onChanged(List<Contact> contacts) {
// List<Contact> sim = getSIMContacts();
if (contacts != null) {
mViewDataBinding.tvPeople.setText(contacts.size() + "");
// if (sim.size() != 0) {
// contacts.addAll(sim);
// }
}
mContactAdapter.setContactList(contacts);
}
});
@@ -123,63 +115,19 @@ public class ContactFragment extends BaseMvvmFragment<ContactViewModel, Fragment
mViewModel.getContact();
}
});
mViewModel.getCacheContact();
}
@Override
public void fetchData() {
Log.e(TAG, "fetchData: ");
mViewModel.getContact();
}
@Override
public void onResume() {
super.onResume();
mViewModel.getContact();
Log.e(TAG, "onResume: ");
mViewModel.getCacheContact();
}
public static final String NAME = "name";
public static final String NUMBER = "number";
private List<Contact> getSIMContacts() {
getAll();
List<Contact> 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;

View File

@@ -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<FragmentContactBinding, Frag
public MutableLiveData<List<Contact>> mContactListData = new MutableLiveData<>();
public void getCacheContact() {
String jsonString = mMMKV.getString(UrlAddress.GET_MAIL_LIST, null);
Gson gson = new Gson();
Type type = new TypeToken<List<Contact>>() {
}.getType();
if (!TextUtils.isEmpty(jsonString)) {
List<Contact> contacts = gson.fromJson(jsonString, type);
if (contacts != null) {
mContactListData.setValue(contacts);
}
}
getContact();
}
public void getContact() {
NetInterfaceManager.getInstance()
.getContactListObservable()
.compose(RxLifecycle.bindUntilEvent(getLifecycle(), FragmentEvent.DESTROY))
.subscribe(new Observer<BaseResponse<List<Contact>>>() {
NetInterfaceManager.getInstance().getContactListObserverCache(UrlAddress.GET_MAIL_LIST, new NetInterfaceManager.ContactCallback() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e("getContactList", "onSubscribe: ");
}
@Override
public void onNext(@NonNull BaseResponse<List<Contact>> listBaseResponse) {
Log.e("getContactList", "onNext: " + listBaseResponse);
if (listBaseResponse.code == 200) {
List<Contact> contactList = listBaseResponse.data;
String oldCache = mMMKV.getString(UrlAddress.GET_MAIL_LIST, "");
if (!oldCache.equals(GsonUtils.toJSONString(contactList))) {
ContactsUtils.saveContactPhone(getCtx(), contactList);
}
public void setContact(List<Contact> 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<List<Contact>>() {
}.getType();
List<Contact> contacts = gson.fromJson(jsonString, type);
if (contacts == null) {
mContactListData.setValue(new ArrayList<>());
} else {
mContactListData.setValue(contacts);
}
onComplete();
}
@Override
public void onComplete() {
Log.e("getContactList", "onComplete: ");
}
});
NetInterfaceManager.getInstance()
.getContactListFragment(getLifecycle(), new NetInterfaceManager.ContactCallback() {
@Override
public void setContact(List<Contact> contactList) {
mContactListData.setValue(contactList);
}
@Override
public void onComplete() {
}
});
}
@@ -135,6 +93,9 @@ public class ContactViewModel extends BaseViewModel<FragmentContactBinding, Frag
@Override
public void onNext(@NonNull BaseResponse baseResponse) {
Log.e("deleteContact", "onNext: " + baseResponse);
if (baseResponse.code == 200) {
ContactsUtils.deleteRawContact(getCtx(), contact.getMobile());
}
mDeleteData.setValue(baseResponse);
}

View File

@@ -37,7 +37,7 @@ public class DialerFragment extends BaseMvvmFragment<DialerViewModel, FragmentDi
private Context mContext;
private SoundPool soundPool;
private SoundPool mSoundPool;
private HashMap<Integer, Integer> soundMap = new HashMap<>();
public DialerFragment() {
@@ -67,23 +67,23 @@ public class DialerFragment extends BaseMvvmFragment<DialerViewModel, FragmentDi
protected void initView(Bundle bundle) {
AudioAttributes attr = new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_GAME) // 设置音效使用场景
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC).build(); // 设置音效的类型
soundPool = new SoundPool.Builder().setAudioAttributes(attr) // 设置音效池的属性
mSoundPool = new SoundPool.Builder().setAudioAttributes(attr) // 设置音效池的属性
.setMaxStreams(12) // 设置最多可容纳10个音频流
.build(); // ①
// load方法加载指定音频文件并返回所加载的音效ID
// 此处使用HashMap来管理这些音频流
soundMap.put(0, soundPool.load(mContext, R.raw.s_0, 1));
soundMap.put(1, soundPool.load(mContext, R.raw.s_1, 1));
soundMap.put(2, soundPool.load(mContext, R.raw.s_2, 1));
soundMap.put(3, soundPool.load(mContext, R.raw.s_3, 1));
soundMap.put(4, soundPool.load(mContext, R.raw.s_4, 1));
soundMap.put(5, soundPool.load(mContext, R.raw.s_5, 1));
soundMap.put(6, soundPool.load(mContext, R.raw.s_6, 1));
soundMap.put(7, soundPool.load(mContext, R.raw.s_7, 1));
soundMap.put(8, soundPool.load(mContext, R.raw.s_8, 1));
soundMap.put(9, soundPool.load(mContext, R.raw.s_9, 1));
soundMap.put(10, soundPool.load(mContext, R.raw.s_x, 1));
soundMap.put(11, soundPool.load(mContext, R.raw.s_j, 1));
soundMap.put(0, mSoundPool.load(mContext, R.raw.s_0, 1));
soundMap.put(1, mSoundPool.load(mContext, R.raw.s_1, 1));
soundMap.put(2, mSoundPool.load(mContext, R.raw.s_2, 1));
soundMap.put(3, mSoundPool.load(mContext, R.raw.s_3, 1));
soundMap.put(4, mSoundPool.load(mContext, R.raw.s_4, 1));
soundMap.put(5, mSoundPool.load(mContext, R.raw.s_5, 1));
soundMap.put(6, mSoundPool.load(mContext, R.raw.s_6, 1));
soundMap.put(7, mSoundPool.load(mContext, R.raw.s_7, 1));
soundMap.put(8, mSoundPool.load(mContext, R.raw.s_8, 1));
soundMap.put(9, mSoundPool.load(mContext, R.raw.s_9, 1));
soundMap.put(10, mSoundPool.load(mContext, R.raw.s_x, 1));
soundMap.put(11, mSoundPool.load(mContext, R.raw.s_j, 1));
mViewDataBinding.etPhone.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
@@ -149,6 +149,15 @@ public class DialerFragment extends BaseMvvmFragment<DialerViewModel, FragmentDi
}
@Override
public void onDestroy() {
super.onDestroy();
if (mSoundPool != null) {
mSoundPool.release();
mSoundPool = null;
}
}
private void callNumber() {
String phone = mViewDataBinding.etPhone.getText().toString();
if (TextUtils.isEmpty(phone)) {
@@ -181,7 +190,7 @@ public class DialerFragment extends BaseMvvmFragment<DialerViewModel, FragmentDi
}
boolean dialTone = mMMKV.decodeBool(CommonConfig.DISABLE_DIAL_TONE_MODIFY, true);
if (dialTone) {
soundPool.play(soundMap.get(position), 1, 1, 0, 0, 1);
mSoundPool.play(soundMap.get(position), 1, 1, 0, 0, 1);
}
}

View File

@@ -54,7 +54,6 @@ import com.xxpatx.os.network.api.uiui.ArticleCategorysListApi;
import com.xxpatx.os.network.api.uiui.ArticleListApi;
import com.xxpatx.os.network.api.uiui.DemandListApi;
import com.xxpatx.os.network.api.uiui.GetAdminSnSettingApi;
import com.xxpatx.os.network.api.uiui.GetMailList;
import com.xxpatx.os.network.api.uiui.GetUserIDApi;
import com.xxpatx.os.network.api.uiui.GoodsListApi;
import com.xxpatx.os.network.api.uiui.GoodsTypeApi;
@@ -74,6 +73,7 @@ import com.xxpatx.os.network.api.uiui.alarmclock.AlarmClockGetApi;
import com.xxpatx.os.network.api.uiui.alarmclock.AlarmClockQueryApi;
import com.xxpatx.os.network.api.uiui.alarmclock.AlarmClockUpdateApi;
import com.xxpatx.os.network.api.uiui.app.RunNewApp;
import com.xxpatx.os.network.api.uiui.contact.GetMailList;
import com.xxpatx.os.network.api.uiui.contact.MailListAddApi;
import com.xxpatx.os.network.api.uiui.contact.MailListDeleteApi;
import com.xxpatx.os.network.api.uiui.contact.MailListEditApi;
@@ -92,10 +92,12 @@ import com.xxpatx.os.network.api.uiui.sn.SnInfoApi;
import com.xxpatx.os.network.api.uiui.sn.SosRecordApi;
import com.xxpatx.os.network.api.uiui.sn.UpdateAddressApi;
import com.xxpatx.os.network.interceptor.RepeatRequestInterceptor;
import com.xxpatx.os.utils.ContactsUtils;
import com.xxpatx.os.utils.Utils;
import java.io.File;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -121,6 +123,8 @@ import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
public class NetInterfaceManager {
private static final String TAG = "NetInterfaceManager";
@SuppressLint("StaticFieldLeak")
private static NetInterfaceManager INSTANCE;
private Context mContext;
@@ -1105,16 +1109,6 @@ public class NetInterfaceManager {
});
}
public interface ContactCallback {
void setContact(List<Contact> contactList);
void setEmergencyContact(List<Contact> emergencyContact);
void setEmpty();
void onComplete();
}
// public void getSystemSettings(boolean refresh, BehaviorSubject<ActivityEvent> 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<List<Contact>>() {
}.getType();
List<Contact> 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<Contact> contactList);
public void getContactList(boolean refresh, BehaviorSubject<ActivityEvent> 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<List<Contact>>() {
}.getType();
List<Contact> 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<ActivityEvent> lifecycle, ContactCallback callback) {
@@ -1244,16 +1216,12 @@ public class NetInterfaceManager {
.subscribe(getContactListObserver(callback));
}
public void getContactList(ContactCallback callback) {
public void getContactListFragment(BehaviorSubject<FragmentEvent> lifecycle, ContactCallback callback) {
getContactListObservable()
.compose(RxLifecycle.bindUntilEvent(lifecycle, FragmentEvent.DESTROY))
.subscribe(getContactListObserver(callback));
}
public void getContactList() {
getContactListObservable()
.subscribe(getContactListObserver(null));
}
public Observer<BaseResponse<List<Contact>>> getContactListObserver(ContactCallback callback) {
return new Observer<BaseResponse<List<Contact>>>() {
@Override
@@ -1267,25 +1235,27 @@ public class NetInterfaceManager {
if (listBaseResponse.code == 200) {
List<Contact> 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<Contact> 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<Contact> 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<List<Contact>>() {
}.getType();
try {
List<Contact> 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<ActivityEvent> lifecycle, onCompleteCallback callback) {
ConnectMode connectMode = ConnectMode.ONE_MINUTE;
if (refresh) {

View File

@@ -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";
/*添加联系人*/

View File

@@ -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;

View File

@@ -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);

View File

@@ -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.498.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<AccessibilityNodeInfo> findNodesByViewId(String id) {
List<AccessibilityNodeInfo> 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();
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<AccessibilityWindowInfo> 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 {
}
//实现对xy坐标进行点击操作。
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,

View File

@@ -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<Integer>() {
@Override
public void subscribe(@NonNull ObservableEmitter<Integer> 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<Integer>() {
@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)) {
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) {

View File

@@ -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");

View File

@@ -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<Contact> contactList) {
Log.e(TAG, "saveContactPhone: ");
// List<ContactId> contactIdList = ContactsUtils.getLocalContacts(context);
public static void saveContactPhone(Context context, Contact contact) {
Observable.create(new ObservableOnSubscribe<Long>() {
@Override
public void subscribe(@NonNull ObservableEmitter<Long> 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<Bitmap>() {
@Override
public void onResourceReady(@androidx.annotation.NonNull Bitmap resource, @Nullable Transition<? super Bitmap> 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<Bitmap>() {
@Override
public void onResourceReady(@androidx.annotation.NonNull Bitmap resource, @Nullable Transition<? super Bitmap> 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<Long>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
@@ -141,6 +86,313 @@ public class ContactsUtils {
});
}
public static void saveContactPhone(Context context, List<Contact> contactList) {
Log.e(TAG, "saveContactPhone: ");
// List<ContactId> contactIdList = ContactsUtils.getLocalContacts(context);
Observable.create(new ObservableOnSubscribe<Long>() {
@Override
public void subscribe(@NonNull ObservableEmitter<Long> 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<Long>() {
@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<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
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<Long>() {
@Override
public void subscribe(@NonNull ObservableEmitter<Long> emitter) throws Throwable {
deleteRawContact(context, contact.getMobile());
emitter.onNext(0L);
}
})
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.newThread())
.subscribe(new Observer<Long>() {
@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<ContactId> getLocalContacts(Context context) {
ContentResolver resolver = context.getContentResolver();
Uri uri = ContactsContract.Contacts.CONTENT_URI;

View File

@@ -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();
}
}
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());
}
/**

View File

@@ -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);
}
}

View File

@@ -66,7 +66,7 @@ public class Utils {
Log.e("e", "读取设备序列号异常:" + e.toString());
}
if (BuildConfig.DEBUG) {
// return "QNG2DKB00463";
// return "TYZ185P5250101467";
}
return serial;
}

View File

@@ -34,7 +34,7 @@ public class ToggleButton extends View {
/**
* 关闭颜色
*/
private int offBorderColor = Color.parseColor("#f62626");
private int offBorderColor = Color.parseColor("#626E82");
/**
* 灰色带颜色
*/

View File

@@ -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"

View File

@@ -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 @@
<com.xxpatx.os.view.ToggleButton
android:id="@+id/toggleButton"
android:layout_width="37dp"
android:layout_height="20dp"
android:layout_width="48dp"
android:layout_height="24dp"
android:layout_marginEnd="32dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_margin="8dp"
android:background="@drawable/add_wechat_contact_background">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:text="在快捷联系人显示"
android:textColor="@color/black"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.xxpatx.os.view.ToggleButton
android:id="@+id/tb_show"
android:layout_width="48dp"
android:layout_height="24dp"
app:tbAsDefaultOn="true"
android:layout_marginEnd="32dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
@@ -316,7 +347,6 @@
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="60dp"

View File

@@ -73,8 +73,6 @@
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@+id/constraintLayout3">
@@ -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 @@
<com.xxpatx.os.view.ToggleButton
android:id="@+id/toggleButton"
android:layout_width="37dp"
android:layout_height="20dp"
android:layout_width="44dp"
android:layout_height="22dp"
android:layout_marginEnd="32dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_margin="8dp"
android:background="@drawable/add_wechat_contact_background">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:text="在快捷联系人显示"
android:textColor="@color/black"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.xxpatx.os.view.ToggleButton
android:id="@+id/tb_show"
android:layout_width="44dp"
android:layout_height="22dp"
android:layout_marginEnd="32dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
@@ -314,6 +342,7 @@
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
</ScrollView>
<androidx.constraintlayout.widget.ConstraintLayout

View File

@@ -24,182 +24,15 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_weather"
android:layout_width="330dp"
android:layout_height="165dp"
android:onClick="@{click::toWeather}"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:maxLines="1"
android:textColor="@color/white"
android:textSize="44sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="00:00" />
<TextView
android:id="@+id/tv_data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_marginTop="8dp"
android:maxLines="1"
android:textColor="@color/white"
android:textSize="18sp"
app:layout_constraintStart_toStartOf="@+id/tv_time"
app:layout_constraintTop_toBottomOf="@+id/tv_time"
tools:text="20230621" />
<TextView
android:id="@+id/tv_week"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:maxLines="1"
android:textColor="@color/white"
android:textSize="18sp"
app:layout_constraintStart_toStartOf="@+id/tv_data"
app:layout_constraintTop_toBottomOf="@+id/tv_data"
tools:text="20230621" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraintLayout26"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/tv_temp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="--℃"
android:textColor="@color/white"
android:textSize="40sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="0℃" />
<TextView
android:id="@+id/tv_weather"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="--"
android:textColor="@color/white"
android:textSize="18sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_temp"
tools:text="天气" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_weather">
<ImageView
android:id="@+id/imageView11"
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/home_icon_location"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_location"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:text="--"
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="位置" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_contact"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/cl_weather" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_nodata"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="12dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/cl_weather">
<TextView
android:id="@+id/tv_no_contact"
android:layout_width="match_parent"
android:layout_height="64dp"
android:layout_marginStart="32dp"
android:layout_marginEnd="32dp"
android:gravity="center"
android:text="暂无联系人"
android:textColor="@color/white"
android:textSize="20sp"
app:layout_constraintBottom_toTopOf="@+id/tv_add"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_add"
android:layout_width="match_parent"
android:layout_height="64dp"
android:layout_marginStart="32dp"
android:layout_marginEnd="32dp"
android:background="@drawable/fragment_add_contact_background"
android:gravity="center"
android:onClick="@{click::toAdd}"
android:text="添加联系人"
android:textColor="@color/white"
android:textSize="16sp"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -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="城市" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -83,16 +83,15 @@
<ImageView
android:id="@+id/iv_clear"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginEnd="8dp"
android:layout_width="26dp"
android:layout_height="26dp"
android:layout_marginEnd="16dp"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:src="@drawable/icon_menu"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.322" />
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,16 +0,0 @@
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/settings"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@@ -1,7 +1,7 @@
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityEventTypes="typeAllMask"
android:accessibilityFeedbackType="feedbackSpoken"
android:accessibilityFlags="flagIncludeNotImportantViews"
android:accessibilityEventTypes="typeAllMask|typeViewClicked|typeViewFocused|typeWindowStateChanged|typeWindowsChanged|typeContextClicked|typeWindowContentChanged"
android:accessibilityFeedbackType="feedbackAllMask|feedbackGeneric|feedbackSpoken"
android:accessibilityFlags="flagDefault|flagRetrieveInteractiveWindows|flagIncludeNotImportantViews"
android:canPerformGestures="true"
android:canRetrieveWindowContent="true"
android:description="@string/accessibility_service_description"