version:2.0.7

bugfixes:修复闹钟黑屏
update:增加报时亮屏,优化闹钟排序,显示优化
This commit is contained in:
2025-02-10 17:04:15 +08:00
parent 17a9c60979
commit e4ce6a79c0
21 changed files with 318 additions and 121 deletions

View File

@@ -16,8 +16,8 @@ android {
minSdkVersion 24 minSdkVersion 24
targetSdkVersion 29 targetSdkVersion 29
versionCode 207 versionCode 208
versionName "2.0.6" versionName "2.0.7"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

View File

@@ -31,7 +31,7 @@ import com.vscool.os.databinding.ActivityAlarmAddBinding;
import com.vscool.os.service.main.MainService; import com.vscool.os.service.main.MainService;
import com.vscool.os.utils.FFmpegUtils; import com.vscool.os.utils.FFmpegUtils;
import com.vscool.os.utils.FileUtil; import com.vscool.os.utils.FileUtil;
import com.vscool.os.utils.ScreenUtil; import com.vscool.os.utils.ScreenUtils;
import com.vscool.os.utils.TimeUtils; import com.vscool.os.utils.TimeUtils;
import java.io.File; import java.io.File;
@@ -135,7 +135,7 @@ public class AlarmAddActivity extends BaseMvvmActivity<AlarmAddViewModel, Activi
mPictrueFilePath = result.get(0).getRealPath(); mPictrueFilePath = result.get(0).getRealPath();
File file = new File(mPictrueFilePath); File file = new File(mPictrueFilePath);
if (file.exists()) { if (file.exists()) {
RequestOptions options = new RequestOptions().transform(new RoundedCorners(ScreenUtil.dip2px(AlarmAddActivity.this, 8F))); RequestOptions options = new RequestOptions().transform(new RoundedCorners(ScreenUtils.dip2px(AlarmAddActivity.this, 8F)));
Glide.with(mViewDataBinding.nvPic).load(file).apply(options).into(mViewDataBinding.nvPic); Glide.with(mViewDataBinding.nvPic).load(file).apply(options).into(mViewDataBinding.nvPic);
mViewDataBinding.nvPic.setVisibility(View.VISIBLE); mViewDataBinding.nvPic.setVisibility(View.VISIBLE);
mViewDataBinding.clPic.setVisibility(View.GONE); mViewDataBinding.clPic.setVisibility(View.GONE);
@@ -259,6 +259,7 @@ public class AlarmAddActivity extends BaseMvvmActivity<AlarmAddViewModel, Activi
@Override @Override
public void onClick(View view) { public void onClick(View view) {
mDayType = 1; mDayType = 1;
mViewDataBinding.tvType.setText("一次");
mTypePopupWindow.dismiss(); mTypePopupWindow.dismiss();
} }
}); });
@@ -267,6 +268,7 @@ public class AlarmAddActivity extends BaseMvvmActivity<AlarmAddViewModel, Activi
@Override @Override
public void onClick(View view) { public void onClick(View view) {
mDayType = 2; mDayType = 2;
mViewDataBinding.tvType.setText("每天");
mTypePopupWindow.dismiss(); mTypePopupWindow.dismiss();
} }
}); });

View File

@@ -36,7 +36,7 @@ import com.vscool.os.network.NetInterfaceManager;
import com.vscool.os.utils.FFmpegUtils; import com.vscool.os.utils.FFmpegUtils;
import com.vscool.os.utils.FileUtil; import com.vscool.os.utils.FileUtil;
import com.vscool.os.utils.GlideLoadUtils; import com.vscool.os.utils.GlideLoadUtils;
import com.vscool.os.utils.ScreenUtil; import com.vscool.os.utils.ScreenUtils;
import com.vscool.os.utils.TimeUtils; import com.vscool.os.utils.TimeUtils;
import com.vscool.os.utils.Utils; import com.vscool.os.utils.Utils;
@@ -262,7 +262,7 @@ public class AlarmEditActivity extends BaseMvvmActivity<AlarmEditViewModel, Acti
mPictrueFilePath = result.get(0).getRealPath(); mPictrueFilePath = result.get(0).getRealPath();
File file = new File(mPictrueFilePath); File file = new File(mPictrueFilePath);
if (file.exists()) { if (file.exists()) {
RequestOptions options = new RequestOptions().transform(new RoundedCorners(ScreenUtil.dip2px(AlarmEditActivity.this, 8F))); RequestOptions options = new RequestOptions().transform(new RoundedCorners(ScreenUtils.dip2px(AlarmEditActivity.this, 8F)));
Glide.with(mViewDataBinding.nvPic).load(file).apply(options).into(mViewDataBinding.nvPic); Glide.with(mViewDataBinding.nvPic).load(file).apply(options).into(mViewDataBinding.nvPic);
mViewDataBinding.nvPic.setVisibility(View.VISIBLE); mViewDataBinding.nvPic.setVisibility(View.VISIBLE);
mViewDataBinding.clPic.setVisibility(View.GONE); mViewDataBinding.clPic.setVisibility(View.GONE);
@@ -405,6 +405,7 @@ public class AlarmEditActivity extends BaseMvvmActivity<AlarmEditViewModel, Acti
@Override @Override
public void onClick(View view) { public void onClick(View view) {
mDayType = 1; mDayType = 1;
mViewDataBinding.tvType.setText("一次");
mTypePopupWindow.dismiss(); mTypePopupWindow.dismiss();
} }
}); });
@@ -413,6 +414,7 @@ public class AlarmEditActivity extends BaseMvvmActivity<AlarmEditViewModel, Acti
@Override @Override
public void onClick(View view) { public void onClick(View view) {
mDayType = 2; mDayType = 2;
mViewDataBinding.tvType.setText("每天");
mTypePopupWindow.dismiss(); mTypePopupWindow.dismiss();
} }
}); });

