version:2.0.6

bugfixes:修复闹钟修改默认值,联系人为空时不显示占用,屏幕旋转会错乱,整点报时会息屏亮屏多次播报
update:主页不显示地址,微信拨号优化,优化离线联系人
This commit is contained in:
2025-02-08 17:57:38 +08:00
parent 8eb83634d0
commit 17a9c60979
267 changed files with 1213 additions and 1632 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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()) {

View File

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

View File

@@ -11,6 +11,7 @@ import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.Cursor;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCharacteristics;
@@ -93,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: ");

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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() {

View File

@@ -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("Md日");
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);
}
}

View File

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

View File

@@ -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*/

View File

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

View File

@@ -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() {

View File

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

View File

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

View File

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

View File

@@ -9,13 +9,10 @@ import android.net.Uri;
import android.provider.ContactsContract;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.text.TextUtils;
import android.util.Log;
import androidx.lifecycle.MutableLiveData;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.tencent.mmkv.MMKV;
import com.trello.rxlifecycle4.RxLifecycle;
import com.trello.rxlifecycle4.android.FragmentEvent;
@@ -24,12 +21,10 @@ import com.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);
}

View File

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

View File

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

View File

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

View File

@@ -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.498.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 {
}
//实现对xy坐标进行点击操作。
private boolean clickByNode(int x, int y) {
private boolean clickByPoint(int x, int y) {
Log.e(TAG, "clickByNode: x = " + x);
Log.e(TAG, "clickByNode: y = " + y);
Point point = new Point(x, y);
Path path = new Path();
path.moveTo(point.x, point.y);
GestureDescription.Builder builder = new GestureDescription.Builder();
builder.addStroke(new GestureDescription.StrokeDescription(path, 0, 200));
GestureDescription gesture = builder.build();
boolean isDispatched = dispatchGesture(gesture, new GestureResultCallback() {
boolean dispatched = dispatchGesture(gesture, new GestureResultCallback() {
@Override
public void onCompleted(GestureDescription gestureDescription) {
super.onCompleted(gestureDescription);
@@ -419,10 +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,

View File

@@ -28,6 +28,8 @@ import com.google.gson.reflect.TypeToken;
import com.hjq.toast.Toaster;
import com.shehuan.niv.NiceImageView;
import com.tencent.mmkv.MMKV;
import com.trello.rxlifecycle4.RxLifecycle;
import com.trello.rxlifecycle4.android.ActivityEvent;
import com.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) {

View File

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

View File

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

View File

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

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Some files were not shown because too many files have changed in this diff Show More