version:1.3.4

fix:修复闪退
update:优化联系人添加
This commit is contained in:
2024-10-23 09:19:18 +08:00
parent b5b12c3e83
commit d215329e28
74 changed files with 2251 additions and 1138 deletions

View File

@@ -15,8 +15,8 @@ android {
applicationId "com.xxpatx.os"
minSdkVersion 24
targetSdkVersion 29
versionCode 1030
versionName "1.2.9"
versionCode 1035
versionName "1.3.4"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -72,6 +72,7 @@ android {
buildTypes {
debug {
buildConfigField "String", "platform", '"MTK01"'
versionNameSuffix "-debug"
//Zipalign优化
zipAlignEnabled true
@@ -93,6 +94,7 @@ android {
}
release {
buildConfigField "String", "platform", '"MTK01"'
//Zipalign优化
zipAlignEnabled true
shrinkResources true
@@ -164,6 +166,11 @@ dependencies {
//Gson
implementation 'com.google.code.gson:gson:2.9.0'
implementation 'com.google.zxing:core:3.5.0'
//libphonenumber
implementation 'com.googlecode.libphonenumber:libphonenumber:8.13.47'
implementation 'com.googlecode.libphonenumber:carrier:1.230'
implementation 'com.googlecode.libphonenumber:geocoder:2.241'
implementation 'com.googlecode.libphonenumber:prefixmapper:2.241'
//生命周期管理
implementation 'com.trello.rxlifecycle4:rxlifecycle:4.0.2'
implementation 'com.trello.rxlifecycle4:rxlifecycle-android:4.0.2'

View File

@@ -155,7 +155,11 @@
android:launchMode="singleTask"
android:screenOrientation="portrait" />
<activity
android:name=".activity.contact.ContactActivity"
android:name=".activity.sim.SimCardActivity"
android:launchMode="singleTask"
android:screenOrientation="portrait" />
<activity
android:name=".activity.contact.ContactListActivity"
android:launchMode="singleTask"
android:theme="@style/AppTheme"
android:screenOrientation="portrait" />
@@ -167,10 +171,6 @@
android:name=".activity.setting.TouchActivity"
android:launchMode="singleTask"
android:screenOrientation="portrait" />
<activity
android:name=".activity.contact.AddContactActivity"
android:launchMode="singleTask"
android:screenOrientation="portrait" />
<activity
android:name=".activity.contact.EditContactActivity"
android:launchMode="singleTask"
@@ -252,7 +252,7 @@
android:launchMode="singleTask"
android:screenOrientation="portrait" />
<activity
android:name=".activity.contact.AddWechatContactActivity"
android:name=".activity.contact.AddContactActivity"
android:launchMode="singleTask"
android:theme="@style/AppTheme"
android:screenOrientation="portrait" />

View File

@@ -121,7 +121,7 @@ public class AlarmListActivity extends BaseMvvmActivity<AlarmListViewModel, Acti
@Override
public void initData() {
registerAlarmClockReceiver();
mViewModel.getAlarmClockData().observe(this, new androidx.lifecycle.Observer<List<AlarmClockData>>() {
mViewModel.mAlarmClockData.observe(this, new androidx.lifecycle.Observer<List<AlarmClockData>>() {
@Override
public void onChanged(List<AlarmClockData> alarmClockData) {
setAlarmClock(alarmClockData);

View File

@@ -32,11 +32,7 @@ public class AlarmListViewModel extends BaseViewModel<ActivityAlarmListBinding,
}
private MutableLiveData<List<AlarmClockData>> mAlarmClockData = new MutableLiveData<>();
public MutableLiveData<List<AlarmClockData>> getAlarmClockData() {
return mAlarmClockData;
}
public MutableLiveData<List<AlarmClockData>> mAlarmClockData = new MutableLiveData<>();
public void getAlarmClock() {
NetInterfaceManager.getInstance().getAlarmClock(getLifecycle(), new NetInterfaceManager.AlarmClockCallback() {

View File

@@ -1,46 +1,57 @@
package com.xxpatx.os.activity.contact;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.graphics.Bitmap;
import android.net.Uri;
import android.provider.ContactsContract;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import androidx.annotation.Nullable;
import androidx.lifecycle.Observer;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.transition.Transition;
import com.hjq.toast.Toaster;
import com.luck.picture.lib.basic.PictureSelector;
import com.luck.picture.lib.config.SelectMimeType;
import com.luck.picture.lib.entity.LocalMedia;
import com.luck.picture.lib.interfaces.OnResultCallbackListener;
import com.trello.rxlifecycle4.RxLifecycle;
import com.trello.rxlifecycle4.android.ActivityEvent;
import com.tencent.mmkv.MMKV;
import com.xiasuhuei321.loadingdialog.view.LoadingDialog;
import com.xxpatx.os.R;
import com.xxpatx.os.base.mvvm.BaseMvvmActivity;
import com.xxpatx.os.bean.BaseResponse;
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.network.NetInterfaceManager;
import com.xxpatx.os.utils.FileUtil;
import com.xxpatx.os.utils.GlideLoadUtils;
import com.xxpatx.os.utils.Utils;
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.zackratos.ultimatebarx.ultimatebarx.java.UltimateBarX;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.Disposable;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import java.util.concurrent.ThreadLocalRandom;
public class AddContactActivity extends BaseMvvmActivity<AddContactViewModel, ActivityAddContactBinding> {
private static final String TAG = "AddContactActivity";
private String avatarFilePath;
private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE);
private LoadingDialog mLoadingDialog;
// public String avatarFilePath = "";
@Override
public boolean setfitWindow() {
public boolean setNightMode() {
return true;
}
@@ -52,113 +63,229 @@ public class AddContactActivity extends BaseMvvmActivity<AddContactViewModel, Ac
@Override
protected void initDataBinding() {
mViewModel.setCtx(this);
mViewModel.setLifecycle(getLifecycleSubject());
mViewModel.setVDBinding(mViewDataBinding);
mViewModel.setLifecycle(getLifecycleSubject());
mViewDataBinding.setClick(new BtnClick());
}
@Override
public void initView() {
protected void initView() {
UltimateBarX.addStatusBarTopPadding(mViewDataBinding.clExit);
UltimateBarX.addNavigationBarBottomPadding(mViewDataBinding.clBottom);
mLoadingDialog = new LoadingDialog(this);
mLoadingDialog.setLoadingText("正在上传")
.setSuccessText("添加成功")
.setFailedText("添加失败")
.setInterceptBack(true)
.setLoadSpeed(LoadingDialog.Speed.SPEED_TWO)
.closeSuccessAnim()
.closeFailedAnim();
}
@Override
public void initData() {
protected void initData() {
mViewModel.mAddData.observe(this, new Observer<Boolean>() {
@Override
public void onChanged(Boolean aBoolean) {
if (aBoolean) {
mLoadingDialog.loadSuccess();
finish();
} else {
mLoadingDialog.loadFailed();
}
}
});
mViewModel.mContactData.observe(this, new Observer<Contact>() {
@Override
public void onChanged(Contact contact) {
ContactCacheUtils.getInstance().addContact(contact);
Toaster.showLong("已保存至本地");
finish();
}
});
}
private void selectPicture() {
PictureSelector.create(this)
.openGallery(SelectMimeType.ofImage())
@Override
protected void onDestroy() {
super.onDestroy();
mLoadingDialog.close();
mLoadingDialog = null;
}
@Override
protected void onPause() {
super.onPause();
}
private void openSelector() {
PictureSelector.create(AddContactActivity.this)
.openGallery(SelectMimeType.ofAll())
.setSelectionMode(1)
.setImageEngine(GlideEngine.createGlideEngine())
.forResult(new OnResultCallbackListener<LocalMedia>() {
@Override
public void onResult(ArrayList<LocalMedia> result) {
avatarFilePath = result.get(0).getPath();
Log.e("selectPicture", "onResult: " + avatarFilePath);
GlideLoadUtils.getInstance().glideLoad(AddContactActivity.this, avatarFilePath, mViewDataBinding.nvAvatar, R.drawable.default_avatar);
}
@Override
public void onCancel() {
}
});
}
private void checkContact() {
String name = mViewDataBinding.etName.getText().toString();
if (TextUtils.isEmpty(name)) {
Toaster.show("请输入联系人姓名");
return;
}
String phone = mViewDataBinding.etPhone.getText().toString();
if (TextUtils.isEmpty(phone)) {
Toaster.show("请输入手机号码");
return;
}
File avatarFile;
Log.e("checkContact", "avatarFilePath: " + avatarFilePath);
if (TextUtils.isEmpty(avatarFilePath)) {
avatarFile = FileUtil.drawableToFile(AddContactActivity.this, R.drawable.default_avatar, "avatar");
} else {
Uri uri = Uri.parse(avatarFilePath);
avatarFile = FileUtil.uriToFile(uri, AddContactActivity.this);
}
MediaType mediaType = MediaType.Companion.parse("image/png");
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("is_urgent", String.valueOf(mViewDataBinding.toggleButton.isToggleOn()));
NetInterfaceManager.getInstance()
.getMailListAddObservable(params, body)
.compose(RxLifecycle.bindUntilEvent(getLifecycleSubject(), ActivityEvent.DESTROY))
.subscribe(new Observer<BaseResponse>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e("checkContact", "onSubscribe: ");
}
@Override
public void onNext(@NonNull BaseResponse baseResponse) {
Log.e("checkContact", "onNext: " + baseResponse);
if (baseResponse.code == 200) {
Toaster.show("已添加");
finish();
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)));
Glide.with(mViewDataBinding.nvAvatar).load(file).apply(options).into(mViewDataBinding.nvAvatar);
} else {
Toaster.show(baseResponse.msg);
mViewModel.avatarFilePath = "";
}
}
@Override
public void onError(@NonNull Throwable e) {
Log.e("checkContact", "onError: " + e.getMessage());
}
@Override
public void onComplete() {
Log.e("checkContact", "onComplete: ");
public void onCancel() {
Log.e(TAG, "onCancel: ");
}
});
}
public void testAddContacts() {
//插入raw_contacts表并获取_id属性
Uri uri = Uri.parse("content://icc/adn");
ContentResolver resolver = getContentResolver();
ContentValues values = new ContentValues();
long contact_id = ContentUris.parseId(resolver.insert(uri, values));
//插入data表
uri = Uri.parse("content://com.android.contacts/data");
//add Name
values.put("raw_contact_id", contact_id);
values.put(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/name");
values.put("data2", "zdong");
values.put("data1", "xzdong");
resolver.insert(uri, values);
values.clear();
//add Phone
values.put("raw_contact_id", contact_id);
values.put(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/phone_v2");
values.put("data2", "2"); //手机
values.put("data1", "87654321");
resolver.insert(uri, values);
values.clear();
//add email
values.put("raw_contact_id", contact_id);
values.put(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/email_v2");
values.put("data2", "2"); //单位
values.put("data1", "xzdong@xzdong.com");
resolver.insert(uri, values);
}
private void addLocalContact() {
Contact contact = new Contact();
ThreadLocalRandom random = ThreadLocalRandom.current();
int fakeId = random.nextInt(Integer.MAX_VALUE);
Log.e(TAG, "addLocalContact: fakeId = " + fakeId);
contact.setId(fakeId);
contact.setMobile(mViewDataBinding.etPhone.getText().toString());
contact.setName(mViewDataBinding.etName.getText().toString());
contact.setTag(mViewDataBinding.etTag.getText().toString());
contact.setIs_urgent(mViewDataBinding.toggleButton.isToggleOn());
contact.setAvatar(mViewModel.avatarFilePath);
LocalContactUtils.addLocalContact(contact);
if (ContactsUtils.isExist(AddContactActivity.this, contact.getMobile())) {
long rawContactId = ContactsUtils.getContactId(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) {
ContentResolver resolver = AddContactActivity.this.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});
}
});
} else {
ContentValues values = new ContentValues();
long rawContactId = ContentUris.parseId(AddContactActivity.this.getContentResolver().insert(ContactsContract.RawContacts.CONTENT_URI, values));
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) {
ContentResolver resolver = AddContactActivity.this.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);
}
});
}
}
public void createContact(String name, String phoneNumber) {
Uri simUri = Uri.parse("content://icc/adn");
ContentValues values = new ContentValues();
values.put("tag", name);
values.put("number", phoneNumber);
getContentResolver().insert(simUri, values);
finish();
}
public class BtnClick {
public void selectPic(View view) {
openSelector();
}
public void exit(View view) {
finish();
}
public void selectPic(View v) {
selectPicture();
}
public void confirm(View v) {
checkContact();
public void addContact(View view) {
String name = mViewDataBinding.etName.getText().toString();
if (TextUtils.isEmpty(name)) {
Toaster.show("请输入联系人姓名");
return;
}
String phone = mViewDataBinding.etPhone.getText().toString();
if (TextUtils.isEmpty(phone)) {
Toaster.show("请输入手机号码");
return;
}
if (mViewDataBinding.tbSim.isToggleOn() == 1) {
createContact(name, phone);
} else {
Log.e("checkContact", "avatarFilePath: " + mViewModel.avatarFilePath);
mLoadingDialog.setLoadingText("正在上传");
mLoadingDialog.show();
// addLocalContact();
mViewModel.checkContact();
}
}
}
}

View File

@@ -1,10 +1,37 @@
package com.xxpatx.os.activity.contact;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
import androidx.lifecycle.MutableLiveData;
import com.hjq.toast.Toaster;
import com.trello.rxlifecycle4.RxLifecycle;
import com.trello.rxlifecycle4.android.ActivityEvent;
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.network.NetInterfaceManager;
import com.xxpatx.os.utils.FileUtil;
import com.xxpatx.os.utils.Utils;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;
import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.Disposable;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
public class AddContactViewModel extends BaseViewModel<ActivityAddContactBinding, ActivityEvent> {
private static final String TAG = "AddContactViewModel";
@Override
public ActivityAddContactBinding getVDBinding() {
@@ -15,4 +42,93 @@ public class AddContactViewModel extends BaseViewModel<ActivityAddContactBinding
public void onDestroy() {
}
public String avatarFilePath = "";
public MutableLiveData<Boolean> mAddData = new MutableLiveData<>();
public MutableLiveData<Contact> mContactData = new MutableLiveData<>();
public void checkContact() {
String name = binding.etName.getText().toString();
String phone = binding.etPhone.getText().toString();
String tag = binding.etTag.getText().toString();
File avatarFile;
Log.e("checkContact", "avatarFilePath: " + avatarFilePath);
if (TextUtils.isEmpty(avatarFilePath)) {
avatarFile = FileUtil.drawableToFile(getCtx(), R.drawable.default_avatar, "avatar");
} else {
Uri uri = Uri.parse(avatarFilePath);
avatarFile = FileUtil.uriToFile(uri, getCtx());
}
if (avatarFile == null) {
Toaster.showShort("图片加载失败");
return;
}
MediaType mediaType = MediaType.Companion.parse("image/png");
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()));
NetInterfaceManager.getInstance()
.getMailListAddObservable(params, body)
.compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY))
.subscribe(new Observer<BaseResponse>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e("checkContact", "onSubscribe: ");
}
@Override
public void onNext(@NonNull BaseResponse baseResponse) {
Log.e("checkContact", "onNext: " + baseResponse);
if (baseResponse.code == 200) {
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);
}
}
@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);
}
@Override
public void onComplete() {
Log.e("checkContact", "onComplete: ");
}
});
}
}

View File

@@ -1,209 +0,0 @@
package com.xxpatx.os.activity.contact;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.net.Uri;
import android.provider.ContactsContract;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import androidx.lifecycle.Observer;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
import com.bumptech.glide.request.RequestOptions;
import com.hjq.toast.Toaster;
import com.luck.picture.lib.basic.PictureSelector;
import com.luck.picture.lib.config.SelectMimeType;
import com.luck.picture.lib.entity.LocalMedia;
import com.luck.picture.lib.interfaces.OnResultCallbackListener;
import com.xiasuhuei321.loadingdialog.view.LoadingDialog;
import com.xxpatx.os.R;
import com.xxpatx.os.base.mvvm.BaseMvvmActivity;
import com.xxpatx.os.bean.Contact;
import com.xxpatx.os.custom.GlideEngine;
import com.xxpatx.os.databinding.ActivityAddWechatContactBinding;
import com.xxpatx.os.db.ContactCacheUtils;
import com.xxpatx.os.utils.ScreenUtil;
import com.zackratos.ultimatebarx.ultimatebarx.java.UltimateBarX;
import java.io.File;
import java.util.ArrayList;
public class AddWechatContactActivity extends BaseMvvmActivity<AddWechatContactViewModel, ActivityAddWechatContactBinding> {
private static final String TAG = "AddWechatContactActivity";
private LoadingDialog mLoadingDialog;
// private String mPictrueFilePath;
@Override
public boolean setNightMode() {
return true;
}
// @Override
// public boolean setfitWindow() {
// return true;
// }
@Override
protected int getLayoutId() {
return R.layout.activity_add_wechat_contact;
}
@Override
protected void initDataBinding() {
mViewModel.setCtx(this);
mViewModel.setVDBinding(mViewDataBinding);
mViewModel.setLifecycle(getLifecycleSubject());
mViewDataBinding.setClick(new BtnClick());
}
@Override
protected void initView() {
UltimateBarX.addStatusBarTopPadding(mViewDataBinding.clExit);
UltimateBarX.addNavigationBarBottomPadding(mViewDataBinding.clBottom);
mLoadingDialog = new LoadingDialog(this);
mLoadingDialog.setLoadingText("正在上传")
.setSuccessText("添加成功")
.setFailedText("添加失败")
.setInterceptBack(true)
.setLoadSpeed(LoadingDialog.Speed.SPEED_TWO)
.closeSuccessAnim()
.closeFailedAnim();
}
@Override
protected void initData() {
mViewModel.getAddData().observe(this, new Observer<Boolean>() {
@Override
public void onChanged(Boolean aBoolean) {
if (aBoolean) {
mLoadingDialog.loadSuccess();
finish();
} else {
mLoadingDialog.loadFailed();
}
}
});
mViewModel.getContactData().observe(this, new Observer<Contact>() {
@Override
public void onChanged(Contact contact) {
ContactCacheUtils.getInstance().addContact(contact);
Toaster.showLong("已保存至本地");
finish();
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
mLoadingDialog.close();
mLoadingDialog = null;
}
@Override
protected void onPause() {
super.onPause();
}
private void openSelector() {
PictureSelector.create(AddWechatContactActivity.this)
.openGallery(SelectMimeType.ofAll())
.setSelectionMode(1)
.setImageEngine(GlideEngine.createGlideEngine())
.forResult(new OnResultCallbackListener<LocalMedia>() {
@Override
public void onResult(ArrayList<LocalMedia> result) {
mViewModel.avatarFilePath = result.get(0).getRealPath();
File file = new File(mViewModel.avatarFilePath);
if (file.exists()) {
RequestOptions options = new RequestOptions().transform(new RoundedCorners(ScreenUtil.dip2px(AddWechatContactActivity.this, 8F)));
Glide.with(mViewDataBinding.nvAvatar).load(file).apply(options).into(mViewDataBinding.nvAvatar);
} else {
mViewModel.avatarFilePath = "";
}
}
@Override
public void onCancel() {
Log.e(TAG, "onCancel: ");
}
});
}
public void testAddContacts() {
//插入raw_contacts表并获取_id属性
Uri uri = Uri.parse("content://icc/adn");
ContentResolver resolver = getContentResolver();
ContentValues values = new ContentValues();
long contact_id = ContentUris.parseId(resolver.insert(uri, values));
//插入data表
uri = Uri.parse("content://com.android.contacts/data");
//add Name
values.put("raw_contact_id", contact_id);
values.put(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/name");
values.put("data2", "zdong");
values.put("data1", "xzdong");
resolver.insert(uri, values);
values.clear();
//add Phone
values.put("raw_contact_id", contact_id);
values.put(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/phone_v2");
values.put("data2", "2"); //手机
values.put("data1", "87654321");
resolver.insert(uri, values);
values.clear();
//add email
values.put("raw_contact_id", contact_id);
values.put(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/email_v2");
values.put("data2", "2"); //单位
values.put("data1", "xzdong@xzdong.com");
resolver.insert(uri, values);
}
public void createContact(String name, String phoneNumber) {
Uri simUri = Uri.parse("content://icc/adn");
ContentValues values = new ContentValues();
values.put("tag", name);
values.put("number", phoneNumber);
getContentResolver().insert(simUri, values);
finish();
}
public class BtnClick {
public void selectPic(View view) {
openSelector();
}
public void exit(View view) {
finish();
}
public void addContact(View view) {
String name = mViewDataBinding.etName.getText().toString();
if (TextUtils.isEmpty(name)) {
Toaster.show("请输入联系人姓名");
return;
}
String phone = mViewDataBinding.etPhone.getText().toString();
if (TextUtils.isEmpty(phone)) {
Toaster.show("请输入手机号码");
return;
}
if (mViewDataBinding.tbSim.isToggleOn() == 1) {
createContact(name, phone);
} else {
Log.e("checkContact", "avatarFilePath: " + mViewModel.avatarFilePath);
mLoadingDialog.setLoadingText("正在上传");
mLoadingDialog.show();
mViewModel.checkContact();
}
}
}
}

View File

@@ -1,144 +0,0 @@
package com.xxpatx.os.activity.contact;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
import androidx.lifecycle.MutableLiveData;
import com.hjq.toast.Toaster;
import com.trello.rxlifecycle4.RxLifecycle;
import com.trello.rxlifecycle4.android.ActivityEvent;
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.ActivityAddWechatContactBinding;
import com.xxpatx.os.network.NetInterfaceManager;
import com.xxpatx.os.utils.FileUtil;
import com.xxpatx.os.utils.Utils;
import java.io.File;
import java.io.FileOutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;
import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.Disposable;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
public class AddWechatContactViewModel extends BaseViewModel<ActivityAddWechatContactBinding, ActivityEvent> {
private static final String TAG = "AddWechatContactViewModel";
@Override
public ActivityAddWechatContactBinding getVDBinding() {
return binding;
}
@Override
public void onDestroy() {
}
public String avatarFilePath = "";
private MutableLiveData<Boolean> mAddData = new MutableLiveData<>();
public MutableLiveData<Boolean> getAddData() {
return mAddData;
}
private MutableLiveData<Contact> mContactData = new MutableLiveData<>();
public MutableLiveData<Contact> getContactData() {
return mContactData;
}
public void checkContact() {
String name = binding.etName.getText().toString();
String phone = binding.etPhone.getText().toString();
String tag = binding.etTag.getText().toString();
File avatarFile;
Log.e("checkContact", "avatarFilePath: " + avatarFilePath);
if (TextUtils.isEmpty(avatarFilePath)) {
avatarFile = FileUtil.drawableToFile(getCtx(), R.drawable.default_avatar, "avatar");
} else {
Uri uri = Uri.parse(avatarFilePath);
avatarFile = FileUtil.uriToFile(uri, getCtx());
}
if (avatarFile == null) {
Toaster.showShort("图片加载失败");
return;
}
MediaType mediaType = MediaType.Companion.parse("image/png");
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()));
NetInterfaceManager.getInstance()
.getMailListAddObservable(params, body)
.compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY))
.subscribe(new Observer<BaseResponse>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e("checkContact", "onSubscribe: ");
}
@Override
public void onNext(@NonNull BaseResponse baseResponse) {
Log.e("checkContact", "onNext: " + baseResponse);
if (baseResponse.code == 200) {
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);
}
}
@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);
}
@Override
public void onComplete() {
Log.e("checkContact", "onComplete: ");
}
});
}
}