View File

@@ -37,7 +37,7 @@ import com.vscool.os.network.NetInterfaceManager;
import com.vscool.os.network.UrlAddress; import com.vscool.os.network.UrlAddress;
import com.vscool.os.utils.ContactsUtils; import com.vscool.os.utils.ContactsUtils;
import com.vscool.os.utils.LocalContactUtils; import com.vscool.os.utils.LocalContactUtils;
import com.vscool.os.utils.ScreenUtil; import com.vscool.os.utils.ScreenUtils;
import com.xiasuhuei321.loadingdialog.view.LoadingDialog; import com.xiasuhuei321.loadingdialog.view.LoadingDialog;
import com.zackratos.ultimatebarx.ultimatebarx.UltimateBarXKt; import com.zackratos.ultimatebarx.ultimatebarx.UltimateBarXKt;
import com.zackratos.ultimatebarx.ultimatebarx.java.UltimateBarX; import com.zackratos.ultimatebarx.ultimatebarx.java.UltimateBarX;
@@ -106,7 +106,7 @@ public class AddContactActivity extends BaseMvvmActivity<AddContactViewModel, Ac
mLoadingDialog.loadSuccess(); mLoadingDialog.loadSuccess();
finish(); finish();
} else { } else {
mLoadingDialog.loadFailed(); mLoadingDialog.loadSuccess();
} }
} }
}); });
@@ -144,7 +144,7 @@ public class AddContactActivity extends BaseMvvmActivity<AddContactViewModel, Ac
mViewModel.avatarFilePath = result.get(0).getRealPath(); mViewModel.avatarFilePath = result.get(0).getRealPath();
File file = new File(mViewModel.avatarFilePath); File file = new File(mViewModel.avatarFilePath);
if (file.exists()) { if (file.exists()) {
RequestOptions options = new RequestOptions().transform(new RoundedCorners(ScreenUtil.dip2px(AddContactActivity.this, 8F))); RequestOptions options = new RequestOptions().transform(new RoundedCorners(ScreenUtils.dip2px(AddContactActivity.this, 8F)));
Glide.with(mViewDataBinding.nvAvatar).load(file).apply(options).into(mViewDataBinding.nvAvatar); Glide.with(mViewDataBinding.nvAvatar).load(file).apply(options).into(mViewDataBinding.nvAvatar);
} else { } else {
mViewModel.avatarFilePath = ""; mViewModel.avatarFilePath = "";

View File

@@ -28,7 +28,7 @@ import com.vscool.os.bean.Contact;
import com.vscool.os.custom.GlideEngine; import com.vscool.os.custom.GlideEngine;
import com.vscool.os.databinding.ActivityContactEditBinding; import com.vscool.os.databinding.ActivityContactEditBinding;
import com.vscool.os.utils.FileUtil; import com.vscool.os.utils.FileUtil;
import com.vscool.os.utils.ScreenUtil; import com.vscool.os.utils.ScreenUtils;
import com.vscool.os.utils.Utils; import com.vscool.os.utils.Utils;
import com.xiasuhuei321.loadingdialog.view.LoadingDialog; import com.xiasuhuei321.loadingdialog.view.LoadingDialog;
@@ -134,7 +134,7 @@ public class EditContactActivity extends BaseMvvmActivity<EditContactViewModel,
mPictrueFilePath = result.get(0).getRealPath(); mPictrueFilePath = result.get(0).getRealPath();
File file = new File(mPictrueFilePath); File file = new File(mPictrueFilePath);
if (file.exists()) { if (file.exists()) {
RequestOptions options = new RequestOptions().transform(new RoundedCorners(ScreenUtil.dip2px(EditContactActivity.this, 8F))); RequestOptions options = new RequestOptions().transform(new RoundedCorners(ScreenUtils.dip2px(EditContactActivity.this, 8F)));
Glide.with(mViewDataBinding.nvAvatar).load(file).apply(options).into(mViewDataBinding.nvAvatar); Glide.with(mViewDataBinding.nvAvatar).load(file).apply(options).into(mViewDataBinding.nvAvatar);
} else { } else {
mPictrueFilePath = ""; mPictrueFilePath = "";

View File

@@ -201,7 +201,8 @@ public class EmergencyActivity extends BaseMvvmActivity<EmergencyViewModel, Acti
} }
}); });
} else { } else {
Toaster.showLong("已呼叫所有联系人"); Log.e(TAG, "onStart: 已呼叫所有联系人");
// Toaster.showLong("已呼叫所有联系人");
finish(); finish();
} }
} else { } else {

View File

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

View File

@@ -76,7 +76,6 @@ public class NoticeInfoActivity extends BaseMvvmActivity<NoticeInfoViewModel, Ac
mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE); mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
mWakeLock = mPowerManager.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_DIM_WAKE_LOCK, "WakeAndLock"); mWakeLock = mPowerManager.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_DIM_WAKE_LOCK, "WakeAndLock");
// mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
int maxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); int maxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
@@ -94,6 +93,7 @@ public class NoticeInfoActivity extends BaseMvvmActivity<NoticeInfoViewModel, Ac
mAlarmClockData = oldData.get(mId); mAlarmClockData = oldData.get(mId);
if (mAlarmClockData == null) { if (mAlarmClockData == null) {
finish(); finish();
return;
} }
Log.e(TAG, "onCreate: " + mAlarmClockData); Log.e(TAG, "onCreate: " + mAlarmClockData);
showPic(mAlarmClockData); showPic(mAlarmClockData);
@@ -179,18 +179,19 @@ public class NoticeInfoActivity extends BaseMvvmActivity<NoticeInfoViewModel, Ac
mViewDataBinding.clVoice.setVisibility(View.GONE); mViewDataBinding.clVoice.setVisibility(View.GONE);
} }
String filePath = alarmClockData.getFile(); String filePath = alarmClockData.getFile();
RequestOptions options = new RequestOptions().transform(new RoundedCorners(ScreenUtils.dip2px(this, 16F))); if (!TextUtils.isEmpty(filePath)) {
String fileName = filePath.substring(filePath.lastIndexOf("/") + 1, filePath.length()); RequestOptions options = new RequestOptions().transform(new RoundedCorners(ScreenUtils.dip2px(this, 16F)));
String realPath = Utils.getDownLoadPath(NoticeInfoActivity.this) + fileName; String fileName = filePath.substring(filePath.lastIndexOf("/") + 1, filePath.length());
File file = new File(realPath); String realPath = Utils.getDownLoadPath(NoticeInfoActivity.this) + fileName;
if (file.exists()) { File file = new File(realPath);
Glide.with(NoticeInfoActivity.this).load(file).apply(options).error(R.drawable.icon_nodata).into(mViewDataBinding.imageView); if (file.exists()) {
} else { Glide.with(NoticeInfoActivity.this).load(file).apply(options).error(R.drawable.icon_nodata).into(mViewDataBinding.imageView);
Glide.with(NoticeInfoActivity.this).load(filePath).apply(options).error(R.drawable.icon_nodata).into(mViewDataBinding.imageView); } else {
Glide.with(NoticeInfoActivity.this).load(filePath).apply(options).error(R.drawable.icon_nodata).into(mViewDataBinding.imageView);
}
} }
} }
private void showData(AlarmClockData alarmClockData) { private void showData(AlarmClockData alarmClockData) {
String filePath = alarmClockData.getFile(); String filePath = alarmClockData.getFile();
if (!TextUtils.isEmpty(filePath)) { if (!TextUtils.isEmpty(filePath)) {

View File

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

View File

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

View File

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

View File

@@ -92,18 +92,19 @@ public class ContactFragment extends BaseMvvmFragment<ContactViewModel, Fragment
}); });
Log.e(TAG, "initData: "); Log.e(TAG, "initData: ");
mViewModel.getContact();
} }
@Override @Override
public void fetchData() { public void fetchData() {
Log.e(TAG, "fetchData: "); Log.e(TAG, "fetchData: ");
mViewModel.getContact(); mViewModel.getContactNoSave();
} }
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
mViewModel.getContact(); mViewModel.getContactNoSave();
} }
public static final String NAME = "name"; public static final String NAME = "name";

