This commit is contained in:
ZhanGSKen 2025-02-26 18:22:10 +08:00
parent a15f6bad8f
commit ecb56df773
16 changed files with 281 additions and 153 deletions

View File

@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle #Created by .winboll/winboll_app_build.gradle
#Wed Feb 26 06:42:40 GMT 2025 #Wed Feb 26 10:15:51 GMT 2025
stageCount=4 stageCount=4
libraryProject= libraryProject=
baseVersion=1.0 baseVersion=1.0
publishVersion=1.0.3 publishVersion=1.0.3
buildCount=8 buildCount=54
baseBetaVersion=1.0.4 baseBetaVersion=1.0.4

View File

@ -66,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>
@ -185,4 +185,4 @@
</application> </application>
</manifest> </manifest>

View File

@ -1,12 +1,16 @@
package cc.winboll.studio.contacts; package cc.winboll.studio.contacts;
import android.Manifest;
import android.app.Activity; import android.app.Activity;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.telecom.TelecomManager; import android.telecom.TelecomManager;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
@ -17,9 +21,9 @@ import android.widget.LinearLayout;
import android.widget.Toast; import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
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.activities.SettingsActivity;
import cc.winboll.studio.contacts.adapters.MyPagerAdapter; import cc.winboll.studio.contacts.adapters.MyPagerAdapter;
import cc.winboll.studio.contacts.beans.MainServiceBean; import cc.winboll.studio.contacts.beans.MainServiceBean;
@ -43,6 +47,7 @@ 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;
@ -56,6 +61,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
@ -88,6 +96,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);
// 初始化工具栏 // 初始化工具栏
@ -135,6 +144,20 @@ final public class MainActivity extends AppCompatActivity implements IWinBollAct
if (mMainServiceBean.isEnable()) { if (mMainServiceBean.isEnable()) {
MainService.startMainService(this); MainService.startMainService(this);
} }
// 初始化TelephonyManager和PhoneStateListener
telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
phoneStateListener = new MyPhoneStateListener();
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
}
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即显示的图片
@ -225,6 +248,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();
@ -325,11 +365,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);

View File

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

View File

@ -5,14 +5,17 @@ package cc.winboll.studio.contacts.adapters;
* @Date 2025/02/26 13:09:32 * @Date 2025/02/26 13:09:32
* @Describe CallLogAdapter * @Describe CallLogAdapter
*/ */
import android.content.Intent;
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.Button;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import cc.winboll.studio.contacts.R; import cc.winboll.studio.contacts.R;
import cc.winboll.studio.contacts.beans.CallLogModel; import cc.winboll.studio.contacts.beans.CallLogModel;
import com.hjq.toast.ToastUtils;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@ -35,11 +38,23 @@ public class CallLogAdapter extends RecyclerView.Adapter<CallLogAdapter.CallLogV
@Override @Override
public void onBindViewHolder(@NonNull CallLogViewHolder holder, int position) { public void onBindViewHolder(@NonNull CallLogViewHolder holder, int position) {
CallLogModel callLog = callLogList.get(position); final CallLogModel callLog = callLogList.get(position);
holder.phoneNumber.setText(callLog.getPhoneNumber()); holder.phoneNumber.setText(callLog.getPhoneNumber());
holder.callStatus.setText(callLog.getCallStatus()); holder.callStatus.setText(callLog.getCallStatus());
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
holder.callDate.setText(dateFormat.format(callLog.getCallDate())); 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 @Override
@ -49,12 +64,15 @@ public class CallLogAdapter extends RecyclerView.Adapter<CallLogAdapter.CallLogV
public class CallLogViewHolder extends RecyclerView.ViewHolder { public class CallLogViewHolder extends RecyclerView.ViewHolder {
TextView phoneNumber, callStatus, callDate; TextView phoneNumber, callStatus, callDate;
Button dialButton;
public CallLogViewHolder(@NonNull View itemView) { public CallLogViewHolder(@NonNull View itemView) {
super(itemView); super(itemView);
phoneNumber = itemView.findViewById(R.id.phone_number); phoneNumber = itemView.findViewById(R.id.phone_number);
callStatus = itemView.findViewById(R.id.call_status); callStatus = itemView.findViewById(R.id.call_status);
callDate = itemView.findViewById(R.id.call_date); callDate = itemView.findViewById(R.id.call_date);
dialButton = itemView.findViewById(R.id.dial_button);
} }
} }
} }

