version:2.0.6
bugfixes:修复闹钟修改默认值,联系人为空时不显示占用,屏幕旋转会错乱,整点报时会息屏亮屏多次播报 update:主页不显示地址,微信拨号优化,优化离线联系人
@@ -1,7 +1,7 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
def appName() {
|
||||
return "XiaoxintongOS"
|
||||
return "QinQingOS"
|
||||
}
|
||||
|
||||
def releaseTime() {
|
||||
@@ -16,8 +16,8 @@ android {
|
||||
minSdkVersion 24
|
||||
targetSdkVersion 29
|
||||
|
||||
versionCode 201
|
||||
versionName "2.0.0"
|
||||
versionCode 207
|
||||
versionName "2.0.6"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
||||
|
||||
@@ -196,6 +196,7 @@
|
||||
<activity
|
||||
android:name=".activity.emergency.EmergencyActivity"
|
||||
android:launchMode="singleTask"
|
||||
android:theme="@style/AppBlackTheme"
|
||||
android:screenOrientation="portrait" />
|
||||
<activity
|
||||
android:name=".activity.noti.NoticeActivity"
|
||||
|
||||
@@ -80,7 +80,7 @@ public class AlarmListActivity extends BaseMvvmActivity<AlarmListViewModel, Acti
|
||||
@Override
|
||||
public void onLongClick(AlarmClockData alarmClockData) {
|
||||
boolean clockModify = mMMKV.decodeBool(CommonConfig.DISABLE_CLOCK_MODIFY, false);
|
||||
int alarm_clock_ctrl = Settings.Global.getInt(getContentResolver(), CommonConfig.ALARM_CLOCK_CTRL, 0);
|
||||
int alarm_clock_ctrl = Settings.Global.getInt(getContentResolver(), CommonConfig.ALARM_CLOCK_CTRL, 1);
|
||||
if (clockModify || alarm_clock_ctrl == 0) {
|
||||
Toaster.showLong("已禁用闹钟修改");
|
||||
} else {
|
||||
@@ -237,7 +237,7 @@ public class AlarmListActivity extends BaseMvvmActivity<AlarmListViewModel, Acti
|
||||
|
||||
public void add(View view) {
|
||||
boolean clockModify = mMMKV.decodeBool(CommonConfig.DISABLE_CLOCK_MODIFY, false);
|
||||
int alarm_clock_ctrl = Settings.Global.getInt(getContentResolver(), CommonConfig.ALARM_CLOCK_CTRL, 0);
|
||||
int alarm_clock_ctrl = Settings.Global.getInt(getContentResolver(), CommonConfig.ALARM_CLOCK_CTRL, 1);
|
||||
if (clockModify || alarm_clock_ctrl == 0) {
|
||||
Toaster.showLong("已禁用闹钟修改");
|
||||
} else {
|
||||
|
||||
@@ -33,6 +33,8 @@ import com.vscool.os.config.CommonConfig;
|
||||
import com.vscool.os.custom.GlideEngine;
|
||||
import com.vscool.os.databinding.ActivityContactAddBinding;
|
||||
import com.vscool.os.db.ContactCacheUtils;
|
||||
import com.vscool.os.network.NetInterfaceManager;
|
||||
import com.vscool.os.network.UrlAddress;
|
||||
import com.vscool.os.utils.ContactsUtils;
|
||||
import com.vscool.os.utils.LocalContactUtils;
|
||||
import com.vscool.os.utils.ScreenUtil;
|
||||
@@ -112,6 +114,7 @@ public class AddContactActivity extends BaseMvvmActivity<AddContactViewModel, Ac
|
||||
@Override
|
||||
public void onChanged(Contact contact) {
|
||||
ContactCacheUtils.getInstance().addContact(contact);
|
||||
NetInterfaceManager.getInstance().addContactCache(UrlAddress.GET_MAIL_LIST, contact);
|
||||
Toaster.showLong("已保存至本地");
|
||||
finish();
|
||||
}
|
||||
|
||||
@@ -15,12 +15,11 @@ import com.vscool.os.bean.BaseResponse;
|
||||
import com.vscool.os.bean.Contact;
|
||||
import com.vscool.os.config.CommonConfig;
|
||||
import com.vscool.os.databinding.ActivityContactListBinding;
|
||||
import com.vscool.os.gson.GsonUtils;
|
||||
import com.vscool.os.network.NetInterfaceManager;
|
||||
import com.vscool.os.network.UrlAddress;
|
||||
import com.vscool.os.utils.ContactsUtils;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import io.reactivex.rxjava3.annotations.NonNull;
|
||||
@@ -62,46 +61,28 @@ public class ContactListViewModel extends BaseViewModel<ActivityContactListBindi
|
||||
}
|
||||
|
||||
public void getContact() {
|
||||
NetInterfaceManager.getInstance()
|
||||
.getContactListObservable()
|
||||
.compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY))
|
||||
.subscribe(new Observer<BaseResponse<List<Contact>>>() {
|
||||
NetInterfaceManager.getInstance().getContactListObserverCache(UrlAddress.GET_MAIL_LIST, new NetInterfaceManager.ContactCallback() {
|
||||
@Override
|
||||
public void onSubscribe(@NonNull Disposable d) {
|
||||
Log.e("getContactList", "onSubscribe: ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(@NonNull BaseResponse<List<Contact>> listBaseResponse) {
|
||||
Log.e("getContactList", "onNext: " + listBaseResponse);
|
||||
if (listBaseResponse.code == 200) {
|
||||
mMMKV.putString(UrlAddress.GET_MAIL_LIST, GsonUtils.toJSONString(listBaseResponse.data));
|
||||
mContactListData.setValue(listBaseResponse.data);
|
||||
} else {
|
||||
mMMKV.putString(UrlAddress.GET_MAIL_LIST, "");
|
||||
mContactListData.setValue(new ArrayList<>());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(@NonNull Throwable e) {
|
||||
Log.e("getContactList", "onError: " + e.getMessage());
|
||||
String jsonString = mMMKV.getString(UrlAddress.GET_MAIL_LIST, null);
|
||||
Gson gson = new Gson();
|
||||
Type type = new TypeToken<List<Contact>>() {
|
||||
}.getType();
|
||||
List<Contact> contacts = gson.fromJson(jsonString, type);
|
||||
if (contacts == null) {
|
||||
mContactListData.setValue(new ArrayList<>());
|
||||
} else {
|
||||
mContactListData.setValue(contacts);
|
||||
}
|
||||
onComplete();
|
||||
public void setContact(List<Contact> contactList) {
|
||||
mContactListData.setValue(contactList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
Log.e("getContactList", "onComplete: ");
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
NetInterfaceManager.getInstance()
|
||||
.getContactList(getLifecycle(), new NetInterfaceManager.ContactCallback() {
|
||||
@Override
|
||||
public void setContact(List<Contact> contactList) {
|
||||
mContactListData.setValue(contactList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -125,6 +106,9 @@ public class ContactListViewModel extends BaseViewModel<ActivityContactListBindi
|
||||
@Override
|
||||
public void onNext(@NonNull BaseResponse baseResponse) {
|
||||
Log.e("deleteContact", "onNext: " + baseResponse);
|
||||
if (baseResponse.code == 200) {
|
||||
ContactsUtils.deleteRawContact(getCtx(), contact.getMobile());
|
||||
}
|
||||
mDeleteData.setValue(baseResponse);
|
||||
}
|
||||
|
||||
|
||||
@@ -116,6 +116,7 @@ public class EditContactActivity extends BaseMvvmActivity<EditContactViewModel,
|
||||
@Override
|
||||
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
|
||||
mPictrueFilePath = FileUtil.bitmapToFile(EditContactActivity.this, resource, "avatar").getAbsolutePath();
|
||||
mViewDataBinding.nvAvatar.setImageBitmap(resource);
|
||||
Log.e(TAG, "onResourceReady: " + mPictrueFilePath);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -130,12 +130,6 @@ public class EmergencyActivity extends BaseMvvmActivity<EmergencyViewModel, Acti
|
||||
mDisposable.dispose();
|
||||
}
|
||||
});
|
||||
mViewDataBinding.ivFinish.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
// TelephonyManager telM = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
|
||||
// telM.listen(new PhoneStateListener() {
|
||||
// /**
|
||||
@@ -162,7 +156,6 @@ public class EmergencyActivity extends BaseMvvmActivity<EmergencyViewModel, Acti
|
||||
mEmergencyContactAdapter.setContactList(mContactList);
|
||||
}
|
||||
});
|
||||
mViewModel.getCacheContact();
|
||||
mViewModel.getContact();
|
||||
}
|
||||
|
||||
@@ -281,8 +274,12 @@ public class EmergencyActivity extends BaseMvvmActivity<EmergencyViewModel, Acti
|
||||
// public static final int PRECISE_CALL_STATE_DISCONNECTING = 8; //正在挂断
|
||||
// }
|
||||
|
||||
public class BtnClick{
|
||||
public void call(View view){
|
||||
public class BtnClick {
|
||||
public void exit(View view) {
|
||||
finish();
|
||||
}
|
||||
|
||||
public void call(View view) {
|
||||
mNeedDial = true;
|
||||
|
||||
if (mContactList == null || mContactList.isEmpty()) {
|
||||
|
||||
@@ -1,33 +1,18 @@
|
||||
package com.vscool.os.activity.emergency;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.tencent.mmkv.MMKV;
|
||||
import com.trello.rxlifecycle4.RxLifecycle;
|
||||
import com.trello.rxlifecycle4.android.ActivityEvent;
|
||||
import com.vscool.os.base.mvvm.BaseViewModel;
|
||||
import com.vscool.os.bean.BaseResponse;
|
||||
import com.vscool.os.bean.Contact;
|
||||
import com.vscool.os.config.CommonConfig;
|
||||
import com.vscool.os.databinding.ActivityEmergencyBinding;
|
||||
import com.vscool.os.gson.GsonUtils;
|
||||
import com.vscool.os.network.NetInterfaceManager;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import io.reactivex.rxjava3.annotations.NonNull;
|
||||
import io.reactivex.rxjava3.core.Observer;
|
||||
import io.reactivex.rxjava3.disposables.Disposable;
|
||||
|
||||
public class EmergencyViewModel extends BaseViewModel<ActivityEmergencyBinding, ActivityEvent> {
|
||||
|
||||
private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE);
|
||||
@@ -44,70 +29,30 @@ public class EmergencyViewModel extends BaseViewModel<ActivityEmergencyBinding,
|
||||
|
||||
public MutableLiveData<List<Contact>> mContactListData = new MutableLiveData<>();
|
||||
|
||||
public void getCacheContact() {
|
||||
String jsonString = mMMKV.getString(CommonConfig.EMERGENCY_CONTACT_LIST_KEY, null);
|
||||
Gson gson = new Gson();
|
||||
Type type = new TypeToken<List<Contact>>() {
|
||||
}.getType();
|
||||
if (!TextUtils.isEmpty(jsonString)) {
|
||||
List<Contact> contacts = gson.fromJson(jsonString, type);
|
||||
if (contacts != null) {
|
||||
mContactListData.setValue(contacts);
|
||||
}
|
||||
}
|
||||
getContact();
|
||||
}
|
||||
|
||||
public void getContact() {
|
||||
NetInterfaceManager.getInstance()
|
||||
.getContactListObservable()
|
||||
.compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY))
|
||||
.subscribe(new Observer<BaseResponse<List<Contact>>>() {
|
||||
NetInterfaceManager.getInstance().getContactListObserverCache(CommonConfig.EMERGENCY_CONTACT_LIST_KEY, new NetInterfaceManager.ContactCallback() {
|
||||
@Override
|
||||
public void onSubscribe(@NonNull Disposable d) {
|
||||
Log.e("getContactList", "onSubscribe: ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(@NonNull BaseResponse<List<Contact>> listBaseResponse) {
|
||||
Log.e("getContactList", "onNext: " + listBaseResponse);
|
||||
if (listBaseResponse.code == 200) {
|
||||
List<Contact> contactList = listBaseResponse.data;
|
||||
if (contactList != null && !contactList.isEmpty()) {
|
||||
List<Contact> emergencyConcacts = contactList.stream().filter(new Predicate<Contact>() {
|
||||
@Override
|
||||
public boolean test(Contact contact) {
|
||||
return contact.getIs_urgent() == 1;
|
||||
}
|
||||
}).collect(Collectors.toList());
|
||||
mMMKV.putString(CommonConfig.EMERGENCY_CONTACT_LIST_KEY, GsonUtils.toJSONString(emergencyConcacts));
|
||||
mContactListData.setValue(emergencyConcacts);
|
||||
}
|
||||
} else {
|
||||
mMMKV.putString(CommonConfig.EMERGENCY_CONTACT_LIST_KEY, "");
|
||||
mContactListData.setValue(new ArrayList<>());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(@NonNull Throwable e) {
|
||||
Log.e("getContactList", "onError: " + e.getMessage());
|
||||
String jsonString = mMMKV.getString(CommonConfig.EMERGENCY_CONTACT_LIST_KEY, null);
|
||||
Gson gson = new Gson();
|
||||
Type type = new TypeToken<List<Contact>>() {
|
||||
}.getType();
|
||||
List<Contact> contacts = gson.fromJson(jsonString, type);
|
||||
if (contacts == null) {
|
||||
mContactListData.setValue(new ArrayList<>());
|
||||
} else {
|
||||
mContactListData.setValue(contacts);
|
||||
}
|
||||
onComplete();
|
||||
public void setContact(List<Contact> contactList) {
|
||||
mContactListData.setValue(contactList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
Log.e("getContactList", "onComplete: ");
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
NetInterfaceManager.getInstance()
|
||||
.getContactList(getLifecycle(), new NetInterfaceManager.ContactCallback() {
|
||||
@Override
|
||||
public void setContact(List<Contact> contactList) {
|
||||
List<Contact> emergencyConcacts = contactList.stream().filter(contact -> contact.getIs_urgent() == 1).collect(Collectors.toList());
|
||||
mContactListData.setValue(emergencyConcacts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import android.content.IntentFilter;
|
||||
import android.content.ServiceConnection;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.database.Cursor;
|
||||
import android.hardware.camera2.CameraAccessException;
|
||||
import android.hardware.camera2.CameraCharacteristics;
|
||||
@@ -93,13 +94,19 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import me.jessyan.autosize.AutoSizeCompat;
|
||||
import me.jessyan.autosize.AutoSizeConfig;
|
||||
|
||||
import static com.arialyy.aria.core.inf.IEntity.STATE_RUNNING;
|
||||
|
||||
public class MainActivity extends BaseMvvmActivity<MainViewModel, ActivityMainBinding> implements NetworkUtils.OnNetworkStatusChangedListener,
|
||||
NotificationService.NotificationListener, TextToSpeech.OnInitListener {
|
||||
NotificationService.NotificationListener, TextToSpeech.OnInitListener
|
||||
// , CustomAdapt
|
||||
{
|
||||
private static final String TAG = "MainActivity";
|
||||
|
||||
|
||||
|
||||
private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE);
|
||||
|
||||
private FragmentManager mFragmentManager;
|
||||
@@ -127,6 +134,32 @@ public class MainActivity extends BaseMvvmActivity<MainViewModel, ActivityMainBi
|
||||
// private DockAppAdapter mDockAppAdapter;
|
||||
private DockAppGridAdapter mDockAppGridAdapter;
|
||||
|
||||
// @Override
|
||||
// public boolean isBaseOnWidth() {
|
||||
// if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
|
||||
// return true;
|
||||
// }else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){
|
||||
// return false;
|
||||
// }else {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public float getSizeInDp() {
|
||||
// // 横屏下的高度不就是竖屏的宽度吗,所以统一返回宽度即可
|
||||
// return 360;
|
||||
// }
|
||||
|
||||
@Override
|
||||
public Resources getResources() {
|
||||
//需要升级到 v1.1.2 及以上版本才能使用 AutoSizeCompat
|
||||
int width = AutoSizeConfig.getInstance().getScreenWidth();
|
||||
int height = AutoSizeConfig.getInstance().getScreenHeight();
|
||||
AutoSizeCompat.autoConvertDensity(super.getResources(), 740, width > height);
|
||||
return super.getResources();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnected() {
|
||||
Log.e(TAG, "onDisconnected: ");
|
||||
|
||||
@@ -397,7 +397,8 @@ public class MainViewModel extends BaseViewModel<ActivityMainBinding, ActivityEv
|
||||
|
||||
public void uploadContacts() {
|
||||
List<Contact> contactList = ContactCacheUtils.getInstance().getDatabaseContact();
|
||||
if (contactList == null || contactList.size() == 0) {
|
||||
Log.e(TAG, "uploadContacts: " + contactList.size());
|
||||
if (contactList.size() == 0) {
|
||||
Log.e(TAG, "uploadContacts: not found local contacts");
|
||||
} else {
|
||||
for (Contact contact : contactList) {
|
||||
|
||||
@@ -231,7 +231,7 @@ public class NoticeInfoActivity extends BaseMvvmActivity<NoticeInfoViewModel, Ac
|
||||
mViewDataBinding.jzVideo.startVideo();
|
||||
}
|
||||
} else {
|
||||
mViewDataBinding.clVp.setVisibility(View.INVISIBLE);
|
||||
mViewDataBinding.clVp.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -76,6 +76,7 @@ public class SettingActivity extends BaseMvvmActivity<SettingViewModel, Activity
|
||||
|
||||
@Override
|
||||
protected void initView() {
|
||||
mViewDataBinding.tvVersion.setText("V" + BuildConfig.VERSION_NAME);
|
||||
mViewDataBinding.tbFloat.setOnToggleChanged(new ToggleButton.OnToggleChanged() {
|
||||
@Override
|
||||
public void onToggle(boolean on) {
|
||||
@@ -344,6 +345,10 @@ public class SettingActivity extends BaseMvvmActivity<SettingViewModel, Activity
|
||||
}
|
||||
|
||||
public class BtnClick {
|
||||
public void exit(View view) {
|
||||
finish();
|
||||
}
|
||||
|
||||
public void openFloat(View view) {
|
||||
boolean floatWindowEnable = Settings.Global.getInt(getContentResolver(), CommonConfig.HOVER_HOME, CommonConfig.HOVER_HOME_STATUS) == 1;
|
||||
if (floatWindowEnable) {
|
||||
|
||||
@@ -46,6 +46,8 @@ public class SettingViewModel extends BaseViewModel<ActivitySettingBinding, Acti
|
||||
if (appInfoBaseResponse.code == 200) {
|
||||
AppInfo appInfo = appInfoBaseResponse.data;
|
||||
mAppInfoData.setValue(appInfo);
|
||||
} else {
|
||||
mAppInfoData.setValue(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.vscool.os.activity.weather;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.icu.util.Calendar;
|
||||
import android.os.Bundle;
|
||||
@@ -18,6 +17,7 @@ import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
|
||||
import com.blankj.utilcode.util.NetworkUtils;
|
||||
import com.google.gson.Gson;
|
||||
@@ -28,35 +28,23 @@ import com.qweather.sdk.bean.weather.WeatherNowBean;
|
||||
import com.tencent.mmkv.MMKV;
|
||||
import com.vscool.os.R;
|
||||
import com.vscool.os.activity.location.LocationAcivity;
|
||||
import com.vscool.os.adapter.WeatherDayApdapterPort;
|
||||
import com.vscool.os.adapter.WeatherDayApdapter;
|
||||
import com.vscool.os.base.mvvm.BaseMvvmActivity;
|
||||
import com.vscool.os.bean.JsonBean;
|
||||
import com.vscool.os.bean.QweatherLocation;
|
||||
import com.vscool.os.config.CommonConfig;
|
||||
import com.vscool.os.databinding.ActivityWeatherBinding;
|
||||
import com.vscool.os.manager.AmapManager;
|
||||
import com.vscool.os.utils.DataUtil;
|
||||
import com.vscool.os.utils.DayUtils;
|
||||
import com.vscool.os.view.FadeInOutAnimator;
|
||||
import com.vscool.os.view.HorizontalItemDecoration;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public class WeatherActivity extends BaseMvvmActivity<WeatherViewModel, ActivityWeatherBinding>
|
||||
implements NetworkUtils.OnNetworkStatusChangedListener {
|
||||
private static final String TAG = "WeatherActivity";
|
||||
|
||||
|
||||
private WeatherDayApdapterPort mWeatherDayApdapter;
|
||||
private WeatherDayApdapter mWeatherDayApdapter;
|
||||
private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE);
|
||||
|
||||
private List<JsonBean> options1Items = new ArrayList<>();
|
||||
private ArrayList<ArrayList<String>> options2Items = new ArrayList<>();
|
||||
private ArrayList<ArrayList<ArrayList<String>>> options3Items = new ArrayList<>();
|
||||
private boolean mLoaded = false;
|
||||
|
||||
|
||||
private ActivityResultLauncher<Intent> register = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
|
||||
@Override
|
||||
@@ -115,44 +103,40 @@ public class WeatherActivity extends BaseMvvmActivity<WeatherViewModel, Activity
|
||||
|
||||
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
|
||||
Resources resources = getResources();
|
||||
if (resources.getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
||||
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
|
||||
mViewDataBinding.rvWeather.addItemDecoration(new HorizontalItemDecoration(30, this));//10表示10dp
|
||||
} else {
|
||||
// if (resources.getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
||||
// linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
|
||||
// mViewDataBinding.rvWeather.addItemDecoration(new HorizontalItemDecoration(30, this));//10表示10dp
|
||||
// } else {
|
||||
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
|
||||
}
|
||||
// }
|
||||
mViewDataBinding.rvWeather.setLayoutManager(linearLayoutManager);
|
||||
mViewDataBinding.rvWeather.setItemAnimator(new FadeInOutAnimator());
|
||||
// mViewDataBinding.rvWeather.setLayoutManager(new GridLayoutManager(this, 3));
|
||||
// mViewDataBinding.rvWeather.addItemDecoration(new RecyclerItemDecoration(ScreenUtils.dp2px(resources, 10), ScreenUtils.dp2px(resources, 10), 3));
|
||||
mWeatherDayApdapter = new WeatherDayApdapterPort();
|
||||
mWeatherDayApdapter = new WeatherDayApdapter();
|
||||
mViewDataBinding.rvWeather.setAdapter(mWeatherDayApdapter);
|
||||
|
||||
mViewDataBinding.tvDate.setText(DataUtil.formatDateDay() + "\t" + DayUtils.getWeek());
|
||||
// mViewDataBinding.tvDate.setText(DataUtil.formatDateDay() + "\t" + DayUtils.getWeek());
|
||||
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(new Date());
|
||||
int hour = calendar.get(Calendar.HOUR_OF_DAY);
|
||||
if (6 < hour && hour < 18) {
|
||||
mViewDataBinding.root.setBackground(getDrawable(R.drawable.weather_background_day));
|
||||
} else {
|
||||
mViewDataBinding.root.setBackground(getDrawable(R.drawable.weather_background_night));
|
||||
// if (6 < hour && hour < 18) {
|
||||
// mViewDataBinding.root.setBackground(getDrawable(R.drawable.weather_background_day));
|
||||
// } else {
|
||||
// mViewDataBinding.root.setBackground(getDrawable(R.drawable.weather_background_night));
|
||||
// }
|
||||
|
||||
mViewDataBinding.swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
|
||||
@Override
|
||||
public void onRefresh() {
|
||||
getWeather();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initData() {
|
||||
// mViewModel.getGeoResultData().observe(this, new Observer<MapGeoResult>() {
|
||||
// @Override
|
||||
// public void onChanged(MapGeoResult mapGeoResult) {
|
||||
// if (mapGeoResult != null) {
|
||||
// mMMKV.encode(CommonConfig.MANUALLY_SELECT_LOCATION_TUDE, mapGeoResult.getLocation().toString());
|
||||
// mViewModel.getWeather(mapGeoResult.getLocation().toString());
|
||||
// } else {
|
||||
// Toaster.show("获取位置信息失败");
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
mViewModel.mQweatherLocationData.observe(this, new Observer<QweatherLocation>() {
|
||||
@Override
|
||||
public void onChanged(QweatherLocation qweatherLocation) {
|
||||
@@ -163,19 +147,21 @@ public class WeatherActivity extends BaseMvvmActivity<WeatherViewModel, Activity
|
||||
} else {
|
||||
Toaster.show("获取位置信息失败");
|
||||
}
|
||||
mViewDataBinding.swipeRefreshLayout.setRefreshing(false);
|
||||
}
|
||||
});
|
||||
mViewModel.mLocationData.observe(this, new Observer<String>() {
|
||||
@Override
|
||||
public void onChanged(String s) {
|
||||
mViewDataBinding.tvLocation.setText(s);
|
||||
Toaster.show("刷新成功");
|
||||
mViewModel.cityLookup(s);
|
||||
}
|
||||
});
|
||||
mViewModel.mWeatherNowData.observe(this, new Observer<WeatherNowBean>() {
|
||||
@Override
|
||||
public void onChanged(WeatherNowBean weatherNowBean) {
|
||||
mViewDataBinding.swipeRefreshLayout.setRefreshing(false);
|
||||
|
||||
//先判断返回的status是否正确,当status正确时获取数据,若status不正确,可查看status对应的Code值找到原因
|
||||
if (weatherNowBean != null) {
|
||||
if (Code.OK == weatherNowBean.getCode()) {
|
||||
@@ -197,21 +183,21 @@ public class WeatherActivity extends BaseMvvmActivity<WeatherViewModel, Activity
|
||||
mViewModel.mWeatherDailyData.observe(this, new Observer<WeatherDailyBean>() {
|
||||
@Override
|
||||
public void onChanged(WeatherDailyBean weatherDailyBean) {
|
||||
mViewDataBinding.swipeRefreshLayout.setRefreshing(false);
|
||||
|
||||
if (weatherDailyBean != null) {
|
||||
mWeatherDayApdapter.setDailyBeans(weatherDailyBean.getDaily());
|
||||
WeatherDailyBean.DailyBean dailyBean = weatherDailyBean.getDaily().get(0);
|
||||
mViewDataBinding.tvMinMax.setText(dailyBean.getTempMin() + "℃ - " + dailyBean.getTempMax() + "℃");
|
||||
// mViewDataBinding.tvMinMax.setText(dailyBean.getTempMin() + "℃ - " + dailyBean.getTempMax() + "℃");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// mViewModel.loadProvince();
|
||||
getWeather();
|
||||
}
|
||||
|
||||
private void getWeather() {
|
||||
// mViewModel.getWeatherCache();
|
||||
String district = mMMKV.decodeString(CommonConfig.MANUALLY_SELECT_LOCATION_DISTRICT, CommonConfig.DEFAULT_LOCATION_DISTRICT);
|
||||
String tude = mMMKV.decodeString(CommonConfig.MANUALLY_SELECT_LOCATION_TUDE, CommonConfig.DEFAULT_LOCATION_TUDE);
|
||||
if (TextUtils.isEmpty(tude)) {
|
||||
@@ -243,11 +229,7 @@ public class WeatherActivity extends BaseMvvmActivity<WeatherViewModel, Activity
|
||||
|
||||
public void selectAddress(View view) {
|
||||
hideSoftKeyBoard(view);
|
||||
// if (!mLoaded) {
|
||||
// Toaster.show("位置数据没有加载完成");
|
||||
// } else {
|
||||
register.launch(new Intent(WeatherActivity.this, LocationAcivity.class));
|
||||
// }
|
||||
}
|
||||
|
||||
public void refresh(View view) {
|
||||
|
||||
@@ -5,7 +5,6 @@ import android.util.Log;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.hjq.toast.Toaster;
|
||||
import com.jeremyliao.liveeventbus.LiveEventBus;
|
||||
import com.qweather.sdk.bean.base.Lang;
|
||||
@@ -17,7 +16,6 @@ import com.tencent.mmkv.MMKV;
|
||||
import com.trello.rxlifecycle4.RxLifecycle;
|
||||
import com.trello.rxlifecycle4.android.ActivityEvent;
|
||||
import com.vscool.os.base.mvvm.BaseViewModel;
|
||||
import com.vscool.os.bean.MapGeoResult;
|
||||
import com.vscool.os.bean.QweatherLocation;
|
||||
import com.vscool.os.bean.QweatherLookup;
|
||||
import com.vscool.os.config.CommonConfig;
|
||||
@@ -27,7 +25,6 @@ import com.vscool.os.network.NetInterfaceManager;
|
||||
import com.vscool.os.utils.ActivationUtil;
|
||||
import com.vscool.os.utils.WiFiUtils;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
|
||||
import io.reactivex.rxjava3.annotations.NonNull;
|
||||
@@ -50,44 +47,6 @@ public class WeatherViewModel extends BaseViewModel<ActivityWeatherBinding, Acti
|
||||
|
||||
}
|
||||
|
||||
public MutableLiveData<MapGeoResult> mGeoResultData = new MutableLiveData<>();
|
||||
|
||||
@Deprecated
|
||||
public void decodeGeo(String address) {
|
||||
Log.e(TAG, "decodeGeo: " + address);
|
||||
// NetInterfaceManager.getInstance().getGeoObservable(address)
|
||||
// .compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY))
|
||||
// .subscribe(new Observer<BaiduMapGeoBean>() {
|
||||
// @Override
|
||||
// public void onSubscribe(@NonNull Disposable d) {
|
||||
// Log.e("decodeGeo", "onSubscribe: ");
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onNext(@NonNull BaiduMapGeoBean baiduMapGeoBean) {
|
||||
// Log.e("decodeGeo", "onNext: " + baiduMapGeoBean);
|
||||
// if (baiduMapGeoBean.getStatus() == 0) {
|
||||
// mGeoResultData.setValue(baiduMapGeoBean.getResult());
|
||||
// } else {
|
||||
// mGeoResultData.setValue(null);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onError(@NonNull Throwable e) {
|
||||
// Log.e("decodeGeo", "onError: " + e.getMessage());
|
||||
// mGeoResultData.setValue(null);
|
||||
// onComplete();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onComplete() {
|
||||
// Log.e("decodeGeo", "onComplete: ");
|
||||
// }
|
||||
// });
|
||||
|
||||
}
|
||||
|
||||
public MutableLiveData<QweatherLocation> mQweatherLocationData = new MutableLiveData<>();
|
||||
|
||||
public void cityLookup(String city) {
|
||||
@@ -124,29 +83,6 @@ public class WeatherViewModel extends BaseViewModel<ActivityWeatherBinding, Acti
|
||||
});
|
||||
}
|
||||
|
||||
public void getWeatherCache() {
|
||||
Log.e(TAG, "getWeatherCache: ");
|
||||
String nowJsonString = mMMKV.decodeString(CommonConfig.WEATHER_NOW_KEY, "");
|
||||
Type nowType = new TypeToken<WeatherNowBean>() {
|
||||
}.getType();
|
||||
try {
|
||||
WeatherNowBean weatherNowBean = new Gson().fromJson(nowJsonString, nowType);
|
||||
mWeatherNowData.setValue(weatherNowBean);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "getWeatherCache: now = " + e.getMessage());
|
||||
}
|
||||
|
||||
String jsonString = mMMKV.decodeString(CommonConfig.WEATHER_DAILY_KEY, "");
|
||||
Type type = new TypeToken<WeatherDailyBean>() {
|
||||
}.getType();
|
||||
try {
|
||||
WeatherDailyBean weatherDailyBean = new Gson().fromJson(jsonString, type);
|
||||
mWeatherDailyData.setValue(weatherDailyBean);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "getWeatherCache: Daily = " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public MutableLiveData<String> mLocationData = new MutableLiveData<>();
|
||||
|
||||
public void getLocation() {
|
||||
@@ -210,7 +146,6 @@ public class WeatherViewModel extends BaseViewModel<ActivityWeatherBinding, Acti
|
||||
@Override
|
||||
public void onError(Throwable throwable) {
|
||||
Log.e("getWeather7D", "onError: " + throwable.getMessage());
|
||||
// mWeatherDailyData.setValue(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.vscool.os.bean.Contact;
|
||||
import com.vscool.os.bean.RecordsInfo;
|
||||
import com.vscool.os.dialog.CallPhoneDialog;
|
||||
import com.vscool.os.utils.GlideLoadUtils;
|
||||
import com.vscool.os.utils.TimeUtils;
|
||||
import com.vscool.os.utils.Utils;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
@@ -97,6 +98,7 @@ public class CallRecordAdapter extends RecyclerView.Adapter<CallRecordAdapter.Ho
|
||||
break;
|
||||
}
|
||||
holder.tv_time.setText(mSimpleDateFormat.format(new Date(recordsInfo.getDate())));
|
||||
holder.tv_date.setText(TimeUtils.getDateWeek(new Date(recordsInfo.getDate())));
|
||||
|
||||
holder.iv_remove.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
@@ -187,6 +189,7 @@ public class CallRecordAdapter extends RecyclerView.Adapter<CallRecordAdapter.Ho
|
||||
TextView tv_name;
|
||||
TextView tv_phone;
|
||||
TextView tv_time;
|
||||
TextView tv_date;
|
||||
|
||||
public Holder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
@@ -198,6 +201,7 @@ public class CallRecordAdapter extends RecyclerView.Adapter<CallRecordAdapter.Ho
|
||||
tv_name = itemView.findViewById(R.id.tv_name);
|
||||
tv_phone = itemView.findViewById(R.id.tv_phone);
|
||||
tv_time = itemView.findViewById(R.id.tv_time);
|
||||
tv_date = itemView.findViewById(R.id.tv_date);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ import com.hjq.toast.Toaster;
|
||||
import com.vscool.os.R;
|
||||
import com.vscool.os.activity.contact.ContactListActivity;
|
||||
import com.vscool.os.activity.phone.PhoneActivity;
|
||||
import com.vscool.os.activity.service.ServiceActivity;
|
||||
import com.vscool.os.bean.DailyAppBean;
|
||||
import com.vscool.os.config.CommonConfig;
|
||||
import com.vscool.os.config.PackagesName;
|
||||
@@ -72,9 +71,6 @@ public class DailyAppAdapter extends RecyclerView.Adapter<DailyAppAdapter.Holder
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
switch (packageName) {
|
||||
case PackagesName.VSCOOL_SERVICE:
|
||||
mContext.startActivity(new Intent(mContext, ServiceActivity.class));
|
||||
break;
|
||||
case PackagesName.VSCOOL_CONTACTS:
|
||||
mContext.startActivity(new Intent(mContext, ContactListActivity.class));
|
||||
break;
|
||||
@@ -108,9 +104,7 @@ public class DailyAppAdapter extends RecyclerView.Adapter<DailyAppAdapter.Holder
|
||||
return;
|
||||
}
|
||||
DailyAppDialog dailyAppDialog = new DailyAppDialog(mContext);
|
||||
dailyAppDialog.setTitle("放到桌面");
|
||||
dailyAppDialog.setMessage(dailyAppBean.getAppName());
|
||||
dailyAppDialog.setIconImage(dailyAppBean.getIcon(mContext));
|
||||
dailyAppDialog.setTitle(String.format(mContext.getString(R.string.move_app_desktop), dailyAppBean.getAppName()));
|
||||
dailyAppDialog.setOnClickBottomListener(new DailyAppDialog.OnClickBottomListener() {
|
||||
@Override
|
||||
public void onPositiveClick() {
|
||||
|
||||
@@ -14,14 +14,15 @@ import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.qweather.sdk.bean.weather.WeatherDailyBean;
|
||||
import com.vscool.os.R;
|
||||
import com.vscool.os.utils.DayUtils;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public class WeatherDayApdapterPort extends RecyclerView.Adapter<WeatherDayApdapterPort.WeatherHolder> {
|
||||
private static final String TAG = "WeatherDayApdapterPort";
|
||||
public class WeatherDayApdapter extends RecyclerView.Adapter<WeatherDayApdapter.WeatherHolder> {
|
||||
private static final String TAG = "WeatherDayApdapter";
|
||||
private List<WeatherDailyBean.DailyBean> mDailyBeans;
|
||||
private Context mContext;
|
||||
|
||||
@@ -34,7 +35,7 @@ public class WeatherDayApdapterPort extends RecyclerView.Adapter<WeatherDayApdap
|
||||
@Override
|
||||
public WeatherHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
mContext = parent.getContext();
|
||||
return new WeatherHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_weather_port, parent, false));
|
||||
return new WeatherHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_weather, parent, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -42,29 +43,19 @@ public class WeatherDayApdapterPort extends RecyclerView.Adapter<WeatherDayApdap
|
||||
WeatherDailyBean.DailyBean dailyBean = mDailyBeans.get(position);
|
||||
String dateString;
|
||||
switch (position) {
|
||||
// case 0:
|
||||
// dateString = "今天";
|
||||
// break;
|
||||
// case 1:
|
||||
// dateString = "明天";
|
||||
// break;
|
||||
// case 2:
|
||||
// dateString = "后天";
|
||||
// break;
|
||||
default:
|
||||
dateString = dailyBean.getFxDate();
|
||||
try {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||
Date date = sdf.parse(dailyBean.getFxDate());
|
||||
SimpleDateFormat now = new SimpleDateFormat("MM月dd日");
|
||||
dateString = now.format(date);
|
||||
SimpleDateFormat now = new SimpleDateFormat("M月d日");
|
||||
dateString = now.format(date) + "\t" + DayUtils.getWeek(date);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
holder.tv_date.setText(dateString);
|
||||
holder.tv_temp.setText(dailyBean.getTempMin() + "℃ / " + dailyBean.getTempMax() + "℃");
|
||||
holder.tv_weather.setText(dailyBean.getTextDay());
|
||||
holder.tv_temp.setText(dailyBean.getTextDay() + "\t" + dailyBean.getTempMin() + "℃ / " + dailyBean.getTempMax() + "℃");
|
||||
String iconDay = dailyBean.getIconDay();
|
||||
|
||||
holder.iv_weather.setImageDrawable(getWeatherDrawable(iconDay));
|
||||
@@ -88,14 +79,12 @@ public class WeatherDayApdapterPort extends RecyclerView.Adapter<WeatherDayApdap
|
||||
static class WeatherHolder extends RecyclerView.ViewHolder {
|
||||
TextView tv_date;
|
||||
ImageView iv_weather;
|
||||
TextView tv_weather;
|
||||
TextView tv_temp;
|
||||
|
||||
public WeatherHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
tv_date = itemView.findViewById(R.id.tv_date);
|
||||
iv_weather = itemView.findViewById(R.id.iv_weather);
|
||||
tv_weather = itemView.findViewById(R.id.tv_weather);
|
||||
tv_temp = itemView.findViewById(R.id.tv_temp);
|
||||
}
|
||||
}
|
||||
@@ -61,8 +61,7 @@ public class WechatContactAdapter extends RecyclerView.Adapter<WechatContactAdap
|
||||
Contact contact = mContactList.get(position);
|
||||
contactHolder.tv_name.setText(contact.getName());
|
||||
contactHolder.tv_phone.setText(contact.getMobile());
|
||||
|
||||
Glide.with(contactHolder.iv_head).load(contact.getAvatar()).override(200, 200).error(R.drawable.default_avatar).into(contactHolder.iv_head);
|
||||
Glide.with(contactHolder.iv_head).load(contact.getAvatar()).dontAnimate().override(200, 200).placeholder(contactHolder.iv_head.getDrawable()).error(R.drawable.default_avatar).into(contactHolder.iv_head);
|
||||
|
||||
// switch (position % 6) {
|
||||
// case 0:
|
||||
|
||||
@@ -12,8 +12,8 @@ public class PackagesName {
|
||||
public static final String VSCOOL_DESKTOP_SETTING = "xxpatx.os.desktop.setting";
|
||||
/*更多应用*/
|
||||
public static final String VSCOOL_USER_CENTER = "xxpatx.os.user.center";
|
||||
/*联系客服*/
|
||||
public static final String VSCOOL_SERVICE = "xxpatx.os.service";
|
||||
// /*联系客服*/
|
||||
// public static final String VSCOOL_SERVICE = "xxpatx.os.service";
|
||||
/*爱心闹钟*/
|
||||
public static final String VSCOOL_ALARM_CLOCK = "xxpatx.os.alarm.clock";
|
||||
/*SOS*/
|
||||
|
||||
@@ -1,19 +1,15 @@
|
||||
package com.vscool.os.dialog;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
|
||||
import com.vscool.os.R;
|
||||
|
||||
|
||||
/**
|
||||
* description:自定义dialog
|
||||
*/
|
||||
@@ -24,19 +20,12 @@ public class DailyAppDialog extends AlertDialog {
|
||||
*/
|
||||
private TextView titleTv;
|
||||
|
||||
/**
|
||||
* 显示的消息
|
||||
*/
|
||||
private TextView messageTv;
|
||||
|
||||
/**
|
||||
* 确认和取消按钮
|
||||
*/
|
||||
private TextView positiveBn;
|
||||
private TextView negtiveBn;
|
||||
|
||||
private ImageView ivIcon;
|
||||
|
||||
private Context mContext;
|
||||
|
||||
public DailyAppDialog(Context context) {
|
||||
@@ -47,14 +36,8 @@ public class DailyAppDialog extends AlertDialog {
|
||||
/**
|
||||
* 都是内容数据
|
||||
*/
|
||||
private String message;
|
||||
private String title;
|
||||
private String positive, negtive;
|
||||
private Drawable mDrawable;
|
||||
/**
|
||||
* 底部是否只有一个按钮
|
||||
*/
|
||||
private boolean isSingle = false;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@@ -105,9 +88,6 @@ public class DailyAppDialog extends AlertDialog {
|
||||
} else {
|
||||
titleTv.setVisibility(View.GONE);
|
||||
}
|
||||
if (!TextUtils.isEmpty(message)) {
|
||||
messageTv.setText(message);
|
||||
}
|
||||
//如果设置按钮的文字
|
||||
if (!TextUtils.isEmpty(positive)) {
|
||||
positiveBn.setText(positive);
|
||||
@@ -119,7 +99,6 @@ public class DailyAppDialog extends AlertDialog {
|
||||
} else {
|
||||
negtiveBn.setText("取消");
|
||||
}
|
||||
ivIcon.setImageDrawable(mDrawable);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -135,8 +114,6 @@ public class DailyAppDialog extends AlertDialog {
|
||||
negtiveBn = findViewById(R.id.negtive);
|
||||
positiveBn = findViewById(R.id.positive);
|
||||
titleTv = findViewById(R.id.title);
|
||||
messageTv = findViewById(R.id.message);
|
||||
ivIcon = findViewById(R.id.iv_icon);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -160,15 +137,6 @@ public class DailyAppDialog extends AlertDialog {
|
||||
void onNegtiveClick();
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public DailyAppDialog setMessage(String message) {
|
||||
this.message = message;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
@@ -201,20 +169,6 @@ public class DailyAppDialog extends AlertDialog {
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isSingle() {
|
||||
return isSingle;
|
||||
}
|
||||
|
||||
public DailyAppDialog setSingle(boolean single) {
|
||||
isSingle = single;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DailyAppDialog setIconImage(Drawable drawable) {
|
||||
this.mDrawable = drawable;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dismiss() {
|
||||
super.dismiss();
|
||||
|
||||
@@ -28,7 +28,6 @@ import com.vscool.os.R;
|
||||
import com.vscool.os.activity.contact.ContactListActivity;
|
||||
import com.vscool.os.activity.dailyapp.DailyAppActivity;
|
||||
import com.vscool.os.activity.screenlock.ScreenLockActivity;
|
||||
import com.vscool.os.activity.service.ServiceActivity;
|
||||
import com.vscool.os.base.BaseFragment;
|
||||
import com.vscool.os.bean.BaseResponse;
|
||||
import com.vscool.os.bean.DesktopIcon;
|
||||
@@ -217,9 +216,6 @@ public class AppListFragment extends BaseFragment {
|
||||
return;
|
||||
}
|
||||
switch (desktopIcon.getPackage()) {
|
||||
case PackagesName.VSCOOL_SERVICE:
|
||||
startActivity(new Intent(mContext, ServiceActivity.class));
|
||||
break;
|
||||
case PackagesName.VSCOOL_CONTACTS:
|
||||
startActivity(new Intent(mContext, ContactListActivity.class));
|
||||
break;
|
||||
@@ -382,9 +378,7 @@ public class AppListFragment extends BaseFragment {
|
||||
String label = desktopIcon.getTitle();
|
||||
String pkg = desktopIcon.getPackage();
|
||||
DailyAppDialog dailyAppDialog = new DailyAppDialog(mContext);
|
||||
dailyAppDialog.setTitle("移到日常应用");
|
||||
dailyAppDialog.setMessage(label);
|
||||
dailyAppDialog.setIconImage(DesktopIconManager.getInstance().getPackageIcon(pkg));
|
||||
dailyAppDialog.setTitle(String.format(getString(R.string.move_app_hide), label));
|
||||
dailyAppDialog.setOnClickBottomListener(new DailyAppDialog.OnClickBottomListener() {
|
||||
@Override
|
||||
public void onPositiveClick() {
|
||||
|
||||
@@ -7,33 +7,21 @@ import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
|
||||
import com.hjq.toast.Toaster;
|
||||
import com.jeremyliao.liveeventbus.LiveEventBus;
|
||||
import com.qweather.sdk.bean.weather.WeatherNowBean;
|
||||
import com.tencent.mmkv.MMKV;
|
||||
import com.vscool.os.R;
|
||||
import com.vscool.os.activity.contact.AddContactActivity;
|
||||
import com.vscool.os.activity.contact.EditContactActivity;
|
||||
import com.vscool.os.activity.weather.WeatherActivity;
|
||||
import com.vscool.os.adapter.WechatContactAdapter;
|
||||
import com.vscool.os.base.mvvm.fragment.BaseMvvmFragment;
|
||||
import com.vscool.os.bean.BaseResponse;
|
||||
import com.vscool.os.bean.Contact;
|
||||
import com.vscool.os.bean.MapBean;
|
||||
import com.vscool.os.config.CommonConfig;
|
||||
import com.vscool.os.databinding.FragmentContactHomeBinding;
|
||||
import com.vscool.os.dialog.EditContactDialog;
|
||||
import com.vscool.os.utils.DayUtils;
|
||||
import com.vscool.os.utils.TimeUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -79,196 +67,43 @@ public class ContactFragment extends BaseMvvmFragment<ContactViewModel, Fragment
|
||||
// EquallyDividedItemDecoration equallyDividedItemDecoration = new EquallyDividedItemDecoration(SPAN_COUNT, 2);
|
||||
// mViewDataBinding.rvContact.addItemDecoration(equallyDividedItemDecoration);
|
||||
mViewDataBinding.rvContact.setAdapter(mContactAdapter);
|
||||
setTime();
|
||||
initAmap();
|
||||
}
|
||||
|
||||
private void setTime() {
|
||||
mViewDataBinding.tvTime.setText(TimeUtils.getNowTime(mContext));
|
||||
mViewDataBinding.tvData.setText(TimeUtils.getDateWeek());
|
||||
mViewDataBinding.tvWeek.setText(DayUtils.getWeek());
|
||||
}
|
||||
|
||||
private void initAmap() {
|
||||
boolean manual = mMMKV.decodeBool(CommonConfig.MANUALLY_SELECT_LOCATION_KEY, false);
|
||||
if (!manual) {
|
||||
LiveEventBus.get(CommonConfig.AMAP_LOCATION_MAP_BEAN, MapBean.class)
|
||||
.observe(this, new Observer<MapBean>() {
|
||||
@Override
|
||||
public void onChanged(@Nullable MapBean mapBean) {
|
||||
mViewDataBinding.tvLocation.setText(mapBean.getDistrict());
|
||||
}
|
||||
});
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
private List<Contact> mContacts = new ArrayList<Contact>() {{
|
||||
this.add(new Contact("未设置"));
|
||||
this.add(new Contact("未设置"));
|
||||
this.add(new Contact("未设置"));
|
||||
this.add(new Contact("未设置"));
|
||||
this.add(new Contact("未设置"));
|
||||
this.add(new Contact("未设置"));
|
||||
}};
|
||||
|
||||
@Override
|
||||
protected void initData(Bundle savedInstanceState) {
|
||||
LiveEventBus
|
||||
.get("getWeatherNowKey", WeatherNowBean.NowBaseBean.class)
|
||||
.observe(this, new Observer<WeatherNowBean.NowBaseBean>() {
|
||||
@Override
|
||||
public void onChanged(@Nullable WeatherNowBean.NowBaseBean nowBaseBean) {
|
||||
mViewDataBinding.tvTemp.setText(nowBaseBean.getTemp() + "℃");
|
||||
if (DayUtils.isNight()) {
|
||||
// mViewDataBinding.clWeather.setBackground(mContext.getDrawable(R.drawable.custom_bg_weather_night));
|
||||
} else {
|
||||
switch (nowBaseBean.getIcon()) {
|
||||
default:
|
||||
case "100":
|
||||
case "150":
|
||||
//晴
|
||||
// mViewDataBinding.clWeather.setBackground(mContext.getDrawable(R.drawable.custom_bg_weather));
|
||||
break;
|
||||
case "102":
|
||||
case "152":
|
||||
//少云
|
||||
// mViewDataBinding.clWeather.setBackground(mContext.getDrawable(R.drawable.custom_bg_weather_rain));
|
||||
break;
|
||||
}
|
||||
}
|
||||
// mViewDataBinding.tvWeather.setText(nowBaseBean.getText());
|
||||
}
|
||||
});
|
||||
|
||||
// LiveEventBus
|
||||
// .get("getWeather24HourlyKey", WeatherHourlyBean.HourlyBean.class)
|
||||
// .observe(this, new Observer<WeatherHourlyBean.HourlyBean>() {
|
||||
// @Override
|
||||
// public void onChanged(@Nullable WeatherHourlyBean.HourlyBean hourlyBean) {
|
||||
// String imageName = "he" + hourlyBean.getIcon();
|
||||
// Log.e(TAG, "onSuccess: " + imageName);
|
||||
// if (isAdded()) {
|
||||
// int resId = getResources().getIdentifier(imageName, "drawable", mContext.getPackageName());
|
||||
//// Log.e(TAG, "onSuccess: " + resId);
|
||||
//// if (resId == 0) {
|
||||
//// mViewDataBinding.ivPic.setImageDrawable(mContext.getDrawable(R.drawable.he100));
|
||||
//// } else {
|
||||
//// mViewDataBinding.ivPic.setImageDrawable(mContext.getDrawable(resId));
|
||||
//// }
|
||||
// mViewDataBinding.tvTemp.setText(hourlyBean.getTemp() + "℃");
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// LiveEventBus
|
||||
// .get("getWeather7DKey", WeatherDailyBean.DailyBean.class)
|
||||
// .observe(this, new Observer<WeatherDailyBean.DailyBean>() {
|
||||
// @Override
|
||||
// public void onChanged(@Nullable WeatherDailyBean.DailyBean dailyBean) {
|
||||
// mViewDataBinding.tvWeather.setText(dailyBean.getTempMin() + "℃ - " + dailyBean.getTempMax() + "℃");
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// LiveEventBus
|
||||
// .get("time", String.class)
|
||||
// .observe(this, new Observer<String>() {
|
||||
// @Override
|
||||
// public void onChanged(@Nullable String s) {
|
||||
// mViewDataBinding.tvTime.setText(s);
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// LiveEventBus
|
||||
// .get("date", String.class)
|
||||
// .observe(this, new Observer<String>() {
|
||||
// @Override
|
||||
// public void onChanged(@Nullable String s) {
|
||||
// mViewDataBinding.tvData.setText(s);
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// LiveEventBus
|
||||
// .get("week", String.class)
|
||||
// .observe(this, new Observer<String>() {
|
||||
// @Override
|
||||
// public void onChanged(@Nullable String s) {
|
||||
// mViewDataBinding.tvWeek.setText(s);
|
||||
// }
|
||||
// });
|
||||
|
||||
mViewModel.mContactListData.observe(this, new Observer<List<Contact>>() {
|
||||
@Override
|
||||
public void onChanged(List<Contact> contacts) {
|
||||
if (contacts == null || contacts.size() == 0) {
|
||||
contacts .add(new Contact("未设置"));
|
||||
contacts .add(new Contact("未设置"));
|
||||
contacts .add(new Contact("未设置"));
|
||||
contacts .add(new Contact("未设置"));
|
||||
contacts .add(new Contact("未设置"));
|
||||
contacts .add(new Contact("未设置"));
|
||||
// mViewDataBinding.clNodata.setVisibility(View.VISIBLE);
|
||||
// mViewDataBinding.rvContact.setVisibility(View.GONE);
|
||||
if (contacts == null || contacts.isEmpty()) {
|
||||
mContactAdapter.setContactList(mContacts);
|
||||
} else {
|
||||
// mViewDataBinding.clNodata.setVisibility(View.GONE);
|
||||
// mViewDataBinding.rvContact.setVisibility(View.VISIBLE);
|
||||
// List<Contact> sim = getSIMContacts();
|
||||
// if (sim.size() != 0) {
|
||||
// contacts.addAll(sim);
|
||||
// }
|
||||
}
|
||||
mContactAdapter.setContactList(contacts);
|
||||
}
|
||||
});
|
||||
mViewModel.mDeleteData.observe(this, new Observer<BaseResponse>() {
|
||||
@Override
|
||||
public void onChanged(BaseResponse baseResponse) {
|
||||
if (baseResponse.code == 200) {
|
||||
Toaster.show("删除成功");
|
||||
} else {
|
||||
Toaster.show("删除失败:" + baseResponse.msg);
|
||||
}
|
||||
mViewModel.getContact();
|
||||
}
|
||||
});
|
||||
|
||||
Log.e(TAG, "initData: ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fetchData() {
|
||||
Log.e(TAG, "fetchData: ");
|
||||
mViewModel.getCacheContact();
|
||||
mViewModel.getContact();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
String district = mMMKV.decodeString(CommonConfig.MANUALLY_SELECT_LOCATION_DISTRICT, CommonConfig.DEFAULT_LOCATION_DISTRICT);
|
||||
mViewDataBinding.tvLocation.setText(district);
|
||||
}
|
||||
|
||||
private EditContactDialog mEditContactDialog;
|
||||
|
||||
private void showDialog(Contact contact) {
|
||||
if (mEditContactDialog == null) {
|
||||
mEditContactDialog = new EditContactDialog(getContext());
|
||||
}
|
||||
mEditContactDialog
|
||||
.setPhoneNumber(contact.getMobile())
|
||||
.setOnClickBottomListener(new EditContactDialog.OnClickBottomListener() {
|
||||
@Override
|
||||
public void onEditClick() {
|
||||
Intent intent = new Intent(getContext(), EditContactActivity.class);
|
||||
intent.putExtra("Contact", contact);
|
||||
startActivity(intent);
|
||||
mEditContactDialog.dismiss();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeleteClick() {
|
||||
mViewModel.deleteContact(contact.getId());
|
||||
mEditContactDialog.dismiss();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancelClick() {
|
||||
mEditContactDialog.dismiss();
|
||||
}
|
||||
});
|
||||
Window window = mEditContactDialog.getWindow();
|
||||
window.setGravity(Gravity.BOTTOM);
|
||||
mEditContactDialog.show();
|
||||
mViewModel.getContact();
|
||||
}
|
||||
|
||||
public static final String NAME = "name";
|
||||
|
||||
@@ -1,34 +1,18 @@
|
||||
package com.vscool.os.fragment.contact;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.tencent.mmkv.MMKV;
|
||||
import com.trello.rxlifecycle4.RxLifecycle;
|
||||
import com.trello.rxlifecycle4.android.FragmentEvent;
|
||||
import com.vscool.os.base.mvvm.BaseViewModel;
|
||||
import com.vscool.os.bean.BaseResponse;
|
||||
import com.vscool.os.bean.Contact;
|
||||
import com.vscool.os.config.CommonConfig;
|
||||
import com.vscool.os.databinding.FragmentContactHomeBinding;
|
||||
import com.vscool.os.db.ContactCacheUtils;
|
||||
import com.vscool.os.gson.GsonUtils;
|
||||
import com.vscool.os.network.NetInterfaceManager;
|
||||
import com.vscool.os.network.UrlAddress;
|
||||
import com.vscool.os.utils.ContactsUtils;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import io.reactivex.rxjava3.annotations.NonNull;
|
||||
import io.reactivex.rxjava3.core.Observer;
|
||||
import io.reactivex.rxjava3.disposables.Disposable;
|
||||
|
||||
public class ContactViewModel extends BaseViewModel<FragmentContactHomeBinding, FragmentEvent> {
|
||||
private static final String TAG = "ContactListViewModel";
|
||||
private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE);
|
||||
@@ -45,98 +29,29 @@ public class ContactViewModel extends BaseViewModel<FragmentContactHomeBinding,
|
||||
|
||||
public MutableLiveData<List<Contact>> mContactListData = new MutableLiveData<>();
|
||||
|
||||
public void getCacheContact() {
|
||||
String jsonString = mMMKV.getString(UrlAddress.GET_MAIL_LIST, null);
|
||||
Gson gson = new Gson();
|
||||
Type type = new TypeToken<List<Contact>>() {
|
||||
}.getType();
|
||||
if (!TextUtils.isEmpty(jsonString)) {
|
||||
List<Contact> contacts = gson.fromJson(jsonString, type);
|
||||
if (contacts != null) {
|
||||
contacts.addAll(ContactCacheUtils.getInstance().getDatabaseContact());
|
||||
mContactListData.setValue(contacts);
|
||||
|
||||
}
|
||||
}
|
||||
getContact();
|
||||
}
|
||||
|
||||
public void getContact() {
|
||||
NetInterfaceManager.getInstance()
|
||||
.getContactListObservable()
|
||||
.compose(RxLifecycle.bindUntilEvent(getLifecycle(), FragmentEvent.DESTROY))
|
||||
.subscribe(new Observer<BaseResponse<List<Contact>>>() {
|
||||
NetInterfaceManager.getInstance().getContactListObserverCache(UrlAddress.GET_MAIL_LIST, new NetInterfaceManager.ContactCallback() {
|
||||
@Override
|
||||
public void onSubscribe(@NonNull Disposable d) {
|
||||
Log.e("getContactList", "onSubscribe: ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(@NonNull BaseResponse<List<Contact>> listBaseResponse) {
|
||||
Log.e("getContactList", "onNext: " + listBaseResponse);
|
||||
if (listBaseResponse.code == 200) {
|
||||
List<Contact> contactList = listBaseResponse.data;
|
||||
String oldCache = mMMKV.getString(UrlAddress.GET_MAIL_LIST, "");
|
||||
if (!oldCache.equals(GsonUtils.toJSONString(listBaseResponse.data))) {
|
||||
ContactsUtils.saveContactPhone(getCtx(), contactList);
|
||||
}
|
||||
public void setContact(List<Contact> contactList) {
|
||||
mContactListData.setValue(contactList);
|
||||
mMMKV.putString(UrlAddress.GET_MAIL_LIST, GsonUtils.toJSONString(listBaseResponse.data));
|
||||
} else {
|
||||
mMMKV.putString(UrlAddress.GET_MAIL_LIST, "");
|
||||
mContactListData.setValue(new ArrayList<>());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(@NonNull Throwable e) {
|
||||
Log.e("getContactList", "onError: " + e.getMessage());
|
||||
String jsonString = mMMKV.getString(UrlAddress.GET_MAIL_LIST, null);
|
||||
Gson gson = new Gson();
|
||||
Type type = new TypeToken<List<Contact>>() {
|
||||
}.getType();
|
||||
List<Contact> contacts = gson.fromJson(jsonString, type);
|
||||
if (contacts == null) {
|
||||
mContactListData.setValue(ContactCacheUtils.getInstance().getDatabaseContact());
|
||||
} else {
|
||||
contacts.addAll(ContactCacheUtils.getInstance().getDatabaseContact());
|
||||
mContactListData.setValue(contacts);
|
||||
}
|
||||
onComplete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
Log.e("getContactList", "onComplete: ");
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public MutableLiveData<BaseResponse> mDeleteData = new MutableLiveData<>();
|
||||
|
||||
public void deleteContact(long id) {
|
||||
NetInterfaceManager.getInstance().getMailListDeleteObservable(id)
|
||||
.compose(RxLifecycle.bindUntilEvent(getLifecycle(), FragmentEvent.DESTROY))
|
||||
.subscribe(new Observer<BaseResponse>() {
|
||||
NetInterfaceManager.getInstance()
|
||||
.getContactListFragment(getLifecycle(), new NetInterfaceManager.ContactCallback() {
|
||||
@Override
|
||||
public void onSubscribe(@NonNull Disposable d) {
|
||||
Log.e("deleteContact", "onSubscribe: ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(@NonNull BaseResponse baseResponse) {
|
||||
Log.e("deleteContact", "onNext: " + baseResponse);
|
||||
mDeleteData.setValue(baseResponse);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(@NonNull Throwable e) {
|
||||
Log.e("deleteContact", "onError: " + e.getMessage());
|
||||
public void setContact(List<Contact> contactList) {
|
||||
mContactListData.setValue(contactList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
Log.e("deleteContact", "onComplete: ");
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -123,19 +123,19 @@ public class ContactFragment extends BaseMvvmFragment<ContactViewModel, Fragment
|
||||
mViewModel.getContact();
|
||||
}
|
||||
});
|
||||
mViewModel.getCacheContact();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fetchData() {
|
||||
|
||||
Log.e(TAG, "fetchData: ");
|
||||
mViewModel.getContact();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
Log.e(TAG, "onResume: ");
|
||||
mViewModel.getCacheContact();
|
||||
mViewModel.getContact();
|
||||
}
|
||||
|
||||
public static final String NAME = "name";
|
||||
|
||||
@@ -9,13 +9,10 @@ import android.net.Uri;
|
||||
import android.provider.ContactsContract;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.tencent.mmkv.MMKV;
|
||||
import com.trello.rxlifecycle4.RxLifecycle;
|
||||
import com.trello.rxlifecycle4.android.FragmentEvent;
|
||||
@@ -24,12 +21,10 @@ import com.vscool.os.bean.BaseResponse;
|
||||
import com.vscool.os.bean.Contact;
|
||||
import com.vscool.os.config.CommonConfig;
|
||||
import com.vscool.os.databinding.FragmentContactBinding;
|
||||
import com.vscool.os.gson.GsonUtils;
|
||||
import com.vscool.os.network.NetInterfaceManager;
|
||||
import com.vscool.os.network.UrlAddress;
|
||||
import com.vscool.os.utils.ContactsUtils;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -56,66 +51,28 @@ public class ContactViewModel extends BaseViewModel<FragmentContactBinding, Frag
|
||||
|
||||
public MutableLiveData<List<Contact>> mContactListData = new MutableLiveData<>();
|
||||
|
||||
public void getCacheContact() {
|
||||
String jsonString = mMMKV.getString(UrlAddress.GET_MAIL_LIST, null);
|
||||
Gson gson = new Gson();
|
||||
Type type = new TypeToken<List<Contact>>() {
|
||||
}.getType();
|
||||
if (!TextUtils.isEmpty(jsonString)) {
|
||||
List<Contact> contacts = gson.fromJson(jsonString, type);
|
||||
if (contacts != null) {
|
||||
mContactListData.setValue(contacts);
|
||||
}
|
||||
}
|
||||
getContact();
|
||||
}
|
||||
|
||||
public void getContact() {
|
||||
NetInterfaceManager.getInstance()
|
||||
.getContactListObservable()
|
||||
.compose(RxLifecycle.bindUntilEvent(getLifecycle(), FragmentEvent.DESTROY))
|
||||
.subscribe(new Observer<BaseResponse<List<Contact>>>() {
|
||||
NetInterfaceManager.getInstance().getContactListObserverCache(UrlAddress.GET_MAIL_LIST, new NetInterfaceManager.ContactCallback() {
|
||||
@Override
|
||||
public void onSubscribe(@NonNull Disposable d) {
|
||||
Log.e("getContactList", "onSubscribe: ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(@NonNull BaseResponse<List<Contact>> listBaseResponse) {
|
||||
Log.e("getContactList", "onNext: " + listBaseResponse);
|
||||
if (listBaseResponse.code == 200) {
|
||||
List<Contact> contactList = listBaseResponse.data;
|
||||
String oldCache = mMMKV.getString(UrlAddress.GET_MAIL_LIST, "");
|
||||
if (!oldCache.equals(GsonUtils.toJSONString(contactList))) {
|
||||
ContactsUtils.saveContactPhone(getCtx(), contactList);
|
||||
}
|
||||
public void setContact(List<Contact> contactList) {
|
||||
mContactListData.setValue(contactList);
|
||||
mMMKV.putString(UrlAddress.GET_MAIL_LIST, GsonUtils.toJSONString(contactList));
|
||||
} else {
|
||||
mMMKV.putString(UrlAddress.GET_MAIL_LIST, "");
|
||||
mContactListData.setValue(new ArrayList<>());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(@NonNull Throwable e) {
|
||||
Log.e("getContactList", "onError: " + e.getMessage());
|
||||
String jsonString = mMMKV.getString(UrlAddress.GET_MAIL_LIST, null);
|
||||
Gson gson = new Gson();
|
||||
Type type = new TypeToken<List<Contact>>() {
|
||||
}.getType();
|
||||
List<Contact> contacts = gson.fromJson(jsonString, type);
|
||||
if (contacts == null) {
|
||||
mContactListData.setValue(new ArrayList<>());
|
||||
} else {
|
||||
mContactListData.setValue(contacts);
|
||||
}
|
||||
onComplete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
Log.e("getContactList", "onComplete: ");
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
NetInterfaceManager.getInstance().getContactListFragment(getLifecycle(), new NetInterfaceManager.ContactCallback() {
|
||||
@Override
|
||||
public void setContact(List<Contact> contactList) {
|
||||
mContactListData.setValue(contactList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -135,6 +92,9 @@ public class ContactViewModel extends BaseViewModel<FragmentContactBinding, Frag
|
||||
@Override
|
||||
public void onNext(@NonNull BaseResponse baseResponse) {
|
||||
Log.e("deleteContact", "onNext: " + baseResponse);
|
||||
if (baseResponse.code == 200) {
|
||||
ContactsUtils.deleteRawContact(getCtx(), contact.getMobile());
|
||||
}
|
||||
mDeleteData.setValue(baseResponse);
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ public class AppStatusManager {
|
||||
|
||||
private static final Set<String> mExcludeApp = new HashSet<String>() {{
|
||||
this.add("com.android.contacts");
|
||||
this.add("com.android.dialer");
|
||||
// this.add("com.android.dialer");
|
||||
// this.add("com.mediatek.camera");
|
||||
this.add("cn.etouch.ecalendar");
|
||||
}};
|
||||
|
||||
@@ -76,8 +76,6 @@ public class DesktopIconManager {
|
||||
|
||||
public Drawable getPackageIcon(String pkg) {
|
||||
switch (pkg) {
|
||||
case PackagesName.VSCOOL_SERVICE:
|
||||
return mContext.getDrawable(R.drawable.icon_wechat_service);
|
||||
case PackagesName.VSCOOL_EXIT_DESKTOP:
|
||||
return mContext.getDrawable(R.drawable.exit_icon);
|
||||
default:
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.vscool.os.network;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.os.Environment;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
@@ -92,10 +93,12 @@ import com.vscool.os.network.api.uiui.sn.SnInfoApi;
|
||||
import com.vscool.os.network.api.uiui.sn.SosRecordApi;
|
||||
import com.vscool.os.network.api.uiui.sn.UpdateAddressApi;
|
||||
import com.vscool.os.network.interceptor.RepeatRequestInterceptor;
|
||||
import com.vscool.os.utils.ContactsUtils;
|
||||
import com.vscool.os.utils.Utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -121,6 +124,8 @@ import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory;
|
||||
import retrofit2.converter.gson.GsonConverterFactory;
|
||||
|
||||
public class NetInterfaceManager {
|
||||
private static final String TAG = "NetInterfaceManager";
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private static NetInterfaceManager INSTANCE;
|
||||
private Context mContext;
|
||||
@@ -1105,16 +1110,6 @@ public class NetInterfaceManager {
|
||||
});
|
||||
}
|
||||
|
||||
public interface ContactCallback {
|
||||
void setContact(List<Contact> contactList);
|
||||
|
||||
void setEmergencyContact(List<Contact> emergencyContact);
|
||||
|
||||
void setEmpty();
|
||||
|
||||
void onComplete();
|
||||
}
|
||||
|
||||
// public void getSystemSettings(boolean refresh, BehaviorSubject<ActivityEvent> lifecycle, ContactCallback callback) {
|
||||
// ConnectMode connectMode = ConnectMode.ONE_MINUTE;
|
||||
// if (refresh) {
|
||||
@@ -1176,7 +1171,7 @@ public class NetInterfaceManager {
|
||||
String s = systemSettings.getSetting_sos();
|
||||
} else {
|
||||
mCacheHelper.put(UrlAddress.GET_SETTINGS, "");
|
||||
if (callback != null) callback.setEmpty();
|
||||
if (callback != null) callback.setContact(null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1186,14 +1181,14 @@ public class NetInterfaceManager {
|
||||
String jsonString = mCacheHelper.getAsString(UrlAddress.GET_SETTINGS);
|
||||
//为 "" 是已经请求成功的
|
||||
if (jsonString == null) {
|
||||
if (callback != null) callback.setEmpty();
|
||||
if (callback != null) callback.setContact(null);
|
||||
} else {
|
||||
Gson gson = new Gson();
|
||||
Type type = new TypeToken<List<Contact>>() {
|
||||
}.getType();
|
||||
List<Contact> setting_sos = gson.fromJson(jsonString, type);
|
||||
if (setting_sos == null || setting_sos.size() == 0) {
|
||||
if (callback != null) callback.setEmpty();
|
||||
if (callback != null) callback.setContact(null);
|
||||
} else {
|
||||
if (callback != null) callback.setContact(setting_sos);
|
||||
}
|
||||
@@ -1210,32 +1205,10 @@ public class NetInterfaceManager {
|
||||
};
|
||||
}
|
||||
|
||||
public interface ContactCallback {
|
||||
void setContact(List<Contact> contactList);
|
||||
|
||||
public void getContactList(boolean refresh, BehaviorSubject<ActivityEvent> lifecycle, ContactCallback callback) {
|
||||
ConnectMode connectMode = ConnectMode.ONE_MINUTE;
|
||||
if (refresh) {
|
||||
connectMode = ConnectMode.DEFAULT;
|
||||
}
|
||||
if (ConnectManager.getInstance().isNeedConnect(UrlAddress.GET_MAIL_LIST, connectMode)) {
|
||||
getContactList(lifecycle, callback);
|
||||
} else {
|
||||
String jsonString = mCacheHelper.getAsString(UrlAddress.GET_MAIL_LIST);
|
||||
//为 "" 是已经请求成功的
|
||||
if (jsonString == null) {
|
||||
getContactList(lifecycle, callback);
|
||||
} else {
|
||||
Gson gson = new Gson();
|
||||
Type type = new TypeToken<List<Contact>>() {
|
||||
}.getType();
|
||||
List<Contact> setting_sos = gson.fromJson(jsonString, type);
|
||||
if (setting_sos == null || setting_sos.size() == 0) {
|
||||
if (callback != null) callback.setEmpty();
|
||||
} else {
|
||||
if (callback != null) callback.setContact(setting_sos);
|
||||
}
|
||||
if (callback != null) callback.onComplete();
|
||||
}
|
||||
}
|
||||
void onComplete();
|
||||
}
|
||||
|
||||
public void getContactList(BehaviorSubject<ActivityEvent> lifecycle, ContactCallback callback) {
|
||||
@@ -1244,16 +1217,12 @@ public class NetInterfaceManager {
|
||||
.subscribe(getContactListObserver(callback));
|
||||
}
|
||||
|
||||
public void getContactList(ContactCallback callback) {
|
||||
public void getContactListFragment(BehaviorSubject<FragmentEvent> lifecycle, ContactCallback callback) {
|
||||
getContactListObservable()
|
||||
.compose(RxLifecycle.bindUntilEvent(lifecycle, FragmentEvent.DESTROY))
|
||||
.subscribe(getContactListObserver(callback));
|
||||
}
|
||||
|
||||
public void getContactList() {
|
||||
getContactListObservable()
|
||||
.subscribe(getContactListObserver(null));
|
||||
}
|
||||
|
||||
public Observer<BaseResponse<List<Contact>>> getContactListObserver(ContactCallback callback) {
|
||||
return new Observer<BaseResponse<List<Contact>>>() {
|
||||
@Override
|
||||
@@ -1267,25 +1236,27 @@ public class NetInterfaceManager {
|
||||
if (listBaseResponse.code == 200) {
|
||||
List<Contact> contactList = listBaseResponse.data;
|
||||
if (contactList == null || contactList.size() == 0) {
|
||||
mCacheHelper.put(UrlAddress.GET_MAIL_LIST, "");
|
||||
if (callback != null) callback.setEmpty();
|
||||
mMMKV.putString(UrlAddress.GET_MAIL_LIST, "");
|
||||
if (callback != null) callback.setContact(new ArrayList<>());
|
||||
} else {
|
||||
mCacheHelper.put(UrlAddress.GET_MAIL_LIST, GsonUtils.toJSONString(contactList));
|
||||
List<Contact> emergencyContact = contactList.stream().filter(contact -> contact.getIs_urgent() == 1).collect(Collectors.toList());
|
||||
mMMKV.putString(UrlAddress.GET_MAIL_LIST, GsonUtils.toJSONString(contactList));
|
||||
ContactsUtils.saveContactPhone(mContext, contactList);
|
||||
List<Contact> emergencyConcacts = contactList.stream().filter(contact -> contact.getIs_urgent() == 1).collect(Collectors.toList());
|
||||
mMMKV.putString(CommonConfig.EMERGENCY_CONTACT_LIST_KEY, GsonUtils.toJSONString(emergencyConcacts));
|
||||
if (callback != null) {
|
||||
callback.setContact(contactList);
|
||||
callback.setEmergencyContact(emergencyContact);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mCacheHelper.put(UrlAddress.GET_MAIL_LIST, "");
|
||||
if (callback != null) callback.setEmpty();
|
||||
mMMKV.putString(UrlAddress.GET_MAIL_LIST, "");
|
||||
if (callback != null) callback.setContact(new ArrayList<>());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(@NonNull Throwable e) {
|
||||
Log.e("getContactList", "onError: " + e.getMessage());
|
||||
getContactListObserverCache(UrlAddress.GET_MAIL_LIST, callback);
|
||||
onComplete();
|
||||
}
|
||||
|
||||
@@ -1298,6 +1269,49 @@ public class NetInterfaceManager {
|
||||
};
|
||||
}
|
||||
|
||||
public void addContactCache(String tag, Contact contact) {
|
||||
String jsonString = mMMKV.getString(tag, null);
|
||||
Gson gson = new Gson();
|
||||
Type type = new TypeToken<List<Contact>>() {
|
||||
}.getType();
|
||||
if (TextUtils.isEmpty(jsonString)) {
|
||||
List<Contact> contacts = new ArrayList<>();
|
||||
contacts.add(contact);
|
||||
mMMKV.putString(tag, GsonUtils.toJSONString(contacts));
|
||||
} else {
|
||||
try {
|
||||
List<Contact> contacts = gson.fromJson(jsonString, type);
|
||||
if (contacts == null) {
|
||||
contacts = new ArrayList<>();
|
||||
}
|
||||
contacts.add(contact);
|
||||
mMMKV.putString(tag, GsonUtils.toJSONString(contacts));
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "addContactCache: " + e.getMessage());
|
||||
mMMKV.remove(tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void getContactListObserverCache(String tag, ContactCallback callback) {
|
||||
String jsonString = mMMKV.getString(tag, null);
|
||||
Gson gson = new Gson();
|
||||
Type type = new TypeToken<List<Contact>>() {
|
||||
}.getType();
|
||||
if (TextUtils.isEmpty(jsonString)) {
|
||||
if (callback != null) callback.setContact(new ArrayList<>());
|
||||
} else {
|
||||
try {
|
||||
List<Contact> contacts = gson.fromJson(jsonString, type);
|
||||
if (callback != null) callback.setContact(contacts);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "getContactListObserverCache: " + e.getMessage());
|
||||
mMMKV.remove(tag);
|
||||
if (callback != null) callback.setContact(new ArrayList<>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void getAdminSnSetting(boolean refresh, BehaviorSubject<ActivityEvent> lifecycle, onCompleteCallback callback) {
|
||||
ConnectMode connectMode = ConnectMode.ONE_MINUTE;
|
||||
if (refresh) {
|
||||
|
||||
@@ -19,10 +19,13 @@ import android.view.accessibility.AccessibilityEvent;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.hjq.toast.Toaster;
|
||||
import com.tencent.mmkv.MMKV;
|
||||
import com.vscool.os.bean.Contact;
|
||||
import com.vscool.os.config.CommonConfig;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 通过微信标签最高支持8.0.49,8.0.50 获取不到数据
|
||||
*/
|
||||
@@ -35,7 +38,7 @@ public class WeAccessibilityService extends AccessibilityService {
|
||||
private static final String DIALER_TEXT = "音视频通话";
|
||||
private static final String CONTACT_TEXT = "通讯录";
|
||||
private static final String TAG_TEXT = "标签";
|
||||
private static final String TAG_NAME = "孝心通";
|
||||
private static final String TAG_NAME = "亲情桌面";
|
||||
private static final String MORE_NAME = "更多功能按钮,已折叠";
|
||||
private static final String PARENT_VIDEO_TEXT = "视频通话";
|
||||
|
||||
@@ -129,6 +132,21 @@ public class WeAccessibilityService extends AccessibilityService {
|
||||
* @param event
|
||||
*/
|
||||
private void _onAccessibilityEvent(AccessibilityEvent event) {
|
||||
|
||||
switch (mCurrentStep) {
|
||||
case WAITING:
|
||||
break;
|
||||
default:
|
||||
if (!TextUtils.isEmpty(event.getClassName())) {
|
||||
if ("com.tencent.mm.ui.LauncherUI".contentEquals(event.getClassName())) {
|
||||
if (mCurrentStep != Step.FIND_CONTACT) {
|
||||
mCurrentStep = Step.CLICK_CONTACT;
|
||||
}
|
||||
} else if ("com.tencent.mm.plugin.label.ui.ContactLabelManagerUI".contentEquals(event.getClassName())) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Log.e(TAG, "_onAccessibilityEvent: " + mCurrentStep);
|
||||
switch (mCurrentStep) {
|
||||
case WAITING:
|
||||
@@ -149,10 +167,12 @@ public class WeAccessibilityService extends AccessibilityService {
|
||||
break;
|
||||
|
||||
case CLICK_CONTACT://进入通讯录界面
|
||||
step(Property.TEXT, CONTACT_TEXT, Step.FIND_TAG);
|
||||
touchContact();
|
||||
// step(Property.TEXT, CONTACT_TEXT, Step.FIND_TAG);
|
||||
break;
|
||||
case FIND_CONTACT://模拟滑动找到联系人
|
||||
findContact(Property.TEXT, mName, Step.CLICK_NAME);
|
||||
break;
|
||||
case FIND_TAG:
|
||||
step(Property.TEXT, TAG_TEXT, Step.CLICK_TAG);
|
||||
break;
|
||||
@@ -213,6 +233,12 @@ public class WeAccessibilityService extends AccessibilityService {
|
||||
private boolean step(Property type, String text, Step nextStep) {
|
||||
AccessibilityNodeInfo node = findNode(getRootInActiveWindow(), type, text);
|
||||
if (node != null) {
|
||||
Rect rect = new Rect();
|
||||
node.getBoundsInScreen(rect);
|
||||
Log.e(TAG, "step: rect = " + rect);
|
||||
if (rect.left < 0 || rect.top < 0 || rect.right < 0 || rect.bottom < 0) {
|
||||
return false;
|
||||
}
|
||||
clickNode(node);
|
||||
Log.e(TAG, "step: mCurrentStep: " + mCurrentStep + " done");
|
||||
mCurrentStep = nextStep;
|
||||
@@ -223,6 +249,40 @@ public class WeAccessibilityService extends AccessibilityService {
|
||||
}
|
||||
}
|
||||
|
||||
private void touchContact() {
|
||||
boolean successful = clickByPoint(268, 1440);
|
||||
if (successful) {
|
||||
mCurrentStep = Step.FIND_TAG;
|
||||
} else {
|
||||
mCurrentStep = Step.WAITING;
|
||||
Toaster.show("点击失败,请重试");
|
||||
}
|
||||
}
|
||||
|
||||
private List<AccessibilityNodeInfo> findNodesByViewId(String id) {
|
||||
List<AccessibilityNodeInfo> accessibilityNodeInfos = getRootInActiveWindow().findAccessibilityNodeInfosByViewId(id);
|
||||
return accessibilityNodeInfos;
|
||||
}
|
||||
|
||||
private AccessibilityNodeInfo findNodeByText(AccessibilityNodeInfo root, String text) {
|
||||
if (root == null) return null;
|
||||
Log.e(TAG, "findNodeByText: getText = " + root.getText());
|
||||
Log.e(TAG, "findNodeByText: getContentDescription = " + root.getContentDescription());
|
||||
boolean found = root.getText() != null && text.contentEquals(root.getText());
|
||||
if (found) {
|
||||
return root;
|
||||
} else {
|
||||
for (int i = 0; i < root.getChildCount(); i++) {
|
||||
AccessibilityNodeInfo result = findNodeByText(root.getChild(i), text);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
root.recycle();
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean stepCallDialog(Property type, String text, Step nextStep) {
|
||||
AccessibilityNodeInfo node = findNode(getRootInActiveWindow(), type, text);
|
||||
if (node != null) {
|
||||
@@ -234,12 +294,23 @@ public class WeAccessibilityService extends AccessibilityService {
|
||||
Log.e(TAG, "stepCallDialog: next: " + mCurrentStep);
|
||||
return true;
|
||||
} else {
|
||||
scrolDown();
|
||||
scrollDown();
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
scrolDown();
|
||||
if (mFindCount == mMaxCount) {
|
||||
Log.e("stepCallDialog", "mCurrentStep: max");
|
||||
Toast.makeText(this, "没有找到联系人", Toast.LENGTH_LONG).show();
|
||||
mCurrentStep = Step.WAITING;
|
||||
mFindCount = 0;
|
||||
return false;
|
||||
} else {
|
||||
Log.e("stepCallDialog", "mCurrentStep: not found");
|
||||
mFindCount++;
|
||||
Log.e("stepCallDialog", "mCurrentStep: mFindCount = " + mFindCount);
|
||||
scrollDown();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,7 +352,7 @@ public class WeAccessibilityService extends AccessibilityService {
|
||||
Log.e("findContact", "mCurrentStep: not found");
|
||||
mFindCount++;
|
||||
Log.e("findContact", "mCurrentStep: mFindCount = " + mFindCount);
|
||||
scrolDown();
|
||||
scrollDown();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -324,32 +395,37 @@ public class WeAccessibilityService extends AccessibilityService {
|
||||
private void clickNode(AccessibilityNodeInfo node) {
|
||||
try {
|
||||
Log.e(TAG, "clickNode: getText = " + node.getText());
|
||||
Log.e(TAG, "clickNode: isClickable = " + node.isClickable());
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "clickNode: e = " + e.getMessage());
|
||||
}
|
||||
Log.e(TAG, "clickNode: isClickable = " + node.isClickable());
|
||||
if (node.isClickable()) {
|
||||
boolean performAction = node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
|
||||
Log.e(TAG, "clickNode: performAction = " + performAction);
|
||||
if (!performAction) {
|
||||
Rect rect = new Rect();
|
||||
node.getBoundsInScreen(rect);
|
||||
int x = rect.left;
|
||||
int y = rect.top;
|
||||
Log.e(TAG, "clickNode: x = " + x);
|
||||
Log.e(TAG, "clickNode: y = " + y);
|
||||
int width = rect.width();
|
||||
int height = rect.height();
|
||||
Log.e(TAG, "clickNode: width = " + width);
|
||||
Log.e(TAG, "clickNode: height = " + height);
|
||||
Log.e(TAG, "clickNode: clickByNode = " + clickByNode(x + width / 2, y + height / 2));
|
||||
Log.e(TAG, "clickNode: rect = " + rect);
|
||||
// 点击节点的中心位置
|
||||
int centerX = (rect.left + rect.right) / 2;
|
||||
int centerY = (rect.top + rect.bottom) / 2;
|
||||
Log.e(TAG, "clickNode: clickByNode = " + clickByPoint(centerX, centerY));
|
||||
}
|
||||
node.recycle();
|
||||
} else {
|
||||
AccessibilityNodeInfo parent = node.getParent();
|
||||
node.recycle();
|
||||
clickNode(parent);
|
||||
Rect rect = new Rect();
|
||||
node.getBoundsInScreen(rect);
|
||||
Log.e(TAG, "clickNode: rect = " + rect);
|
||||
// 点击节点的中心位置
|
||||
int centerX = (rect.left + rect.right) / 2;
|
||||
int centerY = (rect.top + rect.bottom) / 2;
|
||||
Log.e(TAG, "clickNode: clickByNode = " + clickByPoint(centerX, centerY));
|
||||
}
|
||||
// else {
|
||||
// AccessibilityNodeInfo parent = node.getParent();
|
||||
// node.recycle();
|
||||
// clickNode(parent);
|
||||
// }
|
||||
}
|
||||
|
||||
private boolean stepCall(Property type, String text) {
|
||||
@@ -357,7 +433,7 @@ public class WeAccessibilityService extends AccessibilityService {
|
||||
if (node != null) {
|
||||
Point point = getPointtByNode(node);
|
||||
Log.e(TAG, "stepCall: " + point);
|
||||
clickByNode(point.x, point.y + 30);
|
||||
clickByPoint(point.x, point.y + 30);
|
||||
// clickNode(node);
|
||||
Log.e(TAG, "stepCall: mCurrentStep " + mCurrentStep + " done");
|
||||
mCurrentStep = Step.CLICK_CALL;
|
||||
@@ -374,8 +450,8 @@ public class WeAccessibilityService extends AccessibilityService {
|
||||
if (node != null) {
|
||||
Point point = getPointtByNode(node);
|
||||
Log.e(TAG, "stepAnswer: " + point);
|
||||
clickByNode(point.x, point.y - 50);
|
||||
clickByNode(point.x, point.y);
|
||||
clickByPoint(point.x, point.y - 50);
|
||||
clickByPoint(point.x, point.y);
|
||||
// clickNode(node);
|
||||
Log.e(TAG, "stepAnswer: mCurrentStep " + mCurrentStep + " done");
|
||||
mCurrentStep = Step.WAITING;
|
||||
@@ -399,14 +475,16 @@ public class WeAccessibilityService extends AccessibilityService {
|
||||
}
|
||||
|
||||
//实现对(x,y)坐标进行点击操作。
|
||||
private boolean clickByNode(int x, int y) {
|
||||
private boolean clickByPoint(int x, int y) {
|
||||
Log.e(TAG, "clickByNode: x = " + x);
|
||||
Log.e(TAG, "clickByNode: y = " + y);
|
||||
Point point = new Point(x, y);
|
||||
Path path = new Path();
|
||||
path.moveTo(point.x, point.y);
|
||||
GestureDescription.Builder builder = new GestureDescription.Builder();
|
||||
builder.addStroke(new GestureDescription.StrokeDescription(path, 0, 200));
|
||||
GestureDescription gesture = builder.build();
|
||||
boolean isDispatched = dispatchGesture(gesture, new GestureResultCallback() {
|
||||
boolean dispatched = dispatchGesture(gesture, new GestureResultCallback() {
|
||||
@Override
|
||||
public void onCompleted(GestureDescription gestureDescription) {
|
||||
super.onCompleted(gestureDescription);
|
||||
@@ -419,10 +497,10 @@ public class WeAccessibilityService extends AccessibilityService {
|
||||
Log.e("clickByNode", "onCompleted: ");
|
||||
}
|
||||
}, null);
|
||||
return isDispatched;
|
||||
return dispatched;
|
||||
}
|
||||
|
||||
private boolean scrolDown() {
|
||||
private boolean scrollScreen(double startY, double endY) {
|
||||
WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
|
||||
DisplayMetrics dm = new DisplayMetrics();
|
||||
wm.getDefaultDisplay().getRealMetrics(dm);
|
||||
@@ -433,34 +511,40 @@ public class WeAccessibilityService extends AccessibilityService {
|
||||
// 屏幕宽度算法:屏幕宽度(像素)/屏幕密度
|
||||
// int screenWidth = (int) (width / density); // 屏幕宽度(dp)
|
||||
// int screenHeight = (int) (height / density);// 屏幕高度(dp)
|
||||
Log.e(TAG, "scrolDown: screenWidth = " + width);
|
||||
Log.e(TAG, "scrolDown: screenHeight = " + height);
|
||||
Log.e(TAG, "scrollScreen: screenWidth = " + width);
|
||||
Log.e(TAG, "scrollScreen: screenHeight = " + height);
|
||||
int center_X = width / 2;
|
||||
int center_Y = height / 2;
|
||||
Log.e("scrolDown", "center position:" + "(" + center_X + "," + center_Y + ")");
|
||||
Log.e("scrollScreen", "center position:" + "(" + center_X + "," + center_Y + ")");
|
||||
Path path = new Path();
|
||||
path.moveTo(center_X, (int) (center_Y * 1.5)); //起点坐标。
|
||||
path.lineTo(center_X, (int) (center_Y * 0.5)); //终点坐标。
|
||||
path.moveTo(center_X, (int) (center_Y * startY)); //起点坐标。
|
||||
path.lineTo(center_X, (int) (center_Y * endY)); //终点坐标。
|
||||
GestureDescription.Builder builder = new GestureDescription.Builder();
|
||||
GestureDescription gestureDescription = builder.addStroke(new GestureDescription.StrokeDescription(path, 0, 200)).build();
|
||||
boolean isDispatched = dispatchGesture(gestureDescription, new GestureResultCallback() {
|
||||
boolean dispatched = dispatchGesture(gestureDescription, new GestureResultCallback() {
|
||||
@Override
|
||||
public void onCompleted(GestureDescription gestureDescription) {
|
||||
super.onCompleted(gestureDescription);
|
||||
Log.d("scrolDown", "dispatchGesture ScrollUp onCompleted.");
|
||||
Log.d("scrollScreen", "dispatchGesture ScrollUp onCompleted.");
|
||||
path.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancelled(GestureDescription gestureDescription) {
|
||||
super.onCancelled(gestureDescription);
|
||||
Log.d("scrolDown", "dispatchGesture ScrollUp cancel.");
|
||||
Log.d("scrollScreen", "dispatchGesture ScrollUp cancel.");
|
||||
}
|
||||
}, null);
|
||||
|
||||
return isDispatched;
|
||||
return dispatched;
|
||||
}
|
||||
|
||||
private boolean scrollDown() {
|
||||
return scrollScreen(1.5, 0.5);
|
||||
}
|
||||
|
||||
private boolean scrollUp() {
|
||||
return scrollScreen(0.5, 1.5);
|
||||
}
|
||||
|
||||
private enum Step {
|
||||
WAITING,
|
||||
|
||||
@@ -28,6 +28,8 @@ import com.google.gson.reflect.TypeToken;
|
||||
import com.hjq.toast.Toaster;
|
||||
import com.shehuan.niv.NiceImageView;
|
||||
import com.tencent.mmkv.MMKV;
|
||||
import com.trello.rxlifecycle4.RxLifecycle;
|
||||
import com.trello.rxlifecycle4.android.ActivityEvent;
|
||||
import com.vscool.os.BuildConfig;
|
||||
import com.vscool.os.R;
|
||||
import com.vscool.os.activity.main.MainActivity;
|
||||
@@ -55,8 +57,10 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.rxjava3.annotations.NonNull;
|
||||
import io.reactivex.rxjava3.core.Observable;
|
||||
import io.reactivex.rxjava3.core.ObservableEmitter;
|
||||
import io.reactivex.rxjava3.core.ObservableOnSubscribe;
|
||||
@@ -222,6 +226,38 @@ public class MainService extends BaseRxService implements MainSContact.MainSView
|
||||
registerOperateAlarmClockReceiver();
|
||||
registerScreenLockReceiver();
|
||||
registerSmsReceiver();
|
||||
|
||||
Observable.create(new ObservableOnSubscribe<Integer>() {
|
||||
@Override
|
||||
public void subscribe(@NonNull ObservableEmitter<Integer> emitter) throws Throwable {
|
||||
mTimeSignalCallback = emitter::onNext;
|
||||
}
|
||||
}).throttleFirst(1, TimeUnit.MINUTES)
|
||||
.compose(RxLifecycle.bindUntilEvent(lifecycleSubject, ActivityEvent.DESTROY))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Observer<Integer>() {
|
||||
@Override
|
||||
public void onSubscribe(@NonNull Disposable d) {
|
||||
Log.e("mTimeSignalCallback", "onSubscribe: ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(@NonNull Integer hour) {
|
||||
Log.e("mTimeSignalCallback", "onNext: ");
|
||||
mSoundPool.play(soundMap.get(hour), 1, 1, 0, 0, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(@NonNull Throwable e) {
|
||||
Log.e("mTimeSignalCallback", "onError: ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
Log.e("mTimeSignalCallback", "onComplete: ");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -374,19 +410,31 @@ public class MainService extends BaseRxService implements MainSContact.MainSView
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (Intent.ACTION_DATE_CHANGED.equals(intent.getAction())) {
|
||||
switch (intent.getAction()) {
|
||||
case Intent.ACTION_DATE_CHANGED:
|
||||
Log.e(TAG, "TimeChangedReceiver:" + "data changed");
|
||||
} else if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
|
||||
break;
|
||||
case Intent.ACTION_TIME_CHANGED:
|
||||
Log.e(TAG, "TimeChangedReceiver:" + "time changed");
|
||||
} else if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
|
||||
break;
|
||||
case Intent.ACTION_TIMEZONE_CHANGED:
|
||||
Log.e(TAG, "TimeChangedReceiver:" + "timezone changed");
|
||||
} else if (Intent.ACTION_TIME_TICK.equals(intent.getAction())) {
|
||||
break;
|
||||
case Intent.ACTION_TIME_TICK:
|
||||
Log.e(TAG, "TimeChangedReceiver:" + "time tick");
|
||||
hourlyTimeSignal();
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private interface TimeSignalCallback {
|
||||
void timeTick(int hour);
|
||||
}
|
||||
|
||||
private TimeSignalCallback mTimeSignalCallback;
|
||||
|
||||
private void hourlyTimeSignal() {
|
||||
boolean hourly_time = mMMKV.decodeBool(CommonConfig.HOURLY_TIME_SIGNAL_KEY, false);
|
||||
if (hourly_time) {
|
||||
@@ -396,7 +444,7 @@ public class MainService extends BaseRxService implements MainSContact.MainSView
|
||||
int min = cal.get(Calendar.MINUTE);
|
||||
Log.e(TAG, "hourlyTimeSignal: min = " + min);
|
||||
if (min == 0) {
|
||||
mSoundPool.play(soundMap.get(hour), 1, 1, 0, 0, 1);
|
||||
mTimeSignalCallback.timeTick(hour);
|
||||
}
|
||||
} else {
|
||||
Log.e(TAG, "hourlyTimeSignal: not enable hourly time signal");
|
||||
@@ -409,12 +457,14 @@ public class MainService extends BaseRxService implements MainSContact.MainSView
|
||||
}
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(HOURLY_TIME_SIGNAL_KEY);
|
||||
filter.addAction(WECHAT_AUTO_ACCEPT);
|
||||
registerReceiver(mTimeSignalReceiver, filter);
|
||||
}
|
||||
|
||||
private TimeSignalReceiver mTimeSignalReceiver;
|
||||
|
||||
private static final String HOURLY_TIME_SIGNAL_KEY = "hourly_time_signal";
|
||||
private static final String WECHAT_AUTO_ACCEPT = "wechat_auto_accept";
|
||||
|
||||
private class TimeSignalReceiver extends BroadcastReceiver {
|
||||
|
||||
@@ -422,11 +472,18 @@ public class MainService extends BaseRxService implements MainSContact.MainSView
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
String action = intent.getAction();
|
||||
Log.e("TimeSignalReceiver", "onReceive: " + action);
|
||||
if (HOURLY_TIME_SIGNAL_KEY.equals(action)) {
|
||||
switch (action) {
|
||||
case HOURLY_TIME_SIGNAL_KEY:
|
||||
int hour_notify = intent.getIntExtra("hour_notify", 0);
|
||||
Log.e("TimeSignalReceiver", "onReceive: hour_notify = " + hour_notify);
|
||||
mMMKV.encode(CommonConfig.HOURLY_TIME_SIGNAL_KEY, hour_notify == 1);
|
||||
|
||||
break;
|
||||
case WECHAT_AUTO_ACCEPT:
|
||||
int wechat_auto_accept = intent.getIntExtra("wechat_auto_accept", 0);
|
||||
Log.e("TimeSignalReceiver", "onReceive: wechat_auto_accept = " + wechat_auto_accept);
|
||||
mMMKV.encode(CommonConfig.WECHAT_CALL_AUTO_ACCEPT, wechat_auto_accept == 1);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -756,7 +813,8 @@ public class MainService extends BaseRxService implements MainSContact.MainSView
|
||||
}
|
||||
killBackgroundProcesses(pkg);
|
||||
}
|
||||
Toaster.show(String.format(getString(R.string.clear_app_size), pkgList.size()));
|
||||
// Toaster.show(String.format(getString(R.string.clear_app_size), pkgList.size()));
|
||||
Toaster.show("后台清理应用中");
|
||||
}
|
||||
|
||||
private void killBackgroundProcesses(String packageName) {
|
||||
|
||||
@@ -82,7 +82,7 @@ public class ApkUtils {
|
||||
this.add("com.uiui.aios");
|
||||
this.add("com.uiui.videoplayer");
|
||||
// this.add("com.uiui.health");
|
||||
this.add("com.tencent.android.qqdownloader");
|
||||
// this.add("com.tencent.android.qqdownloader");
|
||||
// this.add("com.vscool.store");
|
||||
this.add("com.joytv.live");
|
||||
this.add("com.vscool.store");
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.vscool.os.utils;
|
||||
|
||||
import android.content.ContentProviderOperation;
|
||||
import android.content.ContentProviderResult;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentUris;
|
||||
import android.content.ContentValues;
|
||||
@@ -41,82 +43,24 @@ import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||
public class ContactsUtils {
|
||||
private static final String TAG = "ContactsUtils";
|
||||
|
||||
|
||||
public static void saveContactPhone(Context context, List<Contact> contactList) {
|
||||
Log.e(TAG, "saveContactPhone: ");
|
||||
// List<ContactId> contactIdList = ContactsUtils.getLocalContacts(context);
|
||||
public static void saveContactPhone(Context context, Contact contact) {
|
||||
Observable.create(new ObservableOnSubscribe<Long>() {
|
||||
@Override
|
||||
public void subscribe(@NonNull ObservableEmitter<Long> emitter) throws Throwable {
|
||||
for (Contact contact : contactList) {
|
||||
if (TextUtils.isEmpty(contact.getMobile())) {
|
||||
continue;
|
||||
}
|
||||
Log.e(TAG, "saveContactPhone: " + contact.getMobile() + " isExist = " + ContactsUtils.isExist(context, contact.getMobile()));
|
||||
Glide.with(context).asBitmap().load(contact.getAvatar()).override(200, 200).into(new SimpleTarget<Bitmap>() {
|
||||
@Override
|
||||
public void onResourceReady(@androidx.annotation.NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
|
||||
if (ContactsUtils.isExist(context, contact.getMobile())) {
|
||||
long rawContactId = ContactsUtils.getContactId(context, contact.getMobile());
|
||||
Glide.with(context).asBitmap().load(contact.getAvatar()).override(200, 200).into(new SimpleTarget<Bitmap>() {
|
||||
@Override
|
||||
public void onResourceReady(@androidx.annotation.NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
ContentValues nameValues = new ContentValues();
|
||||
//add Name
|
||||
nameValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
|
||||
nameValues.put(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/name");
|
||||
nameValues.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, contact.getName());
|
||||
resolver.update(ContactsContract.Data.CONTENT_URI, nameValues, "raw_contact_id=?" + rawContactId, new String[]{ContactsContract.Data.CONTACT_ID});
|
||||
|
||||
ContentValues photoValues = new ContentValues();
|
||||
photoValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
resource.compress(Bitmap.CompressFormat.PNG, 100, out);
|
||||
photoValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE);
|
||||
photoValues.put(ContactsContract.CommonDataKinds.Photo.PHOTO, out.toByteArray());
|
||||
resolver.update(ContactsContract.Data.CONTENT_URI, photoValues, "raw_contact_id=?" + rawContactId, new String[]{ContactsContract.Data.CONTACT_ID});
|
||||
|
||||
ContentValues phoneValues = new ContentValues();
|
||||
phoneValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
|
||||
phoneValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
|
||||
phoneValues.put(ContactsContract.CommonDataKinds.Phone.NUMBER, contact.getMobile());
|
||||
phoneValues.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE);
|
||||
resolver.update(ContactsContract.Data.CONTENT_URI, phoneValues, "raw_contact_id=?" + rawContactId, new String[]{ContactsContract.Data.CONTACT_ID});
|
||||
}
|
||||
});
|
||||
updateContactPhone(context, contact, resource);
|
||||
} else {
|
||||
ContentValues values = new ContentValues();
|
||||
long rawContactId = ContentUris.parseId(context.getContentResolver().insert(ContactsContract.RawContacts.CONTENT_URI, values));
|
||||
Glide.with(context).asBitmap().load(contact.getAvatar()).override(200, 200).into(new SimpleTarget<Bitmap>() {
|
||||
@Override
|
||||
public void onResourceReady(@androidx.annotation.NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
ContentValues nameValues = new ContentValues();
|
||||
//add Name
|
||||
nameValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
|
||||
nameValues.put(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/name");
|
||||
nameValues.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, contact.getName());
|
||||
resolver.insert(ContactsContract.Data.CONTENT_URI, nameValues);
|
||||
|
||||
ContentValues photoValues = new ContentValues();
|
||||
photoValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
resource.compress(Bitmap.CompressFormat.PNG, 100, out);
|
||||
photoValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE);
|
||||
photoValues.put(ContactsContract.CommonDataKinds.Photo.PHOTO, out.toByteArray());
|
||||
resolver.insert(ContactsContract.Data.CONTENT_URI, photoValues);
|
||||
|
||||
ContentValues phoneValues = new ContentValues();
|
||||
phoneValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
|
||||
phoneValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
|
||||
phoneValues.put(ContactsContract.CommonDataKinds.Phone.NUMBER, contact.getMobile());
|
||||
phoneValues.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE);
|
||||
resolver.insert(ContactsContract.Data.CONTENT_URI, phoneValues);
|
||||
insertContactPhone(context, contact, resource);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
emitter.onNext(1L);
|
||||
}
|
||||
})
|
||||
.subscribeOn(Schedulers.io())
|
||||
}).subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Observer<Long>() {
|
||||
@Override
|
||||
@@ -141,6 +85,275 @@ public class ContactsUtils {
|
||||
});
|
||||
}
|
||||
|
||||
public static void saveContactPhone(Context context, List<Contact> contactList) {
|
||||
Log.e(TAG, "saveContactPhone: ");
|
||||
// List<ContactId> contactIdList = ContactsUtils.getLocalContacts(context);
|
||||
Observable.create(new ObservableOnSubscribe<Long>() {
|
||||
@Override
|
||||
public void subscribe(@NonNull ObservableEmitter<Long> emitter) throws Throwable {
|
||||
for (Contact contact : contactList) {
|
||||
if (TextUtils.isEmpty(contact.getMobile())) {
|
||||
continue;
|
||||
}
|
||||
Log.e(TAG, "saveContactPhone: " + contact.getMobile() + " isExist = " + ContactsUtils.isExist(context, contact.getMobile()));
|
||||
Glide.with(context).asBitmap().load(contact.getAvatar()).error(R.drawable.default_avatar).override(200, 200).into(new SimpleTarget<Bitmap>() {
|
||||
@Override
|
||||
public void onResourceReady(@androidx.annotation.NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
|
||||
if (ContactsUtils.isExist(context, contact.getMobile())) {
|
||||
updateContactPhone(context, contact, resource);
|
||||
emitter.onNext(0L);
|
||||
} else {
|
||||
insertContactPhone(context, contact, resource);
|
||||
emitter.onNext(1L);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}).subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Observer<Long>() {
|
||||
@Override
|
||||
public void onSubscribe(@NonNull Disposable d) {
|
||||
Log.e("saveContactPhone", "onSubscribe: ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(@NonNull Long aLong) {
|
||||
Log.e("saveContactPhone", "onNext: " + aLong);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(@NonNull Throwable e) {
|
||||
Log.e("saveContactPhone", "onError: " + e.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
Log.e("saveContactPhone", "onComplete: ");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void insertContactPhone(Context context, Contact contact, Bitmap bitmap) {
|
||||
ContentValues values = new ContentValues();
|
||||
long rawContactId = ContentUris.parseId(context.getContentResolver().insert(ContactsContract.RawContacts.CONTENT_URI, values));
|
||||
Log.e(TAG, "insertContactPhone: rawContactId = " + rawContactId);
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
|
||||
values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
|
||||
values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
|
||||
values.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, contact.getName());
|
||||
resolver.insert(ContactsContract.Data.CONTENT_URI, values);
|
||||
values.clear();
|
||||
|
||||
values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
|
||||
values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE);
|
||||
values.put(ContactsContract.CommonDataKinds.Photo.PHOTO, out.toByteArray());
|
||||
resolver.insert(ContactsContract.Data.CONTENT_URI, values);
|
||||
values.clear();
|
||||
|
||||
values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
|
||||
values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
|
||||
values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, contact.getMobile());
|
||||
values.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE);
|
||||
resolver.insert(ContactsContract.Data.CONTENT_URI, values);
|
||||
}
|
||||
|
||||
|
||||
public static void updateContactPhone(Context context, Contact contact, Bitmap bitmap) {
|
||||
long rawContactId = ContactsUtils.getRawContactId(context, contact.getMobile());
|
||||
Log.e(TAG, "updateContactPhone: rawContactId = " + rawContactId);
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
|
||||
values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
|
||||
values.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, contact.getName());
|
||||
resolver.insert(ContactsContract.Data.CONTENT_URI, values);
|
||||
values.clear();
|
||||
|
||||
values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
|
||||
values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE);
|
||||
values.put(ContactsContract.CommonDataKinds.Photo.PHOTO, out.toByteArray());
|
||||
resolver.insert(ContactsContract.Data.CONTENT_URI, values);
|
||||
values.clear();
|
||||
|
||||
// values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
|
||||
// values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
|
||||
// values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, contact.getMobile());
|
||||
// values.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE);
|
||||
// resolver.insert(ContactsContract.Data.CONTENT_URI, values);
|
||||
|
||||
// Log.e(TAG, "updateContactPhone: phoneValues = " +
|
||||
// resolver.update(ContactsContract.Data.CONTENT_URI, values, ContactsContract.Data.RAW_CONTACT_ID + "='" + rawContactId+"'", null));
|
||||
|
||||
// String selection = ContactsContract.Data.CONTACT_ID + "=" + contacts.getContactId() + " AND " + Data.MIMETYPE + "='" + StructuredName.CONTENT_ITEM_TYPE + "'";
|
||||
// ContentValues values = new ContentValues();
|
||||
// values.put(StructuredName.DISPLAY_NAME, contacts.getName()); // make sure getName() returns a String!!!
|
||||
// getContentResolver().update(Data.CONTENT_URI, values, selection, null);
|
||||
|
||||
// ContentValues values = new ContentValues();
|
||||
// values.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, name);
|
||||
// values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phone);
|
||||
// Log.d("updateContact", "values已经产生");
|
||||
// int result = resolver.update(ContactsContract.Data.CONTENT_URI, values, ContactsContract.Data.RAW_CONTACT_ID + "=?", new String[]{String.valueOf(bean.getId())});
|
||||
}
|
||||
|
||||
public static void update(Context context, Contact contact, Bitmap bitmap) {
|
||||
long rawContactId = ContactsUtils.getRawContactId(context, contact.getMobile());
|
||||
|
||||
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
|
||||
ContentProviderOperation op1 = ContentProviderOperation
|
||||
.newUpdate(ContactsContract.Data.CONTENT_URI)
|
||||
.withSelection(
|
||||
ContactsContract.Data.RAW_CONTACT_ID + "=? and "
|
||||
+ ContactsContract.Data.MIMETYPE + "=?",
|
||||
new String[]{
|
||||
String.valueOf(rawContactId),
|
||||
ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE})
|
||||
.withValue(
|
||||
ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME,// 对应data表中的data1字段
|
||||
contact.getName()).build();
|
||||
ops.add(op1);
|
||||
|
||||
ContentProviderOperation op2 = ContentProviderOperation
|
||||
.newUpdate(ContactsContract.Data.CONTENT_URI)
|
||||
.withSelection(
|
||||
ContactsContract.Data.RAW_CONTACT_ID + "=? and "
|
||||
+ ContactsContract.Data.MIMETYPE + "=?",
|
||||
new String[]{String.valueOf(rawContactId),
|
||||
ContactsContract.CommonDataKinds.Phone.MIMETYPE})
|
||||
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER,// 对应data表中的data1字段
|
||||
contact.getMobile()).build();
|
||||
ops.add(op2);
|
||||
|
||||
// ContentProviderOperation op3 = ContentProviderOperation
|
||||
// .newUpdate(ContactsContract.Data.CONTENT_URI)
|
||||
// .withSelection(
|
||||
// ContactsContract.Data.RAW_CONTACT_ID + "=? and "
|
||||
// + ContactsContract.Data.MIMETYPE + "=?",
|
||||
// new String[]{String.valueOf(rawContactId),
|
||||
// ContactsContract.CommonDataKinds.Phone.MIMETYPE})
|
||||
// .withValue(ContactsContract.CommonDataKinds.Email.ADDRESS,// 对应data表中的data1字段
|
||||
// "test@email.com").build();
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
|
||||
ContentProviderOperation op3 = ContentProviderOperation
|
||||
.newUpdate(ContactsContract.Data.CONTENT_URI)
|
||||
.withSelection(
|
||||
ContactsContract.Data.RAW_CONTACT_ID + "=? and "
|
||||
+ ContactsContract.Data.MIMETYPE + "=?",
|
||||
new String[]{String.valueOf(rawContactId),
|
||||
ContactsContract.CommonDataKinds.Photo.MIMETYPE})
|
||||
.withValue(ContactsContract.CommonDataKinds.Photo.PHOTO,// 对应data表中的data1字段
|
||||
out.toByteArray()).build();
|
||||
ops.add(op3);
|
||||
|
||||
try {
|
||||
ContentProviderResult[] contentProviderResults = context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
|
||||
Log.e(TAG, "update: " + Arrays.toString(contentProviderResults));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Log.e(TAG, "update: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public static void deleteContactPhone(Context context, Contact contact) {
|
||||
Observable.create(new ObservableOnSubscribe<Long>() {
|
||||
@Override
|
||||
public void subscribe(@NonNull ObservableEmitter<Long> emitter) throws Throwable {
|
||||
deleteRawContact(context, contact.getMobile());
|
||||
emitter.onNext(0L);
|
||||
}
|
||||
})
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Observer<Long>() {
|
||||
@Override
|
||||
public void onSubscribe(@NonNull Disposable d) {
|
||||
Log.e("deleteContactPhone", "onSubscribe: ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(@NonNull Long aLong) {
|
||||
Log.e("deleteContactPhone", "onNext: " + aLong);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(@NonNull Throwable e) {
|
||||
Log.e("deleteContactPhone", "onError: " + e.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
Log.e("deleteContactPhone", "onComplete: ");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void deleteRawContact(Context context, String phoneNum) {
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
cursor = resolver.query(ContactsContract.Data.CONTENT_URI,
|
||||
new String[]{ContactsContract.Data.RAW_CONTACT_ID, ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME},
|
||||
ContactsContract.CommonDataKinds.Phone.NUMBER + "=?", new String[]{phoneNum}, null);
|
||||
if (cursor.moveToFirst()) {
|
||||
long rawContactId = cursor.getLong(cursor.getColumnIndexOrThrow(ContactsContract.Data.RAW_CONTACT_ID));
|
||||
Log.e(TAG, "deleteRawContact: rawContactId = " + rawContactId);
|
||||
// int idCode = resolver.delete(ContactsContract.Contacts.CONTENT_URI, ContactsContract.Contacts._ID + " =?", new String[]{String.valueOf(rawContactId)});
|
||||
// Log.e(TAG, "deleteRawContact: idCode = " + idCode);
|
||||
// int phoneCode = resolver.delete(ContactsContract.Data.CONTENT_URI, ContactsContract.CommonDataKinds.Phone.NUMBER + "=?", new String[]{phoneNum});
|
||||
// Log.e(TAG, "deleteRawContact: phoneCode = " + phoneCode);
|
||||
// int contactIdCode = resolver.delete(ContactsContract.RawContacts.CONTENT_URI, ContactsContract.RawContacts.CONTACT_ID + " =?", new String[]{String.valueOf(rawContactId)});
|
||||
// Log.e(TAG, "deleteRawContact: contactIdCode = " + contactIdCode);
|
||||
// String name
|
||||
// int nameCode = resolver.delete(ContactsContract.RawContacts.CONTENT_URI, "display_name=?", new String[]{name});
|
||||
// Log.e(TAG, "deleteRawContact: nameCode = " + nameCode);
|
||||
|
||||
int result = resolver.delete(ContactsContract.RawContacts.CONTENT_URI,
|
||||
ContactsContract.RawContacts._ID + "=?",
|
||||
new String[]{String.valueOf(rawContactId)});
|
||||
Log.e(TAG, "deleteRawContact: result = " + result);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Log.e(TAG, "deleteRawContact: " + e.getMessage());
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static long getRawContactId(Context context, String phoneNum) {
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
cursor = resolver.query(ContactsContract.Data.CONTENT_URI,
|
||||
new String[]{ContactsContract.Data.RAW_CONTACT_ID, ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME},
|
||||
ContactsContract.CommonDataKinds.Phone.NUMBER + "=?", new String[]{phoneNum}, null);
|
||||
if (cursor.moveToFirst()) {
|
||||
long rawContactId = cursor.getLong(cursor.getColumnIndexOrThrow(ContactsContract.Data.RAW_CONTACT_ID));
|
||||
Log.e(TAG, "getRawContactId: rawContactId = " + rawContactId);
|
||||
return rawContactId;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Log.e(TAG, "deleteRawContact: " + e.getMessage());
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加联系人信息
|
||||
*/
|
||||
@@ -156,7 +369,7 @@ public class ContactsUtils {
|
||||
//插入data表
|
||||
//add Name
|
||||
nameValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
|
||||
nameValues.put(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/name");
|
||||
nameValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
|
||||
nameValues.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, name);
|
||||
resolver.insert(ContactsContract.Data.CONTENT_URI, nameValues);
|
||||
|
||||
|
||||
@@ -12,18 +12,30 @@ public class DayUtils {
|
||||
return hour >= 16 && minute >= 30;
|
||||
}
|
||||
|
||||
private static final String[] WEEKS = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
|
||||
|
||||
|
||||
/**
|
||||
* @return 根据日期取得星期几
|
||||
*/
|
||||
public static String getWeek() {
|
||||
Date date = new Date();
|
||||
String[] weeks = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
|
||||
public static String getWeek(Date date) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(date);
|
||||
int weekIndex = cal.get(Calendar.DAY_OF_WEEK) - 1;
|
||||
if (weekIndex < 0) {
|
||||
weekIndex = 0;
|
||||
}
|
||||
return weeks[weekIndex];
|
||||
return WEEKS[weekIndex];
|
||||
}
|
||||
|
||||
public static String getWeek() {
|
||||
Date date = new Date();
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(date);
|
||||
int weekIndex = cal.get(Calendar.DAY_OF_WEEK) - 1;
|
||||
if (weekIndex < 0) {
|
||||
weekIndex = 0;
|
||||
}
|
||||
return WEEKS[weekIndex];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,4 +69,8 @@ public class TimeUtils {
|
||||
return sdf2.format(date2);
|
||||
}
|
||||
|
||||
public static String getDateWeek(Date date) {
|
||||
SimpleDateFormat sdf2 = new SimpleDateFormat("MM/dd");
|
||||
return sdf2.format(date);
|
||||
}
|
||||
}
|
||||
|
||||
BIN
app/src/main/res/drawable-hdpi/call_service.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 12 KiB |
BIN
app/src/main/res/drawable-hdpi/he151.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
app/src/main/res/drawable-hdpi/he152.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 9.5 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 14 KiB |