这几天刚刚整理了两篇文章:Xamarin.Android实现拨打电话的功能 和 Xamarin.Android实现闹钟的功能。就和apple-pen的故事一样,于是两篇文章又攒出一个新的:定时打电话功能
本篇纯属技术交流,请务必正确使用。
先定义一个广播接收器,监听闹钟的状态。当闹钟到点后,广播接收器接收到信息,于是启动拨打电话的activity
(本篇中的PhoneActivity
),在PhoneActivity
中启用电话监听器(PhoneStateListener
),当发现电话已接通时,进行如下动作:关闭电话、关闭PhoneActivity
。然后继续循环以上。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="@+id/phoneNumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="28dp"
android:textSize="25dp"
android:textStyle="bold"
android:ems="10"
android:hint="设置要呼叫的电话号码"
android:inputType="phone" />
<EditText
android:id="@+id/timeTxt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="28dp"
android:textSize="25dp"
android:textStyle="bold"
android:layout_below="@+id/phoneNumber"
android:ems="10"
android:hint="设置当前时间几秒后开始"
android:inputType="numberDecimal" />
<EditText
android:id="@+id/initTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="28dp"
android:textSize="25dp"
android:textStyle="bold"
android:layout_below="@+id/timeTxt"
android:ems="10"
android:hint="设置间隔(请>=60)秒"
android:inputType="numberDecimal" />
<Button
android:id="@+id/startBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="60dp"
android:layout_marginTop="240dp"
android:text="开始" />
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:minWidth="25px"
android:minHeight="25px"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:id="@+id/coordinatorLayout1" />
RelativeLayout>
using Android.Content;
using Android.Widget;
namespace AlarmDemo
{
[BroadcastReceiver]
public class MyReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
Intent phoneIntent = new Intent(context, typeof(PhoneActivity));
phoneIntent.AddFlags(ActivityFlags.NewTask); //新开一个线程承载活动
phoneIntent.PutExtra("phoneNumber", intent.GetStringExtra("phoneNumber"));
context.StartActivity(phoneIntent); //开启新活动,进行拨打电话
}
}
}
完成电话的拨打和挂断
using Android.App;
using Android.Content;
using Android.OS;
using Android.Telephony;
using Android.Widget;
using System;
using System.Threading;
namespace AlarmDemo
{
[Activity(Label = "PhoneActivity")]
public class PhoneActivity : Activity
{
private Android.Telecom.TelecomManager telecomManager = null;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Create your application here
//参数初始化
//关掉电话的manager
telecomManager = (Android.Telecom.TelecomManager)GetSystemService(Context.TelecomService);
//调用系统方法(监听电话状态)
MyPhoneStateListener phoneStateListener = new MyPhoneStateListener(telecomManager,this);
TelephonyManager telephonyManager = (TelephonyManager)GetSystemService(Context.TelephonyService);
telephonyManager.Listen(phoneStateListener, PhoneStateListenerFlags.CallState);
try {
var intent = new Intent(Intent.ActionCall);
intent.SetData(Android.Net.Uri.Parse("tel:" + Intent.GetStringExtra("phoneNumber")));
StartActivity(intent);
}
catch(Exception ex)
{
Toast.MakeText(this, ex.Message, ToastLength.Long).Show();
}
}
}
public class MyPhoneStateListener : PhoneStateListener
{
private Android.Telecom.TelecomManager v_telecomManager;
private PhoneActivity v_phoneActivity;
public MyPhoneStateListener(Android.Telecom.TelecomManager v_telecomManager, PhoneActivity phoneActivity)
{
this.v_telecomManager = v_telecomManager;
this.v_phoneActivity = phoneActivity;
}
public override void OnCallStateChanged(CallState state, string incomingNumber)
{
base.OnCallStateChanged(state, incomingNumber);
switch (state)
{
case CallState.Offhook: //若电话接通了,则进行挂断
Thread.Sleep(3000);
this.v_telecomManager.EndCall(); //关闭电话
v_phoneActivity.Finish();
break;
default:
break;
}
}
}
}
主要完成权限判断,并启动闹钟
using Android;
using Android.App;
using Android.Content;
using Android.Content.PM;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using AndroidX.AppCompat.App;
using AndroidX.CoordinatorLayout.Widget;
using AndroidX.Core.App;
using Google.Android.Material.Snackbar;
using Java.Lang;
using System;
namespace AlarmDemo
{
[Activity(Label = "@string/app_name", Theme = "@style/AppTheme", MainLauncher = true)]
public class MainActivity : AppCompatActivity
{
//DECLARE WIDGETS
private Button startBtn;
private EditText timeTxt,internalTxt,phoneNumberTxt;
private CoordinatorLayout coordinatorLayout;
private const int REQUEST_CALL = 1,STOP_CALL=2, ALL_ALLOW=3;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
this.initializeViews();
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode== ALL_ALLOW)
{
if ((grantResults.Length == 2) && (grantResults[0] == Permission.Granted) && (grantResults[1] == Permission.Granted))
{
go();//调用拨打电话的具体方法
}
else
{
Snackbar.Make(coordinatorLayout, "用户未能授予拨打电话的权限", Snackbar.LengthShort).Show();
}
}
else
{
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
private void initializeViews()
{
timeTxt = FindViewById<EditText>(Resource.Id.timeTxt);
internalTxt = FindViewById<EditText>(Resource.Id.initTime);
phoneNumberTxt = FindViewById<EditText>(Resource.Id.phoneNumber);
startBtn = FindViewById<Button>(Resource.Id.startBtn);
coordinatorLayout= FindViewById<CoordinatorLayout>(Resource.Id.coordinatorLayout1);
startBtn.Click += startBtn_Click;
}
void startBtn_Click(object sender, EventArgs e)
{
//checkPermission(this, "是否授予拨打电话的权限?", Manifest.Permission.CallPhone, REQUEST_CALL);
checkPermission();
}
private void go()
{
//获取界面设置
int time = Convert.ToInt32(timeTxt.Text);
int intervalTime = Convert.ToInt32(internalTxt.Text);
string phoneNulber = phoneNumberTxt.Text;
Intent i = new Intent(this, typeof(MyReceiver));
i.PutExtra("phoneNumber", phoneNulber);
PendingIntent pi = PendingIntent.GetBroadcast(this, 0, i, 0);
AlarmManager alarmManager = (AlarmManager)GetSystemService(AlarmService);
//设置间隔
alarmManager.SetRepeating(AlarmType.RtcWakeup, JavaSystem.CurrentTimeMillis() + (time * 1000), intervalTime*1000, pi);
Toast.MakeText(this, "闹钟将在 " + time + " 秒之后启动!并间隔 "+ intervalTime+" 秒重复运行!", ToastLength.Short).Show();
}
private void checkPermission(Activity activity, string tips, string permission, int permission_code)
{
if (ActivityCompat.ShouldShowRequestPermissionRationale(activity, permission))
{
var requiredPermissions = new System.String[] { permission };
Snackbar.Make(coordinatorLayout, tips, Snackbar.LengthIndefinite)
.SetAction("同意授权",
new Action<View>(delegate (View obj)
{
ActivityCompat.RequestPermissions(this, requiredPermissions, permission_code);
})
).Show();
}
else
{
var requiredPermissions = new System.String[] { permission };
ActivityCompat.RequestPermissions(this, requiredPermissions, permission_code);
}
}
private void checkPermission()
{
if (ActivityCompat.ShouldShowRequestPermissionRationale(this, Manifest.Permission.CallPhone))
{
var requiredPermissions = new System.String[] { Manifest.Permission.CallPhone };
Snackbar.Make(coordinatorLayout, "是否授予拨打电话的权限?", Snackbar.LengthIndefinite)
.SetAction("同意授权",
new Action<View>(delegate (View obj)
{
ActivityCompat.RequestPermissions(this, requiredPermissions, REQUEST_CALL);
})
).Show();
}else if (ActivityCompat.ShouldShowRequestPermissionRationale(this, Manifest.Permission.AnswerPhoneCalls))
{
var requiredPermissions = new System.String[] { Manifest.Permission.AnswerPhoneCalls };
Snackbar.Make(coordinatorLayout, "是否授予拨打电话的权限?", Snackbar.LengthIndefinite)
.SetAction("同意授权",
new Action<View>(delegate (View obj)
{
ActivityCompat.RequestPermissions(this, requiredPermissions, STOP_CALL);
})
).Show();
}
else
{
var requiredPermissions = new System.String[] { Manifest.Permission.CallPhone, Manifest.Permission.AnswerPhoneCalls };
ActivityCompat.RequestPermissions(this, requiredPermissions, ALL_ALLOW);
}
}
}
}
代码下载
1、主要参考了这篇
2、这个是如何监听电话状态的
3、广播接收器的官网材料
4、如何通过程序停掉电话