View File

@ -6,7 +6,6 @@ package cc.winboll.studio.contacts.adapters;
* @Describe ContactAdapter * @Describe ContactAdapter
*/ */
import android.content.Intent; import android.content.Intent;
import android.net.Uri;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -16,12 +15,14 @@ import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import cc.winboll.studio.contacts.R; import cc.winboll.studio.contacts.R;
import cc.winboll.studio.contacts.beans.ContactModel; import cc.winboll.studio.contacts.beans.ContactModel;
import com.hjq.toast.ToastUtils;
import java.util.List; import java.util.List;
public class ContactAdapter extends RecyclerView.Adapter<ContactAdapter.ContactViewHolder> { public class ContactAdapter extends RecyclerView.Adapter<ContactAdapter.ContactViewHolder> {
public static final String TAG = "ContactAdapter"; public static final String TAG = "ContactAdapter";
private static final int REQUEST_CALL_PHONE = 1;
private List<ContactModel> contactList; private List<ContactModel> contactList;
@ -45,8 +46,12 @@ public class ContactAdapter extends RecyclerView.Adapter<ContactAdapter.ContactV
holder.dialButton.setOnClickListener(new View.OnClickListener() { holder.dialButton.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
String phoneNumber = contact.getNumber(); String phoneNumber = contact.getNumber().replaceAll("\\s", "");
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + phoneNumber)); 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); holder.itemView.getContext().startActivity(intent);
} }
}); });

View File

@ -16,7 +16,7 @@ public class CallLogModel {
private Date callDate; private Date callDate;
public CallLogModel(String phoneNumber, String callStatus, Date callDate) { public CallLogModel(String phoneNumber, String callStatus, Date callDate) {
this.phoneNumber = phoneNumber; this.phoneNumber = phoneNumber.replaceAll("\\s", "");
this.callStatus = callStatus; this.callStatus = callStatus;
this.callDate = callDate; this.callDate = callDate;
} }

View File

@ -21,7 +21,7 @@ public class ContactModel {
public ContactModel(String name, String number) { public ContactModel(String name, String number) {
this.name = name; this.name = name;
this.number = number; this.number = number.replaceAll("\\s", "");
this.pinyin = convertToPinyin(name); this.pinyin = convertToPinyin(name);
} }
@ -33,7 +33,7 @@ public class ContactModel {
StringBuilder pinyin = new StringBuilder(); StringBuilder pinyin = new StringBuilder();
for (int i = 0; i < chinese.length(); i++) { for (int i = 0; i < chinese.length(); i++) {
char ch = chinese.charAt(i); char ch = chinese.charAt(i);
if (Character.toString(ch).matches("[\\u4e00 - \\u9fa5]")) { if (Character.toString(ch).matches("[\\u4e00-\\u9fa5]")) {
try { try {
String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(ch, format); String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(ch, format);
if (pinyinArray != null) { if (pinyinArray != null) {

View File

@ -6,6 +6,7 @@ package cc.winboll.studio.contacts.fragments;
* @Describe 联系人 * @Describe 联系人
*/ */
import android.Manifest; import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.database.Cursor; import android.database.Cursor;
import android.os.Bundle; import android.os.Bundle;
@ -15,6 +16,7 @@ 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.Button;
import android.widget.EditText; import android.widget.EditText;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@ -25,9 +27,11 @@ 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.adapters.ContactAdapter;
import cc.winboll.studio.contacts.beans.ContactModel; import cc.winboll.studio.contacts.beans.ContactModel;
import com.hjq.toast.ToastUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; 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";
@ -93,6 +97,21 @@ public class ContactsFragment extends Fragment {
} else { } else {
readContacts(); 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 @Override

View File

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

View File

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

View File

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

View File

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

View File

@ -1,21 +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">
<EditText <LinearLayout
android:id="@+id/search_edit_text" android:orientation="horizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content">
android:hint="Search contacts"
android:padding="16dp"/>
<androidx.recyclerview.widget.RecyclerView <EditText
android:id="@+id/contacts_recycler_view" android:id="@+id/search_edit_text"
android:layout_width="match_parent" android:layout_width="0dp"
android:layout_height="match_parent"/> 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"/>
</LinearLayout> </LinearLayout>

View File

@ -27,6 +27,13 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textSize="14sp" android:textSize="14sp"
android:layout_marginTop="4dp" /> 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> </LinearLayout>

View File

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