Xamarin.Android实现自动拨打及挂断电话的功能

目录

  • 1、说明
  • 2、具体实现
    • 2.1 效果
    • 2.2 原理说明
    • 2.3 具体代码实现
      • 2.3.1 layout
      • 2.3.3 广播接收器
      • 2.3.3 拨打电话的Activity
      • 2.3.4 主界面Activity
  • 3、代码下载
  • 4、参考资料

1、说明

这几天刚刚整理了两篇文章:Xamarin.Android实现拨打电话的功能 和 Xamarin.Android实现闹钟的功能。就和apple-pen的故事一样,于是两篇文章又攒出一个新的:定时打电话功能

本篇纯属技术交流,请务必正确使用。

2、具体实现

2.1 效果

Xamarin.Android实现自动拨打及挂断电话的功能_第1张图片

2.2 原理说明

先定义一个广播接收器,监听闹钟的状态。当闹钟到点后,广播接收器接收到信息,于是启动拨打电话的activity(本篇中的PhoneActivity),在PhoneActivity中启用电话监听器(PhoneStateListener),当发现电话已接通时,进行如下动作:关闭电话、关闭PhoneActivity。然后继续循环以上。

2.3 具体代码实现

2.3.1 layout


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

2.3.3 广播接收器

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); //开启新活动,进行拨打电话
        }
    }
}

2.3.3 拨打电话的Activity

完成电话的拨打和挂断

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

    }
}

2.3.4 主界面Activity

主要完成权限判断,并启动闹钟

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

    }
}

3、代码下载

代码下载

4、参考资料

1、主要参考了这篇
2、这个是如何监听电话状态的
3、广播接收器的官网材料
4、如何通过程序停掉电话

你可能感兴趣的:(Xamarin,Xamarin.Android,自动拨打电话)