View File

@@ -1,18 +1,27 @@
package com.vscool.os.fragment.contact; package com.vscool.os.fragment.contact;
import android.util.Log;
import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.MutableLiveData;
import com.tencent.mmkv.MMKV; import com.tencent.mmkv.MMKV;
import com.trello.rxlifecycle4.RxLifecycle;
import com.trello.rxlifecycle4.android.FragmentEvent; import com.trello.rxlifecycle4.android.FragmentEvent;
import com.vscool.os.base.mvvm.BaseViewModel; import com.vscool.os.base.mvvm.BaseViewModel;
import com.vscool.os.bean.BaseResponse;
import com.vscool.os.bean.Contact; import com.vscool.os.bean.Contact;
import com.vscool.os.config.CommonConfig; import com.vscool.os.config.CommonConfig;
import com.vscool.os.databinding.FragmentContactHomeBinding; import com.vscool.os.databinding.FragmentContactHomeBinding;
import com.vscool.os.gson.GsonUtils;
import com.vscool.os.network.NetInterfaceManager; import com.vscool.os.network.NetInterfaceManager;
import com.vscool.os.network.UrlAddress; import com.vscool.os.network.UrlAddress;
import java.util.List; 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> { public class ContactViewModel extends BaseViewModel<FragmentContactHomeBinding, FragmentEvent> {
private static final String TAG = "ContactListViewModel"; private static final String TAG = "ContactListViewModel";
private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE);
@@ -55,4 +64,37 @@ public class ContactViewModel extends BaseViewModel<FragmentContactHomeBinding,
} }
}); });
} }
public void getContactNoSave() {
NetInterfaceManager.getInstance().getContactListObservable()
.compose(RxLifecycle.bindUntilEvent(getLifecycle(), FragmentEvent.DESTROY))
.subscribe(new Observer<BaseResponse<List<Contact>>>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e("getContactNoSave", "onSubscribe: ");
}
@Override
public void onNext(@NonNull BaseResponse<List<Contact>> listBaseResponse) {
Log.e("getContactNoSave", "onNext: ");
if (listBaseResponse.code == 200) {
List<Contact> contactList = listBaseResponse.data;
mMMKV.putString(UrlAddress.GET_MAIL_LIST, GsonUtils.toJSONString(contactList));
mContactListData.setValue(contactList);
} else {
mMMKV.remove(UrlAddress.GET_MAIL_LIST);
}
}
@Override
public void onError(@NonNull Throwable e) {
Log.e("getContactNoSave", "onError: ");
}
@Override
public void onComplete() {
Log.e("getContactNoSave", "onComplete: ");
}
});
}
} }

