Compare commits
10 Commits
apputils-v
...
contacts-v
Author | SHA1 | Date | |
---|---|---|---|
![]() |
02673d19dd | ||
![]() |
38884d3457 | ||
![]() |
ecb56df773 | ||
![]() |
a15f6bad8f | ||
![]() |
2f0293103c | ||
![]() |
d4135f0104 | ||
![]() |
bdb9bc7637 | ||
![]() |
e7633e53ed | ||
![]() |
3734a659ff | ||
![]() |
b9f740c386 |
@@ -18,13 +18,13 @@ def genVersionName(def versionName){
|
|||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 32
|
compileSdkVersion 30
|
||||||
buildToolsVersion "33.0.3"
|
buildToolsVersion "30.0.3"
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "cc.winboll.studio.contacts"
|
applicationId "cc.winboll.studio.contacts"
|
||||||
minSdkVersion 21
|
minSdkVersion 26
|
||||||
targetSdkVersion 30
|
targetSdkVersion 29
|
||||||
versionCode 1
|
versionCode 1
|
||||||
// versionName 更新后需要手动设置
|
// versionName 更新后需要手动设置
|
||||||
// 项目模块目录的 build.gradle 文件的 stageCount=0
|
// 项目模块目录的 build.gradle 文件的 stageCount=0
|
||||||
@@ -49,23 +49,19 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// 二维码使用的类库
|
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
api 'com.google.zxing:core:3.4.1'
|
|
||||||
api 'com.journeyapps:zxing-android-embedded:3.6.0'
|
|
||||||
|
|
||||||
api 'io.github.medyo:android-about-page:2.0.0'
|
// https://mvnrepository.com/artifact/com.github.open-android/pinyin4j
|
||||||
api 'com.github.getActivity:ToastUtils:10.5'
|
implementation 'com.github.open-android:pinyin4j:2.5.0'
|
||||||
api 'com.jcraft:jsch:0.1.55'
|
|
||||||
api 'org.jsoup:jsoup:1.13.1'
|
implementation 'io.github.medyo:android-about-page:2.0.0'
|
||||||
api 'com.squareup.okhttp3:okhttp:4.4.1'
|
implementation 'com.github.getActivity:ToastUtils:10.5'
|
||||||
|
|
||||||
api 'androidx.appcompat:appcompat:1.1.0'
|
implementation 'androidx.appcompat:appcompat:1.1.0'
|
||||||
api 'androidx.viewpager:viewpager:1.0.0'
|
implementation 'androidx.viewpager:viewpager:1.0.0'
|
||||||
api 'androidx.fragment:fragment:1.1.0'
|
implementation 'androidx.fragment:fragment:1.1.0'
|
||||||
api 'com.google.android.material:material:1.4.0'
|
implementation 'com.google.android.material:material:1.4.0'
|
||||||
|
|
||||||
api 'cc.winboll.studio:libapputils:9.3.2'
|
implementation 'cc.winboll.studio:libapputils:9.3.2'
|
||||||
api 'cc.winboll.studio:libappbase:1.5.6'
|
implementation 'cc.winboll.studio:libappbase:1.5.6'
|
||||||
|
|
||||||
api fileTree(dir: 'libs', include: ['*.jar'])
|
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
#Created by .winboll/winboll_app_build.gradle
|
#Created by .winboll/winboll_app_build.gradle
|
||||||
#Tue Feb 25 00:17:29 HKT 2025
|
#Wed Feb 26 19:10:28 HKT 2025
|
||||||
stageCount=2
|
stageCount=5
|
||||||
libraryProject=
|
libraryProject=
|
||||||
baseVersion=1.0
|
baseVersion=1.0
|
||||||
publishVersion=1.0.1
|
publishVersion=1.0.4
|
||||||
buildCount=0
|
buildCount=0
|
||||||
baseBetaVersion=1.0.2
|
baseBetaVersion=1.0.5
|
||||||
|
@@ -29,9 +29,10 @@
|
|||||||
|
|
||||||
<!-- 更改您的音频设置 -->
|
<!-- 更改您的音频设置 -->
|
||||||
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
|
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
|
<!-- 读取通话记录 -->
|
||||||
|
<uses-permission android:name="android.permission.READ_CALL_LOG"/>
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name=".App"
|
android:name=".App"
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
@@ -65,7 +66,7 @@
|
|||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".phonecallui.PhoneCallActivity"
|
android:name=".phonecallui.PhoneCallActivity"
|
||||||
android:launchMode="singleInstance"
|
android:launchMode="singleTask"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
@@ -1,38 +1,36 @@
|
|||||||
package cc.winboll.studio.contacts;
|
package cc.winboll.studio.contacts;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.annotation.SuppressLint;
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
import android.app.role.RoleManager;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.provider.Settings;
|
|
||||||
import android.telecom.TelecomManager;
|
import android.telecom.TelecomManager;
|
||||||
import android.view.LayoutInflater;
|
import android.telephony.PhoneStateListener;
|
||||||
|
import android.telephony.TelephonyManager;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.WindowManager;
|
|
||||||
import android.widget.CheckBox;
|
import android.widget.CheckBox;
|
||||||
import android.widget.CompoundButton;
|
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.Switch;
|
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.appcompat.widget.Toolbar;
|
import androidx.appcompat.widget.Toolbar;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.app.ActivityCompat;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
import androidx.fragment.app.FragmentPagerAdapter;
|
||||||
import androidx.viewpager.widget.ViewPager;
|
import androidx.viewpager.widget.ViewPager;
|
||||||
import cc.winboll.studio.contacts.R;
|
import cc.winboll.studio.contacts.R;
|
||||||
import cc.winboll.studio.contacts.activities.CallActivity;
|
import cc.winboll.studio.contacts.activities.SettingsActivity;
|
||||||
import cc.winboll.studio.contacts.adapters.MyPagerAdapter;
|
|
||||||
import cc.winboll.studio.contacts.beans.MainServiceBean;
|
import cc.winboll.studio.contacts.beans.MainServiceBean;
|
||||||
|
import cc.winboll.studio.contacts.fragments.CallLogFragment;
|
||||||
|
import cc.winboll.studio.contacts.fragments.ContactsFragment;
|
||||||
|
import cc.winboll.studio.contacts.fragments.LogFragment;
|
||||||
import cc.winboll.studio.contacts.services.MainService;
|
import cc.winboll.studio.contacts.services.MainService;
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
import cc.winboll.studio.libappbase.LogView;
|
import cc.winboll.studio.libappbase.LogView;
|
||||||
@@ -40,13 +38,9 @@ import cc.winboll.studio.libapputils.app.IWinBollActivity;
|
|||||||
import cc.winboll.studio.libapputils.app.WinBollActivityManager;
|
import cc.winboll.studio.libapputils.app.WinBollActivityManager;
|
||||||
import cc.winboll.studio.libapputils.bean.APPInfo;
|
import cc.winboll.studio.libapputils.bean.APPInfo;
|
||||||
import cc.winboll.studio.libapputils.view.YesNoAlertDialog;
|
import cc.winboll.studio.libapputils.view.YesNoAlertDialog;
|
||||||
import cc.winboll.studio.contacts.listenphonecall.CallListenerService;
|
|
||||||
import com.google.android.material.tabs.TabLayout;
|
import com.google.android.material.tabs.TabLayout;
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import android.content.DialogInterface;
|
|
||||||
import cc.winboll.studio.contacts.activities.SettingsActivity;
|
|
||||||
|
|
||||||
final public class MainActivity extends AppCompatActivity implements IWinBollActivity, ViewPager.OnPageChangeListener, View.OnClickListener {
|
final public class MainActivity extends AppCompatActivity implements IWinBollActivity, ViewPager.OnPageChangeListener, View.OnClickListener {
|
||||||
|
|
||||||
@@ -57,11 +51,13 @@ final public class MainActivity extends AppCompatActivity implements IWinBollAct
|
|||||||
|
|
||||||
public static final String ACTION_SOS = "cc.winboll.studio.libappbase.WinBoll.ACTION_SOS";
|
public static final String ACTION_SOS = "cc.winboll.studio.libappbase.WinBoll.ACTION_SOS";
|
||||||
|
|
||||||
|
static MainActivity _MainActivity;
|
||||||
LogView mLogView;
|
LogView mLogView;
|
||||||
Toolbar mToolbar;
|
Toolbar mToolbar;
|
||||||
CheckBox cbMainService;
|
CheckBox cbMainService;
|
||||||
MainServiceBean mMainServiceBean;
|
MainServiceBean mMainServiceBean;
|
||||||
ViewPager viewPager;
|
private TabLayout tabLayout;
|
||||||
|
private ViewPager viewPager;
|
||||||
private List<View> views; //用来存放放进ViewPager里面的布局
|
private List<View> views; //用来存放放进ViewPager里面的布局
|
||||||
//实例化存储imageView(导航原点)的集合
|
//实例化存储imageView(导航原点)的集合
|
||||||
ImageView[] imageViews;
|
ImageView[] imageViews;
|
||||||
@@ -70,6 +66,9 @@ final public class MainActivity extends AppCompatActivity implements IWinBollAct
|
|||||||
LinearLayout linearLayout;//下标所在在LinearLayout布局里
|
LinearLayout linearLayout;//下标所在在LinearLayout布局里
|
||||||
int currentPoint = 0;//当前被选中中页面的下标
|
int currentPoint = 0;//当前被选中中页面的下标
|
||||||
|
|
||||||
|
private TelephonyManager telephonyManager;
|
||||||
|
private MyPhoneStateListener phoneStateListener;
|
||||||
|
|
||||||
private static final int DIALER_REQUEST_CODE = 1;
|
private static final int DIALER_REQUEST_CODE = 1;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -102,6 +101,7 @@ final public class MainActivity extends AppCompatActivity implements IWinBollAct
|
|||||||
//if (prosessIntents(getIntent())) return;
|
//if (prosessIntents(getIntent())) return;
|
||||||
// 以下正常创建主窗口
|
// 以下正常创建主窗口
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
_MainActivity = this;
|
||||||
setContentView(R.layout.activity_main);
|
setContentView(R.layout.activity_main);
|
||||||
|
|
||||||
// 初始化工具栏
|
// 初始化工具栏
|
||||||
@@ -112,17 +112,39 @@ final public class MainActivity extends AppCompatActivity implements IWinBollAct
|
|||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
}
|
}
|
||||||
getSupportActionBar().setSubtitle(getTag());
|
getSupportActionBar().setSubtitle(getTag());
|
||||||
|
|
||||||
|
tabLayout = findViewById(R.id.tabLayout);
|
||||||
|
viewPager = findViewById(R.id.viewPager);
|
||||||
|
|
||||||
initData();
|
// 创建Fragment列表和标题列表
|
||||||
initView();
|
List<Fragment> fragmentList = new ArrayList<>();
|
||||||
//initPoint();//调用初始化导航原点的方法
|
List<String> tabTitleList = new ArrayList<>();
|
||||||
viewPager.addOnPageChangeListener(this);//滑动事件
|
fragmentList.add(CallLogFragment.newInstance(0));
|
||||||
|
fragmentList.add(ContactsFragment.newInstance(1));
|
||||||
|
fragmentList.add(LogFragment.newInstance(2));
|
||||||
|
tabTitleList.add("通话记录");
|
||||||
|
tabTitleList.add("联系人");
|
||||||
|
tabTitleList.add("应用日志");
|
||||||
|
|
||||||
ViewPager viewPager = findViewById(R.id.activitymainViewPager1);
|
// 设置ViewPager的适配器
|
||||||
MyPagerAdapter pagerAdapter = new MyPagerAdapter(getSupportFragmentManager());
|
MyPagerAdapter adapter = new MyPagerAdapter(getSupportFragmentManager(), fragmentList, tabTitleList);
|
||||||
viewPager.setAdapter(pagerAdapter);
|
viewPager.setAdapter(adapter);
|
||||||
TabLayout tabLayout = findViewById(R.id.activitymainTabLayout1);
|
|
||||||
|
// 关联TabLayout和ViewPager
|
||||||
tabLayout.setupWithViewPager(viewPager);
|
tabLayout.setupWithViewPager(viewPager);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// initData();
|
||||||
|
// initView();
|
||||||
|
// //initPoint();//调用初始化导航原点的方法
|
||||||
|
// viewPager.addOnPageChangeListener(this);//滑动事件
|
||||||
|
|
||||||
|
//ViewPager viewPager = findViewById(R.id.activitymainViewPager1);
|
||||||
|
//MyPagerAdapter pagerAdapter = new MyPagerAdapter(getSupportFragmentManager());
|
||||||
|
//viewPager.setAdapter(pagerAdapter);
|
||||||
|
//TabLayout tabLayout = findViewById(R.id.activitymainTabLayout1);
|
||||||
|
//tabLayout.setupWithViewPager(viewPager);
|
||||||
|
|
||||||
// mMainServiceBean = MainServiceBean.loadBean(this, MainServiceBean.class);
|
// mMainServiceBean = MainServiceBean.loadBean(this, MainServiceBean.class);
|
||||||
// if (mMainServiceBean == null) {
|
// if (mMainServiceBean == null) {
|
||||||
@@ -140,36 +162,86 @@ final public class MainActivity extends AppCompatActivity implements IWinBollAct
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// });
|
// });
|
||||||
MainService.startMainService(MainActivity.this);
|
|
||||||
|
MainServiceBean mMainServiceBean = MainServiceBean.loadBean(this, MainServiceBean.class);
|
||||||
|
if (mMainServiceBean == null) {
|
||||||
|
mMainServiceBean = new MainServiceBean();
|
||||||
|
MainServiceBean.saveBean(this, mMainServiceBean);
|
||||||
|
}
|
||||||
|
if (mMainServiceBean.isEnable()) {
|
||||||
|
MainService.startMainService(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化TelephonyManager和PhoneStateListener
|
||||||
|
telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
|
||||||
|
phoneStateListener = new MyPhoneStateListener();
|
||||||
|
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ViewPager的适配器
|
||||||
|
private class MyPagerAdapter extends FragmentPagerAdapter {
|
||||||
|
|
||||||
|
private List<Fragment> fragmentList;
|
||||||
|
private List<String> tabTitleList;
|
||||||
|
|
||||||
|
public MyPagerAdapter(FragmentManager fm, List<Fragment> fragmentList, List<String> tabTitleList) {
|
||||||
|
super(fm);
|
||||||
|
this.fragmentList = fragmentList;
|
||||||
|
this.tabTitleList = tabTitleList;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Fragment getItem(int position) {
|
||||||
|
return fragmentList.get(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
return fragmentList.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CharSequence getPageTitle(int position) {
|
||||||
|
return tabTitleList.get(position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void dialPhoneNumber(String phoneNumber) {
|
||||||
|
Intent intent = new Intent(Intent.ACTION_DIAL);
|
||||||
|
intent.setData(android.net.Uri.parse("tel:" + phoneNumber));
|
||||||
|
if (ActivityCompat.checkSelfPermission(_MainActivity, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_MainActivity.startActivity(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
//初始化view,即显示的图片
|
//初始化view,即显示的图片
|
||||||
void initView() {
|
// void initView() {
|
||||||
viewPager = findViewById(R.id.activitymainViewPager1);
|
// viewPager = findViewById(R.id.activitymainViewPager1);
|
||||||
pagerAdapter = new MyPagerAdapter(getSupportFragmentManager());
|
// pagerAdapter = new MyPagerAdapter(getSupportFragmentManager());
|
||||||
viewPager.setAdapter(pagerAdapter);
|
// viewPager.setAdapter(pagerAdapter);
|
||||||
//adapter = new MyPagerAdapter(views);
|
// //adapter = new MyPagerAdapter(views);
|
||||||
//viewPager = findViewById(R.id.activitymainViewPager1);
|
// //viewPager = findViewById(R.id.activitymainViewPager1);
|
||||||
//viewPager.setAdapter(adapter);
|
// //viewPager.setAdapter(adapter);
|
||||||
//linearLayout = findViewById(R.id.activitymainLinearLayout1);
|
// //linearLayout = findViewById(R.id.activitymainLinearLayout1);
|
||||||
//initPoint();//初始化页面下方的点
|
// //initPoint();//初始化页面下方的点
|
||||||
viewPager.setOnPageChangeListener(this);
|
// viewPager.setOnPageChangeListener(this);
|
||||||
|
//
|
||||||
}
|
// }
|
||||||
|
|
||||||
//初始化所要显示的布局
|
//初始化所要显示的布局
|
||||||
void initData() {
|
// void initData() {
|
||||||
ViewPager viewPager = findViewById(R.id.activitymainViewPager1);
|
// LayoutInflater inflater = LayoutInflater.from(getActivity());
|
||||||
LayoutInflater inflater = LayoutInflater.from(getActivity());
|
// View view1 = inflater.inflate(R.layout.fragment_call_log, viewPager, false);
|
||||||
View view1 = inflater.inflate(R.layout.fragment_call, viewPager, false);
|
// View view2 = inflater.inflate(R.layout.fragment_contacts, viewPager, false);
|
||||||
View view2 = inflater.inflate(R.layout.fragment_contacts, viewPager, false);
|
// View view3 = inflater.inflate(R.layout.fragment_log, viewPager, false);
|
||||||
View view3 = inflater.inflate(R.layout.fragment_log, viewPager, false);
|
//
|
||||||
|
// views = new ArrayList<>();
|
||||||
views = new ArrayList<>();
|
// views.add(view1);
|
||||||
views.add(view1);
|
// views.add(view2);
|
||||||
views.add(view2);
|
// views.add(view3);
|
||||||
views.add(view3);
|
// }
|
||||||
}
|
|
||||||
|
|
||||||
// void initPoint() {
|
// void initPoint() {
|
||||||
// imageViews = new ImageView[5];//实例化5个图片
|
// imageViews = new ImageView[5];//实例化5个图片
|
||||||
@@ -231,6 +303,23 @@ final public class MainActivity extends AppCompatActivity implements IWinBollAct
|
|||||||
//setSubTitle("");
|
//setSubTitle("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class MyPhoneStateListener extends PhoneStateListener {
|
||||||
|
@Override
|
||||||
|
public void onCallStateChanged(int state, String incomingNumber) {
|
||||||
|
switch (state) {
|
||||||
|
case TelephonyManager.CALL_STATE_IDLE:
|
||||||
|
LogUtils.d(TAG, "电话已挂断");
|
||||||
|
break;
|
||||||
|
case TelephonyManager.CALL_STATE_OFFHOOK:
|
||||||
|
LogUtils.d(TAG, "正在通话中");
|
||||||
|
break;
|
||||||
|
case TelephonyManager.CALL_STATE_RINGING:
|
||||||
|
LogUtils.d(TAG, "来电: " + incomingNumber);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDestroy() {
|
protected void onDestroy() {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
@@ -302,25 +391,25 @@ final public class MainActivity extends AppCompatActivity implements IWinBollAct
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
public void onBackPressed() {
|
// public void onBackPressed() {
|
||||||
exit();
|
// exit();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
void exit() {
|
// void exit() {
|
||||||
YesNoAlertDialog.OnDialogResultListener listener = new YesNoAlertDialog.OnDialogResultListener(){
|
// YesNoAlertDialog.OnDialogResultListener listener = new YesNoAlertDialog.OnDialogResultListener(){
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public void onYes() {
|
// public void onYes() {
|
||||||
WinBollActivityManager.getInstance(getApplicationContext()).finishAll();
|
// WinBollActivityManager.getInstance(getApplicationContext()).finishAll();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public void onNo() {
|
// public void onNo() {
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
YesNoAlertDialog.show(this, "[ " + getString(R.string.app_name) + " ]", "Exit(Yes/No).\nIs close all activity?", listener);
|
// YesNoAlertDialog.show(this, "[ " + getString(R.string.app_name) + " ]", "Exit(Yes/No).\nIs close all activity?", listener);
|
||||||
}
|
// }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
@@ -331,11 +420,7 @@ final public class MainActivity extends AppCompatActivity implements IWinBollAct
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
if (item.getItemId() == R.id.item_call) {
|
if (item.getItemId() == R.id.item_settings) {
|
||||||
Intent intent = new Intent(this, CallActivity.class);
|
|
||||||
startActivity(intent);
|
|
||||||
//WinBollActivityManager.getInstance(this).startWinBollActivity(this, CallActivity.class);
|
|
||||||
} else if (item.getItemId() == R.id.item_settings) {
|
|
||||||
Intent intent = new Intent(this, SettingsActivity.class);
|
Intent intent = new Intent(this, SettingsActivity.class);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
//WinBollActivityManager.getInstance(this).startWinBollActivity(this, CallActivity.class);
|
//WinBollActivityManager.getInstance(this).startWinBollActivity(this, CallActivity.class);
|
||||||
|
@@ -1,35 +0,0 @@
|
|||||||
package cc.winboll.studio.contacts;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Author ZhanGSKen@AliYun.Com
|
|
||||||
* @Date 2025/02/20 21:14:52
|
|
||||||
* @Describe PhoneCallManager
|
|
||||||
*/
|
|
||||||
|
|
||||||
import android.telecom.Call;
|
|
||||||
import android.telecom.VideoProfile;
|
|
||||||
|
|
||||||
public class PhoneCallManager {
|
|
||||||
|
|
||||||
public static final String TAG = "PhoneCallManager";
|
|
||||||
|
|
||||||
public static Call call;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 接听电话
|
|
||||||
*/
|
|
||||||
public void answer() {
|
|
||||||
if (call != null) {
|
|
||||||
call.answer(VideoProfile.STATE_AUDIO_ONLY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 断开电话,包括来电时的拒接以及接听后的挂断
|
|
||||||
*/
|
|
||||||
public void disconnect() {
|
|
||||||
if (call != null) {
|
|
||||||
call.disconnect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -34,6 +34,7 @@ public class CallActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
//setContentView(R.layout.activity_main);
|
//setContentView(R.layout.activity_main);
|
||||||
setContentView(R.layout.activity_call);
|
setContentView(R.layout.activity_call);
|
||||||
|
@@ -26,6 +26,10 @@ import cc.winboll.studio.libappbase.IWinBollActivity;
|
|||||||
import cc.winboll.studio.libappbase.bean.APPInfo;
|
import cc.winboll.studio.libappbase.bean.APPInfo;
|
||||||
import com.hjq.toast.ToastUtils;
|
import com.hjq.toast.ToastUtils;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
import android.widget.SeekBar;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import cc.winboll.studio.contacts.beans.MainServiceBean;
|
||||||
|
import cc.winboll.studio.contacts.services.MainService;
|
||||||
|
|
||||||
public class SettingsActivity extends AppCompatActivity implements IWinBollActivity {
|
public class SettingsActivity extends AppCompatActivity implements IWinBollActivity {
|
||||||
|
|
||||||
@@ -33,6 +37,12 @@ public class SettingsActivity extends AppCompatActivity implements IWinBollActiv
|
|||||||
|
|
||||||
Toolbar mToolbar;
|
Toolbar mToolbar;
|
||||||
Switch swSilent;
|
Switch swSilent;
|
||||||
|
SeekBar msbVolume;
|
||||||
|
TextView mtvVolume;
|
||||||
|
int mnStreamMaxVolume;
|
||||||
|
int mnStreamVolume;
|
||||||
|
Switch mswMainService;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public APPInfo getAppInfo() {
|
public APPInfo getAppInfo() {
|
||||||
@@ -77,6 +87,69 @@ public class SettingsActivity extends AppCompatActivity implements IWinBollActiv
|
|||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
}
|
}
|
||||||
getSupportActionBar().setSubtitle(getTag());
|
getSupportActionBar().setSubtitle(getTag());
|
||||||
|
|
||||||
|
mswMainService = findViewById(R.id.sw_mainservice);
|
||||||
|
MainServiceBean mMainServiceBean = MainServiceBean.loadBean(this, MainServiceBean.class);
|
||||||
|
mswMainService.setChecked(mMainServiceBean.isEnable());
|
||||||
|
mswMainService.setOnClickListener(new View.OnClickListener(){
|
||||||
|
@Override
|
||||||
|
public void onClick(View arg0) {
|
||||||
|
// TODO: Implement this method
|
||||||
|
if (mswMainService.isChecked()) {
|
||||||
|
//ToastUtils.show("Is Checked");
|
||||||
|
MainService.startMainService(SettingsActivity.this);
|
||||||
|
} else {
|
||||||
|
//ToastUtils.show("Not Checked");
|
||||||
|
MainService.stopMainService(SettingsActivity.this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
msbVolume = findViewById(R.id.bellvolume);
|
||||||
|
mtvVolume = findViewById(R.id.tv_volume);
|
||||||
|
final AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
|
||||||
|
|
||||||
|
// 设置SeekBar的最大值为系统铃声音量的最大刻度
|
||||||
|
mnStreamMaxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_RING);
|
||||||
|
msbVolume.setMax(mnStreamMaxVolume);
|
||||||
|
// 获取当前铃声音量并设置为SeekBar的初始进度
|
||||||
|
mnStreamVolume = audioManager.getStreamVolume(AudioManager.STREAM_RING);
|
||||||
|
msbVolume.setProgress(mnStreamVolume);
|
||||||
|
|
||||||
|
updateStreamVolumeTextView();
|
||||||
|
|
||||||
|
msbVolume.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||||
|
if (fromUser) {
|
||||||
|
// 设置铃声音量
|
||||||
|
audioManager.setStreamVolume(AudioManager.STREAM_RING, progress, 0);
|
||||||
|
RingTongBean bean = RingTongBean.loadBean(SettingsActivity.this, RingTongBean.class);
|
||||||
|
if (bean == null) {
|
||||||
|
bean = new RingTongBean();
|
||||||
|
}
|
||||||
|
bean.setStreamVolume(progress);
|
||||||
|
RingTongBean.saveBean(SettingsActivity.this, bean);
|
||||||
|
mnStreamVolume = progress;
|
||||||
|
updateStreamVolumeTextView();
|
||||||
|
//Toast.makeText(SettingsActivity.this, "音量设置为: " + progress, Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||||
|
// 当开始拖动SeekBar时的操作
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||||
|
// 当停止拖动SeekBar时的操作
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateStreamVolumeTextView() {
|
||||||
|
mtvVolume.setText(String.format("%d/%d", mnStreamVolume, mnStreamMaxVolume));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onDefaultPhone(View view) {
|
public void onDefaultPhone(View view) {
|
||||||
|
@@ -0,0 +1,79 @@
|
|||||||
|
package cc.winboll.studio.contacts.adapters;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen@AliYun.Com
|
||||||
|
* @Date 2025/02/26 13:09:32
|
||||||
|
* @Describe CallLogAdapter
|
||||||
|
*/
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
import cc.winboll.studio.contacts.R;
|
||||||
|
import cc.winboll.studio.contacts.beans.CallLogModel;
|
||||||
|
import com.hjq.toast.ToastUtils;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
public class CallLogAdapter extends RecyclerView.Adapter<CallLogAdapter.CallLogViewHolder> {
|
||||||
|
public static final String TAG = "CallLogAdapter";
|
||||||
|
|
||||||
|
private List<CallLogModel> callLogList;
|
||||||
|
|
||||||
|
public CallLogAdapter(List<CallLogModel> callLogList) {
|
||||||
|
this.callLogList = callLogList;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public CallLogViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
|
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_call_log, parent, false);
|
||||||
|
return new CallLogViewHolder(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull CallLogViewHolder holder, int position) {
|
||||||
|
final CallLogModel callLog = callLogList.get(position);
|
||||||
|
holder.phoneNumber.setText(callLog.getPhoneNumber());
|
||||||
|
holder.callStatus.setText(callLog.getCallStatus());
|
||||||
|
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
|
||||||
|
holder.callDate.setText(dateFormat.format(callLog.getCallDate()));
|
||||||
|
holder.dialButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
String phoneNumber = callLog.getPhoneNumber().replaceAll("\\s", "");
|
||||||
|
ToastUtils.show(phoneNumber);
|
||||||
|
Intent intent = new Intent(Intent.ACTION_CALL);
|
||||||
|
intent.setData(android.net.Uri.parse("tel:" + phoneNumber));
|
||||||
|
// 添加 FLAG_ACTIVITY_NEW_TASK 标志
|
||||||
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
holder.itemView.getContext().startActivity(intent);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return callLogList.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CallLogViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
TextView phoneNumber, callStatus, callDate;
|
||||||
|
Button dialButton;
|
||||||
|
|
||||||
|
|
||||||
|
public CallLogViewHolder(@NonNull View itemView) {
|
||||||
|
super(itemView);
|
||||||
|
phoneNumber = itemView.findViewById(R.id.phone_number);
|
||||||
|
callStatus = itemView.findViewById(R.id.call_status);
|
||||||
|
callDate = itemView.findViewById(R.id.call_date);
|
||||||
|
dialButton = itemView.findViewById(R.id.dial_button);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -0,0 +1,78 @@
|
|||||||
|
package cc.winboll.studio.contacts.adapters;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen@AliYun.Com
|
||||||
|
* @Date 2025/02/26 13:35:44
|
||||||
|
* @Describe ContactAdapter
|
||||||
|
*/
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
import cc.winboll.studio.contacts.R;
|
||||||
|
import cc.winboll.studio.contacts.beans.ContactModel;
|
||||||
|
import com.hjq.toast.ToastUtils;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ContactAdapter extends RecyclerView.Adapter<ContactAdapter.ContactViewHolder> {
|
||||||
|
|
||||||
|
public static final String TAG = "ContactAdapter";
|
||||||
|
|
||||||
|
private static final int REQUEST_CALL_PHONE = 1;
|
||||||
|
|
||||||
|
private List<ContactModel> contactList;
|
||||||
|
|
||||||
|
public ContactAdapter(List<ContactModel> contactList) {
|
||||||
|
this.contactList = contactList;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public ContactViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
|
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_contact, parent, false);
|
||||||
|
return new ContactViewHolder(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull ContactViewHolder holder, int position) {
|
||||||
|
final ContactModel contact = contactList.get(position);
|
||||||
|
holder.contactName.setText(contact.getName());
|
||||||
|
holder.contactNumber.setText(contact.getNumber());
|
||||||
|
|
||||||
|
holder.dialButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
String phoneNumber = contact.getNumber().replaceAll("\\s", "");
|
||||||
|
ToastUtils.show(phoneNumber);
|
||||||
|
Intent intent = new Intent(Intent.ACTION_CALL);
|
||||||
|
intent.setData(android.net.Uri.parse("tel:" + phoneNumber));
|
||||||
|
// 添加 FLAG_ACTIVITY_NEW_TASK 标志
|
||||||
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
holder.itemView.getContext().startActivity(intent);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return contactList.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ContactViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
TextView contactName;
|
||||||
|
TextView contactNumber;
|
||||||
|
Button dialButton;
|
||||||
|
|
||||||
|
public ContactViewHolder(@NonNull View itemView) {
|
||||||
|
super(itemView);
|
||||||
|
contactName = itemView.findViewById(R.id.contact_name);
|
||||||
|
contactNumber = itemView.findViewById(R.id.contact_number);
|
||||||
|
dialButton = itemView.findViewById(R.id.dial_button);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -9,16 +9,16 @@ import androidx.annotation.NonNull;
|
|||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
import androidx.fragment.app.FragmentPagerAdapter;
|
import androidx.fragment.app.FragmentPagerAdapter;
|
||||||
import cc.winboll.studio.contacts.fragments.CallFragment;
|
import cc.winboll.studio.contacts.fragments.CallLogFragment;
|
||||||
import cc.winboll.studio.contacts.fragments.ContactsFragment;
|
import cc.winboll.studio.contacts.fragments.ContactsFragment;
|
||||||
import cc.winboll.studio.contacts.fragments.LogFragment;
|
import cc.winboll.studio.contacts.fragments.LogFragment;
|
||||||
|
|
||||||
public class MyPagerAdapter extends FragmentPagerAdapter {
|
public class MyPagerAdapter2 extends FragmentPagerAdapter {
|
||||||
public static final String TAG = "MyPagerAdapter";
|
public static final String TAG = "MyPagerAdapter";
|
||||||
|
|
||||||
private static final int PAGE_COUNT = 3;
|
private static final int PAGE_COUNT = 3;
|
||||||
|
|
||||||
public MyPagerAdapter(@NonNull FragmentManager fm) {
|
public MyPagerAdapter2(@NonNull FragmentManager fm) {
|
||||||
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
|
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ public class MyPagerAdapter extends FragmentPagerAdapter {
|
|||||||
} else if(position == 2) {
|
} else if(position == 2) {
|
||||||
return LogFragment.newInstance(position);
|
return LogFragment.newInstance(position);
|
||||||
} else {
|
} else {
|
||||||
return CallFragment.newInstance(position);
|
return CallLogFragment.newInstance(position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@@ -0,0 +1,36 @@
|
|||||||
|
package cc.winboll.studio.contacts.beans;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen@AliYun.Com
|
||||||
|
* @Date 2025/02/26 13:10:57
|
||||||
|
* @Describe CallLogModel
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
public class CallLogModel {
|
||||||
|
public static final String TAG = "CallLogModel";
|
||||||
|
|
||||||
|
private String phoneNumber;
|
||||||
|
private String callStatus;
|
||||||
|
private Date callDate;
|
||||||
|
|
||||||
|
public CallLogModel(String phoneNumber, String callStatus, Date callDate) {
|
||||||
|
this.phoneNumber = phoneNumber.replaceAll("\\s", "");
|
||||||
|
this.callStatus = callStatus;
|
||||||
|
this.callDate = callDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPhoneNumber() {
|
||||||
|
return phoneNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCallStatus() {
|
||||||
|
return callStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getCallDate() {
|
||||||
|
return callDate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -0,0 +1,64 @@
|
|||||||
|
package cc.winboll.studio.contacts.beans;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen@AliYun.Com
|
||||||
|
* @Date 2025/02/26 13:37:00
|
||||||
|
* @Describe ContactModel
|
||||||
|
*/
|
||||||
|
import net.sourceforge.pinyin4j.PinyinHelper;
|
||||||
|
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
|
||||||
|
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
|
||||||
|
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
|
||||||
|
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
|
||||||
|
|
||||||
|
public class ContactModel {
|
||||||
|
|
||||||
|
public static final String TAG = "ContactModel";
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
private String number;
|
||||||
|
private String pinyin;
|
||||||
|
|
||||||
|
public ContactModel(String name, String number) {
|
||||||
|
this.name = name;
|
||||||
|
this.number = number.replaceAll("\\s", "");
|
||||||
|
this.pinyin = convertToPinyin(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String convertToPinyin(String chinese) {
|
||||||
|
HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
|
||||||
|
format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
|
||||||
|
format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
|
||||||
|
|
||||||
|
StringBuilder pinyin = new StringBuilder();
|
||||||
|
for (int i = 0; i < chinese.length(); i++) {
|
||||||
|
char ch = chinese.charAt(i);
|
||||||
|
if (Character.toString(ch).matches("[\\u4e00-\\u9fa5]")) {
|
||||||
|
try {
|
||||||
|
String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(ch, format);
|
||||||
|
if (pinyinArray != null) {
|
||||||
|
pinyin.append(pinyinArray[0]);
|
||||||
|
}
|
||||||
|
} catch (BadHanyuPinyinOutputFormatCombination e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pinyin.append(ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pinyin.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNumber() {
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPinyin() {
|
||||||
|
return pinyin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -12,26 +12,26 @@ import android.media.AudioManager;
|
|||||||
import android.util.JsonReader;
|
import android.util.JsonReader;
|
||||||
|
|
||||||
public class RingTongBean extends BaseBean {
|
public class RingTongBean extends BaseBean {
|
||||||
|
|
||||||
public static final String TAG = "AudioRingTongBean";
|
public static final String TAG = "AudioRingTongBean";
|
||||||
|
|
||||||
// 模式
|
// 铃声音量
|
||||||
int ringerMode;
|
int streamVolume;
|
||||||
|
|
||||||
public RingTongBean() {
|
public RingTongBean() {
|
||||||
this.ringerMode = AudioManager.RINGER_MODE_NORMAL;
|
this.streamVolume = 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RingTongBean(int ringerMode) {
|
public RingTongBean(int streamVolume) {
|
||||||
this.ringerMode = ringerMode;
|
this.streamVolume = streamVolume;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRingerMode(int ringerMode) {
|
public void setStreamVolume(int streamVolume) {
|
||||||
this.ringerMode = ringerMode;
|
this.streamVolume = streamVolume;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getRingerMode() {
|
public int getStreamVolume() {
|
||||||
return ringerMode;
|
return streamVolume;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -42,15 +42,15 @@ public class RingTongBean extends BaseBean {
|
|||||||
@Override
|
@Override
|
||||||
public void writeThisToJsonWriter(JsonWriter jsonWriter) throws IOException {
|
public void writeThisToJsonWriter(JsonWriter jsonWriter) throws IOException {
|
||||||
super.writeThisToJsonWriter(jsonWriter);
|
super.writeThisToJsonWriter(jsonWriter);
|
||||||
jsonWriter.name("ringerMode").value(getRingerMode());
|
jsonWriter.name("streamVolume").value(getStreamVolume());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean initObjectsFromJsonReader(JsonReader jsonReader, String name) throws IOException {
|
public boolean initObjectsFromJsonReader(JsonReader jsonReader, String name) throws IOException {
|
||||||
if (super.initObjectsFromJsonReader(jsonReader, name)) { return true; } else {
|
if (super.initObjectsFromJsonReader(jsonReader, name)) { return true; } else {
|
||||||
if (name.equals("ringerMode")) {
|
if (name.equals("streamVolume")) {
|
||||||
setRingerMode(jsonReader.nextInt());
|
setStreamVolume(jsonReader.nextInt());
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@@ -1,51 +0,0 @@
|
|||||||
package cc.winboll.studio.contacts.fragments;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Author ZhanGSKen@AliYun.Com
|
|
||||||
* @Date 2025/02/20 12:57:00
|
|
||||||
* @Describe 拨号
|
|
||||||
*/
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
import cc.winboll.studio.contacts.R;
|
|
||||||
import cc.winboll.studio.libappbase.LogView;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
public class CallFragment extends Fragment {
|
|
||||||
|
|
||||||
public static final String TAG = "CallFragment";
|
|
||||||
|
|
||||||
private static final String ARG_PAGE = "ARG_PAGE";
|
|
||||||
private int mPage;
|
|
||||||
|
|
||||||
public static CallFragment newInstance(int page) {
|
|
||||||
Bundle args = new Bundle();
|
|
||||||
args.putInt(ARG_PAGE, page);
|
|
||||||
CallFragment fragment = new CallFragment();
|
|
||||||
fragment.setArguments(args);
|
|
||||||
return fragment;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
if (getArguments()!= null) {
|
|
||||||
mPage = getArguments().getInt(ARG_PAGE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
|
||||||
@Nullable Bundle savedInstanceState) {
|
|
||||||
View view = inflater.inflate(R.layout.fragment_call, container, false);
|
|
||||||
TextView textView = view.findViewById(R.id.page_text);
|
|
||||||
textView.setText("这是第 " + mPage + " 页");
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -0,0 +1,125 @@
|
|||||||
|
package cc.winboll.studio.contacts.fragments;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen@AliYun.Com
|
||||||
|
* @Date 2025/02/20 12:57:00
|
||||||
|
* @Describe 拨号
|
||||||
|
*/
|
||||||
|
import android.Manifest;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.provider.CallLog;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.core.app.ActivityCompat;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
import cc.winboll.studio.contacts.R;
|
||||||
|
import cc.winboll.studio.contacts.adapters.CallLogAdapter;
|
||||||
|
import cc.winboll.studio.contacts.beans.CallLogModel;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class CallLogFragment extends Fragment {
|
||||||
|
|
||||||
|
public static final String TAG = "CallFragment";
|
||||||
|
|
||||||
|
private static final String ARG_PAGE = "ARG_PAGE";
|
||||||
|
private int mPage;
|
||||||
|
|
||||||
|
private static final int REQUEST_READ_CALL_LOG = 1;
|
||||||
|
private RecyclerView recyclerView;
|
||||||
|
private CallLogAdapter callLogAdapter;
|
||||||
|
private List<CallLogModel> callLogList = new ArrayList<>();
|
||||||
|
|
||||||
|
public static CallLogFragment newInstance(int page) {
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putInt(ARG_PAGE, page);
|
||||||
|
CallLogFragment fragment = new CallLogFragment();
|
||||||
|
fragment.setArguments(args);
|
||||||
|
return fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||||
|
return inflater.inflate(R.layout.fragment_call_log, container, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
if (getArguments()!= null) {
|
||||||
|
mPage = getArguments().getInt(ARG_PAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
recyclerView = view.findViewById(R.id.recyclerView);
|
||||||
|
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||||
|
callLogAdapter = new CallLogAdapter(callLogList);
|
||||||
|
recyclerView.setAdapter(callLogAdapter);
|
||||||
|
|
||||||
|
if (ActivityCompat.checkSelfPermission(requireContext(), Manifest.permission.READ_CALL_LOG)!= PackageManager.PERMISSION_GRANTED) {
|
||||||
|
ActivityCompat.requestPermissions(requireActivity(), new String[]{Manifest.permission.READ_CALL_LOG}, REQUEST_READ_CALL_LOG);
|
||||||
|
} else {
|
||||||
|
readCallLog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||||
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||||
|
if (requestCode == REQUEST_READ_CALL_LOG) {
|
||||||
|
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
readCallLog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readCallLog() {
|
||||||
|
Cursor cursor = requireContext().getContentResolver().query(
|
||||||
|
CallLog.Calls.CONTENT_URI,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
CallLog.Calls.DATE + " DESC");
|
||||||
|
|
||||||
|
if (cursor!= null) {
|
||||||
|
while (cursor.moveToNext()) {
|
||||||
|
String phoneNumber = cursor.getString(cursor.getColumnIndex(CallLog.Calls.NUMBER));
|
||||||
|
int callType = cursor.getInt(cursor.getColumnIndex(CallLog.Calls.TYPE));
|
||||||
|
long callDateLong = cursor.getLong(cursor.getColumnIndex(CallLog.Calls.DATE));
|
||||||
|
Date callDate = new Date(callDateLong);
|
||||||
|
|
||||||
|
String callStatus = getCallStatus(callType);
|
||||||
|
|
||||||
|
callLogList.add(new CallLogModel(phoneNumber, callStatus, callDate));
|
||||||
|
}
|
||||||
|
cursor.close();
|
||||||
|
callLogAdapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getCallStatus(int callType) {
|
||||||
|
switch (callType) {
|
||||||
|
case CallLog.Calls.OUTGOING_TYPE:
|
||||||
|
return "Outgoing";
|
||||||
|
case CallLog.Calls.INCOMING_TYPE:
|
||||||
|
return "Incoming";
|
||||||
|
case CallLog.Calls.MISSED_TYPE:
|
||||||
|
return "Missed";
|
||||||
|
default:
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -5,23 +5,47 @@ package cc.winboll.studio.contacts.fragments;
|
|||||||
* @Date 2025/02/20 12:57:50
|
* @Date 2025/02/20 12:57:50
|
||||||
* @Describe 联系人
|
* @Describe 联系人
|
||||||
*/
|
*/
|
||||||
|
import android.Manifest;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.database.Cursor;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.provider.ContactsContract;
|
||||||
|
import android.text.Editable;
|
||||||
|
import android.text.TextWatcher;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.TextView;
|
import android.widget.Button;
|
||||||
|
import android.widget.EditText;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.core.app.ActivityCompat;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import cc.winboll.studio.contacts.R;
|
import cc.winboll.studio.contacts.R;
|
||||||
|
import cc.winboll.studio.contacts.adapters.ContactAdapter;
|
||||||
|
import cc.winboll.studio.contacts.beans.ContactModel;
|
||||||
|
import com.hjq.toast.ToastUtils;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
public class ContactsFragment extends Fragment {
|
public class ContactsFragment extends Fragment {
|
||||||
|
|
||||||
public static final String TAG = "ContactsFragment";
|
public static final String TAG = "ContactsFragment";
|
||||||
|
|
||||||
private static final String ARG_PAGE = "ARG_PAGE";
|
private static final String ARG_PAGE = "ARG_PAGE";
|
||||||
private int mPage;
|
private int mPage;
|
||||||
|
|
||||||
|
private static final int REQUEST_READ_CONTACTS = 1;
|
||||||
|
private RecyclerView recyclerView;
|
||||||
|
private ContactAdapter contactAdapter;
|
||||||
|
private List<ContactModel> contactList = new ArrayList<>();
|
||||||
|
private List<ContactModel> originalContactList = new ArrayList<>();
|
||||||
|
private EditText searchEditText;
|
||||||
|
|
||||||
public static ContactsFragment newInstance(int page) {
|
public static ContactsFragment newInstance(int page) {
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
args.putInt(ARG_PAGE, page);
|
args.putInt(ARG_PAGE, page);
|
||||||
@@ -33,18 +57,110 @@ public class ContactsFragment extends Fragment {
|
|||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
if (getArguments()!= null) {
|
if (getArguments() != null) {
|
||||||
mPage = getArguments().getInt(ARG_PAGE);
|
mPage = getArguments().getInt(ARG_PAGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||||
@Nullable Bundle savedInstanceState) {
|
return inflater.inflate(R.layout.fragment_contacts, container, false);
|
||||||
View view = inflater.inflate(R.layout.fragment_contacts, container, false);
|
}
|
||||||
TextView textView = view.findViewById(R.id.page_text);
|
|
||||||
textView.setText("这是第 " + mPage + " 页");
|
@Override
|
||||||
return view;
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
recyclerView = view.findViewById(R.id.contacts_recycler_view);
|
||||||
|
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||||
|
contactAdapter = new ContactAdapter(contactList);
|
||||||
|
recyclerView.setAdapter(contactAdapter);
|
||||||
|
|
||||||
|
searchEditText = view.findViewById(R.id.search_edit_text);
|
||||||
|
searchEditText.addTextChangedListener(new TextWatcher() {
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
filterContacts(s.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable s) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (ActivityCompat.checkSelfPermission(requireContext(), Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
ActivityCompat.requestPermissions(requireActivity(), new String[]{Manifest.permission.READ_CONTACTS}, REQUEST_READ_CONTACTS);
|
||||||
|
} else {
|
||||||
|
readContacts();
|
||||||
|
}
|
||||||
|
|
||||||
|
Button btnDial = view.findViewById(R.id.btn_dial);
|
||||||
|
btnDial.setOnClickListener(new View.OnClickListener(){
|
||||||
|
@Override
|
||||||
|
public void onClick(View p1) {
|
||||||
|
|
||||||
|
String phoneNumber = searchEditText.getText().toString().replaceAll("\\s", "");
|
||||||
|
ToastUtils.show(phoneNumber);
|
||||||
|
Intent intent = new Intent(Intent.ACTION_CALL);
|
||||||
|
intent.setData(android.net.Uri.parse("tel:" + phoneNumber));
|
||||||
|
// 添加 FLAG_ACTIVITY_NEW_TASK 标志
|
||||||
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||||
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||||
|
if (requestCode == REQUEST_READ_CONTACTS) {
|
||||||
|
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
readContacts();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readContacts() {
|
||||||
|
contactList.clear();
|
||||||
|
originalContactList.clear();
|
||||||
|
Cursor cursor = requireContext().getContentResolver().query(
|
||||||
|
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
|
||||||
|
|
||||||
|
if (cursor != null) {
|
||||||
|
while (cursor.moveToNext()) {
|
||||||
|
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
|
||||||
|
String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
|
||||||
|
ContactModel contact = new ContactModel(name, number);
|
||||||
|
contactList.add(contact);
|
||||||
|
originalContactList.add(contact);
|
||||||
|
}
|
||||||
|
cursor.close();
|
||||||
|
contactAdapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void filterContacts(String query) {
|
||||||
|
contactList.clear();
|
||||||
|
if (query.isEmpty()) {
|
||||||
|
contactList.addAll(originalContactList);
|
||||||
|
} else {
|
||||||
|
for (ContactModel contact : originalContactList) {
|
||||||
|
if (contact.getName().toLowerCase().contains(query.toLowerCase()) ||
|
||||||
|
contact.getPinyin().toLowerCase().contains(query.toLowerCase()) ||
|
||||||
|
contact.getNumber().toLowerCase().contains(query.toLowerCase())) {
|
||||||
|
contactList.add(contact);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
contactAdapter.notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -21,6 +21,8 @@ import android.widget.TextView;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import cc.winboll.studio.contacts.MainActivity;
|
import cc.winboll.studio.contacts.MainActivity;
|
||||||
import cc.winboll.studio.contacts.R;
|
import cc.winboll.studio.contacts.R;
|
||||||
|
import cc.winboll.studio.contacts.phonecallui.PhoneCallActivity;
|
||||||
|
import cc.winboll.studio.contacts.phonecallui.PhoneCallService;
|
||||||
|
|
||||||
|
|
||||||
public class CallListenerService extends Service {
|
public class CallListenerService extends Service {
|
||||||
@@ -152,9 +154,12 @@ public class CallListenerService extends Service {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
|
// Intent intent = new Intent(getApplicationContext(), MainActivity.class);
|
||||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
// intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
CallListenerService.this.startActivity(intent);
|
// CallListenerService.this.startActivity(intent);
|
||||||
|
|
||||||
|
PhoneCallService.CallType callType = isCallingIn ? PhoneCallService.CallType.CALL_IN: PhoneCallService.CallType.CALL_OUT;
|
||||||
|
PhoneCallActivity.actionStart(CallListenerService.this, callNumber, callType);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -57,10 +57,9 @@ public class PhoneCallActivity extends AppCompatActivity implements View.OnClick
|
|||||||
setContentView(R.layout.activity_phone_call);
|
setContentView(R.layout.activity_phone_call);
|
||||||
|
|
||||||
ActivityStack.getInstance().addActivity(this);
|
ActivityStack.getInstance().addActivity(this);
|
||||||
|
|
||||||
initData();
|
initData();
|
||||||
|
|
||||||
initView();
|
initView();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initData() {
|
private void initData() {
|
||||||
@@ -74,9 +73,9 @@ public class PhoneCallActivity extends AppCompatActivity implements View.OnClick
|
|||||||
|
|
||||||
private void initView() {
|
private void initView() {
|
||||||
int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||||
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION //hide navigationBar
|
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION //hide navigationBar
|
||||||
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
|
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
|
||||||
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
|
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
|
||||||
getWindow().getDecorView().setSystemUiVisibility(uiOptions);
|
getWindow().getDecorView().setSystemUiVisibility(uiOptions);
|
||||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
|
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
|
||||||
|
|
||||||
@@ -94,9 +93,7 @@ public class PhoneCallActivity extends AppCompatActivity implements View.OnClick
|
|||||||
if (callType == PhoneCallService.CallType.CALL_IN) {
|
if (callType == PhoneCallService.CallType.CALL_IN) {
|
||||||
tvCallNumberLabel.setText("来电号码");
|
tvCallNumberLabel.setText("来电号码");
|
||||||
tvPickUp.setVisibility(View.VISIBLE);
|
tvPickUp.setVisibility(View.VISIBLE);
|
||||||
}
|
} else if (callType == PhoneCallService.CallType.CALL_OUT) {
|
||||||
// 打出的电话
|
|
||||||
else if (callType == PhoneCallService.CallType.CALL_OUT) {
|
|
||||||
tvCallNumberLabel.setText("呼叫号码");
|
tvCallNumberLabel.setText("呼叫号码");
|
||||||
tvPickUp.setVisibility(View.GONE);
|
tvPickUp.setVisibility(View.GONE);
|
||||||
phoneCallManager.openSpeaker();
|
phoneCallManager.openSpeaker();
|
||||||
@@ -107,13 +104,13 @@ public class PhoneCallActivity extends AppCompatActivity implements View.OnClick
|
|||||||
|
|
||||||
public void showOnLockScreen() {
|
public void showOnLockScreen() {
|
||||||
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON |
|
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON |
|
||||||
WindowManager.LayoutParams.FLAG_FULLSCREEN |
|
WindowManager.LayoutParams.FLAG_FULLSCREEN |
|
||||||
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
|
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
|
||||||
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON,
|
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON,
|
||||||
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON |
|
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON |
|
||||||
WindowManager.LayoutParams.FLAG_FULLSCREEN |
|
WindowManager.LayoutParams.FLAG_FULLSCREEN |
|
||||||
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
|
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
|
||||||
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
|
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -123,18 +120,18 @@ public class PhoneCallActivity extends AppCompatActivity implements View.OnClick
|
|||||||
tvPickUp.setVisibility(View.GONE);
|
tvPickUp.setVisibility(View.GONE);
|
||||||
tvCallingTime.setVisibility(View.VISIBLE);
|
tvCallingTime.setVisibility(View.VISIBLE);
|
||||||
onGoingCallTimer.schedule(new TimerTask() {
|
onGoingCallTimer.schedule(new TimerTask() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
runOnUiThread(new Runnable() {
|
runOnUiThread(new Runnable() {
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
callingTime++;
|
callingTime++;
|
||||||
tvCallingTime.setText("通话中:" + getCallingTime());
|
tvCallingTime.setText("通话中:" + getCallingTime());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, 0, 1000);
|
}, 0, 1000);
|
||||||
} else if (v.getId() == R.id.tv_phone_hang_up) {
|
} else if (v.getId() == R.id.tv_phone_hang_up) {
|
||||||
phoneCallManager.disconnect();
|
phoneCallManager.disconnect();
|
||||||
stopTimer();
|
stopTimer();
|
||||||
@@ -145,8 +142,8 @@ public class PhoneCallActivity extends AppCompatActivity implements View.OnClick
|
|||||||
int minute = callingTime / 60;
|
int minute = callingTime / 60;
|
||||||
int second = callingTime % 60;
|
int second = callingTime % 60;
|
||||||
return (minute < 10 ? "0" + minute : minute) +
|
return (minute < 10 ? "0" + minute : minute) +
|
||||||
":" +
|
":" +
|
||||||
(second < 10 ? "0" + second : second);
|
(second < 10 ? "0" + second : second);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void stopTimer() {
|
private void stopTimer() {
|
||||||
@@ -160,7 +157,6 @@ public class PhoneCallActivity extends AppCompatActivity implements View.OnClick
|
|||||||
@Override
|
@Override
|
||||||
protected void onDestroy() {
|
protected void onDestroy() {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
|
|
||||||
phoneCallManager.destroy();
|
phoneCallManager.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -21,8 +21,6 @@ import cc.winboll.studio.libappbase.LogUtils;
|
|||||||
public class PhoneCallService extends InCallService {
|
public class PhoneCallService extends InCallService {
|
||||||
|
|
||||||
public static final String TAG = "PhoneCallService";
|
public static final String TAG = "PhoneCallService";
|
||||||
|
|
||||||
private volatile int originalRingVolume;
|
|
||||||
|
|
||||||
private final Call.Callback callback = new Call.Callback() {
|
private final Call.Callback callback = new Call.Callback() {
|
||||||
@Override
|
@Override
|
||||||
@@ -61,25 +59,58 @@ public class PhoneCallService extends InCallService {
|
|||||||
String phoneNumber = details.getHandle().getSchemeSpecificPart();
|
String phoneNumber = details.getHandle().getSchemeSpecificPart();
|
||||||
|
|
||||||
// 记录原始铃声音量
|
// 记录原始铃声音量
|
||||||
|
//
|
||||||
AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
|
AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
|
||||||
originalRingVolume = audioManager.getStreamVolume(AudioManager.STREAM_RING);
|
int ringerVolume = audioManager.getStreamVolume(AudioManager.STREAM_RING);
|
||||||
|
// 恢复铃声音量,预防其他意外条件导致的音量变化问题
|
||||||
|
//
|
||||||
|
|
||||||
|
// 读取应用配置,未配置就初始化配置文件
|
||||||
|
RingTongBean bean = RingTongBean.loadBean(this, RingTongBean.class);
|
||||||
|
if (bean == null) {
|
||||||
|
// 初始化配置
|
||||||
|
bean = new RingTongBean();
|
||||||
|
RingTongBean.saveBean(this, bean);
|
||||||
|
}
|
||||||
|
// 如果当前音量和应用保存的不一致就恢复为应用设定值
|
||||||
|
// 恢复铃声音量
|
||||||
|
try {
|
||||||
|
if (ringerVolume != bean.getStreamVolume()) {
|
||||||
|
audioManager.setStreamVolume(AudioManager.STREAM_RING, bean.getStreamVolume(), 0);
|
||||||
|
//audioManager.setMode(AudioManager.RINGER_MODE_NORMAL);
|
||||||
|
}
|
||||||
|
} catch (java.lang.SecurityException e) {
|
||||||
|
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
||||||
|
}
|
||||||
|
|
||||||
// 检查电话接收规则
|
// 检查电话接收规则
|
||||||
if (!Rules.getInstance(this).isAllowed(phoneNumber)) {
|
if (!Rules.getInstance(this).isAllowed(phoneNumber)) {
|
||||||
// 预先静音
|
// 调低音量
|
||||||
audioManager.setStreamVolume(AudioManager.STREAM_RING, 0, 0);
|
try {
|
||||||
|
audioManager.setStreamVolume(AudioManager.STREAM_RING, 0, 0);
|
||||||
|
//audioManager.setMode(AudioManager.RINGER_MODE_SILENT);
|
||||||
|
} catch (java.lang.SecurityException e) {
|
||||||
|
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
||||||
|
}
|
||||||
// 断开电话
|
// 断开电话
|
||||||
call.disconnect();
|
call.disconnect();
|
||||||
// 停顿1秒,预防第一声铃声响动
|
// 停顿1秒,预防第一声铃声响动
|
||||||
try {
|
try {
|
||||||
Thread.sleep(1000);
|
Thread.sleep(500);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
LogUtils.d(TAG, "");
|
LogUtils.d(TAG, "");
|
||||||
}
|
}
|
||||||
// 恢复铃声音量
|
// 恢复铃声音量
|
||||||
audioManager.setStreamVolume(AudioManager.STREAM_RING, originalRingVolume, 0);
|
try {
|
||||||
|
audioManager.setStreamVolume(AudioManager.STREAM_RING, bean.getStreamVolume(), 0);
|
||||||
|
//audioManager.setMode(AudioManager.RINGER_MODE_NORMAL);
|
||||||
|
} catch (java.lang.SecurityException e) {
|
||||||
|
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
||||||
|
}
|
||||||
// 屏蔽电话结束
|
// 屏蔽电话结束
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 正常接听电话
|
// 正常接听电话
|
||||||
PhoneCallActivity.actionStart(this, phoneNumber, callType);
|
PhoneCallActivity.actionStart(this, phoneNumber, callType);
|
||||||
}
|
}
|
||||||
@@ -88,12 +119,8 @@ public class PhoneCallService extends InCallService {
|
|||||||
@Override
|
@Override
|
||||||
public void onCallRemoved(Call call) {
|
public void onCallRemoved(Call call) {
|
||||||
super.onCallRemoved(call);
|
super.onCallRemoved(call);
|
||||||
|
|
||||||
call.unregisterCallback(callback);
|
call.unregisterCallback(callback);
|
||||||
PhoneCallManager.call = null;
|
PhoneCallManager.call = null;
|
||||||
AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
|
|
||||||
// 恢复铃声音量
|
|
||||||
audioManager.setStreamVolume(AudioManager.STREAM_RING, originalRingVolume, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum CallType {
|
public enum CallType {
|
||||||
|
@@ -9,13 +9,9 @@ import android.content.BroadcastReceiver;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.media.RingtoneManager;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.util.Log;
|
|
||||||
import cc.winboll.studio.contacts.services.MainService;
|
import cc.winboll.studio.contacts.services.MainService;
|
||||||
import com.hjq.toast.ToastUtils;
|
import com.hjq.toast.ToastUtils;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
|
||||||
|
|
||||||
public class MainReceiver extends BroadcastReceiver {
|
public class MainReceiver extends BroadcastReceiver {
|
||||||
|
|
||||||
@@ -43,7 +39,7 @@ public class MainReceiver extends BroadcastReceiver {
|
|||||||
public void registerAction(Context context) {
|
public void registerAction(Context context) {
|
||||||
IntentFilter filter=new IntentFilter();
|
IntentFilter filter=new IntentFilter();
|
||||||
filter.addAction(ACTION_BOOT_COMPLETED);
|
filter.addAction(ACTION_BOOT_COMPLETED);
|
||||||
//filter.addAction(Intent.ACTION_BATTERY_CHANGED);
|
//filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
|
||||||
context.registerReceiver(this, filter);
|
context.registerReceiver(this, filter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -15,8 +15,6 @@ import android.os.IBinder;
|
|||||||
import cc.winboll.studio.contacts.beans.MainServiceBean;
|
import cc.winboll.studio.contacts.beans.MainServiceBean;
|
||||||
import cc.winboll.studio.contacts.services.MainService;
|
import cc.winboll.studio.contacts.services.MainService;
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
import cc.winboll.studio.libappbase.SOS;
|
|
||||||
import cc.winboll.studio.libappbase.bean.APPSOSBean;
|
|
||||||
|
|
||||||
public class AssistantService extends Service {
|
public class AssistantService extends Service {
|
||||||
|
|
||||||
|
@@ -11,25 +11,26 @@ package cc.winboll.studio.contacts.services;
|
|||||||
* https://blog.csdn.net/cyp331203/article/details/38920491
|
* https://blog.csdn.net/cyp331203/article/details/38920491
|
||||||
*/
|
*/
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import cc.winboll.studio.contacts.listenphonecall.CallListenerService;
|
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.ServiceConnection;
|
import android.content.ServiceConnection;
|
||||||
|
import android.media.AudioManager;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import cc.winboll.studio.contacts.beans.MainServiceBean;
|
import cc.winboll.studio.contacts.beans.MainServiceBean;
|
||||||
|
import cc.winboll.studio.contacts.beans.RingTongBean;
|
||||||
|
import cc.winboll.studio.contacts.dun.Rules;
|
||||||
import cc.winboll.studio.contacts.handlers.MainServiceHandler;
|
import cc.winboll.studio.contacts.handlers.MainServiceHandler;
|
||||||
|
import cc.winboll.studio.contacts.listenphonecall.CallListenerService;
|
||||||
import cc.winboll.studio.contacts.receivers.MainReceiver;
|
import cc.winboll.studio.contacts.receivers.MainReceiver;
|
||||||
import cc.winboll.studio.contacts.services.MainService;
|
import cc.winboll.studio.contacts.services.MainService;
|
||||||
import cc.winboll.studio.contacts.threads.MainServiceThread;
|
import cc.winboll.studio.contacts.threads.MainServiceThread;
|
||||||
import cc.winboll.studio.contacts.widgets.APPStatusWidget;
|
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
import cc.winboll.studio.libappbase.SOS;
|
import cc.winboll.studio.libappbase.SOS;
|
||||||
import cc.winboll.studio.libappbase.bean.APPSOSBean;
|
import cc.winboll.studio.libappbase.bean.APPSOSBean;
|
||||||
import cc.winboll.studio.contacts.dun.Rules;
|
import java.util.Timer;
|
||||||
import android.media.AudioManager;
|
import java.util.TimerTask;
|
||||||
import com.hjq.toast.ToastUtils;
|
|
||||||
|
|
||||||
public class MainService extends Service {
|
public class MainService extends Service {
|
||||||
|
|
||||||
@@ -48,8 +49,8 @@ public class MainService extends Service {
|
|||||||
AssistantService mAssistantService;
|
AssistantService mAssistantService;
|
||||||
boolean isBound = false;
|
boolean isBound = false;
|
||||||
MainReceiver mMainReceiver;
|
MainReceiver mMainReceiver;
|
||||||
|
Timer mStreamVolumeCheckTimer;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBinder onBind(Intent intent) {
|
public IBinder onBind(Intent intent) {
|
||||||
return new MyBinder();
|
return new MyBinder();
|
||||||
@@ -71,9 +72,37 @@ public class MainService extends Service {
|
|||||||
mMyServiceConnection = new MyServiceConnection();
|
mMyServiceConnection = new MyServiceConnection();
|
||||||
}
|
}
|
||||||
mMainServiceHandler = new MainServiceHandler(this);
|
mMainServiceHandler = new MainServiceHandler(this);
|
||||||
|
|
||||||
|
// 铃声检查定时器
|
||||||
|
mStreamVolumeCheckTimer = new Timer();
|
||||||
|
mStreamVolumeCheckTimer.schedule(new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
|
||||||
|
int ringerVolume = audioManager.getStreamVolume(AudioManager.STREAM_RING);
|
||||||
|
// 恢复铃声音量,预防其他意外条件导致的音量变化问题
|
||||||
|
//
|
||||||
|
|
||||||
|
// 读取应用配置,未配置就初始化配置文件
|
||||||
|
RingTongBean bean = RingTongBean.loadBean(MainService.this, RingTongBean.class);
|
||||||
|
if (bean == null) {
|
||||||
|
// 初始化配置
|
||||||
|
bean = new RingTongBean();
|
||||||
|
RingTongBean.saveBean(MainService.this, bean);
|
||||||
|
}
|
||||||
|
// 如果当前音量和应用保存的不一致就恢复为应用设定值
|
||||||
|
// 恢复铃声音量
|
||||||
|
try {
|
||||||
|
if (ringerVolume != bean.getStreamVolume()) {
|
||||||
|
audioManager.setStreamVolume(AudioManager.STREAM_RING, bean.getStreamVolume(), 0);
|
||||||
|
//audioManager.setMode(AudioManager.RINGER_MODE_NORMAL);
|
||||||
|
}
|
||||||
|
} catch (java.lang.SecurityException e) {
|
||||||
|
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 1000, 60000);
|
||||||
|
|
||||||
// 运行服务内容
|
// 运行服务内容
|
||||||
mainService();
|
mainService();
|
||||||
}
|
}
|
||||||
@@ -104,11 +133,11 @@ public class MainService extends Service {
|
|||||||
mMainReceiver = new MainReceiver(this);
|
mMainReceiver = new MainReceiver(this);
|
||||||
mMainReceiver.registerAction(this);
|
mMainReceiver.registerAction(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Rules.getInstance(this);
|
Rules.getInstance(this);
|
||||||
//Rules.getInstance(this).add("18888888888", true);
|
//Rules.getInstance(this).add("18888888888", true);
|
||||||
//Rules.getInstance(this).add("16769764848", true);
|
//Rules.getInstance(this).add("16769764848", true);
|
||||||
|
|
||||||
startPhoneCallListener();
|
startPhoneCallListener();
|
||||||
|
|
||||||
MainServiceThread.getInstance(this, mMainServiceHandler).start();
|
MainServiceThread.getInstance(this, mMainServiceHandler).start();
|
||||||
@@ -137,7 +166,7 @@ public class MainService extends Service {
|
|||||||
// LogUtils.d(TAG, "startService(intent)");
|
// LogUtils.d(TAG, "startService(intent)");
|
||||||
// bindService(new Intent(this, AssistantService.class), mMyServiceConnection, Context.BIND_IMPORTANT);
|
// bindService(new Intent(this, AssistantService.class), mMyServiceConnection, Context.BIND_IMPORTANT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void startPhoneCallListener() {
|
void startPhoneCallListener() {
|
||||||
Intent callListener = new Intent(this, CallListenerService.class);
|
Intent callListener = new Intent(this, CallListenerService.class);
|
||||||
startService(callListener);
|
startService(callListener);
|
||||||
@@ -168,7 +197,7 @@ public class MainService extends Service {
|
|||||||
|
|
||||||
// 停止主要进程
|
// 停止主要进程
|
||||||
MainServiceThread.getInstance(this, mMainServiceHandler).setIsExit(true);
|
MainServiceThread.getInstance(this, mMainServiceHandler).setIsExit(true);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
|
@@ -0,0 +1,27 @@
|
|||||||
|
package cc.winboll.studio.contacts.utils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen@AliYun.Com
|
||||||
|
* @Date 2025/02/26 15:21:48
|
||||||
|
* @Describe PhoneUtils
|
||||||
|
*/
|
||||||
|
import android.Manifest;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import androidx.core.app.ActivityCompat;
|
||||||
|
|
||||||
|
public class PhoneUtils {
|
||||||
|
|
||||||
|
public static final String TAG = "PhoneUtils";
|
||||||
|
|
||||||
|
public static void call(Context context, String phoneNumber) {
|
||||||
|
Intent intent = new Intent(Intent.ACTION_CALL);
|
||||||
|
intent.setData(android.net.Uri.parse("tel:" + phoneNumber));
|
||||||
|
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
context.startActivity(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -16,12 +16,12 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_weight="1.0"
|
android:layout_weight="1.0"
|
||||||
android:id="@+id/activitymainViewPager1"/>
|
android:id="@+id/viewPager"/>
|
||||||
|
|
||||||
<com.google.android.material.tabs.TabLayout
|
<com.google.android.material.tabs.TabLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="60dp"
|
android:layout_height="60dp"
|
||||||
android:id="@+id/activitymainTabLayout1"/>
|
android:id="@+id/tabLayout"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
@@ -1,95 +1,98 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
tools:context=".phonecallui.PhoneCallActivity">
|
tools:context=".phonecallui.PhoneCallActivity">
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:id="@+id/rl_user_info"
|
android:id="@+id/rl_user_info"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="300dp"
|
android:layout_height="300dp"
|
||||||
android:background="@color/colorPrimaryDark">
|
android:background="@color/colorPrimaryDark"
|
||||||
|
android:layout_marginTop="100dp">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tv_call_number_label"
|
android:id="@+id/tv_call_number_label"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_above="@+id/tv_call_number"
|
android:layout_above="@+id/tv_call_number"
|
||||||
android:layout_marginBottom="16dp"
|
android:layout_marginBottom="16dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:text="来电号码"
|
android:text="来电号码"
|
||||||
android:textColor="@android:color/white"
|
android:textColor="@android:color/white"
|
||||||
android:textSize="18sp" />
|
android:textSize="18sp"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_call_number"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:textColor="@android:color/white"
|
||||||
|
android:textSize="28sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
tools:text="133-9527-9527"/>
|
||||||
|
|
||||||
<TextView
|
</RelativeLayout>
|
||||||
android:id="@+id/tv_call_number"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:gravity="center"
|
|
||||||
android:textAlignment="center"
|
|
||||||
android:textColor="@android:color/white"
|
|
||||||
android:textSize="28sp"
|
|
||||||
android:textStyle="bold"
|
|
||||||
android:layout_centerInParent="true"
|
|
||||||
tools:text="133-9527-9527" />
|
|
||||||
|
|
||||||
</RelativeLayout>
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@android:color/white">
|
||||||
|
|
||||||
<RelativeLayout
|
<TextView
|
||||||
android:layout_width="match_parent"
|
android:id="@+id/tv_phone_calling_time"
|
||||||
android:layout_height="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:background="@android:color/white">
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:text="通话中:01:33"
|
||||||
|
android:textColor="@android:color/black"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible"/>
|
||||||
|
|
||||||
<TextView
|
<RelativeLayout
|
||||||
android:id="@+id/tv_phone_calling_time"
|
android:layout_width="wrap_content"
|
||||||
android:layout_width="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_centerInParent="true">
|
||||||
android:layout_centerHorizontal="true"
|
|
||||||
android:layout_marginTop="24dp"
|
|
||||||
android:text="通话中:01:33"
|
|
||||||
android:textColor="@android:color/black"
|
|
||||||
android:textSize="18sp"
|
|
||||||
android:visibility="gone"
|
|
||||||
tools:visibility="visible" />
|
|
||||||
|
|
||||||
<RelativeLayout
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:id="@+id/tv_phone_hang_up"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_centerInParent="true">
|
android:layout_height="wrap_content"
|
||||||
|
android:drawablePadding="16dp"
|
||||||
|
android:drawableTop="@drawable/ic_phone_hang_up"
|
||||||
|
android:foreground="?android:attr/selectableItemBackground"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="8dp"
|
||||||
|
android:text="挂 断"
|
||||||
|
android:textColor="@android:color/black"
|
||||||
|
tools:visibility="visible"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tv_phone_hang_up"
|
android:id="@+id/tv_phone_pick_up"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:drawablePadding="16dp"
|
android:layout_marginLeft="50dp"
|
||||||
android:drawableTop="@drawable/ic_phone_hang_up"
|
android:layout_toRightOf="@id/tv_phone_hang_up"
|
||||||
android:foreground="?android:attr/selectableItemBackground"
|
android:drawablePadding="16dp"
|
||||||
android:gravity="center"
|
android:drawableTop="@drawable/ic_phone_pick_up"
|
||||||
android:padding="8dp"
|
android:foreground="?android:attr/selectableItemBackground"
|
||||||
android:text="挂 断"
|
android:gravity="center"
|
||||||
android:textColor="@android:color/black"
|
android:padding="8dp"
|
||||||
tools:visibility="visible" />
|
android:text="接 听"
|
||||||
|
android:textColor="@android:color/black"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible"/>
|
||||||
|
|
||||||
<TextView
|
</RelativeLayout>
|
||||||
android:id="@+id/tv_phone_pick_up"
|
|
||||||
android:layout_width="wrap_content"
|
</RelativeLayout>
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginLeft="50dp"
|
</LinearLayout>
|
||||||
android:layout_toRightOf="@id/tv_phone_hang_up"
|
|
||||||
android:drawablePadding="16dp"
|
|
||||||
android:drawableTop="@drawable/ic_phone_pick_up"
|
|
||||||
android:foreground="?android:attr/selectableItemBackground"
|
|
||||||
android:gravity="center"
|
|
||||||
android:padding="8dp"
|
|
||||||
android:text="接 听"
|
|
||||||
android:textColor="@android:color/black"
|
|
||||||
android:visibility="gone"
|
|
||||||
tools:visibility="visible" />
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
</LinearLayout>
|
|
@@ -18,6 +18,25 @@
|
|||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_weight="1.0">
|
android:layout_weight="1.0">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="服务设置:"/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<Switch
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="主要服务"
|
||||||
|
android:id="@+id/sw_mainservice"
|
||||||
|
android:layout_margin="10dp"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@@ -45,6 +64,32 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="音量设置:"/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="10dp"
|
||||||
|
android:id="@+id/tv_volume"/>
|
||||||
|
|
||||||
|
<SeekBar
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="10dp"
|
||||||
|
android:max="100"
|
||||||
|
android:id="@+id/bellvolume"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@@ -1,29 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:ems="10"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1.0"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Text"
|
|
||||||
android:id="@+id/page_text"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
15
contacts/src/main/res/layout/fragment_call_log.xml
Normal file
15
contacts/src/main/res/layout/fragment_call_log.xml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recyclerView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
@@ -1,15 +1,36 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/search_edit_text"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="Search contacts"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:layout_weight="1.0"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Dial"
|
||||||
|
android:id="@+id/btn_dial"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/contacts_recycler_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"/>
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Text"
|
|
||||||
android:id="@+id/page_text"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
39
contacts/src/main/res/layout/item_call_log.xml
Normal file
39
contacts/src/main/res/layout/item_call_log.xml
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/phone_number"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/call_status"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:layout_marginTop="4dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/call_date"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:layout_marginTop="4dp" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/dial_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Dial"
|
||||||
|
android:layout_marginTop="8dp"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
31
contacts/src/main/res/layout/item_contact.xml
Normal file
31
contacts/src/main/res/layout/item_contact.xml
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/contact_name"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/contact_number"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:layout_marginTop="4dp"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/dial_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Dial"
|
||||||
|
android:layout_marginTop="8dp"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
@@ -1,12 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/item_call"
|
|
||||||
android:title="CallActivity"/>
|
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/item_settings"
|
android:id="@+id/item_settings"
|
||||||
android:title="SettingsActivity"/>
|
android:title="Settings"
|
||||||
|
app:showAsAction="ifRoom"/>
|
||||||
</menu>
|
</menu>
|
||||||
|
Reference in New Issue
Block a user