View File

@@ -21,15 +21,15 @@ import com.xxpatx.os.base.mvvm.BaseMvvmActivity;
import com.xxpatx.os.bean.BaseResponse;
import com.xxpatx.os.bean.Contact;
import com.xxpatx.os.config.CommonConfig;
import com.xxpatx.os.databinding.ActivityContactBinding;
import com.xxpatx.os.databinding.ActivityContactListBinding;
import com.xxpatx.os.dialog.EditContactDialog;
import com.zackratos.ultimatebarx.ultimatebarx.java.UltimateBarX;
import java.util.ArrayList;
import java.util.List;
public class ContactActivity extends BaseMvvmActivity<ContactViewModel, ActivityContactBinding> {
private static final String TAG = "ContactActivity";
public class ContactListActivity extends BaseMvvmActivity<ContactListViewModel, ActivityContactListBinding> {
private static final String TAG = "ContactListActivity";
private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE);
@@ -37,7 +37,7 @@ public class ContactActivity extends BaseMvvmActivity<ContactViewModel, Activity
@Override
protected int getLayoutId() {
return R.layout.activity_contact;
return R.layout.activity_contact_list;
}
@Override
@@ -69,7 +69,7 @@ public class ContactActivity extends BaseMvvmActivity<ContactViewModel, Activity
}
}
});
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(ContactActivity.this);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(ContactListActivity.this);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mViewDataBinding.rvContact.setLayoutManager(linearLayoutManager);
// if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
@@ -163,7 +163,7 @@ public class ContactActivity extends BaseMvvmActivity<ContactViewModel, Activity
private void showDialog(Contact contact) {
if (mEditContactDialog == null) {
mEditContactDialog = new EditContactDialog(ContactActivity.this);
mEditContactDialog = new EditContactDialog(ContactListActivity.this);
}
if (contact.isSimContact()) {
mEditContactDialog.setHideDelete(true);
@@ -175,7 +175,7 @@ public class ContactActivity extends BaseMvvmActivity<ContactViewModel, Activity
.setOnClickBottomListener(new EditContactDialog.OnClickBottomListener() {
@Override
public void onEditClick() {
Intent intent = new Intent(ContactActivity.this, EditContactActivity.class);
Intent intent = new Intent(ContactListActivity.this, EditContactActivity.class);
intent.putExtra("Contact", contact);
startActivity(intent);
mEditContactDialog.dismiss();
@@ -211,7 +211,7 @@ public class ContactActivity extends BaseMvvmActivity<ContactViewModel, Activity
if (disableModify) {
Toaster.showLong("已禁用联系人修改");
} else {
Intent intent = new Intent(ContactActivity.this, AddWechatContactActivity.class);
Intent intent = new Intent(ContactListActivity.this, AddContactActivity.class);
startActivity(intent);
}
}

View File

@@ -14,7 +14,7 @@ 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.ActivityContactBinding;
import com.xxpatx.os.databinding.ActivityContactListBinding;
import com.xxpatx.os.gson.GsonUtils;
import com.xxpatx.os.network.NetInterfaceManager;
import com.xxpatx.os.network.UrlAddress;
@@ -27,12 +27,12 @@ import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.Disposable;
public class ContactViewModel extends BaseViewModel<ActivityContactBinding, ActivityEvent> {
private static final String TAG = "ContactViewModel";
public class ContactListViewModel extends BaseViewModel<ActivityContactListBinding, ActivityEvent> {
private static final String TAG = "ContactListViewModel";
private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE);
@Override
public ActivityContactBinding getVDBinding() {
public ActivityContactListBinding getVDBinding() {
return binding;
}

View File

@@ -80,7 +80,7 @@ public class EditContactActivity extends BaseMvvmActivity<EditContactViewModel,
@Override
protected void initData() {
mViewModel.getBaseResponseMutableLiveData().observe(this, new Observer<BaseResponse>() {
mViewModel.mBaseResponseMutableLiveData.observe(this, new Observer<BaseResponse>() {
@Override
public void onChanged(BaseResponse baseResponse) {
if (baseResponse.code == 200) {

View File

@@ -30,11 +30,7 @@ public class EditContactViewModel extends BaseViewModel<ActivityEditContactBindi
}
private MutableLiveData<BaseResponse> mBaseResponseMutableLiveData = new MutableLiveData<>();
public MutableLiveData<BaseResponse> getBaseResponseMutableLiveData() {
return mBaseResponseMutableLiveData;
}
public MutableLiveData<BaseResponse> mBaseResponseMutableLiveData = new MutableLiveData<>();
public void editContact(Map<String, String> params, MultipartBody.Part body) {
NetInterfaceManager.getInstance()

View File

@@ -76,7 +76,7 @@ public class DockActivity extends BaseMvvmActivity<DockViewModel, ActivityDockBi
@Override
protected void initData() {
mViewModel.getAppSelectBeanListData().observe(this, new Observer<List<DockApp>>() {
mViewModel.mAppSelectBeanListData.observe(this, new Observer<List<DockApp>>() {
@Override
public void onChanged(List<DockApp> dockApps) {
mDockAppSelectedAdapter.setDockAppList(dockApps);

View File

@@ -28,11 +28,7 @@ public class DockViewModel extends BaseViewModel<ActivityDockBinding, ActivityDo
}
private MutableLiveData<List<DockApp>> mAppSelectBeanListData = new MutableLiveData<>();
public MutableLiveData<List<DockApp>> getAppSelectBeanListData() {
return mAppSelectBeanListData;
}
public MutableLiveData<List<DockApp>> mAppSelectBeanListData = new MutableLiveData<>();
public void getPackageList() {
PackageManager pm = getCtx().getPackageManager();

View File

@@ -1,10 +1,7 @@
package com.xxpatx.os.activity.emergency;
import android.content.ComponentName;
import android.content.Intent;
import android.net.Uri;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
@@ -23,7 +20,6 @@ import com.xxpatx.os.config.CommonConfig;
import com.xxpatx.os.databinding.ActivityEmergencyBinding;
import com.xxpatx.os.manager.AmapManager;
import com.xxpatx.os.network.NetInterfaceManager;
import com.xxpatx.os.receiver.BootReceiver;
import java.util.List;
import java.util.concurrent.TimeUnit;
@@ -156,7 +152,7 @@ public class EmergencyActivity extends BaseMvvmActivity<EmergencyViewModel, Acti
@Override
protected void initData() {
mViewModel.getContactListData().observe(this, new androidx.lifecycle.Observer<List<Contact>>() {
mViewModel.mContactListData.observe(this, new androidx.lifecycle.Observer<List<Contact>>() {
@Override
public void onChanged(List<Contact> contacts) {
phoneList = contacts;

View File

@@ -10,7 +10,6 @@ import com.google.gson.reflect.TypeToken;
import com.tencent.mmkv.MMKV;
import com.trello.rxlifecycle4.RxLifecycle;
import com.trello.rxlifecycle4.android.ActivityEvent;
import com.trello.rxlifecycle4.android.FragmentEvent;
import com.xxpatx.os.base.mvvm.BaseViewModel;
import com.xxpatx.os.bean.BaseResponse;
import com.xxpatx.os.bean.Contact;
@@ -18,7 +17,6 @@ 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 com.xxpatx.os.network.UrlAddress;
import java.lang.reflect.Type;
import java.util.ArrayList;
@@ -44,11 +42,7 @@ public class EmergencyViewModel extends BaseViewModel<ActivityEmergencyBinding,
}
private MutableLiveData<List<Contact>> mContactListData = new MutableLiveData<>();
public MutableLiveData<List<Contact>> getContactListData() {
return mContactListData;
}
public MutableLiveData<List<Contact>> mContactListData = new MutableLiveData<>();
public void getCacheContact() {
String jsonString = mMMKV.getString(CommonConfig.EMERGENCY_CONTACT_LIST_KEY, null);

View File

@@ -150,7 +150,7 @@ public class LocationAcivity extends BaseMvvmActivity<LocationViewModel, Activit
*/
@Override
public void initData() {
mViewModel.getAddressBeanListData().observe(this, new Observer<List<AddressBean>>() {
mViewModel.mAddressBeanListData.observe(this, new Observer<List<AddressBean>>() {
@Override
public void onChanged(List<AddressBean> addressBeans) {
mDistrict = addressBeans;

View File

@@ -38,11 +38,7 @@ public class LocationViewModel extends BaseViewModel<ActivityLocationBinding, Ac
}
private MutableLiveData<List<AddressBean>> mAddressBeanListData =new MutableLiveData<>();
public MutableLiveData<List<AddressBean>> getAddressBeanListData() {
return mAddressBeanListData;
}
public MutableLiveData<List<AddressBean>> mAddressBeanListData = new MutableLiveData<>();
public void initJsonData() {
if (getCtx() == null) return;

View File

@@ -33,6 +33,8 @@ import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.lifecycle.Observer;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.download.DownloadEntity;
import com.blankj.utilcode.util.NetworkUtils;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
@@ -54,6 +56,7 @@ import com.xxpatx.os.bean.AppInfo;
import com.xxpatx.os.bean.DesktopIcon;
import com.xxpatx.os.bean.DockApp;
import com.xxpatx.os.bean.MapBean;
import com.xxpatx.os.bean.TestAppInfo;
import com.xxpatx.os.config.CommonConfig;
import com.xxpatx.os.databinding.ActivityMainBinding;
import com.xxpatx.os.fragment.app.AppListFragment;
@@ -64,6 +67,7 @@ import com.xxpatx.os.manager.AmapManager;
import com.xxpatx.os.service.NotificationService;
import com.xxpatx.os.utils.ApkUtils;
import com.xxpatx.os.utils.AppUsedTimeUtils;
import com.xxpatx.os.utils.ContactsUtils;
import com.xxpatx.os.utils.DayUtils;
import com.xxpatx.os.utils.TimeUtils;
import com.xxpatx.os.utils.Utils;
@@ -78,6 +82,8 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import static com.arialyy.aria.core.inf.IEntity.STATE_RUNNING;
public class MainActivity extends BaseMvvmActivity<MainViewModel, ActivityMainBinding> implements NetworkUtils.OnNetworkStatusChangedListener, NotificationService.NotificationListener {
private static final String TAG = "MainActivity";
@@ -98,8 +104,8 @@ public class MainActivity extends BaseMvvmActivity<MainViewModel, ActivityMainBi
private ContactFragment mContactFragment;
private boolean is_twoscreen = false;
private int appListIndex = 3;
private int defaultCurrent = 2;
private int appListIndex = 0;
private int defaultCurrent = 0;
private CameraManager cameraManager;
private boolean flashing = false;
@@ -116,6 +122,7 @@ public class MainActivity extends BaseMvvmActivity<MainViewModel, ActivityMainBi
public void onConnected(NetworkUtils.NetworkType networkType) {
Log.e(TAG, "onConnected: " + networkType);
mViewModel.uploadContacts();
mViewModel.getTestApp();
}
@Override
@@ -150,6 +157,14 @@ public class MainActivity extends BaseMvvmActivity<MainViewModel, ActivityMainBi
Log.e(TAG, "initView: ");
NetworkUtils.registerNetworkStatusChangedListener(this);
Log.e(TAG, "getContacts: " + ContactsUtils.isExist(MainActivity.this, "13220282310"));
Log.e(TAG, "getContacts: " + ContactsUtils.getContactId(MainActivity.this, "13220282310"));
ContactsUtils.isThePhoneExist(MainActivity.this, "13220282310");
ContactsUtils.getContacts(MainActivity.this);
ContactsUtils.getLocalContacts(MainActivity.this);
// UltimateBarX.addStatusBarTopPadding(mViewDataBinding.root);
UltimateBarX.addNavigationBarBottomPadding(mViewDataBinding.clBottom);
toggleNotificationListenerService(this);
@@ -173,20 +188,35 @@ public class MainActivity extends BaseMvvmActivity<MainViewModel, ActivityMainBi
// fragmentTransaction.commit();
// mControlFragment = new ControlFragment();
// mFragments.add(mControlFragment);
mSettingsFragment = new SettingsFragment();
appListIndex += 1;
defaultCurrent += 1;
mFragments.add(mSettingsFragment);
// is_twoscreen = Settings.Global.getInt(getContentResolver(), "is_twoscreen", 1) == 1;
// if (is_twoscreen) {
// appListIndex = 2;
// defaultCurrent = 1;
int contact_desktop = Settings.Global.getInt(getContentResolver(), CommonConfig.CONTACT_HOME_KEY, 0);
Log.e(TAG, "initView: contact_desktop = " + contact_desktop);
appListIndex += 1;
if (contact_desktop == 0) {
defaultCurrent += 1;
}
mContactFragment = new ContactFragment();
mFragments.add(mContactFragment);
// }
appListIndex += 1;
// mCustomFragment = new CustomFragment();
// mFragments.add(mCustomFragment);
mHomeFragment = new HomeFragment();
mFragments.add(mHomeFragment);
Log.e(TAG, "initView: appListIndex = " + appListIndex);
Log.e(TAG, "initView: defaultCurrent = " + defaultCurrent);
ArrayList<DesktopIcon> desktopIcons = ApkUtils.getAppstoreAppInfo(this);
int x = 0;
for (int i = 0; i <= desktopIcons.size(); i++) {
@@ -459,6 +489,38 @@ public class MainActivity extends BaseMvvmActivity<MainViewModel, ActivityMainBi
});
mViewModel.checkUpdate();
mViewModel.mTestAppInfoData.observe(this, new Observer<TestAppInfo>() {
@Override
public void onChanged(TestAppInfo testAppInfo) {
if (testAppInfo != null) {
if (ApkUtils.checkAppUpdate(MainActivity.this, testAppInfo)) {
DownloadEntity entity = Aria.download(this).getFirstDownloadEntity(testAppInfo.getApp_url());
if (null != entity) {
if (entity.isComplete()) {
ApkUtils.installApp(MainActivity.this, entity.getFilePath());
} else {
if (entity.getState() != STATE_RUNNING) {
Aria.download(this).resumeAllTask();
}
}
} else {
AppInfo appInfo = new AppInfo();
appInfo.setApp_name(testAppInfo.getApp_name());
appInfo.setApp_package(testAppInfo.getApp_package());
appInfo.setApp_version_name(testAppInfo.getApp_version_name());
appInfo.setApp_version_code(testAppInfo.getApp_version_code());
appInfo.setApp_size(testAppInfo.getApp_size());
appInfo.setApp_desc(testAppInfo.getApp_desc());
appInfo.setApp_md5(testAppInfo.getApp_md5());
appInfo.setApp_url(testAppInfo.getApp_url());
ApkUtils.ariaDownload(MainActivity.this, testAppInfo.getApp_url(), appInfo);
}
}
}
}
});
mViewModel.getTestApp();
registReceiver();
initAmap();
}

View File

@@ -31,6 +31,7 @@ import com.xxpatx.os.bean.BaseResponse;
import com.xxpatx.os.bean.Contact;
import com.xxpatx.os.bean.DesktopIcon;
import com.xxpatx.os.bean.SnInfo;
import com.xxpatx.os.bean.TestAppInfo;
import com.xxpatx.os.config.CommonConfig;
import com.xxpatx.os.databinding.ActivityMainBinding;
import com.xxpatx.os.db.ContactCacheUtils;
@@ -195,7 +196,6 @@ public class MainViewModel extends BaseViewModel<ActivityMainBinding, ActivityEv
private MutableLiveData<SnInfo> mSnInfoData = new MutableLiveData<>();
public void getSnInfo() {
NetInterfaceManager.getInstance().getSnInfoControl()
.compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY))
@@ -362,6 +362,38 @@ public class MainViewModel extends BaseViewModel<ActivityMainBinding, ActivityEv
});
}
public MutableLiveData<TestAppInfo> mTestAppInfoData = new MutableLiveData<>();
public void getTestApp() {
NetInterfaceManager.getInstance().getTestAppObservable()
.subscribe(new Observer<BaseResponse<TestAppInfo>>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e("getTestApp", "onSubscribe: ");
}
@Override
public void onNext(@NonNull BaseResponse<TestAppInfo> testAppInfoBaseResponse) {
Log.e("getTestApp", "onNext: " + testAppInfoBaseResponse);
if (testAppInfoBaseResponse.code == 200) {
TestAppInfo testAppInfo = testAppInfoBaseResponse.data;
mTestAppInfoData.setValue(testAppInfo);
}
}
@Override
public void onError(@NonNull Throwable e) {
Log.e("getTestApp", "onError: " + e.getMessage());
}
@Override
public void onComplete() {
Log.e("getTestApp", "onComplete: ");
}
});
}
public void uploadContacts() {
List<Contact> contactList = ContactCacheUtils.getInstance().getDatabaseContact();

View File

@@ -2,7 +2,7 @@ package com.xxpatx.os.activity.selectnumber;
import android.content.Context;
import android.content.Intent;
import android.telecom.PhoneAccountHandle;
import android.net.Uri;
import android.telecom.TelecomManager;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
@@ -15,23 +15,34 @@ import android.view.View;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.tencent.mmkv.MMKV;
import com.xxpatx.os.R;
import com.xxpatx.os.adapter.PhoneAdapter;
import com.xxpatx.os.base.mvvm.BaseMvvmActivity;
import com.xxpatx.os.config.CommonConfig;
import com.xxpatx.os.databinding.ActivitySelectNumberBinding;
import com.xxpatx.os.utils.MobileNetworkUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class SelectNumberActivity extends BaseMvvmActivity<SelectNumberViewModel, ActivitySelectNumberBinding> {
private static final String TAG = "SelectNumberActivity";
//指定SIM卡拨打
public static final String[] DUAL_SIM_TYPES = {"subscription", "Subscription",
"com.android.phone.extra.slot",
"phone", "com.android.phone.DialingMode",
"simId", "simnum", "phone_type",
"simSlot"};
private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE);
private TelephonyManager mTelephonyManager;
private SubscriptionManager subscriptionManager;
private TelecomManager telecomManager;
private PhoneAdapter mPhoneAdapter;
private String mDefaultNumber;
private String mPhone;
@Override
public boolean setNightMode() {
@@ -66,11 +77,12 @@ public class SelectNumberActivity extends BaseMvvmActivity<SelectNumberViewModel
return;
}
String phone = intent.getStringExtra("phone_number");
if (TextUtils.isEmpty(phone)) {
mPhone = intent.getStringExtra("phone_number");
if (TextUtils.isEmpty(mPhone)) {
finish();
return;
}
mDefaultNumber = mMMKV.decodeString(CommonConfig.DEFAULT_PHONE_NUMBER_KEY, "");
mPhoneAdapter = new PhoneAdapter();
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(SelectNumberActivity.this);
@@ -78,7 +90,7 @@ public class SelectNumberActivity extends BaseMvvmActivity<SelectNumberViewModel
mViewDataBinding.recyclerView.setLayoutManager(linearLayoutManager);
mViewDataBinding.recyclerView.setAdapter(mPhoneAdapter);
mPhoneAdapter.setPhone(phone);
mPhoneAdapter.setPhone(mPhone);
mPhoneAdapter.setOutCallback(new PhoneAdapter.OutCallback() {
@Override
public void onCall() {
@@ -89,8 +101,6 @@ public class SelectNumberActivity extends BaseMvvmActivity<SelectNumberViewModel
mTelephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
subscriptionManager = (SubscriptionManager) getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
telecomManager = (TelecomManager) getSystemService(Context.TELECOM_SERVICE);
}
@Override
@@ -101,16 +111,37 @@ public class SelectNumberActivity extends BaseMvvmActivity<SelectNumberViewModel
Log.e(TAG, "initData: id = " + subscriptionInfo.getSubscriptionId());
Log.e(TAG, "initData: mCardString = " + subscriptionInfo.getCardString());
Log.e(TAG, "initData: phone = " + mTelephonyManager.getLine1Number(subscriptionInfo.getSubscriptionId()));
Log.e(TAG, "initData: phone2 = " + MobileNetworkUtils.getCurrentCarrierNameForDisplay(SelectNumberActivity.this, subscriptionInfo.getSubscriptionId()));
stringList.add(mTelephonyManager.getLine1Number(subscriptionInfo.getSubscriptionId()));
}
mPhoneAdapter.setPhoneList(stringList);
List<PhoneAccountHandle> phoneAccountHandleList = telecomManager.getCallCapablePhoneAccounts();
Map<String, PhoneAccountHandle> phoneAccountHandleMap = new HashMap<>();
for (PhoneAccountHandle phoneAccountHandle : phoneAccountHandleList) {
phoneAccountHandleMap.put(phoneAccountHandle.getId(), phoneAccountHandle);
// List<PhoneAccountHandle> phoneAccountHandleList = telecomManager.getCallCapablePhoneAccounts();
// Map<String, PhoneAccountHandle> phoneAccountHandleMap = new HashMap<>();
// for (PhoneAccountHandle phoneAccountHandle : phoneAccountHandleList) {
// phoneAccountHandleMap.put(phoneAccountHandle.getId(), phoneAccountHandle);
// }
// Log.e(TAG, "initData: " + phoneAccountHandleList);
if (!TextUtils.isEmpty(mDefaultNumber)) {
int position = stringList.indexOf(mDefaultNumber);
if (position != -1) {
Intent dialIntent = new Intent(Intent.ACTION_CALL);
Uri data = Uri.parse("tel:" + mPhone);
dialIntent.setData(data);
for (int i = 0; i < DUAL_SIM_TYPES.length; i++) {
//0代表卡1,1代表卡2
dialIntent.putExtra(DUAL_SIM_TYPES[i], position);
}
try {
startActivity(dialIntent);
finish();
} catch (Exception e) {
Log.e(TAG, "initData: " + e.getMessage());
}
}
}
Log.e(TAG, "initData: end");
}
public class BtnClick {

View File

@@ -22,6 +22,7 @@ import com.tencent.mmkv.MMKV;
import com.xxpatx.os.BuildConfig;
import com.xxpatx.os.R;
import com.xxpatx.os.activity.dock.DockActivity;
import com.xxpatx.os.activity.sim.SimCardActivity;
import com.xxpatx.os.activity.tts.TtsActivity;
import com.xxpatx.os.activity.update.UpdateActivity;
import com.xxpatx.os.base.mvvm.BaseMvvmActivity;
@@ -73,7 +74,7 @@ public class SettingActivity extends BaseMvvmActivity<SettingViewModel, Activity
@Override
protected void initData() {
mViewModel.getAppInfoData().observe(this, new Observer<AppInfo>() {
mViewModel.mAppInfoData.observe(this, new Observer<AppInfo>() {
@Override
public void onChanged(AppInfo appInfo) {
if (appInfo == null) {
@@ -302,6 +303,10 @@ public class SettingActivity extends BaseMvvmActivity<SettingViewModel, Activity
Settings.System.putInt(getContentResolver(), CommonConfig.ACTION_STATUS_BAR_STATE, code == 1 ? 0 : 1);
}
public void setSimCard(View view) {
startActivity(new Intent(SettingActivity.this, SimCardActivity.class));
}
public void toInternet(View view) {
startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
}

View File

@@ -28,11 +28,7 @@ public class SettingViewModel extends BaseViewModel<ActivitySettingBinding, Acti
}
private MutableLiveData<AppInfo> mAppInfoData = new MutableLiveData<>();
public MutableLiveData<AppInfo> getAppInfoData() {
return mAppInfoData;
}
public MutableLiveData<AppInfo> mAppInfoData = new MutableLiveData<>();
public void checkUpdate() {
NetInterfaceManager.getInstance().getUpdateObservable()

View File

@@ -0,0 +1,85 @@
package com.xxpatx.os.activity.sim;
import android.content.Context;
import android.telecom.TelecomManager;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.View;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.xxpatx.os.BuildConfig;
import com.xxpatx.os.R;
import com.xxpatx.os.adapter.PhoneSetAdapter;
import com.xxpatx.os.base.mvvm.BaseMvvmActivity;
import com.xxpatx.os.databinding.ActivitySimCardBinding;
import java.util.ArrayList;
import java.util.List;
public class SimCardActivity extends BaseMvvmActivity<SimCardViewModel, ActivitySimCardBinding> {
private static final String TAG = "SimCardActivity";
private TelephonyManager mTelephonyManager;
private SubscriptionManager subscriptionManager;
private TelecomManager telecomManager;
private PhoneSetAdapter mPhoneSetAdapter;
@Override
protected int getLayoutId() {
return R.layout.activity_sim_card;
}
@Override
protected void initDataBinding() {
mViewModel.setCtx(this);
mViewModel.setVDBinding(mViewDataBinding);
mViewModel.setLifecycle(getLifecycleSubject());
mViewDataBinding.setClick(new BtnClick());
}
@Override
protected void initView() {
mPhoneSetAdapter = new PhoneSetAdapter();
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setOrientation(RecyclerView.VERTICAL);
mViewDataBinding.recyclerView.setLayoutManager(linearLayoutManager);
mViewDataBinding.recyclerView.setAdapter(mPhoneSetAdapter);
mTelephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
subscriptionManager = (SubscriptionManager) getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
telecomManager = (TelecomManager) getSystemService(Context.TELECOM_SERVICE);
}
@Override
protected void initData() {
List<SubscriptionInfo> subscriptionInfos = subscriptionManager.getActiveSubscriptionInfoList();
List<String> stringList = new ArrayList<>();
for (SubscriptionInfo subscriptionInfo : subscriptionInfos) {
Log.e(TAG, "initData: id = " + subscriptionInfo.getSubscriptionId());
Log.e(TAG, "initData: mCardString = " + subscriptionInfo.getCardString());
Log.e(TAG, "initData: phone = " + mTelephonyManager.getLine1Number(subscriptionInfo.getSubscriptionId()));
stringList.add(mTelephonyManager.getLine1Number(subscriptionInfo.getSubscriptionId()));
}
if (BuildConfig.DEBUG) {
// stringList.add("+8613220282310");
// stringList.add("+8618108347897");
}
stringList.add(stringList.size(), "默认手动选择");
mPhoneSetAdapter.setPhoneList(stringList);
}
public class BtnClick {
public void exit(View view) {
finish();
}
}
}

View File

@@ -0,0 +1,18 @@
package com.xxpatx.os.activity.sim;
import com.trello.rxlifecycle4.android.ActivityEvent;
import com.xxpatx.os.base.mvvm.BaseViewModel;
import com.xxpatx.os.databinding.ActivitySimCardBinding;
public class SimCardViewModel extends BaseViewModel<ActivitySimCardBinding, ActivityEvent> {
@Override
public ActivitySimCardBinding getVDBinding() {
return binding;
}
@Override
public void onDestroy() {
}
}

View File

@@ -37,7 +37,6 @@ import com.xxpatx.os.databinding.ActivityWeatherBinding;
import com.xxpatx.os.manager.AmapManager;
import com.xxpatx.os.utils.DataUtil;
import com.xxpatx.os.utils.DayUtils;
import com.xxpatx.os.utils.TimeUtils;
import com.xxpatx.os.view.FadeInOutAnimator;
import com.xxpatx.os.view.HorizontalItemDecoration;
@@ -154,7 +153,7 @@ public class WeatherActivity extends BaseMvvmActivity<WeatherViewModel, Activity
// }
// }
// });
mViewModel.getQweatherLocationData().observe(this, new Observer<QweatherLocation>() {
mViewModel.mQweatherLocationData.observe(this, new Observer<QweatherLocation>() {
@Override
public void onChanged(QweatherLocation qweatherLocation) {
if (qweatherLocation != null) {
@@ -166,7 +165,7 @@ public class WeatherActivity extends BaseMvvmActivity<WeatherViewModel, Activity
}
}
});
mViewModel.getLocationData().observe(this, new Observer<String>() {
mViewModel.mLocationData.observe(this, new Observer<String>() {
@Override
public void onChanged(String s) {
mViewDataBinding.tvLocation.setText(s);
@@ -174,7 +173,7 @@ public class WeatherActivity extends BaseMvvmActivity<WeatherViewModel, Activity
mViewModel.cityLookup(s);
}
});
mViewModel.getWeatherNowData().observe(this, new Observer<WeatherNowBean>() {
mViewModel.mWeatherNowData.observe(this, new Observer<WeatherNowBean>() {
@Override
public void onChanged(WeatherNowBean weatherNowBean) {
//先判断返回的status是否正确当status正确时获取数据若status不正确可查看status对应的Code值找到原因
@@ -195,7 +194,7 @@ public class WeatherActivity extends BaseMvvmActivity<WeatherViewModel, Activity
}
}
});
mViewModel.getWeatherDailyData().observe(this, new Observer<WeatherDailyBean>() {
mViewModel.mWeatherDailyData.observe(this, new Observer<WeatherDailyBean>() {
@Override
public void onChanged(WeatherDailyBean weatherDailyBean) {
if (weatherDailyBean != null) {

View File

@@ -50,11 +50,7 @@ public class WeatherViewModel extends BaseViewModel<ActivityWeatherBinding, Acti
}
private MutableLiveData<MapGeoResult> mGeoResultData = new MutableLiveData<>();
public MutableLiveData<MapGeoResult> getGeoResultData() {
return mGeoResultData;
}
public MutableLiveData<MapGeoResult> mGeoResultData = new MutableLiveData<>();
@Deprecated
public void decodeGeo(String address) {
@@ -92,11 +88,7 @@ public class WeatherViewModel extends BaseViewModel<ActivityWeatherBinding, Acti
}
private MutableLiveData<QweatherLocation> mQweatherLocationData = new MutableLiveData<>();
public MutableLiveData<QweatherLocation> getQweatherLocationData() {
return mQweatherLocationData;
}
public MutableLiveData<QweatherLocation> mQweatherLocationData = new MutableLiveData<>();
public void cityLookup(String city) {
NetInterfaceManager.getInstance().getLookupObservable(city)
@@ -155,11 +147,7 @@ public class WeatherViewModel extends BaseViewModel<ActivityWeatherBinding, Acti
}
}
private MutableLiveData<String> mLocationData = new MutableLiveData<>();
public MutableLiveData<String> getLocationData() {
return mLocationData;
}
public MutableLiveData<String> mLocationData = new MutableLiveData<>();
public void getLocation() {
String location = AmapManager.getInstance().getDistrict();
@@ -182,11 +170,7 @@ public class WeatherViewModel extends BaseViewModel<ActivityWeatherBinding, Acti
getWeather7D(location);
}
private MutableLiveData<WeatherNowBean> mWeatherNowData = new MutableLiveData<>();
public MutableLiveData<WeatherNowBean> getWeatherNowData() {
return mWeatherNowData;
}
public MutableLiveData<WeatherNowBean> mWeatherNowData = new MutableLiveData<>();
public void getWeatherNow(String locationTude) {
Log.e(TAG, "getweather: " + locationTude);
@@ -219,11 +203,7 @@ public class WeatherViewModel extends BaseViewModel<ActivityWeatherBinding, Acti
});
}
private MutableLiveData<WeatherDailyBean> mWeatherDailyData = new MutableLiveData<>();
public MutableLiveData<WeatherDailyBean> getWeatherDailyData() {
return mWeatherDailyData;
}
public MutableLiveData<WeatherDailyBean> mWeatherDailyData = new MutableLiveData<>();
public void getWeather7D(String locationTude) {
QWeather.getWeather7D(getCtx(), locationTude, new QWeather.OnResultWeatherDailyListener() {

View File

@@ -20,6 +20,7 @@ import com.xxpatx.os.R;
import com.xxpatx.os.activity.selectnumber.SelectNumberActivity;
import com.xxpatx.os.bean.Contact;
import com.xxpatx.os.bean.RecordsInfo;
import com.xxpatx.os.dialog.CallPhoneDialog;
import com.xxpatx.os.utils.GlideLoadUtils;
import com.xxpatx.os.utils.Utils;
@@ -35,6 +36,7 @@ public class CallRecordAdapter extends RecyclerView.Adapter<CallRecordAdapter.Ho
private Context mContext;
private List<RecordsInfo> mRecordsInfoList;
private SimpleDateFormat mSimpleDateFormat = new SimpleDateFormat("HH:mm");
private CallPhoneDialog mCallPhoneDialog;
public void setRecordsInfoList(List<RecordsInfo> recordsInfoList) {
this.mRecordsInfoList = recordsInfoList;
@@ -48,6 +50,16 @@ public class CallRecordAdapter extends RecyclerView.Adapter<CallRecordAdapter.Ho
notifyDataSetChanged();
}
public void setCallRecordCallback(CallRecordCallback callRecordCallback) {
mCallRecordCallback = callRecordCallback;
}
private CallRecordCallback mCallRecordCallback;
public interface CallRecordCallback {
void onLongClickListener(RecordsInfo recordsInfo);
}
@NonNull
@Override
public Holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
@@ -68,14 +80,14 @@ public class CallRecordAdapter extends RecyclerView.Adapter<CallRecordAdapter.Ho
case CallLog.Calls.INCOMING_TYPE:
holder.tv_state.setImageDrawable(mContext.getDrawable(R.drawable.icon_call_incoming));
holder.tv_name.setTextColor(mContext.getColor(R.color.black));
holder.tv_phone.setTextColor(mContext.getColor(R.color.noti_font_color));
holder.tv_time.setTextColor(mContext.getColor(R.color.noti_font_color));
holder.tv_phone.setTextColor(mContext.getColor(R.color.black));
holder.tv_time.setTextColor(mContext.getColor(R.color.black));
break;
case CallLog.Calls.OUTGOING_TYPE:
holder.tv_state.setImageDrawable(mContext.getDrawable(R.drawable.icon_call_outgoing));
holder.tv_name.setTextColor(mContext.getColor(R.color.black));
holder.tv_phone.setTextColor(mContext.getColor(R.color.noti_font_color));
holder.tv_time.setTextColor(mContext.getColor(R.color.noti_font_color));
holder.tv_phone.setTextColor(mContext.getColor(R.color.black));
holder.tv_time.setTextColor(mContext.getColor(R.color.black));
break;
case CallLog.Calls.MISSED_TYPE:
holder.tv_state.setImageDrawable(mContext.getDrawable(R.drawable.icon_call_missed));
@@ -85,8 +97,6 @@ public class CallRecordAdapter extends RecyclerView.Adapter<CallRecordAdapter.Ho
break;
}
holder.tv_time.setText(mSimpleDateFormat.format(new Date(recordsInfo.getDate())));
holder.iv_avatar.setOnClickListener(view -> call(phone));
holder.cl_info.setOnClickListener(view -> call(phone));
holder.iv_remove.setOnClickListener(new View.OnClickListener() {
@Override
@@ -101,6 +111,30 @@ public class CallRecordAdapter extends RecyclerView.Adapter<CallRecordAdapter.Ho
}
});
holder.root.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mCallPhoneDialog = new CallPhoneDialog(mContext);
mCallPhoneDialog.setOnClickListener(new CallPhoneDialog.OnClickListener() {
@Override
public void onCallClick() {
call(recordsInfo.getNumber());
mCallPhoneDialog.dismiss();
}
});
mCallPhoneDialog.show();
}
});
holder.root.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
if (mCallRecordCallback != null) {
mCallRecordCallback.onLongClickListener(recordsInfo);
}
return false;
}
});
}
private void call(String phone) {

View File

@@ -19,7 +19,7 @@ import com.bumptech.glide.Glide;
import com.hjq.toast.Toaster;
import com.shehuan.niv.NiceImageView;
import com.xxpatx.os.R;
import com.xxpatx.os.activity.contact.AddWechatContactActivity;
import com.xxpatx.os.activity.contact.AddContactActivity;
import com.xxpatx.os.activity.selectnumber.SelectNumberActivity;
import com.xxpatx.os.bean.Contact;
import com.xxpatx.os.utils.GlideLoadUtils;
@@ -83,7 +83,7 @@ public class ContactAdapter extends RecyclerView.Adapter<ContactAdapter.ContactH
Toaster.show("无法打开电话功能");
}
} else if (DIALER_ADD_CONTACT.equals(contact.getMobile())) {
Intent intent = new Intent(mContext, AddWechatContactActivity.class);
Intent intent = new Intent(mContext, AddContactActivity.class);
mContext.startActivity(intent);
} else if (!TextUtils.isEmpty(phone)) {
if (Utils.isMultiSim(mContext)) {

View File

@@ -15,7 +15,7 @@ import androidx.recyclerview.widget.RecyclerView;
import com.hjq.toast.Toaster;
import com.xxpatx.os.R;
import com.xxpatx.os.activity.contact.ContactActivity;
import com.xxpatx.os.activity.contact.ContactListActivity;
import com.xxpatx.os.activity.service.ServiceActivity;
import com.xxpatx.os.bean.DailyAppBean;
import com.xxpatx.os.config.CommonConfig;
@@ -76,7 +76,7 @@ public class DailyAppAdapter extends RecyclerView.Adapter<DailyAppAdapter.Holder
mContext.startActivity(new Intent(mContext, ServiceActivity.class));
break;
case AppManager.CONTACT_PACKAGE:
mContext.startActivity(new Intent(mContext, ContactActivity.class));
mContext.startActivity(new Intent(mContext, ContactListActivity.class));
break;
default:
ApkUtils.openPackage(mContext, packageName, dailyAppBean.getClassName());

View File

@@ -3,6 +3,7 @@ package com.xxpatx.os.adapter;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -14,6 +15,7 @@ import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.recyclerview.widget.RecyclerView;
import com.xxpatx.os.R;
import com.xxpatx.os.utils.MobileNumberUtils;
import java.util.List;
@@ -64,7 +66,16 @@ public class PhoneAdapter extends RecyclerView.Adapter<PhoneAdapter.Holder> {
} else if (position == 1) {
holder.iv_card.setImageDrawable(mContext.getDrawable(R.drawable.sim_card_2));
}
holder.tv_number.setText(phone);
if (TextUtils.isEmpty(phone)) {
holder.tv_number.setText("未知号码");
} else {
holder.tv_number.setText(phone);
}
if (TextUtils.isEmpty(MobileNumberUtils.getCarrier(phone))) {
holder.tv_carrier.setText("未知");
} else {
holder.tv_carrier.setText(MobileNumberUtils.getCarrier(phone));
}
holder.root.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -90,13 +101,14 @@ public class PhoneAdapter extends RecyclerView.Adapter<PhoneAdapter.Holder> {
public class Holder extends RecyclerView.ViewHolder {
ConstraintLayout root;
TextView tv_number;
TextView tv_number, tv_carrier;
ImageView iv_card;
public Holder(@NonNull View itemView) {
super(itemView);
root = itemView.findViewById(R.id.root);
iv_card = itemView.findViewById(R.id.iv_card);
tv_carrier = itemView.findViewById(R.id.tv_carrier);
tv_number = itemView.findViewById(R.id.tv_number);
}
}

View File

@@ -0,0 +1,93 @@
package com.xxpatx.os.adapter;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.recyclerview.widget.RecyclerView;
import com.tencent.mmkv.MMKV;
import com.xxpatx.os.R;
import com.xxpatx.os.config.CommonConfig;
import com.xxpatx.os.utils.MobileNumberUtils;
import java.util.List;
import java.util.Objects;
public class PhoneSetAdapter extends RecyclerView.Adapter<PhoneSetAdapter.Holder> {
private static final String TAG = "PhoneSetAdapter";
private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE);
private Context mContext;
private List<String> mPhoneList;
private String mDefaultNumber;
public void setPhoneList(List<String> phoneList) {
mPhoneList = phoneList;
notifyDataSetChanged();
}
@NonNull
@Override
public Holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
mContext = parent.getContext();
mDefaultNumber = mMMKV.decodeString(CommonConfig.DEFAULT_PHONE_NUMBER_KEY, "");
return new Holder(LayoutInflater.from(mContext).inflate(R.layout.item_phone_set, parent, false));
}
@Override
public void onBindViewHolder(@NonNull Holder holder, int position) {
String phone = mPhoneList.get(position);
if (Objects.equals(mDefaultNumber, phone)) {
holder.iv_select.setImageDrawable(mContext.getDrawable(R.drawable.icon_select));
} else {
holder.iv_select.setImageDrawable(mContext.getDrawable(R.drawable.icon_unselect));
}
holder.tv_number.setText(phone);
holder.tv_carrier.setText(MobileNumberUtils.getCarrier(phone));
holder.root.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.e(TAG, "onClick: " + phone);
mDefaultNumber = phone;
mMMKV.encode(CommonConfig.DEFAULT_PHONE_NUMBER_KEY, phone);
notifyDataSetChanged();
}
});
holder.iv_select.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.e(TAG, "onClick: " + phone);
mDefaultNumber = phone;
mMMKV.encode(CommonConfig.DEFAULT_PHONE_NUMBER_KEY, phone);
notifyDataSetChanged();
}
});
}
@Override
public int getItemCount() {
return mPhoneList == null ? 0 : mPhoneList.size();
}
public class Holder extends RecyclerView.ViewHolder {
ConstraintLayout root;
TextView tv_number, tv_carrier;
ImageView iv_select;
public Holder(@NonNull View itemView) {
super(itemView);
root = itemView.findViewById(R.id.root);
tv_carrier = itemView.findViewById(R.id.tv_carrier);
tv_number = itemView.findViewById(R.id.tv_number);
iv_select = itemView.findViewById(R.id.iv_select);
}
}
}

View File

@@ -19,7 +19,7 @@ import com.bumptech.glide.Glide;
import com.shehuan.niv.NiceImageView;
import com.xxpatx.os.R;
import com.xxpatx.os.activity.callwechat.CallWechatActivity;
import com.xxpatx.os.activity.contact.AddWechatContactActivity;
import com.xxpatx.os.activity.contact.AddContactActivity;
import com.xxpatx.os.bean.Contact;
import com.xxpatx.os.utils.AccessibilityUtils;
@@ -62,7 +62,7 @@ public class WechatContactAdapter extends RecyclerView.Adapter<WechatContactAdap
contactHolder.tv_name.setText(contact.getName());
contactHolder.tv_phone.setText(contact.getMobile());
Glide.with(contactHolder.iv_head).load(contact.getAvatar()).error(R.drawable.default_avatar).into(contactHolder.iv_head);
Glide.with(contactHolder.iv_head).load(contact.getAvatar()).override(200, 200).error(R.drawable.default_avatar).into(contactHolder.iv_head);
switch (position % 6) {
case 0:
@@ -90,7 +90,7 @@ public class WechatContactAdapter extends RecyclerView.Adapter<WechatContactAdap
@Override
public void onClick(View view) {
if ("未设置".equals(contact.getName())) {
Intent intent = new Intent(mContext, AddWechatContactActivity.class);
Intent intent = new Intent(mContext, AddContactActivity.class);
mContext.startActivity(intent);
} else {
Intent intent = new Intent(mContext, CallWechatActivity.class);

View File

@@ -1,11 +1,13 @@
package com.xxpatx.os.bean;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.gson.Gson;
import com.google.gson.JsonParser;
import java.io.Serializable;
import java.util.Objects;
public class Contact implements Serializable {
private static final long serialVersionUID = 8814155739557674021L;
@@ -88,6 +90,20 @@ public class Contact implements Serializable {
this.simContact = simContact;
}
@Override
public int hashCode() {
return super.hashCode();
}
@Override
public boolean equals(@Nullable Object obj) {
if (obj instanceof Contact) {
return Objects.equals(((Contact) obj).mobile, mobile)
|| ((Contact) obj).id == id;
}
return false;
}
@NonNull
@Override
public String toString() {

View File

@@ -0,0 +1,63 @@
package com.xxpatx.os.bean;
import androidx.annotation.NonNull;
import com.google.gson.Gson;
import com.google.gson.JsonParser;
import java.io.Serializable;
public class ContactId implements Serializable {
private static final long serialVersionUID = 6712547690395593591L;
long id;
int inPhone;
String display_name;
String photo_uri;
public ContactId(long id, int inPhone, String display_name, String photo_uri) {
this.id = id;
this.inPhone = inPhone;
this.display_name = display_name;
this.photo_uri = photo_uri;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public int getInPhone() {
return inPhone;
}
public void setInPhone(int inPhone) {
this.inPhone = inPhone;
}
public String getDisplay_name() {
return display_name;
}
public void setDisplay_name(String display_name) {
this.display_name = display_name;
}
public String getPhoto_uri() {
return photo_uri;
}
public void setPhoto_uri(String photo_uri) {
this.photo_uri = photo_uri;
}
@NonNull
@Override
public String toString() {
return JsonParser.parseString(new Gson().toJson(this)).getAsJsonObject().toString();
}
}

View File

@@ -0,0 +1,89 @@
package com.xxpatx.os.bean;
import java.io.Serializable;
public class TestAppInfo implements Serializable {
private static final long serialVersionUID = -1566196988691579627L;
int id;
String app_name;
String app_package;
String app_version_name;
long app_version_code;
long app_size;
String app_desc;
String app_md5;
String app_url;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getApp_name() {
return app_name;
}
public void setApp_name(String app_name) {
this.app_name = app_name;
}
public String getApp_package() {
return app_package;
}
public void setApp_package(String app_package) {
this.app_package = app_package;
}
public String getApp_version_name() {
return app_version_name;
}
public void setApp_version_name(String app_version_name) {
this.app_version_name = app_version_name;
}
public long getApp_version_code() {
return app_version_code;
}
public void setApp_version_code(long app_version_code) {
this.app_version_code = app_version_code;
}
public long getApp_size() {
return app_size;
}
public void setApp_size(long app_size) {
this.app_size = app_size;
}
public String getApp_desc() {
return app_desc;
}
public void setApp_desc(String app_desc) {
this.app_desc = app_desc;
}
public String getApp_md5() {
return app_md5;
}
public void setApp_md5(String app_md5) {
this.app_md5 = app_md5;
}
public String getApp_url() {
return app_url;
}
public void setApp_url(String app_url) {
this.app_url = app_url;
}
}

View File

@@ -45,6 +45,9 @@ public class CommonConfig {
public static final String VIDEO_INFO_BUNDLE = "video_bundle_info";
/*添加联系人本地缓存*/
public static final String CONTACT_LOCAL_CACHE_KEY = "contact_local_cache";
/*是否手动选择位置地址*/
public static final String MANUALLY_SELECT_LOCATION_KEY = "map_manually_select_location";
/*手动选择位置地址*/
@@ -75,6 +78,7 @@ public class CommonConfig {
public static final String EMERGENCY_CONTACT_LIST_KEY = "emergency_contact_phone_list";
public static final String EMERGENCY_CONTACT_KEY = "emergency_contact_phone";
public static final String FAMILY_ADDRESS_KEY = "Family_Address";
public static final String DEFAULT_PHONE_NUMBER_KEY = "default_selected_phone_number";
/*拨号提示音*/
public static final String DISABLE_DIAL_TONE_MODIFY = "disable_dial_modify_key";
@@ -93,6 +97,8 @@ public class CommonConfig {
public static final String DISABLE_CONTACT_MODIFY = "disable_contact_modify_key";
/*禁用闹钟修改*/
public static final String DISABLE_CLOCK_MODIFY = "disable_clock_modify_key";
/*联系人首屏*/
public static final String CONTACT_HOME_KEY = "contact_home_control";
/*后台设置的*/

View File

@@ -0,0 +1,82 @@
package com.xxpatx.os.dialog;
import android.content.Context;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import androidx.appcompat.app.AlertDialog;
import com.xxpatx.os.R;
public class CallPhoneDialog extends AlertDialog {
private ImageView mIvCall;
private Context mContext;
public CallPhoneDialog(Context context) {
super(context, R.style.CustomDialog);
this.mContext = context;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog_call_phone);
//按空白处不能取消动画
setCanceledOnTouchOutside(true);
//初始化界面控件
initView();
//初始化界面控件的事件
initEvent();
getWindow().setGravity(Gravity.BOTTOM);
getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
}
/**
* 初始化界面的确定和取消监听器
*/
private void initEvent() {
//取消按钮被点击后,向外界提供监听
mIvCall.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mOnClickListener != null) {
mOnClickListener.onCallClick();
}
}
});
}
@Override
public void show() {
super.show();
}
/**
* 初始化界面控件
*/
private void initView() {
mIvCall = findViewById(R.id.iv_call);
}
/**
* 设置确定取消按钮的回调
*/
private OnClickListener mOnClickListener;
public void setOnClickListener(OnClickListener onClickListener) {
this.mOnClickListener = onClickListener;
}
public interface OnClickListener {
/**
* 点击取消按钮事件
*/
void onCallClick();
}
}

View File

@@ -1,10 +1,10 @@
package com.xxpatx.os.dialog;
import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.appcompat.app.AlertDialog;
@@ -12,11 +12,6 @@ import androidx.constraintlayout.widget.ConstraintLayout;
import com.xxpatx.os.R;
/**
* description:自定义dialog
*/
public class EditContactDialog extends AlertDialog {
private TextView tvPhoneNumber;
@@ -48,6 +43,7 @@ public class EditContactDialog extends AlertDialog {
refreshView();
//初始化界面控件的事件
initEvent();
getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
}
/**

View File

@@ -27,7 +27,7 @@ import com.trello.rxlifecycle4.RxLifecycle;
import com.trello.rxlifecycle4.android.FragmentEvent;
import com.xxpatx.os.BuildConfig;
import com.xxpatx.os.R;
import com.xxpatx.os.activity.contact.ContactActivity;
import com.xxpatx.os.activity.contact.ContactListActivity;
import com.xxpatx.os.activity.dailyapp.DailyAppActivity;
import com.xxpatx.os.activity.screenlock.ScreenLockActivity;
import com.xxpatx.os.activity.service.ServiceActivity;
@@ -257,7 +257,7 @@ public class AppListFragment extends BaseFragment {
startActivity(new Intent(mContext, ServiceActivity.class));
break;
case AppManager.CONTACT_PACKAGE:
startActivity(new Intent(mContext, ContactActivity.class));
startActivity(new Intent(mContext, ContactListActivity.class));
break;
case "aios.daily.app":
startActivity(new Intent(mContext, DailyAppActivity.class));

View File

@@ -21,7 +21,7 @@ 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.AddWechatContactActivity;
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;
@@ -189,7 +189,7 @@ public class ContactFragment extends BaseMvvmFragment<ContactViewModel, Fragment
// }
// });
mViewModel.getContactListData().observe(this, new Observer<List<Contact>>() {
mViewModel.mContactListData.observe(this, new Observer<List<Contact>>() {
@Override
public void onChanged(List<Contact> contacts) {
if (contacts == null || contacts.size() == 0) {
@@ -212,7 +212,7 @@ public class ContactFragment extends BaseMvvmFragment<ContactViewModel, Fragment
mContactAdapter.setContactList(contacts);
}
});
mViewModel.getDeleteData().observe(this, new Observer<BaseResponse>() {
mViewModel.mDeleteData.observe(this, new Observer<BaseResponse>() {
@Override
public void onChanged(BaseResponse baseResponse) {
if (baseResponse.code == 200) {
@@ -299,7 +299,7 @@ public class ContactFragment extends BaseMvvmFragment<ContactViewModel, Fragment
public class BtnClick {
public void toAdd(View view) {
Intent intent = new Intent(getContext(), AddWechatContactActivity.class);
Intent intent = new Intent(getContext(), AddContactActivity.class);
startActivity(intent);
}

View File

@@ -19,6 +19,7 @@ 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;
@@ -29,6 +30,7 @@ import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.Disposable;
public class ContactViewModel extends BaseViewModel<FragmentContactHomeBinding, FragmentEvent> {
private static final String TAG = "ContactListViewModel";
private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE);
@Override
@@ -41,11 +43,7 @@ public class ContactViewModel extends BaseViewModel<FragmentContactHomeBinding,
}
private MutableLiveData<List<Contact>> mContactListData = new MutableLiveData<>();
public MutableLiveData<List<Contact>> getContactListData() {
return mContactListData;
}
public MutableLiveData<List<Contact>> mContactListData = new MutableLiveData<>();
public void getCacheContact() {
String jsonString = mMMKV.getString(UrlAddress.GET_MAIL_LIST, null);
@@ -76,8 +74,13 @@ public class ContactViewModel extends BaseViewModel<FragmentContactHomeBinding,
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(listBaseResponse.data))) {
ContactsUtils.saveContactPhone(getCtx(), contactList);
}
mContactListData.setValue(contactList);
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<>());
@@ -108,12 +111,7 @@ public class ContactViewModel extends BaseViewModel<FragmentContactHomeBinding,
});
}
private MutableLiveData<BaseResponse> mDeleteData =new MutableLiveData<>();
public MutableLiveData<BaseResponse> getDeleteData() {
return mDeleteData;
}
public MutableLiveData<BaseResponse> mDeleteData = new MutableLiveData<>();
public void deleteContact(long id) {
NetInterfaceManager.getInstance().getMailListDeleteObservable(id)

View File

@@ -27,7 +27,7 @@ import com.xxpatx.os.BuildConfig;
import com.xxpatx.os.R;
import com.xxpatx.os.activity.FlashlightActivity;
import com.xxpatx.os.activity.NetworkActivity;
import com.xxpatx.os.activity.contact.AddWechatContactActivity;
import com.xxpatx.os.activity.contact.AddContactActivity;
import com.xxpatx.os.activity.setting.SettingActivity;
import com.xxpatx.os.activity.weather.WeatherActivity;
import com.xxpatx.os.alarm.AlarmClockData;
@@ -460,7 +460,7 @@ public class HomeFragment extends BaseMvvmFragment<HomeViewModel, FragmentHomeBi
}
public void addContact(View view) {
startActivity(new Intent(mContext, AddWechatContactActivity.class));
startActivity(new Intent(mContext, AddContactActivity.class));
}
public void openWifi(View view) {

View File

@@ -19,7 +19,7 @@ import androidx.recyclerview.widget.LinearLayoutManager;
import com.hjq.toast.Toaster;
import com.tencent.mmkv.MMKV;
import com.xxpatx.os.R;
import com.xxpatx.os.activity.contact.AddWechatContactActivity;
import com.xxpatx.os.activity.contact.AddContactActivity;
import com.xxpatx.os.activity.contact.EditContactActivity;
import com.xxpatx.os.adapter.ContactAdapter;
import com.xxpatx.os.adapter.WechatContactAdapter;
@@ -100,7 +100,7 @@ public class ContactFragment extends BaseMvvmFragment<ContactViewModel, Fragment
@Override
protected void initData(Bundle savedInstanceState) {
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();
@@ -112,7 +112,7 @@ public class ContactFragment extends BaseMvvmFragment<ContactViewModel, Fragment
}
});
mViewModel.getDeleteData().observe(this, new Observer<BaseResponse>() {
mViewModel.mDeleteData.observe(this, new Observer<BaseResponse>() {
@Override
public void onChanged(BaseResponse baseResponse) {
if (baseResponse.code == 200) {
@@ -275,7 +275,7 @@ public class ContactFragment extends BaseMvvmFragment<ContactViewModel, Fragment
if (disableModify) {
Toaster.showLong("已禁用联系人修改");
} else {
Intent intent = new Intent(mContext, AddWechatContactActivity.class);
Intent intent = new Intent(mContext, AddContactActivity.class);
startActivity(intent);
}
}

View File

@@ -27,6 +27,7 @@ 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;
@@ -40,7 +41,7 @@ import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.Disposable;
public class ContactViewModel extends BaseViewModel<FragmentContactBinding, FragmentEvent> {
private static final String TAG = "ContactViewModel";
private static final String TAG = "ContactListViewModel";
private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE);
@Override
@@ -53,11 +54,7 @@ public class ContactViewModel extends BaseViewModel<FragmentContactBinding, Frag
}
private MutableLiveData<List<Contact>> mContactListData = new MutableLiveData<>();
public MutableLiveData<List<Contact>> getContactListData() {
return mContactListData;
}
public MutableLiveData<List<Contact>> mContactListData = new MutableLiveData<>();
public void getCacheContact() {
String jsonString = mMMKV.getString(UrlAddress.GET_MAIL_LIST, null);
@@ -87,8 +84,13 @@ public class ContactViewModel extends BaseViewModel<FragmentContactBinding, Frag
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);
List<Contact> contactList = listBaseResponse.data;
String oldCache = mMMKV.getString(UrlAddress.GET_MAIL_LIST, "");
if (!oldCache.equals(GsonUtils.toJSONString(contactList))) {
ContactsUtils.saveContactPhone(getCtx(), contactList);
}
mContactListData.setValue(contactList);
mMMKV.putString(UrlAddress.GET_MAIL_LIST, GsonUtils.toJSONString(contactList));
} else {
mMMKV.putString(UrlAddress.GET_MAIL_LIST, "");
mContactListData.setValue(new ArrayList<>());
@@ -118,11 +120,7 @@ public class ContactViewModel extends BaseViewModel<FragmentContactBinding, Frag
});
}
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());
@@ -153,7 +151,6 @@ public class ContactViewModel extends BaseViewModel<FragmentContactBinding, Frag
}
public void deleteSimContact(long id) {
ContentResolver contentResolver = getCtx().getContentResolver();
// deleteSimContact(id + "");

View File

@@ -16,7 +16,7 @@ import com.hjq.toast.Toaster;
import com.tencent.mmkv.MMKV;
import com.xxpatx.os.R;
import com.xxpatx.os.activity.ImeiActivity;
import com.xxpatx.os.activity.contact.AddWechatContactActivity;
import com.xxpatx.os.activity.contact.AddContactActivity;
import com.xxpatx.os.activity.selectnumber.SelectNumberActivity;
import com.xxpatx.os.base.mvvm.fragment.BaseMvvmFragment;
import com.xxpatx.os.config.CommonConfig;
@@ -264,7 +264,7 @@ public class DialerFragment extends BaseMvvmFragment<DialerViewModel, FragmentDi
if (disableModify) {
Toaster.showLong("已禁用联系人修改");
} else {
Intent intent = new Intent(mContext, AddWechatContactActivity.class);
Intent intent = new Intent(mContext, AddContactActivity.class);
startActivity(intent);
}
}

View File

@@ -1,6 +1,8 @@
package com.xxpatx.os.fragment.phone.record;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.CallLog;
import android.util.Log;
@@ -10,14 +12,15 @@ import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.recyclerview.widget.LinearLayoutManager;
import com.xxpatx.os.R;
import com.xxpatx.os.activity.selectnumber.SelectNumberActivity;
import com.xxpatx.os.adapter.CallRecordAdapter;
import com.xxpatx.os.base.mvvm.fragment.BaseMvvmFragment;
import com.xxpatx.os.bean.Contact;
import com.xxpatx.os.bean.RecordsInfo;
import com.xxpatx.os.databinding.FragmentRecordBinding;
import com.xxpatx.os.dialog.DeleteDialog;
import com.xxpatx.os.utils.Utils;
import java.util.ArrayList;
import java.util.List;
@@ -35,6 +38,7 @@ public class RecordFragment extends BaseMvvmFragment<RecordViewModel, FragmentRe
private Context mContext;
private CallRecordAdapter mCallRecordAdapter;
private List<RecordsInfo> dataList = new ArrayList<>();
private DeleteDialog mDeleteDialog;
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
@@ -92,6 +96,28 @@ public class RecordFragment extends BaseMvvmFragment<RecordViewModel, FragmentRe
@Override
protected void initView(Bundle bundle) {
mCallRecordAdapter = new CallRecordAdapter();
mCallRecordAdapter.setCallRecordCallback(new CallRecordAdapter.CallRecordCallback() {
@Override
public void onLongClickListener(RecordsInfo recordsInfo) {
mDeleteDialog = new DeleteDialog(mContext);
mDeleteDialog.setTitle("通话记录");
mDeleteDialog.setMessage("是否删除此条记录");
mDeleteDialog.setOnClickBottomListener(new DeleteDialog.OnClickBottomListener() {
@Override
public void onPositiveClick() {
mContext.getContentResolver().delete(CallLog.Calls.CONTENT_URI, CallLog.Calls._ID + "=?", new String[]{String.valueOf(recordsInfo.getId())});
mViewModel.getRecordsInfoList();
mDeleteDialog.dismiss();
}
@Override
public void onNegtiveClick() {
mDeleteDialog.dismiss();
}
});
mDeleteDialog.show();
}
});
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(mContext);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mViewDataBinding.recyclerView.setLayoutManager(linearLayoutManager);
@@ -107,7 +133,7 @@ public class RecordFragment extends BaseMvvmFragment<RecordViewModel, FragmentRe
@Override
protected void initData(Bundle savedInstanceState) {
mViewModel.getRecordsInfoData().observe(this, new Observer<List<RecordsInfo>>() {
mViewModel.mRecordsInfoData.observe(this, new Observer<List<RecordsInfo>>() {
@Override
public void onChanged(List<RecordsInfo> recordsInfos) {
dataList = recordsInfos;
@@ -121,12 +147,13 @@ public class RecordFragment extends BaseMvvmFragment<RecordViewModel, FragmentRe
mCallRecordAdapter.setRecordsInfoList(dataList);
}
});
mViewModel.getContactMapData().observe(this, new Observer<Map<String, Contact>>() {
mViewModel.mContactMapData.observe(this, new Observer<Map<String, Contact>>() {
@Override
public void onChanged(Map<String, Contact> stringContactMap) {
mCallRecordAdapter.setContactMap(stringContactMap);
}
});
mViewModel.getContact();
mViewModel.getRecordsInfoList();
}
@@ -144,6 +171,24 @@ public class RecordFragment extends BaseMvvmFragment<RecordViewModel, FragmentRe
mViewModel.getRecordsInfoList();
}
private void call(String phone) {
if (Utils.isMultiSim(mContext)) {
Intent intent = new Intent(mContext, SelectNumberActivity.class);
intent.putExtra("phone_number", phone);
mContext.startActivity(intent);
} else {
try {
Intent dialIntent = new Intent(Intent.ACTION_CALL);
Uri data = Uri.parse("tel:" + phone);
dialIntent.setData(data);
dialIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(dialIntent);
} catch (Exception e) {
Log.e(TAG, "callNumber: " + e.getMessage());
}
}
}
private void showDialog() {
DeleteDialog dialog = new DeleteDialog(mContext);
dialog.setTitle("提醒")

View File

@@ -40,12 +40,7 @@ public class RecordViewModel extends BaseViewModel<FragmentRecordBinding, Fragme
}
private MutableLiveData<List<RecordsInfo>> mRecordsInfoData = new MutableLiveData<>();
public MutableLiveData<List<RecordsInfo>> getRecordsInfoData() {
return mRecordsInfoData;
}
public MutableLiveData<List<RecordsInfo>> mRecordsInfoData = new MutableLiveData<>();
/**
* 读取数据
@@ -115,11 +110,7 @@ public class RecordViewModel extends BaseViewModel<FragmentRecordBinding, Fragme
mRecordsInfoData.setValue(list);
}
private MutableLiveData<Map<String, Contact>> mContactMapData = new MutableLiveData();
public MutableLiveData<Map<String, Contact>> getContactMapData() {
return mContactMapData;
}
public MutableLiveData<Map<String, Contact>> mContactMapData = new MutableLiveData();
public void getContact() {
String jsonString = mMMKV.decodeString(UrlAddress.GET_MAIL_LIST);
@@ -139,7 +130,7 @@ public class RecordViewModel extends BaseViewModel<FragmentRecordBinding, Fragme
public Contact apply(Contact contact) {
return contact;
}
}));
}, (contact, contact2) -> contact));
mContactMapData.setValue(map);
}
}

View File

@@ -37,6 +37,7 @@ import com.xxpatx.os.bean.RegionInfo;
import com.xxpatx.os.bean.ServeBean;
import com.xxpatx.os.bean.SnInfo;
import com.xxpatx.os.bean.SystemSettings;
import com.xxpatx.os.bean.TestAppInfo;
import com.xxpatx.os.bean.UserAvatarInfo;
import com.xxpatx.os.bean.UserId;
import com.xxpatx.os.bean.WxpayBean;
@@ -65,6 +66,7 @@ import com.xxpatx.os.network.api.uiui.RegionListApi;
import com.xxpatx.os.network.api.uiui.RegionListCall;
import com.xxpatx.os.network.api.uiui.ServeApi;
import com.xxpatx.os.network.api.uiui.SnIsActivationApi;
import com.xxpatx.os.network.api.uiui.TestAppApi;
import com.xxpatx.os.network.api.uiui.UpdateAppIconApi;
import com.xxpatx.os.network.api.uiui.UserInfoControl;
import com.xxpatx.os.network.api.uiui.alarmclock.AlarmClockAddApi;
@@ -600,6 +602,13 @@ public class NetInterfaceManager {
.observeOn(AndroidSchedulers.mainThread());
}
public Observable<BaseResponse<TestAppInfo>> getTestAppObservable() {
return mRetrofit.create(TestAppApi.class)
.getTestApp(Utils.getSerial(), BuildConfig.platform, BuildConfig.APPLICATION_ID)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
public RegionListApi getRegionListApi() {
return mRetrofit.create(RegionListApi.class);
}
@@ -1466,4 +1475,34 @@ public class NetInterfaceManager {
}
};
}
public void getTestApp() {
getTestAppObservable().subscribe(getTestAppObserver());
}
public Observer<BaseResponse<TestAppInfo>> getTestAppObserver() {
return new Observer<BaseResponse<TestAppInfo>>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e("getTestAppObserver", "onSubscribe: ");
}
@Override
public void onNext(@NonNull BaseResponse<TestAppInfo> testAppInfoBaseResponse) {
Log.e("getTestAppObserver", "onNext: " + testAppInfoBaseResponse);
}
@Override
public void onError(@NonNull Throwable e) {
Log.e("getTestAppObserver", "onError: " + e.getMessage());
}
@Override
public void onComplete() {
Log.e("getTestAppObserver", "onComplete: ");
}
};
}
}

View File

@@ -35,6 +35,8 @@ public class UrlAddress {
public static final String FAMILY_ADDRESS = "sn/family-address";
/*根据包名获取更新*/
public final static String GET_NEWESTAPPUPDATE = "app/newestAppUpdate";
/*获取灰度测试应用*/
public static final String GET_TEST_APP = "app/test-app";
/*获取抢购列表*/
public static final String GET_GOODS_LIST = "getGoodsList";

View File

@@ -0,0 +1,18 @@
package com.xxpatx.os.network.api.uiui;
import com.xxpatx.os.bean.BaseResponse;
import com.xxpatx.os.bean.TestAppInfo;
import com.xxpatx.os.network.UrlAddress;
import io.reactivex.rxjava3.core.Observable;
import retrofit2.http.GET;
import retrofit2.http.Query;
public interface TestAppApi {
@GET(UrlAddress.GET_TEST_APP)
Observable<BaseResponse<TestAppInfo>> getTestApp(
@Query("sn") String sn,
@Query("model_name") String model_name,
@Query("app_package") String app_package
);
}

View File

@@ -28,6 +28,7 @@ import com.xxpatx.os.R;
import com.xxpatx.os.activity.quickapp.QuickAppActivity;
import com.xxpatx.os.bean.AppInfo;
import com.xxpatx.os.bean.DesktopIcon;
import com.xxpatx.os.bean.TestAppInfo;
import com.xxpatx.os.config.CommonConfig;
import com.xxpatx.os.gson.GsonUtils;
import com.xxpatx.os.manager.AppManager;
@@ -442,7 +443,8 @@ public class ApkUtils {
DesktopIcon contactIcon = new DesktopIcon();
contactIcon.setTitle("联系人");
contactIcon.setPackage(AppManager.CONTACT_PACKAGE);
desktopIcons.add(1, contactIcon);
// TODO: 2024/10/22 2024-10-22 18:30:22 隐藏了客服中心将会报错
desktopIcons.add(contactIcon);
}
List<ShortcutPkgInfo> shortcutPkgInfos = ShortcutUtils.getInstance().getShortcutList();
@@ -964,6 +966,12 @@ public class ApkUtils {
return checkAppUpdate(context, packageName, versionCode);
}
public static boolean checkAppUpdate(Context context, TestAppInfo appUpdateInfo) {
String packageName = appUpdateInfo.getApp_package();
long versionCode = appUpdateInfo.getApp_version_code();
return checkAppUpdate(context, packageName, versionCode);
}
public static boolean checkAppUpdate(Context context, String packageName, long versionCode) {
PackageInfo packageInfo = null;
try {

View File

@@ -0,0 +1,391 @@
package com.xxpatx.os.utils;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
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;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
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;
import io.reactivex.rxjava3.core.ObservableOnSubscribe;
import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.Disposable;
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);
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;
}
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});
}
});
} 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);
}
});
}
}
emitter.onNext(1L);
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.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 insertConstacts(Context context, String name, String phone, List<String> list) {
long contactId = getContactId(context, name);
if (contactId == -1) {
ContentResolver resolver = context.getContentResolver();
//插入raw_contacts表并获取_id属性
ContentValues nameValues = new ContentValues();
long rawContactId = ContentUris.parseId(resolver.insert(ContactsContract.RawContacts.CONTENT_URI, nameValues));
//插入data表
//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, name);
resolver.insert(ContactsContract.Data.CONTENT_URI, nameValues);
try {
//写入头像
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.default_avatar);
ByteArrayOutputStream out = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
ContentValues photoValues = new ContentValues();
photoValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
photoValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE);
photoValues.put(ContactsContract.CommonDataKinds.Photo.PHOTO, out.toByteArray());
context.getContentResolver().insert(ContactsContract.Data.CONTENT_URI, photoValues);
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
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, phone);
phoneValues.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE);
//插入data表
context.getContentResolver().insert(ContactsContract.Data.CONTENT_URI, phoneValues);
}
}
/**
* 判断某个手机号是否存在
*/
public static boolean isThePhoneExist(Context context, String phoneNum) {
//uri= content://com.android.contacts/data/phones/filter/#
Cursor cursor = null;
try {
Uri uri = Uri.parse("content://com.android.contacts/data/phones/filter/" + phoneNum);
ContentResolver resolver = context.getContentResolver();
cursor = resolver.query(uri, new String[]{ContactsContract.Data.DISPLAY_NAME},
null, null, null); //从raw_contact表中返回display_name
for (String columnName : cursor.getColumnNames()) {
Log.e("isThePhoneExist: ", columnName);
}
while (cursor.moveToNext()) {
for (String columnName : cursor.getColumnNames()) {
Log.e("isThePhoneExist: ", columnName);
Log.e("isThePhoneExist: ", cursor.getColumnIndex(columnName) + "");
if (cursor.getColumnIndex(columnName) != -1) {
Log.e("isThePhoneExist: getString = ", " - " + cursor.getString(cursor.getColumnIndex(columnName)));
}
}
}
if (cursor.moveToFirst()) {
//Log.i(TAG, "name=" + cursor.getString(0) + " , phoneNum = " + phoneNum);
cursor.close();
return true;
}
} catch (Exception e) {
//Log.i(TAG, "163 e =" + e.getMessage());
e.printStackTrace();
} finally {
if (cursor != null) {
cursor.close();
}
}
return false;
}
/**
* 获取所有联系人信息
*/
// public static List<SysContactsListBean> getAllSysContacts(Context context) {
// List<SysContactsListBean> list = new ArrayList<>();
// try {
// ContentResolver resolver = context.getContentResolver();
// SysContactsListBean sysContactsListBean;
// Uri uri = Uri.parse("content://com.android.contacts/data/phones");
//
// Cursor cursor1 = resolver.query(uri,
// new String[]{ContactsContract.Data.RAW_CONTACT_ID,
// ContactsContract.Data.DISPLAY_NAME,
// ContactsContract.CommonDataKinds.Phone.NUMBER},
// null, null, null);
//
// while (cursor1.moveToNext()) {
// sysContactsListBean = new SysContactsListBean();
// sysContactsListBean.setCustomerId(cursor1.getLong(0));
// sysContactsListBean.setCustomerName(cursor1.getString(1));
// sysContactsListBean.setPhoneNumber(cursor1.getString(2));
// list.add(sysContactsListBean);
// }
// } catch (Exception e) {
// e.printStackTrace();
// }
//
// if (!CollectorUtils.isEmpty(list)) {
// Collections.sort(list, new Comparator<SysContactsListBean>() {
// @Override
// public int compare(SysContactsListBean o1, SysContactsListBean o2) {
// return o2.getCustomerName().compareTo(o1.getCustomerName());
// }
// });
// }
// return list;
// }
public static void getContacts(Context context) {
//https://blog.csdn.net/luofeixiongsix/article/details/48849511
//查询raw_contacts表获得联系人
ContentResolver resolver = context.getContentResolver();
// Uri uri = ContactsContract.Data.CONTENT_URI;//content://com.android.contacts/data 有电话+86
// Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;//content://com.android.contacts/data/phones 有电话+86
// Uri uri = ContactsContract.RawContacts.CONTENT_URI;//content://com.android.contacts/raw_contacts 无电话
Uri uri = ContactsContract.Contacts.CONTENT_URI;//content://com.android.contacts/contacts 无电话
Log.e(TAG, "getContacts: " + uri.toString());
//查询联系人
Cursor cursor1 = resolver.query(ContactsContract.Data.CONTENT_URI, null, null, null, null);
Log.e("getContacts: cursor1 = ", Arrays.toString(cursor1.getColumnNames()));
Cursor cursor2 = resolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
Log.e("getContacts: cursor2 = ", Arrays.toString(cursor1.getColumnNames()));
Cursor cursor3 = resolver.query(ContactsContract.RawContacts.CONTENT_URI, null, null, null, null);
Log.e("getContacts: cursor3 = ", Arrays.toString(cursor1.getColumnNames()));
Cursor cursor4 = resolver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
Log.e("getContacts: cursor4 = ", Arrays.toString(cursor1.getColumnNames()));
// while (cursor.moveToNext()) {
// String name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
// String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
// Log.e(TAG, "getContacts: 联系人:" + name);
// Log.e(TAG, "getContacts: 电话:" + number);
// }
// for (String columnName : cursor.getColumnNames()) {
// Log.e("getContacts: ", columnName);
// }
// while (cursor.moveToNext()) {
// for (String columnName : cursor.getColumnNames()) {
// Log.e("getContacts: ", cursor.getColumnIndex(columnName) + "\t" + columnName);
// if (cursor.getColumnIndex(columnName) != -1) {
// Log.e("getContacts: getString =", " " + cursor.getString(cursor.getColumnIndex(columnName)));
// }
// }
// }
// cursor.close();
}
public static List<ContactId> getLocalContacts(Context context) {
ContentResolver resolver = context.getContentResolver();
Uri uri = ContactsContract.Contacts.CONTENT_URI;
Cursor cursor = resolver.query(uri, null, null, null, null);
List<ContactId> contactIds = new ArrayList<>();
while (cursor.moveToNext()) {
long id = cursor.getLong(cursor.getColumnIndexOrThrow("name_raw_contact_id"));
int in_phone = cursor.getInt(cursor.getColumnIndexOrThrow("indicate_phone_or_sim_contact"));
String display_name = cursor.getString(cursor.getColumnIndexOrThrow("display_name"));
String photo_uri = cursor.getString(cursor.getColumnIndexOrThrow("photo_uri"));
ContactId contactId = new ContactId(id, in_phone, display_name, photo_uri);
contactIds.add(contactId);
}
cursor.close();
List<ContactId> filter = contactIds.stream().filter(new Predicate<ContactId>() {
@Override
public boolean test(ContactId contactId) {
return contactId.getInPhone() == -1;
}
}).collect(Collectors.toList());
Log.e(TAG, "getLocalContacts: " + filter);
return filter;
}
/**
* 判断某个手机号是否存在
*/
public static boolean isExist(Context context, String phoneNum) {
//uri= content://com.android.contacts/data/phones/filter/#
Cursor cursor = null;
try {
Uri uri = Uri.parse("content://com.android.contacts/data/phones/filter/" + phoneNum);
ContentResolver resolver = context.getContentResolver();
cursor = resolver.query(uri, new String[]{ContactsContract.Data.DISPLAY_NAME},
null, null, null); //从raw_contact表中返回display_name
if (cursor.moveToFirst()) {
cursor.close();
return true;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null) {
cursor.close();
}
}
return false;
}
/**
* @param context
* @param phoneNum
* @return 获取联系人id
*/
public static long getContactId(Context context, String phoneNum) {
Cursor cursor = null;
try {
Uri uri = Uri.parse("content://com.android.contacts/data/phones/filter/" + phoneNum);
ContentResolver resolver = context.getContentResolver();
cursor = resolver.query(uri, null, null, null, null); //从raw_contact表中返回display_name
if (cursor.moveToFirst()) {
for (String columnName : cursor.getColumnNames()) {
Log.e("getContactId: ", cursor.getColumnIndex(columnName) + "\t" + columnName);
if (cursor.getColumnIndex(columnName) != -1) {
Log.e("getContactId: getString =", " " + cursor.getString(cursor.getColumnIndex(columnName)));
}
}
return cursor.getLong(cursor.getColumnIndexOrThrow(ContactsContract.Data.CONTACT_ID));
}
cursor.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null) {
cursor.close();
}
}
return -1;
}
}

View File

@@ -0,0 +1,84 @@
package com.xxpatx.os.utils;
import android.text.TextUtils;
import android.util.Log;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.tencent.mmkv.MMKV;
import com.xxpatx.os.bean.Contact;
import com.xxpatx.os.config.CommonConfig;
import com.xxpatx.os.gson.GsonUtils;
import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.Set;
public class LocalContactUtils {
private static final String TAG = "LocalContactUtils";
private static MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE);
public static Set<Contact> getLocalContact() {
Set<Contact> contacts = new HashSet<>();
String jsonString = mMMKV.decodeString(CommonConfig.CONTACT_LOCAL_CACHE_KEY, "");
if (TextUtils.isEmpty(jsonString)) {
return contacts;
} else {
Gson gson = new Gson();
Type type = new TypeToken<Set<Contact>>() {
}.getType();
try {
contacts = gson.fromJson(jsonString, type);
return contacts;
} catch (Exception e) {
Log.e(TAG, "getLocalContact: " + e.getMessage());
}
}
return contacts;
}
public static boolean addLocalContact(Contact contact) {
String jsonString = mMMKV.decodeString(CommonConfig.CONTACT_LOCAL_CACHE_KEY, "");
if (TextUtils.isEmpty(jsonString)) {
Set<Contact> contacts = new HashSet<>();
contacts.add(contact);
return mMMKV.encode(CommonConfig.CONTACT_LOCAL_CACHE_KEY, GsonUtils.toJSONString(contacts));
} else {
Gson gson = new Gson();
Type type = new TypeToken<Set<Contact>>() {
}.getType();
try {
Set<Contact> contacts = gson.fromJson(jsonString, type);
if (contacts == null) {
contacts = new HashSet<>();
}
contacts.add(contact);
return mMMKV.encode(CommonConfig.CONTACT_LOCAL_CACHE_KEY, GsonUtils.toJSONString(contacts));
} catch (Exception e) {
Log.e(TAG, "addLocalContact: " + e.getMessage());
mMMKV.encode(CommonConfig.CONTACT_LOCAL_CACHE_KEY, "");
}
}
return false;
}
public static void delLocalContact(Contact contact) {
String jsonString = mMMKV.decodeString(CommonConfig.CONTACT_LOCAL_CACHE_KEY, "");
if (TextUtils.isEmpty(jsonString)) {
return;
}
Gson gson = new Gson();
Type type = new TypeToken<Set<Contact>>() {
}.getType();
try {
Set<Contact> contacts = gson.fromJson(jsonString, type);
contacts.remove(contact);
} catch (Exception e) {
Log.e(TAG, "getLocalContact: " + e.getMessage());
}
}
}

View File

@@ -0,0 +1,47 @@
package com.xxpatx.os.utils;
import android.content.Context;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import java.util.List;
public class MobileNetworkUtils {
public static CharSequence getCurrentCarrierNameForDisplay(Context context, int subId) {
final SubscriptionManager sm = context.getSystemService(SubscriptionManager.class);
if (sm != null) {
final SubscriptionInfo subInfo = getSubscriptionInfo(sm, subId);
if (subInfo != null) {
return subInfo.getCarrierName();
}
}
return getOperatorNameFromTelephonyManager(context);
}
private static SubscriptionInfo getSubscriptionInfo(SubscriptionManager subManager,
int subId) {
List<SubscriptionInfo> subInfos = subManager.getAccessibleSubscriptionInfoList();
if (subInfos == null) {
subInfos = subManager.getActiveSubscriptionInfoList();
}
if (subInfos == null) {
return null;
}
for (SubscriptionInfo subInfo : subInfos) {
if (subInfo.getSubscriptionId() == subId) {
return subInfo;
}
}
return null;
}
private static String getOperatorNameFromTelephonyManager(Context context) {
final TelephonyManager tm =
(TelephonyManager) context.getSystemService(TelephonyManager.class);
if (tm == null) {
return null;
}
return tm.getNetworkOperatorName();
}
}

View File

@@ -0,0 +1,56 @@
package com.xxpatx.os.utils;
import com.google.i18n.phonenumbers.NumberParseException;
import com.google.i18n.phonenumbers.PhoneNumberToCarrierMapper;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.google.i18n.phonenumbers.Phonenumber;
import com.google.i18n.phonenumbers.geocoding.PhoneNumberOfflineGeocoder;
import java.util.Locale;
public class MobileNumberUtils {
private static final String TAG = "MobileNumberUtils";
private static final String LANGUAGE = "CN";
//获取手机号码运营商
public static String getCarrier(String phoneNumber) {
PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.getInstance();
PhoneNumberToCarrierMapper carrierMapper = PhoneNumberToCarrierMapper.getInstance();
Phonenumber.PhoneNumber referencePhonenumber = new Phonenumber.PhoneNumber();
try {
referencePhonenumber = phoneNumberUtil.parse(phoneNumber, LANGUAGE);
} catch (NumberParseException e) {
e.printStackTrace();
}
//返回结果只有英文,自己转成成中文
String carrierEn = carrierMapper.getNameForNumber(referencePhonenumber, Locale.CHINA);
// if (Locale.CHINA.getCountry().equals(Locale.getDefault().getCountry())) {
// switch (carrierEn) {
// case "China Mobile":
// return "中国移动";
// case "China Unicom":
// return "中国联通";
// case "China Telecom":
// return "中国电信";
// default:
// break;
// }
// }
return carrierEn;
}
//获取手机号码归属地
public static String getGeo(String phoneNumber) {
PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.getInstance();
PhoneNumberOfflineGeocoder geocoder = PhoneNumberOfflineGeocoder.getInstance();
Phonenumber.PhoneNumber referencePhonenumber = null;
try {
referencePhonenumber = phoneNumberUtil.parse(phoneNumber, LANGUAGE);
//手机号码归属城市 referenceRegion
return geocoder.getDescriptionForNumber(referencePhonenumber, Locale.CHINA);
} catch (NumberParseException e) {
e.printStackTrace();
}
return "未知";
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -5,6 +5,7 @@
tools:context=".activity.contact.AddContactActivity">
<data>
<variable
name="click"
type="com.xxpatx.os.activity.contact.AddContactActivity.BtnClick" />
@@ -12,11 +13,11 @@
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:background="#FAF8F8"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:background="#FAF8F8">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraintLayout3"
android:id="@+id/cl_exit"
android:layout_width="match_parent"
android:layout_height="64dp"
android:background="@drawable/general_setting_bg"
@@ -26,11 +27,11 @@
<ImageView
android:id="@+id/iv_cancel"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginStart="16dp"
android:onClick="@{click::exit}"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginStart="8dp"
android:adjustViewBounds="true"
android:onClick="@{click::exit}"
android:scaleType="centerInside"
android:src="@drawable/add_contact_back"
app:layout_constraintBottom_toBottomOf="parent"
@@ -49,41 +50,26 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/iv_confirm"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginEnd="8dp"
android:adjustViewBounds="true"
android:onClick="@{click::confirm}"
android:scaleType="centerInside"
android:src="@drawable/icon_confirm"
android:visibility="gone"
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="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@+id/constraintLayout3">
app:layout_constraintBottom_toTopOf="@+id/cl_bottom"
app:layout_constraintTop_toBottomOf="@+id/cl_exit"
tools:layout_editor_absoluteX="16dp">
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="vertical"
app:layout_constraintBottom_toTopOf="@+id/cl_confirm"
app:layout_constraintBottom_toTopOf="@+id/constraintLayout27"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent">
android:layout_height="wrap_content"
android:orientation="vertical">
<com.shehuan.niv.NiceImageView
android:id="@+id/nv_avatar"
@@ -99,25 +85,6 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_margin="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="保存至本机"
android:textColor="@color/black"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="60dp"
@@ -162,7 +129,7 @@
android:layout_marginEnd="8dp"
android:background="@null"
android:ellipsize="end"
android:hint="姓名"
android:hint="请输入微信昵称"
android:inputType="text"
android:maxLines="1"
android:singleLine="true"
@@ -183,7 +150,7 @@
android:background="@drawable/add_wechat_contact_background">
<ImageView
android:id="@+id/imageView8"
android:id="@+id/imageView9"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginStart="12dp"
@@ -220,7 +187,7 @@
android:layout_marginEnd="8dp"
android:background="@null"
android:ellipsize="end"
android:hint="号码"
android:hint="请输入手机号码"
android:inputType="phone"
android:maxLines="1"
android:singleLine="true"
@@ -234,6 +201,65 @@
</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">
<ImageView
android:id="@+id/imageView11"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginStart="12dp"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:src="@drawable/icon_avatar"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView30"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:background="@null"
android:ellipsize="end"
android:gravity="center"
android:maxLines="1"
android:singleLine="true"
android:text="微信"
android:textColor="@color/black"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/et_tag"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="8dp"
android:background="@null"
android:ellipsize="end"
android:hint="请输入微信标签"
android:inputType="text"
android:maxLines="1"
android:singleLine="true"
android:text="@string/app_name"
android:textColor="@color/black"
android:textColorHint="@color/ok_button"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/textView30"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="60dp"
@@ -262,16 +288,89 @@
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_margin="8dp"
android:visibility="gone"
android:background="@drawable/add_wechat_contact_background">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:text="保存到SIM卡"
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_sim"
android:layout_width="37dp"
android:layout_height="20dp"
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"
android:visibility="gone">
<ImageView
android:id="@+id/imageView8"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginStart="12dp"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:src="@drawable/icon_phone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/et_wechat_id"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:background="@null"
android:ellipsize="end"
android:hint="微信号码(可空)"
android:inputType="phone"
android:maxLines="1"
android:singleLine="true"
android:textColor="@color/white"
android:textColorHint="@color/gray"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/imageView8"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
</ScrollView>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_confirm"
android:id="@+id/constraintLayout27"
android:layout_width="match_parent"
android:layout_height="52dp"
android:layout_margin="8dp"
android:onClick="@{click::confirm}"
android:background="@drawable/add_contact_confirm_background"
android:onClick="@{click::addContact}"
app:layout_constraintBottom_toBottomOf="parent"
tools:layout_editor_absoluteX="14dp">
@@ -296,5 +395,12 @@
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_bottom"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@@ -1,405 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".activity.contact.AddWechatContactActivity">
<data>
<variable
name="click"
type="com.xxpatx.os.activity.contact.AddWechatContactActivity.BtnClick" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FAF8F8">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_exit"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="@drawable/general_setting_bg"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/iv_cancel"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginStart="8dp"
android:adjustViewBounds="true"
android:onClick="@{click::exit}"
android:scaleType="centerInside"
android:src="@drawable/add_contact_back"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:text="新建联系人"
android:textColor="@color/white"
android:textSize="22sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/cl_bottom"
app:layout_constraintTop_toBottomOf="@+id/cl_exit"
tools:layout_editor_absoluteX="16dp">
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="vertical"
app:layout_constraintBottom_toTopOf="@+id/constraintLayout27"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.shehuan.niv.NiceImageView
android:id="@+id/nv_avatar"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center"
android:layout_marginTop="32dp"
android:layout_marginBottom="32dp"
android:onClick="@{click::selectPic}"
android:src="@drawable/default_avatar"
app:is_circle="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_margin="8dp"
android:background="@drawable/add_wechat_contact_background">
<ImageView
android:id="@+id/imageView7"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginStart="12dp"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:src="@drawable/icon_avatar"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView18"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:background="@null"
android:ellipsize="end"
android:gravity="center"
android:maxLines="1"
android:singleLine="true"
android:text="姓名"
android:textColor="@color/black"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/et_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="8dp"
android:background="@null"
android:ellipsize="end"
android:hint="请输入微信昵称"
android:inputType="text"
android:maxLines="1"
android:singleLine="true"
android:textColor="@color/black"
android:textColorHint="@color/ok_button"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/textView18"
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">
<ImageView
android:id="@+id/imageView9"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginStart="12dp"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:src="@drawable/icon_phone"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView19"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:background="@null"
android:ellipsize="end"
android:gravity="center"
android:maxLines="1"
android:singleLine="true"
android:text="号码"
android:textColor="@color/black"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/et_phone"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="8dp"
android:background="@null"
android:ellipsize="end"
android:hint="请输入手机号码"
android:inputType="phone"
android:maxLines="1"
android:singleLine="true"
android:textColor="@color/black"
android:textColorHint="@color/ok_button"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/textView19"
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">
<ImageView
android:id="@+id/imageView11"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginStart="12dp"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:src="@drawable/icon_avatar"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView30"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:background="@null"
android:ellipsize="end"
android:gravity="center"
android:maxLines="1"
android:singleLine="true"
android:text="微信"
android:textColor="@color/black"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/et_tag"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="8dp"
android:background="@null"
android:ellipsize="end"
android:hint="请输入微信标签"
android:inputType="text"
android:maxLines="1"
android:singleLine="true"
android:text="@string/app_name"
android:textColor="@color/black"
android:textColorHint="@color/ok_button"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/textView30"
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/toggleButton"
android:layout_width="37dp"
android:layout_height="20dp"
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="保存到SIM卡"
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_sim"
android:layout_width="37dp"
android:layout_height="20dp"
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"
android:visibility="gone">
<ImageView
android:id="@+id/imageView8"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginStart="12dp"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:src="@drawable/icon_phone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/et_wechat_id"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:background="@null"
android:ellipsize="end"
android:hint="微信号码(可空)"
android:inputType="phone"
android:maxLines="1"
android:singleLine="true"
android:textColor="@color/white"
android:textColorHint="@color/gray"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/imageView8"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
</ScrollView>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraintLayout27"
android:layout_width="match_parent"
android:layout_height="52dp"
android:layout_margin="8dp"
android:background="@drawable/add_contact_confirm_background"
android:onClick="@{click::addContact}"
app:layout_constraintBottom_toBottomOf="parent"
tools:layout_editor_absoluteX="14dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:background="@null"
android:ellipsize="end"
android:gravity="center"
android:maxLines="1"
android:singleLine="true"
android:text="保存"
android:textColor="@color/white"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_bottom"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@@ -2,13 +2,13 @@
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".activity.contact.ContactActivity">
tools:context=".activity.contact.ContactListActivity">
<data>
<variable
name="click"
type="com.xxpatx.os.activity.contact.ContactActivity.BtnClick" />
type="com.xxpatx.os.activity.contact.ContactListActivity.BtnClick" />
</data>
<FrameLayout

View File

@@ -288,6 +288,56 @@
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="80dp"
android:onClick="@{click::setSimCard}">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:maxLines="1"
android:text="拨号设置"
android:textColor="@color/black"
android:textSize="25sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:maxLines="1"
android:text="未开启"
android:textColor="@color/setting_disable_color"
android:textSize="25sp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginEnd="16dp"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:src="@drawable/icon_more"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/lightGray"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="80dp"

View File

@@ -0,0 +1,78 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".activity.sim.SimCardActivity">
<data>
<variable
name="click"
type="com.xxpatx.os.activity.sim.SimCardActivity.BtnClick" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraintLayout3"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="@drawable/general_setting_bg"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/iv_cancel"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginStart="8dp"
android:adjustViewBounds="true"
android:onClick="@{click::exit}"
android:scaleType="centerInside"
android:src="@drawable/add_contact_back"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:text="默认拨号设置"
android:textColor="@color/white"
android:textSize="25sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/iv_confirm"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginEnd="8dp"
android:adjustViewBounds="true"
android:scaleType="centerInside"
android:src="@drawable/icon_confirm"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:background="@color/white"
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/constraintLayout3" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="240dp"
android:layout_marginTop="16dp"
android:background="@drawable/wechat_call_background"
app:layout_constraintBottom_toBottomOf="parent">
<TextView
android:id="@+id/tv_call"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:maxLines="1"
android:singleLine="true"
android:text="您是否要拨打电话"
android:textColor="@color/black"
android:textSize="28sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/iv_call"
android:layout_width="100dp"
android:layout_height="100dp"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:src="@drawable/icon_call_phone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_call" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -40,10 +40,11 @@
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_info"
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/tv_time"
app:layout_constraintStart_toEndOf="@+id/iv_avatar"
app:layout_constraintTop_toTopOf="parent">
@@ -62,31 +63,33 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:textColor="@color/noti_font_color"
android:textSize="14sp"
android:textColor="@color/black"
android:textSize="16sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_name"
tools:text="12345665432" />
<TextView
android:id="@+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:layout_marginEnd="8dp"
android:textColor="@color/noti_font_color"
android:textSize="14sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_phone"
tools:text="12:00" />
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:layout_marginEnd="8dp"
android:textColor="@color/black"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
tools:text="12:00" />
<ImageView
android:id="@+id/iv_remove"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginEnd="16dp"
android:visibility="gone"
android:src="@drawable/icon_record_remove"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"

View File

@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
@@ -13,48 +14,55 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
android:layout_weight="2">
<TextView
android:id="@+id/tv_carrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:maxEms="4"
android:gravity="center"
android:minEms="4"
android:minLines="1"
android:singleLine="true"
android:textSize="15sp"
android:textColor="@color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="中国移动" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2">
<ImageView
android:id="@+id/iv_card"
android:layout_width="32dp"
android:layout_height="32dp"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:src="@drawable/sim_card_1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<ImageView
android:id="@+id/iv_card"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginStart="4dp"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:src="@drawable/sim_card_1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/tv_carrier"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_number"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="5"
android:layout_marginStart="4dp"
android:gravity="left|center_vertical"
android:maxLines="1"
android:text="1234567890"
android:textColor="@color/black"
android:textSize="16sp" />
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/iv_card"
tools:text="1234567890" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
<View
android:layout_width="match_parent"

View File

@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="64dp"
android:background="@drawable/phone_background"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="2">
<TextView
android:id="@+id/tv_carrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:maxEms="4"
android:gravity="center"
android:minEms="4"
android:minLines="1"
android:singleLine="true"
android:textSize="15sp"
android:textColor="@color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="中国移动" />
<TextView
android:id="@+id/tv_number"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginStart="4dp"
android:gravity="left|center_vertical"
android:maxLines="1"
android:textColor="@color/black"
android:textSize="16sp"
app:layout_constraintEnd_toStartOf="@+id/iv_select"
app:layout_constraintStart_toEndOf="@+id/tv_carrier"
tools:text="1234567890" />
<ImageView
android:id="@+id/iv_select"
android:src="@drawable/icon_select"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginEnd="4dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:background="@color/gray"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -109,6 +109,8 @@
<item name="android:windowBackground">@android:color/transparent</item>
<!--是否去除标题 -->
<item name="android:windowNoTitle">true</item>
<!--是否全屏 -->
<item name="android:windowFullscreen">true</item>
<!--是否去除边框-->
<item name="android:windowFrame">@null</item>
<!--是否浮现在activity之上-->