View File

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

View File

@@ -98,7 +98,11 @@ import com.vscool.os.utils.Utils;
import java.io.File; import java.io.File;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@@ -1071,13 +1075,50 @@ public class NetInterfaceManager {
if (list == null || list.size() == 0) { if (list == null || list.size() == 0) {
if (callback != null) callback.setAlarmClock(null); if (callback != null) callback.setAlarmClock(null);
} else { } else {
List<AlarmClockData> filter = list.stream().filter(alarmClockData -> !alarmClockData.isDeleted()).collect(Collectors.toList());
List<AlarmClockData> filter = list.stream().filter(alarmClockData -> !alarmClockData.isDeleted())
.sorted(new Comparator<AlarmClockData>() {
@Override
public int compare(AlarmClockData o1, AlarmClockData o2) {
long time1 = getClockTimestamp(o1);
long time2 = getClockTimestamp(o2);
return Long.compare(time1, time2);
}
})
.collect(Collectors.toList());
if (callback != null) callback.setAlarmClock(filter); if (callback != null) callback.setAlarmClock(filter);
} }
} }
}; };
} }
SimpleDateFormat mSimpleDateFormatYear = new SimpleDateFormat("yyyy-MM-dd HH:mm");
SimpleDateFormat mSimpleDateFormatHour = new SimpleDateFormat("HH:mm");
private long getClockTimestamp(AlarmClockData alarmClockData) {
long timestamp;
Date date = new Date();
if (alarmClockData.getType() == 1) {
try {
date = mSimpleDateFormatYear.parse(alarmClockData.getTime());
} catch (ParseException e) {
e.printStackTrace();
Log.e(TAG, "getClockTimestamp: " + e.getMessage());
}
} else {
try {
date = mSimpleDateFormatHour.parse(alarmClockData.getTime());
} catch (ParseException e) {
e.printStackTrace();
Log.e(TAG, "getClockTimestamp: " + e.getMessage());
}
}
timestamp = date.getTime();
return timestamp;
}
public interface SnInfoCallback { public interface SnInfoCallback {
void setSnInfo(SnInfo snInfo); void setSnInfo(SnInfo snInfo);
} }

