diff --git a/app/build.gradle b/app/build.gradle index dd5936e..ebbba13 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c76d78d..73b984b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -155,7 +155,11 @@ android:launchMode="singleTask" android:screenOrientation="portrait" /> + @@ -167,10 +171,6 @@ android:name=".activity.setting.TouchActivity" android:launchMode="singleTask" android:screenOrientation="portrait" /> - diff --git a/app/src/main/java/com/xxpatx/os/activity/alarm/list/AlarmListActivity.java b/app/src/main/java/com/xxpatx/os/activity/alarm/list/AlarmListActivity.java index 04b6cdb..ea86dab 100644 --- a/app/src/main/java/com/xxpatx/os/activity/alarm/list/AlarmListActivity.java +++ b/app/src/main/java/com/xxpatx/os/activity/alarm/list/AlarmListActivity.java @@ -121,7 +121,7 @@ public class AlarmListActivity extends BaseMvvmActivity>() { + mViewModel.mAlarmClockData.observe(this, new androidx.lifecycle.Observer>() { @Override public void onChanged(List alarmClockData) { setAlarmClock(alarmClockData); diff --git a/app/src/main/java/com/xxpatx/os/activity/alarm/list/AlarmListViewModel.java b/app/src/main/java/com/xxpatx/os/activity/alarm/list/AlarmListViewModel.java index 436ae4d..7b63cb3 100644 --- a/app/src/main/java/com/xxpatx/os/activity/alarm/list/AlarmListViewModel.java +++ b/app/src/main/java/com/xxpatx/os/activity/alarm/list/AlarmListViewModel.java @@ -32,11 +32,7 @@ public class AlarmListViewModel extends BaseViewModel> mAlarmClockData = new MutableLiveData<>(); - - public MutableLiveData> getAlarmClockData() { - return mAlarmClockData; - } + public MutableLiveData> mAlarmClockData = new MutableLiveData<>(); public void getAlarmClock() { NetInterfaceManager.getInstance().getAlarmClock(getLifecycle(), new NetInterfaceManager.AlarmClockCallback() { diff --git a/app/src/main/java/com/xxpatx/os/activity/contact/AddContactActivity.java b/app/src/main/java/com/xxpatx/os/activity/contact/AddContactActivity.java index 8fe6048..b8c847f 100644 --- a/app/src/main/java/com/xxpatx/os/activity/contact/AddContactActivity.java +++ b/app/src/main/java/com/xxpatx/os/activity/contact/AddContactActivity.java @@ -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 { 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() { + @Override + public void onChanged(Boolean aBoolean) { + if (aBoolean) { + mLoadingDialog.loadSuccess(); + finish(); + } else { + mLoadingDialog.loadFailed(); + } + } + }); + mViewModel.mContactData.observe(this, new Observer() { + @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() { @Override public void onResult(ArrayList 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 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() { - @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() { + @Override + public void onResourceReady(@androidx.annotation.NonNull Bitmap resource, @Nullable Transition 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() { + @Override + public void onResourceReady(@androidx.annotation.NonNull Bitmap resource, @Nullable Transition 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(); + } } } } diff --git a/app/src/main/java/com/xxpatx/os/activity/contact/AddContactViewModel.java b/app/src/main/java/com/xxpatx/os/activity/contact/AddContactViewModel.java index 943e818..18dd01d 100644 --- a/app/src/main/java/com/xxpatx/os/activity/contact/AddContactViewModel.java +++ b/app/src/main/java/com/xxpatx/os/activity/contact/AddContactViewModel.java @@ -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 { + private static final String TAG = "AddContactViewModel"; @Override public ActivityAddContactBinding getVDBinding() { @@ -15,4 +42,93 @@ public class AddContactViewModel extends BaseViewModel mAddData = new MutableLiveData<>(); + + public MutableLiveData 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 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() { + @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: "); + } + }); + } + } diff --git a/app/src/main/java/com/xxpatx/os/activity/contact/AddWechatContactActivity.java b/app/src/main/java/com/xxpatx/os/activity/contact/AddWechatContactActivity.java deleted file mode 100644 index 14e63a6..0000000 --- a/app/src/main/java/com/xxpatx/os/activity/contact/AddWechatContactActivity.java +++ /dev/null @@ -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 { - 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() { - @Override - public void onChanged(Boolean aBoolean) { - if (aBoolean) { - mLoadingDialog.loadSuccess(); - finish(); - } else { - mLoadingDialog.loadFailed(); - } - } - }); - mViewModel.getContactData().observe(this, new Observer() { - @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() { - @Override - public void onResult(ArrayList 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(); - } - } - } -} diff --git a/app/src/main/java/com/xxpatx/os/activity/contact/AddWechatContactViewModel.java b/app/src/main/java/com/xxpatx/os/activity/contact/AddWechatContactViewModel.java deleted file mode 100644 index 440888e..0000000 --- a/app/src/main/java/com/xxpatx/os/activity/contact/AddWechatContactViewModel.java +++ /dev/null @@ -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 { - private static final String TAG = "AddWechatContactViewModel"; - - @Override - public ActivityAddWechatContactBinding getVDBinding() { - return binding; - } - - @Override - public void onDestroy() { - - } - - public String avatarFilePath = ""; - - private MutableLiveData mAddData = new MutableLiveData<>(); - - public MutableLiveData getAddData() { - return mAddData; - } - - private MutableLiveData mContactData = new MutableLiveData<>(); - - public MutableLiveData 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 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() { - @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: "); - } - }); - } - -} diff --git a/app/src/main/java/com/xxpatx/os/activity/contact/ContactActivity.java b/app/src/main/java/com/xxpatx/os/activity/contact/ContactListActivity.java similarity index 93% rename from app/src/main/java/com/xxpatx/os/activity/contact/ContactActivity.java rename to app/src/main/java/com/xxpatx/os/activity/contact/ContactListActivity.java index 87f3f73..cbe8293 100644 --- a/app/src/main/java/com/xxpatx/os/activity/contact/ContactActivity.java +++ b/app/src/main/java/com/xxpatx/os/activity/contact/ContactListActivity.java @@ -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 { - private static final String TAG = "ContactActivity"; +public class ContactListActivity extends BaseMvvmActivity { + 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 { - private static final String TAG = "ContactViewModel"; +public class ContactListViewModel extends BaseViewModel { + 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; } diff --git a/app/src/main/java/com/xxpatx/os/activity/contact/EditContactActivity.java b/app/src/main/java/com/xxpatx/os/activity/contact/EditContactActivity.java index c05aeed..127483a 100644 --- a/app/src/main/java/com/xxpatx/os/activity/contact/EditContactActivity.java +++ b/app/src/main/java/com/xxpatx/os/activity/contact/EditContactActivity.java @@ -80,7 +80,7 @@ public class EditContactActivity extends BaseMvvmActivity() { + mViewModel.mBaseResponseMutableLiveData.observe(this, new Observer() { @Override public void onChanged(BaseResponse baseResponse) { if (baseResponse.code == 200) { diff --git a/app/src/main/java/com/xxpatx/os/activity/contact/EditContactViewModel.java b/app/src/main/java/com/xxpatx/os/activity/contact/EditContactViewModel.java index f328187..bac480b 100644 --- a/app/src/main/java/com/xxpatx/os/activity/contact/EditContactViewModel.java +++ b/app/src/main/java/com/xxpatx/os/activity/contact/EditContactViewModel.java @@ -30,11 +30,7 @@ public class EditContactViewModel extends BaseViewModel mBaseResponseMutableLiveData = new MutableLiveData<>(); - - public MutableLiveData getBaseResponseMutableLiveData() { - return mBaseResponseMutableLiveData; - } + public MutableLiveData mBaseResponseMutableLiveData = new MutableLiveData<>(); public void editContact(Map params, MultipartBody.Part body) { NetInterfaceManager.getInstance() diff --git a/app/src/main/java/com/xxpatx/os/activity/dock/DockActivity.java b/app/src/main/java/com/xxpatx/os/activity/dock/DockActivity.java index e61c205..e16bcfb 100644 --- a/app/src/main/java/com/xxpatx/os/activity/dock/DockActivity.java +++ b/app/src/main/java/com/xxpatx/os/activity/dock/DockActivity.java @@ -76,7 +76,7 @@ public class DockActivity extends BaseMvvmActivity>() { + mViewModel.mAppSelectBeanListData.observe(this, new Observer>() { @Override public void onChanged(List dockApps) { mDockAppSelectedAdapter.setDockAppList(dockApps); diff --git a/app/src/main/java/com/xxpatx/os/activity/dock/DockViewModel.java b/app/src/main/java/com/xxpatx/os/activity/dock/DockViewModel.java index 462b19f..480843b 100644 --- a/app/src/main/java/com/xxpatx/os/activity/dock/DockViewModel.java +++ b/app/src/main/java/com/xxpatx/os/activity/dock/DockViewModel.java @@ -28,11 +28,7 @@ public class DockViewModel extends BaseViewModel> mAppSelectBeanListData = new MutableLiveData<>(); - - public MutableLiveData> getAppSelectBeanListData() { - return mAppSelectBeanListData; - } + public MutableLiveData> mAppSelectBeanListData = new MutableLiveData<>(); public void getPackageList() { PackageManager pm = getCtx().getPackageManager(); diff --git a/app/src/main/java/com/xxpatx/os/activity/emergency/EmergencyActivity.java b/app/src/main/java/com/xxpatx/os/activity/emergency/EmergencyActivity.java index 0b2efcf..3851911 100644 --- a/app/src/main/java/com/xxpatx/os/activity/emergency/EmergencyActivity.java +++ b/app/src/main/java/com/xxpatx/os/activity/emergency/EmergencyActivity.java @@ -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>() { + mViewModel.mContactListData.observe(this, new androidx.lifecycle.Observer>() { @Override public void onChanged(List contacts) { phoneList = contacts; diff --git a/app/src/main/java/com/xxpatx/os/activity/emergency/EmergencyViewModel.java b/app/src/main/java/com/xxpatx/os/activity/emergency/EmergencyViewModel.java index d897437..47c861f 100644 --- a/app/src/main/java/com/xxpatx/os/activity/emergency/EmergencyViewModel.java +++ b/app/src/main/java/com/xxpatx/os/activity/emergency/EmergencyViewModel.java @@ -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> mContactListData = new MutableLiveData<>(); - - public MutableLiveData> getContactListData() { - return mContactListData; - } + public MutableLiveData> mContactListData = new MutableLiveData<>(); public void getCacheContact() { String jsonString = mMMKV.getString(CommonConfig.EMERGENCY_CONTACT_LIST_KEY, null); diff --git a/app/src/main/java/com/xxpatx/os/activity/location/LocationAcivity.java b/app/src/main/java/com/xxpatx/os/activity/location/LocationAcivity.java index 0974d56..c071b7d 100644 --- a/app/src/main/java/com/xxpatx/os/activity/location/LocationAcivity.java +++ b/app/src/main/java/com/xxpatx/os/activity/location/LocationAcivity.java @@ -150,7 +150,7 @@ public class LocationAcivity extends BaseMvvmActivity>() { + mViewModel.mAddressBeanListData.observe(this, new Observer>() { @Override public void onChanged(List addressBeans) { mDistrict = addressBeans; diff --git a/app/src/main/java/com/xxpatx/os/activity/location/LocationViewModel.java b/app/src/main/java/com/xxpatx/os/activity/location/LocationViewModel.java index 25149e3..b340533 100644 --- a/app/src/main/java/com/xxpatx/os/activity/location/LocationViewModel.java +++ b/app/src/main/java/com/xxpatx/os/activity/location/LocationViewModel.java @@ -38,11 +38,7 @@ public class LocationViewModel extends BaseViewModel> mAddressBeanListData =new MutableLiveData<>(); - - public MutableLiveData> getAddressBeanListData() { - return mAddressBeanListData; - } + public MutableLiveData> mAddressBeanListData = new MutableLiveData<>(); public void initJsonData() { if (getCtx() == null) return; diff --git a/app/src/main/java/com/xxpatx/os/activity/main/MainActivity.java b/app/src/main/java/com/xxpatx/os/activity/main/MainActivity.java index 1dc3a6e..6759b4e 100644 --- a/app/src/main/java/com/xxpatx/os/activity/main/MainActivity.java +++ b/app/src/main/java/com/xxpatx/os/activity/main/MainActivity.java @@ -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 implements NetworkUtils.OnNetworkStatusChangedListener, NotificationService.NotificationListener { private static final String TAG = "MainActivity"; @@ -98,8 +104,8 @@ public class MainActivity extends BaseMvvmActivity 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 contactList = ContactCacheUtils.getInstance().getDatabaseContact(); diff --git a/app/src/main/java/com/xxpatx/os/activity/selectnumber/SelectNumberActivity.java b/app/src/main/java/com/xxpatx/os/activity/selectnumber/SelectNumberActivity.java index 9ee0c9a..37bc548 100644 --- a/app/src/main/java/com/xxpatx/os/activity/selectnumber/SelectNumberActivity.java +++ b/app/src/main/java/com/xxpatx/os/activity/selectnumber/SelectNumberActivity.java @@ -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 { 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() { + mViewModel.mAppInfoData.observe(this, new Observer() { @Override public void onChanged(AppInfo appInfo) { if (appInfo == null) { @@ -302,6 +303,10 @@ public class SettingActivity extends BaseMvvmActivity mAppInfoData = new MutableLiveData<>(); - - public MutableLiveData getAppInfoData() { - return mAppInfoData; - } + public MutableLiveData mAppInfoData = new MutableLiveData<>(); public void checkUpdate() { NetInterfaceManager.getInstance().getUpdateObservable() diff --git a/app/src/main/java/com/xxpatx/os/activity/sim/SimCardActivity.java b/app/src/main/java/com/xxpatx/os/activity/sim/SimCardActivity.java new file mode 100644 index 0000000..3f1bc4a --- /dev/null +++ b/app/src/main/java/com/xxpatx/os/activity/sim/SimCardActivity.java @@ -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 { + 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 subscriptionInfos = subscriptionManager.getActiveSubscriptionInfoList(); + List 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(); + } + } + +} diff --git a/app/src/main/java/com/xxpatx/os/activity/sim/SimCardViewModel.java b/app/src/main/java/com/xxpatx/os/activity/sim/SimCardViewModel.java new file mode 100644 index 0000000..ab85502 --- /dev/null +++ b/app/src/main/java/com/xxpatx/os/activity/sim/SimCardViewModel.java @@ -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 { + + @Override + public ActivitySimCardBinding getVDBinding() { + return binding; + } + + @Override + public void onDestroy() { + + } +} diff --git a/app/src/main/java/com/xxpatx/os/activity/weather/WeatherActivity.java b/app/src/main/java/com/xxpatx/os/activity/weather/WeatherActivity.java index 3b2aba9..967b90c 100644 --- a/app/src/main/java/com/xxpatx/os/activity/weather/WeatherActivity.java +++ b/app/src/main/java/com/xxpatx/os/activity/weather/WeatherActivity.java @@ -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() { + mViewModel.mQweatherLocationData.observe(this, new Observer() { @Override public void onChanged(QweatherLocation qweatherLocation) { if (qweatherLocation != null) { @@ -166,7 +165,7 @@ public class WeatherActivity extends BaseMvvmActivity() { + mViewModel.mLocationData.observe(this, new Observer() { @Override public void onChanged(String s) { mViewDataBinding.tvLocation.setText(s); @@ -174,7 +173,7 @@ public class WeatherActivity extends BaseMvvmActivity() { + mViewModel.mWeatherNowData.observe(this, new Observer() { @Override public void onChanged(WeatherNowBean weatherNowBean) { //先判断返回的status是否正确,当status正确时获取数据,若status不正确,可查看status对应的Code值找到原因 @@ -195,7 +194,7 @@ public class WeatherActivity extends BaseMvvmActivity() { + mViewModel.mWeatherDailyData.observe(this, new Observer() { @Override public void onChanged(WeatherDailyBean weatherDailyBean) { if (weatherDailyBean != null) { diff --git a/app/src/main/java/com/xxpatx/os/activity/weather/WeatherViewModel.java b/app/src/main/java/com/xxpatx/os/activity/weather/WeatherViewModel.java index 5e2f658..94ecbf7 100644 --- a/app/src/main/java/com/xxpatx/os/activity/weather/WeatherViewModel.java +++ b/app/src/main/java/com/xxpatx/os/activity/weather/WeatherViewModel.java @@ -50,11 +50,7 @@ public class WeatherViewModel extends BaseViewModel mGeoResultData = new MutableLiveData<>(); - - public MutableLiveData getGeoResultData() { - return mGeoResultData; - } + public MutableLiveData mGeoResultData = new MutableLiveData<>(); @Deprecated public void decodeGeo(String address) { @@ -92,11 +88,7 @@ public class WeatherViewModel extends BaseViewModel mQweatherLocationData = new MutableLiveData<>(); - - public MutableLiveData getQweatherLocationData() { - return mQweatherLocationData; - } + public MutableLiveData mQweatherLocationData = new MutableLiveData<>(); public void cityLookup(String city) { NetInterfaceManager.getInstance().getLookupObservable(city) @@ -155,11 +147,7 @@ public class WeatherViewModel extends BaseViewModel mLocationData = new MutableLiveData<>(); - - public MutableLiveData getLocationData() { - return mLocationData; - } + public MutableLiveData mLocationData = new MutableLiveData<>(); public void getLocation() { String location = AmapManager.getInstance().getDistrict(); @@ -182,11 +170,7 @@ public class WeatherViewModel extends BaseViewModel mWeatherNowData = new MutableLiveData<>(); - - public MutableLiveData getWeatherNowData() { - return mWeatherNowData; - } + public MutableLiveData mWeatherNowData = new MutableLiveData<>(); public void getWeatherNow(String locationTude) { Log.e(TAG, "getweather: " + locationTude); @@ -219,11 +203,7 @@ public class WeatherViewModel extends BaseViewModel mWeatherDailyData = new MutableLiveData<>(); - - public MutableLiveData getWeatherDailyData() { - return mWeatherDailyData; - } + public MutableLiveData mWeatherDailyData = new MutableLiveData<>(); public void getWeather7D(String locationTude) { QWeather.getWeather7D(getCtx(), locationTude, new QWeather.OnResultWeatherDailyListener() { diff --git a/app/src/main/java/com/xxpatx/os/adapter/CallRecordAdapter.java b/app/src/main/java/com/xxpatx/os/adapter/CallRecordAdapter.java index 9ae2cc1..ca09fd6 100644 --- a/app/src/main/java/com/xxpatx/os/adapter/CallRecordAdapter.java +++ b/app/src/main/java/com/xxpatx/os/adapter/CallRecordAdapter.java @@ -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 mRecordsInfoList; private SimpleDateFormat mSimpleDateFormat = new SimpleDateFormat("HH:mm"); + private CallPhoneDialog mCallPhoneDialog; public void setRecordsInfoList(List recordsInfoList) { this.mRecordsInfoList = recordsInfoList; @@ -48,6 +50,16 @@ public class CallRecordAdapter extends RecyclerView.Adapter 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 { } 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 { 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); } } diff --git a/app/src/main/java/com/xxpatx/os/adapter/PhoneSetAdapter.java b/app/src/main/java/com/xxpatx/os/adapter/PhoneSetAdapter.java new file mode 100644 index 0000000..2fd7873 --- /dev/null +++ b/app/src/main/java/com/xxpatx/os/adapter/PhoneSetAdapter.java @@ -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 { + private static final String TAG = "PhoneSetAdapter"; + + private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); + + private Context mContext; + private List mPhoneList; + private String mDefaultNumber; + + public void setPhoneList(List 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); + } + } +} diff --git a/app/src/main/java/com/xxpatx/os/adapter/WechatContactAdapter.java b/app/src/main/java/com/xxpatx/os/adapter/WechatContactAdapter.java index f7d1db4..2b5fac6 100644 --- a/app/src/main/java/com/xxpatx/os/adapter/WechatContactAdapter.java +++ b/app/src/main/java/com/xxpatx/os/adapter/WechatContactAdapter.java @@ -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>() { + mViewModel.mContactListData.observe(this, new Observer>() { @Override public void onChanged(List contacts) { if (contacts == null || contacts.size() == 0) { @@ -212,7 +212,7 @@ public class ContactFragment extends BaseMvvmFragment() { + mViewModel.mDeleteData.observe(this, new Observer() { @Override public void onChanged(BaseResponse baseResponse) { if (baseResponse.code == 200) { @@ -299,7 +299,7 @@ public class ContactFragment extends BaseMvvmFragment { + 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> mContactListData = new MutableLiveData<>(); - - public MutableLiveData> getContactListData() { - return mContactListData; - } + public MutableLiveData> mContactListData = new MutableLiveData<>(); public void getCacheContact() { String jsonString = mMMKV.getString(UrlAddress.GET_MAIL_LIST, null); @@ -76,8 +74,13 @@ public class ContactViewModel extends BaseViewModel> listBaseResponse) { Log.e("getContactList", "onNext: " + listBaseResponse); if (listBaseResponse.code == 200) { + List contactList = listBaseResponse.data; + String oldCache = mMMKV.getString(UrlAddress.GET_MAIL_LIST, ""); + if (!oldCache.equals(GsonUtils.toJSONString(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 mDeleteData =new MutableLiveData<>(); - - public MutableLiveData getDeleteData() { - return mDeleteData; - } + public MutableLiveData mDeleteData = new MutableLiveData<>(); public void deleteContact(long id) { NetInterfaceManager.getInstance().getMailListDeleteObservable(id) diff --git a/app/src/main/java/com/xxpatx/os/fragment/home/HomeFragment.java b/app/src/main/java/com/xxpatx/os/fragment/home/HomeFragment.java index 80d6cb7..a27ed22 100644 --- a/app/src/main/java/com/xxpatx/os/fragment/home/HomeFragment.java +++ b/app/src/main/java/com/xxpatx/os/fragment/home/HomeFragment.java @@ -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>() { + mViewModel.mContactListData.observe(this, new Observer>() { @Override public void onChanged(List contacts) { List sim = getSIMContacts(); @@ -112,7 +112,7 @@ public class ContactFragment extends BaseMvvmFragment() { + mViewModel.mDeleteData.observe(this, new Observer() { @Override public void onChanged(BaseResponse baseResponse) { if (baseResponse.code == 200) { @@ -275,7 +275,7 @@ public class ContactFragment extends BaseMvvmFragment { - 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> mContactListData = new MutableLiveData<>(); - - public MutableLiveData> getContactListData() { - return mContactListData; - } + public MutableLiveData> mContactListData = new MutableLiveData<>(); public void getCacheContact() { String jsonString = mMMKV.getString(UrlAddress.GET_MAIL_LIST, null); @@ -87,8 +84,13 @@ public class ContactViewModel extends BaseViewModel> 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 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 mDeleteData = new MutableLiveData<>(); - - public MutableLiveData getDeleteData() { - return mDeleteData; - } + public MutableLiveData mDeleteData = new MutableLiveData<>(); public void deleteContact(Contact contact) { Log.e(TAG, "deleteContact: " + contact.getId()); @@ -153,7 +151,6 @@ public class ContactViewModel extends BaseViewModel 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>() { + mViewModel.mRecordsInfoData.observe(this, new Observer>() { @Override public void onChanged(List recordsInfos) { dataList = recordsInfos; @@ -121,12 +147,13 @@ public class RecordFragment extends BaseMvvmFragment>() { + mViewModel.mContactMapData.observe(this, new Observer>() { @Override public void onChanged(Map stringContactMap) { mCallRecordAdapter.setContactMap(stringContactMap); } }); + mViewModel.getContact(); mViewModel.getRecordsInfoList(); } @@ -144,6 +171,24 @@ public class RecordFragment extends BaseMvvmFragment> mRecordsInfoData = new MutableLiveData<>(); - - public MutableLiveData> getRecordsInfoData() { - return mRecordsInfoData; - } + public MutableLiveData> mRecordsInfoData = new MutableLiveData<>(); /** * 读取数据 @@ -115,11 +110,7 @@ public class RecordViewModel extends BaseViewModel> mContactMapData = new MutableLiveData(); - - public MutableLiveData> getContactMapData() { - return mContactMapData; - } + public MutableLiveData> mContactMapData = new MutableLiveData(); public void getContact() { String jsonString = mMMKV.decodeString(UrlAddress.GET_MAIL_LIST); @@ -139,7 +130,7 @@ public class RecordViewModel extends BaseViewModel contact)); mContactMapData.setValue(map); } } diff --git a/app/src/main/java/com/xxpatx/os/network/NetInterfaceManager.java b/app/src/main/java/com/xxpatx/os/network/NetInterfaceManager.java index e2c365c..a86adcc 100644 --- a/app/src/main/java/com/xxpatx/os/network/NetInterfaceManager.java +++ b/app/src/main/java/com/xxpatx/os/network/NetInterfaceManager.java @@ -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> 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> getTestAppObserver() { + return new Observer>() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("getTestAppObserver", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse 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: "); + } + }; + } + + } diff --git a/app/src/main/java/com/xxpatx/os/network/UrlAddress.java b/app/src/main/java/com/xxpatx/os/network/UrlAddress.java index e6c9378..95093e0 100644 --- a/app/src/main/java/com/xxpatx/os/network/UrlAddress.java +++ b/app/src/main/java/com/xxpatx/os/network/UrlAddress.java @@ -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"; diff --git a/app/src/main/java/com/xxpatx/os/network/api/uiui/TestAppApi.java b/app/src/main/java/com/xxpatx/os/network/api/uiui/TestAppApi.java new file mode 100644 index 0000000..95bdb8e --- /dev/null +++ b/app/src/main/java/com/xxpatx/os/network/api/uiui/TestAppApi.java @@ -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> getTestApp( + @Query("sn") String sn, + @Query("model_name") String model_name, + @Query("app_package") String app_package + ); +} diff --git a/app/src/main/java/com/xxpatx/os/utils/ApkUtils.java b/app/src/main/java/com/xxpatx/os/utils/ApkUtils.java index da53a4a..2fcbfe5 100644 --- a/app/src/main/java/com/xxpatx/os/utils/ApkUtils.java +++ b/app/src/main/java/com/xxpatx/os/utils/ApkUtils.java @@ -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 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 { diff --git a/app/src/main/java/com/xxpatx/os/utils/ContactsUtils.java b/app/src/main/java/com/xxpatx/os/utils/ContactsUtils.java new file mode 100644 index 0000000..2d56683 --- /dev/null +++ b/app/src/main/java/com/xxpatx/os/utils/ContactsUtils.java @@ -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 contactList) { + Log.e(TAG, "saveContactPhone: "); +// List contactIdList = ContactsUtils.getLocalContacts(context); + Observable.create(new ObservableOnSubscribe() { + @Override + public void subscribe(@NonNull ObservableEmitter 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() { + @Override + public void onResourceReady(@androidx.annotation.NonNull Bitmap resource, @Nullable Transition transition) { + ContentResolver resolver = context.getContentResolver(); + ContentValues nameValues = new ContentValues(); + //add Name + nameValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId); + nameValues.put(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/name"); + nameValues.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, contact.getName()); + resolver.update(ContactsContract.Data.CONTENT_URI, nameValues, "raw_contact_id=?" + rawContactId, new String[]{ContactsContract.Data.CONTACT_ID}); + + ContentValues photoValues = new ContentValues(); + photoValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + resource.compress(Bitmap.CompressFormat.PNG, 100, out); + photoValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE); + photoValues.put(ContactsContract.CommonDataKinds.Photo.PHOTO, out.toByteArray()); + resolver.update(ContactsContract.Data.CONTENT_URI, photoValues, "raw_contact_id=?" + rawContactId, new String[]{ContactsContract.Data.CONTACT_ID}); + + ContentValues phoneValues = new ContentValues(); + phoneValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId); + phoneValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE); + phoneValues.put(ContactsContract.CommonDataKinds.Phone.NUMBER, contact.getMobile()); + phoneValues.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE); + resolver.update(ContactsContract.Data.CONTENT_URI, phoneValues, "raw_contact_id=?" + rawContactId, new String[]{ContactsContract.Data.CONTACT_ID}); + } + }); + } else { + ContentValues values = new ContentValues(); + long rawContactId = ContentUris.parseId(context.getContentResolver().insert(ContactsContract.RawContacts.CONTENT_URI, values)); + Glide.with(context).asBitmap().load(contact.getAvatar()).override(200, 200).into(new SimpleTarget() { + @Override + public void onResourceReady(@androidx.annotation.NonNull Bitmap resource, @Nullable Transition transition) { + ContentResolver resolver = context.getContentResolver(); + ContentValues nameValues = new ContentValues(); + //add Name + nameValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId); + nameValues.put(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/name"); + nameValues.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, contact.getName()); + resolver.insert(ContactsContract.Data.CONTENT_URI, nameValues); + + ContentValues photoValues = new ContentValues(); + photoValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + resource.compress(Bitmap.CompressFormat.PNG, 100, out); + photoValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE); + photoValues.put(ContactsContract.CommonDataKinds.Photo.PHOTO, out.toByteArray()); + resolver.insert(ContactsContract.Data.CONTENT_URI, photoValues); + + ContentValues phoneValues = new ContentValues(); + phoneValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId); + phoneValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE); + phoneValues.put(ContactsContract.CommonDataKinds.Phone.NUMBER, contact.getMobile()); + phoneValues.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE); + resolver.insert(ContactsContract.Data.CONTENT_URI, phoneValues); + } + }); + } + } + emitter.onNext(1L); + } + }) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("saveContactPhone", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull Long aLong) { + Log.e("saveContactPhone", "onNext: " + aLong); + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("saveContactPhone", "onError: " + e.getMessage()); + } + + @Override + public void onComplete() { + Log.e("saveContactPhone", "onComplete: "); + } + }); + } + + /** + * 添加联系人信息 + */ + public static void insertConstacts(Context context, String name, String phone, List 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 getAllSysContacts(Context context) { +// List 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() { +// @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 getLocalContacts(Context context) { + ContentResolver resolver = context.getContentResolver(); + Uri uri = ContactsContract.Contacts.CONTENT_URI; + Cursor cursor = resolver.query(uri, null, null, null, null); + List 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 filter = contactIds.stream().filter(new Predicate() { + @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; + } + + +} diff --git a/app/src/main/java/com/xxpatx/os/utils/LocalContactUtils.java b/app/src/main/java/com/xxpatx/os/utils/LocalContactUtils.java new file mode 100644 index 0000000..51bfe37 --- /dev/null +++ b/app/src/main/java/com/xxpatx/os/utils/LocalContactUtils.java @@ -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 getLocalContact() { + Set 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>() { + }.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 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>() { + }.getType(); + try { + Set 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>() { + }.getType(); + try { + Set contacts = gson.fromJson(jsonString, type); + contacts.remove(contact); + } catch (Exception e) { + Log.e(TAG, "getLocalContact: " + e.getMessage()); + } + } + +} diff --git a/app/src/main/java/com/xxpatx/os/utils/MobileNetworkUtils.java b/app/src/main/java/com/xxpatx/os/utils/MobileNetworkUtils.java new file mode 100644 index 0000000..18fdeaa --- /dev/null +++ b/app/src/main/java/com/xxpatx/os/utils/MobileNetworkUtils.java @@ -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 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(); + } +} diff --git a/app/src/main/java/com/xxpatx/os/utils/MobileNumberUtils.java b/app/src/main/java/com/xxpatx/os/utils/MobileNumberUtils.java new file mode 100644 index 0000000..24d52e9 --- /dev/null +++ b/app/src/main/java/com/xxpatx/os/utils/MobileNumberUtils.java @@ -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 "未知"; + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable-hdpi/default_avatar.png b/app/src/main/res/drawable-hdpi/default_avatar.png index cf4cb6a..5a95227 100644 Binary files a/app/src/main/res/drawable-hdpi/default_avatar.png and b/app/src/main/res/drawable-hdpi/default_avatar.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_call_incoming.png b/app/src/main/res/drawable-hdpi/icon_call_incoming.png index b0ec3c1..484aa46 100644 Binary files a/app/src/main/res/drawable-hdpi/icon_call_incoming.png and b/app/src/main/res/drawable-hdpi/icon_call_incoming.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_call_missed.png b/app/src/main/res/drawable-hdpi/icon_call_missed.png index 03305eb..ae7a67f 100644 Binary files a/app/src/main/res/drawable-hdpi/icon_call_missed.png and b/app/src/main/res/drawable-hdpi/icon_call_missed.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_call_outgoing.png b/app/src/main/res/drawable-hdpi/icon_call_outgoing.png index c1392c1..12dd83c 100644 Binary files a/app/src/main/res/drawable-hdpi/icon_call_outgoing.png and b/app/src/main/res/drawable-hdpi/icon_call_outgoing.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_call_phone.png b/app/src/main/res/drawable-hdpi/icon_call_phone.png new file mode 100644 index 0000000..481115b Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_call_phone.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_select.png b/app/src/main/res/drawable-hdpi/icon_select.png new file mode 100644 index 0000000..c4ee46d Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_select.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_unselect.png b/app/src/main/res/drawable-hdpi/icon_unselect.png new file mode 100644 index 0000000..2826cb1 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_unselect.png differ diff --git a/app/src/main/res/layout/activity_add_contact.xml b/app/src/main/res/layout/activity_add_contact.xml index ad579dd..5d41b36 100644 --- a/app/src/main/res/layout/activity_add_contact.xml +++ b/app/src/main/res/layout/activity_add_contact.xml @@ -5,6 +5,7 @@ tools:context=".activity.contact.AddContactActivity"> + @@ -12,11 +13,11 @@ + android:layout_height="match_parent" + android:background="#FAF8F8"> - - + app:layout_constraintBottom_toTopOf="@+id/cl_bottom" + app:layout_constraintTop_toBottomOf="@+id/cl_exit" + tools:layout_editor_absoluteX="16dp"> + android:layout_height="wrap_content" + android:orientation="vertical"> - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -296,5 +395,12 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_add_wechat_contact.xml b/app/src/main/res/layout/activity_add_wechat_contact.xml deleted file mode 100644 index 20e9fdf..0000000 --- a/app/src/main/res/layout/activity_add_wechat_contact.xml +++ /dev/null @@ -1,405 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_contact.xml b/app/src/main/res/layout/activity_contact_list.xml similarity index 97% rename from app/src/main/res/layout/activity_contact.xml rename to app/src/main/res/layout/activity_contact_list.xml index 37c3107..c3581b1 100644 --- a/app/src/main/res/layout/activity_contact.xml +++ b/app/src/main/res/layout/activity_contact_list.xml @@ -2,13 +2,13 @@ + tools:context=".activity.contact.ContactListActivity"> + type="com.xxpatx.os.activity.contact.ContactListActivity.BtnClick" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_call_phone.xml b/app/src/main/res/layout/dialog_call_phone.xml new file mode 100644 index 0000000..3f70ef6 --- /dev/null +++ b/app/src/main/res/layout/dialog_call_phone.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_call_record.xml b/app/src/main/res/layout/item_call_record.xml index 64ee993..5a55893 100644 --- a/app/src/main/res/layout/item_call_record.xml +++ b/app/src/main/res/layout/item_call_record.xml @@ -40,10 +40,11 @@ @@ -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" /> - - + + @@ -13,48 +14,55 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"> - + android:layout_weight="2"> + - - - - - - + + android:textSize="16sp" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toEndOf="@+id/iv_card" + tools:text="1234567890" /> + - + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index d1734ea..1e88e32 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -109,6 +109,8 @@ @android:color/transparent true + + true @null diff --git a/build.gradle b/build.gradle index ac3b968..c504270 100644 --- a/build.gradle +++ b/build.gradle @@ -7,8 +7,8 @@ buildscript { mavenCentral() maven { url "https://jitpack.io" } maven { url 'https://developer.huawei.com/repo/' } - maven { url 'https://maven.aliyun.com/repository/central/' } maven { url 'https://maven.aliyun.com/repository/public/' } + maven { url 'https://maven.aliyun.com/repository/central/' } } dependencies { classpath 'com.android.tools.build:gradle:3.6.4' @@ -29,8 +29,8 @@ allprojects { mavenCentral() maven { url "https://jitpack.io" } maven { url 'https://developer.huawei.com/repo/' } - maven { url 'https://maven.aliyun.com/repository/central/' } maven { url 'https://maven.aliyun.com/repository/public/' } + maven { url 'https://maven.aliyun.com/repository/central/' } } gradle.projectsEvaluated { tasks.withType(JavaCompile) {