View File

@@ -17,17 +17,20 @@ import android.util.Log;
import android.view.WindowManager; import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityWindowInfo;
import android.widget.Toast; import android.widget.Toast;
import com.hjq.toast.Toaster; import com.hjq.toast.Toaster;
import com.tencent.mmkv.MMKV; import com.tencent.mmkv.MMKV;
import com.vscool.os.bean.Contact; import com.vscool.os.bean.Contact;
import com.vscool.os.config.CommonConfig; import com.vscool.os.config.CommonConfig;
import com.vscool.os.utils.ForegroundAppUtil;
import java.util.List; import java.util.List;
/** /**
* 通过微信标签最高支持8.0.498.0.50 获取不到数据 * 通过微信标签最高支持8.0.498.0.50 获取不到数据
* 通过 {@link android.accessibilityservice.AccessibilityService#getWindows}和修改accessibility-service 配置能遍历屏幕元素
*/ */
public class WeAccessibilityService extends AccessibilityService { public class WeAccessibilityService extends AccessibilityService {
private static final String TAG = "WeAccessibilityService"; private static final String TAG = "WeAccessibilityService";
@@ -132,7 +135,7 @@ public class WeAccessibilityService extends AccessibilityService {
* @param event * @param event
*/ */
private void _onAccessibilityEvent(AccessibilityEvent event) { private void _onAccessibilityEvent(AccessibilityEvent event) {
Log.e(TAG, "_onAccessibilityEvent: " + mCurrentStep);
switch (mCurrentStep) { switch (mCurrentStep) {
case WAITING: case WAITING:
break; break;
@@ -147,13 +150,18 @@ public class WeAccessibilityService extends AccessibilityService {
} }
} }
} }
Log.e(TAG, "_onAccessibilityEvent: " + mCurrentStep);
switch (mCurrentStep) { switch (mCurrentStep) {
case WAITING: case WAITING:
if (!mAutoAccept) return; mAutoAccept = mMMKV.decodeBool(CommonConfig.WECHAT_CALL_AUTO_ACCEPT, false);
Log.e(TAG, "_onAccessibilityEvent: mAutoAccept = " + mAutoAccept);
if (!mAutoAccept) {
return;
}
if (stepAnswer(Property.DESCRIPTION, RECEIVE_DESCRIPTION)) { if (stepAnswer(Property.DESCRIPTION, RECEIVE_DESCRIPTION)) {
mCurrentStep = Step.WAITING; mCurrentStep = Step.WAITING;
Toast.makeText(this, "已自动接听视频/语音", Toast.LENGTH_LONG).show(); Toast.makeText(this, "已自动接听视频/语音", Toast.LENGTH_LONG).show();
} else {
// clickAnswer();
} }
break; break;
case CLICK_HOME://主页能找到直接点击进去更多 case CLICK_HOME://主页能找到直接点击进去更多
@@ -167,8 +175,11 @@ public class WeAccessibilityService extends AccessibilityService {
break; break;
case CLICK_CONTACT://进入通讯录界面 case CLICK_CONTACT://进入通讯录界面
touchContact(); if (stepHome(Property.TEXT, CONTACT_TEXT, Step.FIND_TAG)) {
// step(Property.TEXT, CONTACT_TEXT, Step.FIND_TAG); Log.e(TAG, "_onAccessibilityEvent: enter contact");
} else {
touchContact();
}
break; break;
case FIND_CONTACT://模拟滑动找到联系人 case FIND_CONTACT://模拟滑动找到联系人
findContact(Property.TEXT, mName, Step.CLICK_NAME); findContact(Property.TEXT, mName, Step.CLICK_NAME);
@@ -230,6 +241,23 @@ public class WeAccessibilityService extends AccessibilityService {
} }
} }
@Deprecated
private void clickAnswer() {
String className = ForegroundAppUtil.getForegroundActivityName(WeAccessibilityService.this);
Log.e(TAG, "clickAnswer: " + className);
if (!TextUtils.isEmpty(className)) {
if ("com.tencent.mm.plugin.voip.ui.VideoActivity".contentEquals(className)) {
boolean successful = clickByPoint(595, 1376);
Log.e(TAG, "clickAnswer: " + successful);
if (successful) {
Toast.makeText(this, "已自动接听视频/语音", Toast.LENGTH_LONG).show();
}
} else {
Log.e(TAG, "clickAnswer: Not in the answering interface");
}
}
}
private boolean step(Property type, String text, Step nextStep) { private boolean step(Property type, String text, Step nextStep) {
AccessibilityNodeInfo node = findNode(getRootInActiveWindow(), type, text); AccessibilityNodeInfo node = findNode(getRootInActiveWindow(), type, text);
if (node != null) { if (node != null) {
@@ -249,6 +277,27 @@ public class WeAccessibilityService extends AccessibilityService {
} }
} }
// TODO: 2025/2/8 先把通讯录点击的换成node
private boolean stepHome(Property type, String text, Step nextStep) {
AccessibilityNodeInfo node = findNode(getWindows(), type, text);
if (node != null) {
Rect rect = new Rect();
node.getBoundsInScreen(rect);
Log.e(TAG, "step: rect = " + rect);
if (rect.left < 0 || rect.top < 0 || rect.right < 0 || rect.bottom < 0) {
return false;
}
clickNode(node);
Log.e(TAG, "step: mCurrentStep: " + mCurrentStep + " done");
mCurrentStep = nextStep;
Log.e(TAG, "step: next: " + mCurrentStep);
return true;
} else {
return false;
}
}
@Deprecated
private void touchContact() { private void touchContact() {
boolean successful = clickByPoint(268, 1440); boolean successful = clickByPoint(268, 1440);
if (successful) { if (successful) {
@@ -392,6 +441,18 @@ public class WeAccessibilityService extends AccessibilityService {
return null; return null;
} }
private AccessibilityNodeInfo findNode(List<AccessibilityWindowInfo> windows, Property type, String text) {
for (AccessibilityWindowInfo accessibilityWindowInfo : windows) {
AccessibilityNodeInfo nodeInfo = findNode(accessibilityWindowInfo.getRoot(), type, text);
if (nodeInfo != null) {
return nodeInfo;
}
}
Log.e(TAG, "findNode windows: not found");
return null;
}
private void clickNode(AccessibilityNodeInfo node) { private void clickNode(AccessibilityNodeInfo node) {
try { try {
Log.e(TAG, "clickNode: getText = " + node.getText()); Log.e(TAG, "clickNode: getText = " + node.getText());
@@ -446,7 +507,7 @@ public class WeAccessibilityService extends AccessibilityService {
} }
private boolean stepAnswer(Property type, String text) { private boolean stepAnswer(Property type, String text) {
AccessibilityNodeInfo node = findNode(getRootInActiveWindow(), type, text); AccessibilityNodeInfo node = findNode(getWindows(), type, text);
if (node != null) { if (node != null) {
Point point = getPointtByNode(node); Point point = getPointtByNode(node);
Log.e(TAG, "stepAnswer: " + point); Log.e(TAG, "stepAnswer: " + point);

View File

@@ -79,6 +79,9 @@ public class MainService extends BaseRxService implements MainSContact.MainSView
private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE);
public MainSPresenter mPresenter; public MainSPresenter mPresenter;
private PowerManager mPowerManager;
private PowerManager.WakeLock mWakeLock;
private SoundPool mSoundPool; private SoundPool mSoundPool;
private HashMap<Integer, Integer> soundMap = new HashMap<>(); private HashMap<Integer, Integer> soundMap = new HashMap<>();
@@ -161,8 +164,9 @@ public class MainService extends BaseRxService implements MainSContact.MainSView
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
Log.e(TAG, "onCreate: "); Log.e(TAG, "onCreate: ");
// ApkUtils.UninstallAPP(this, "com.joytv.live");
// ApkUtils.UninstallAPP(this, "com.tencent.android.qqdownloader"); mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
mWakeLock = mPowerManager.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_DIM_WAKE_LOCK, "WakeAndLock");
AudioAttributes attr = new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_ALARM) // 设置音效使用场景 AudioAttributes attr = new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_ALARM) // 设置音效使用场景
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION).build(); // 设置音效的类型 .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION).build(); // 设置音效的类型
@@ -245,6 +249,7 @@ public class MainService extends BaseRxService implements MainSContact.MainSView
@Override @Override
public void onNext(@NonNull Integer hour) { public void onNext(@NonNull Integer hour) {
Log.e("mTimeSignalCallback", "onNext: "); Log.e("mTimeSignalCallback", "onNext: ");
mWakeLock.acquire(60 * 1000L);
mSoundPool.play(soundMap.get(hour), 1, 1, 0, 0, 1); mSoundPool.play(soundMap.get(hour), 1, 1, 0, 0, 1);
} }
@@ -317,6 +322,11 @@ public class MainService extends BaseRxService implements MainSContact.MainSView
if (mSmsReceiver != null) { if (mSmsReceiver != null) {
unregisterReceiver(mSmsReceiver); unregisterReceiver(mSmsReceiver);
} }
if (mSoundPool != null) {
mSoundPool.release();
mSoundPool = null;
}
} }
public boolean isScreenOn() { public boolean isScreenOn() {

View File

@@ -14,11 +14,7 @@ import android.provider.ContactsContract;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import androidx.annotation.Nullable;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.transition.Transition;
import com.vscool.os.R; import com.vscool.os.R;
import com.vscool.os.bean.Contact; import com.vscool.os.bean.Contact;
import com.vscool.os.bean.ContactId; import com.vscool.os.bean.ContactId;
@@ -31,7 +27,6 @@ import java.util.List;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.annotations.NonNull; import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.ObservableEmitter; import io.reactivex.rxjava3.core.ObservableEmitter;
@@ -47,21 +42,27 @@ public class ContactsUtils {
Observable.create(new ObservableOnSubscribe<Long>() { Observable.create(new ObservableOnSubscribe<Long>() {
@Override @Override
public void subscribe(@NonNull ObservableEmitter<Long> emitter) throws Throwable { public void subscribe(@NonNull ObservableEmitter<Long> emitter) throws Throwable {
long time = System.currentTimeMillis();
Log.e(TAG, "saveContactPhone: " + contact.getMobile() + " isExist = " + ContactsUtils.isExist(context, contact.getMobile())); 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>() { if (TextUtils.isEmpty(contact.getAvatar())) {
@Override Bitmap bitmap = Glide.with(context).asBitmap().load(R.drawable.default_avatar).override(200, 200).submit().get();
public void onResourceReady(@androidx.annotation.NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) { if (ContactsUtils.isExist(context, contact.getMobile())) {
if (ContactsUtils.isExist(context, contact.getMobile())) { updateContactPhone(context, contact, bitmap);
updateContactPhone(context, contact, resource); } else {
} else { insertContactPhone(context, contact, bitmap);
insertContactPhone(context, contact, resource);
}
} }
}); } else {
emitter.onNext(1L); Bitmap bitmap = Glide.with(context).asBitmap().load(contact.getAvatar()).override(200, 200).error(R.drawable.default_avatar).submit().get();
if (ContactsUtils.isExist(context, contact.getMobile())) {
updateContactPhone(context, contact, bitmap);
} else {
insertContactPhone(context, contact, bitmap);
}
}
emitter.onNext(System.currentTimeMillis() - time);
} }
}).subscribeOn(Schedulers.io()) }).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(Schedulers.newThread())
.subscribe(new Observer<Long>() { .subscribe(new Observer<Long>() {
@Override @Override
public void onSubscribe(@NonNull Disposable d) { public void onSubscribe(@NonNull Disposable d) {
@@ -91,27 +92,33 @@ public class ContactsUtils {
Observable.create(new ObservableOnSubscribe<Long>() { Observable.create(new ObservableOnSubscribe<Long>() {
@Override @Override
public void subscribe(@NonNull ObservableEmitter<Long> emitter) throws Throwable { public void subscribe(@NonNull ObservableEmitter<Long> emitter) throws Throwable {
long time = System.currentTimeMillis();
for (Contact contact : contactList) { for (Contact contact : contactList) {
if (TextUtils.isEmpty(contact.getMobile())) { if (TextUtils.isEmpty(contact.getMobile())) {
continue; continue;
} }
Log.e(TAG, "saveContactPhone: " + contact.getMobile() + " isExist = " + ContactsUtils.isExist(context, contact.getMobile())); 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>() { if (TextUtils.isEmpty(contact.getAvatar())) {
@Override Bitmap bitmap = Glide.with(context).asBitmap().load(R.drawable.default_avatar).override(200, 200).submit().get();
public void onResourceReady(@androidx.annotation.NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) { if (ContactsUtils.isExist(context, contact.getMobile())) {
if (ContactsUtils.isExist(context, contact.getMobile())) { updateContactPhone(context, contact, bitmap);
updateContactPhone(context, contact, resource); } else {
emitter.onNext(0L); insertContactPhone(context, contact, bitmap);
} else {
insertContactPhone(context, contact, resource);
emitter.onNext(1L);
}
} }
}); } else {
Bitmap bitmap = Glide.with(context).asBitmap().load(contact.getAvatar()).override(200, 200).error(R.drawable.default_avatar).submit().get();
if (ContactsUtils.isExist(context, contact.getMobile())) {
updateContactPhone(context, contact, bitmap);
} else {
insertContactPhone(context, contact, bitmap);
}
}
} }
emitter.onNext(System.currentTimeMillis() - time);
} }
}).subscribeOn(Schedulers.io()) }).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(Schedulers.newThread())
.subscribe(new Observer<Long>() { .subscribe(new Observer<Long>() {
@Override @Override
public void onSubscribe(@NonNull Disposable d) { public void onSubscribe(@NonNull Disposable d) {
@@ -162,6 +169,24 @@ public class ContactsUtils {
resolver.insert(ContactsContract.Data.CONTENT_URI, values); resolver.insert(ContactsContract.Data.CONTENT_URI, values);
} }
public static void insertContactPhone(Context context, Contact contact) {
ContentValues values = new ContentValues();
long rawContactId = ContentUris.parseId(context.getContentResolver().insert(ContactsContract.RawContacts.CONTENT_URI, values));
Log.e(TAG, "insertContactPhone: rawContactId = " + rawContactId);
ContentResolver resolver = context.getContentResolver();
values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
values.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, contact.getName());
resolver.insert(ContactsContract.Data.CONTENT_URI, values);
values.clear();
values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, contact.getMobile());
values.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE);
resolver.insert(ContactsContract.Data.CONTENT_URI, values);
}
public static void updateContactPhone(Context context, Contact contact, Bitmap bitmap) { public static void updateContactPhone(Context context, Contact contact, Bitmap bitmap) {
long rawContactId = ContactsUtils.getRawContactId(context, contact.getMobile()); long rawContactId = ContactsUtils.getRawContactId(context, contact.getMobile());
@@ -173,6 +198,7 @@ public class ContactsUtils {
values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE); values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
values.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, contact.getName()); values.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, contact.getName());
resolver.insert(ContactsContract.Data.CONTENT_URI, values); resolver.insert(ContactsContract.Data.CONTENT_URI, values);
values.clear(); values.clear();
values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId); values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
@@ -181,6 +207,7 @@ public class ContactsUtils {
values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE); values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE);
values.put(ContactsContract.CommonDataKinds.Photo.PHOTO, out.toByteArray()); values.put(ContactsContract.CommonDataKinds.Photo.PHOTO, out.toByteArray());
resolver.insert(ContactsContract.Data.CONTENT_URI, values); resolver.insert(ContactsContract.Data.CONTENT_URI, values);
values.clear(); values.clear();
// values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId); // values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
@@ -204,6 +231,18 @@ public class ContactsUtils {
// int result = resolver.update(ContactsContract.Data.CONTENT_URI, values, ContactsContract.Data.RAW_CONTACT_ID + "=?", new String[]{String.valueOf(bean.getId())}); // int result = resolver.update(ContactsContract.Data.CONTENT_URI, values, ContactsContract.Data.RAW_CONTACT_ID + "=?", new String[]{String.valueOf(bean.getId())});
} }
public static void updateContactPhone(Context context, Contact contact) {
long rawContactId = ContactsUtils.getRawContactId(context, contact.getMobile());
Log.e(TAG, "updateContactPhone: rawContactId = " + rawContactId);
ContentResolver resolver = context.getContentResolver();
ContentValues values = new ContentValues();
values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
values.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, contact.getName());
resolver.insert(ContactsContract.Data.CONTENT_URI, values);
}
public static void update(Context context, Contact contact, Bitmap bitmap) { public static void update(Context context, Contact contact, Bitmap bitmap) {
long rawContactId = ContactsUtils.getRawContactId(context, contact.getMobile()); long rawContactId = ContactsUtils.getRawContactId(context, contact.getMobile());
@@ -272,7 +311,7 @@ public class ContactsUtils {
} }
}) })
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(Schedulers.newThread())
.subscribe(new Observer<Long>() { .subscribe(new Observer<Long>() {
@Override @Override
public void onSubscribe(@NonNull Disposable d) { public void onSubscribe(@NonNull Disposable d) {

View File

@@ -31,16 +31,8 @@ public class ForegroundAppUtil {
* 获取栈顶的应用包名 * 获取栈顶的应用包名
*/ */
public static String getForegroundActivityName(Context context) { public static String getForegroundActivityName(Context context) {
String currentClassName = ""; ActivityManager manager = (ActivityManager) context.getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { String currentClassName = manager.getRunningTasks(1).get(0).topActivity.getClassName();
ActivityManager manager = (ActivityManager) context.getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
currentClassName = manager.getRunningTasks(1).get(0).topActivity.getPackageName();
} else {
UsageStats initStat = getForegroundUsageStats(context, START_TIME, END_TIME);
if (initStat != null) {
currentClassName = initStat.getPackageName();
}
}
return currentClassName; return currentClassName;
} }

View File

@@ -1,21 +0,0 @@
package com.vscool.os.utils;
import android.content.Context;
public class ScreenUtil {
/**
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
*/
public static int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
/**
* 根据手机的分辨率从 px(像素) 的单位 转成为 dp
*/
public static int px2dip(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f);
}
}

View File

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