Xamarin Android Реакция на входящие и исходящие звонки - PullRequest
0 голосов
/ 11 февраля 2020

Я хочу реагировать на звонки (входящие и исходящие) на устройстве. Основная проблема заключается в том, что приемник Broadcast, который отслеживает Phone.State, никогда не получает уведомления о входящих и исходящих вызовах, поэтому код для записи информации о вызовах в журнал никогда не выполняется. Я также пробовал большинство ссылок в стеке потока, относящихся к широковещательным приемникам, но ни одна из них, похоже, не работает. Вот мой текущий исходный код;

[assembly: UsesPermission(Manifest.Permission.ReadCallLog)]
[assembly: UsesPermission(Manifest.Permission.ReadPhoneNumbers)]
[assembly: UsesPermission(Manifest.Permission.ReadPhoneState)]
[assembly: UsesPermission(Manifest.Permission.ProcessOutgoingCalls)]
[assembly: UsesPermission(Manifest.Permission.ReadExternalStorage)]
[assembly: UsesPermission(Manifest.Permission.WriteExternalStorage)]
namespace IncomingOutgoingCall
{
    [Activity(Label = "@string/app_name", Theme = "@style/AppTheme", MainLauncher = true)]
    public class MainActivity : AppCompatActivity
    {

        #region Private Properties

        IncomingOutgoingBroadcastReceiver callReceiver;
        int REQUEST_PERMISSION_CODE = 1003;

        #endregion

        protected override void OnCreate(Bundle savedInstanceState)
        {

            base.OnCreate(savedInstanceState);
            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.activity_main);

            RequestPermission(Manifest.Permission.ReadPhoneState, Manifest.Permission.ProcessOutgoingCalls, Manifest.Permission.ReadPhoneNumbers, Manifest.Permission.WriteExternalStorage, Manifest.Permission.ReadExternalStorage);

            callReceiver = new IncomingOutgoingBroadcastReceiver();

            var callMonitorIntent = new Intent(ApplicationContext, typeof(IncomingOutgoingBroadcastReceiver));
            // SendBroadcast(callMonitorIntent);
        }

        public void RequestPermission(params string[] permissions)
        {
            // Request required permission
            ActivityCompat.RequestPermissions(this, permissions, REQUEST_PERMISSION_CODE);
        }

    }

    [BroadcastReceiver(Name = "com.callmonitor.app.IncomingOutgoingBroadcastReceiver", Enabled = true, Exported = false)]
    [IntentFilter(new[] { TelephonyManager.ActionPhoneStateChanged, "android.intent.action.PHONE_STATE", "android.intent.action.NEW_OUTGOING_CALL" }, Priority = (int)IntentFilterPriority.HighPriority)]
    public class IncomingOutgoingBroadcastReceiver : BroadcastReceiver
    {
        public override void OnReceive(Context context, Intent intent)
        {
            string dirPath = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath + "/" + AppInfo.Name;

            if (!Directory.Exists(dirPath))
            {
                Directory.CreateDirectory(dirPath);

                string filePath = Path.Combine(dirPath, "logFile.txt");
                if (!File.Exists(filePath))
                    File.Create(filePath);

                using (StreamWriter sw = new StreamWriter(filePath))
                {
                   // Code to register call information omitted
                }

            }
        }
    }
}

А это мой android файл манифеста

<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.callmonitor" android:installLocation="auto">
    <uses-sdk android:minSdkVersion="15" android:targetSdkVersion="27" />
    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.READ_CALL_LOG" />
    <uses-permission android:name="android.permission.READ_PHONE_NUMBERS" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_CALL_LOG" />
    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
    <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme" android:label="CallMonitor"></application>


</manifest>

Если у кого-то есть ссылка / предложение ИСПЫТАННОГО И РАБОЧЕГО РЕШЕНИЯ о том, как заставить мой Broadcast Receiver работать каждый раз, когда идет вызов, я хотел бы попробовать.

1 Ответ

0 голосов
/ 12 февраля 2020

Кажется, что это не так просто читать журналы телефонных звонков с BroadcastReceiver, лучший способ читать журналы телефонных звонков из базы данных Android через курсор.

 public IEnumerable<CallLogModel> GetCallLogs()
    {
        var phoneContacts = new List<CallLogModel>();
        // filter in desc order limit by no
        string querySorter = String.Format("{0} desc ", CallLog.Calls.Date);
        using (var phones = Android.App.Application.Context.ContentResolver.Query(CallLog.Calls.ContentUri, null, null, null, querySorter))
        {
            if (phones != null)
            {
                while (phones.MoveToNext())
                {
                    try
                    {
                        string callNumber = phones.GetString(phones.GetColumnIndex(CallLog.Calls.Number));

                        string callDuration = phones.GetString(phones.GetColumnIndex(CallLog.Calls.Duration));

                        long callDate = phones.GetLong(phones.GetColumnIndex(CallLog.Calls.Date));

                        string callName = phones.GetString(phones.GetColumnIndex(CallLog.Calls.CachedName));

                        int callTypeInt = phones.GetInt(phones.GetColumnIndex(CallLog.Calls.Type));
                        string callType = Enum.GetName(typeof(CallType), callTypeInt);                           
                        var log = new CallLogModel();
                        log.CallName = callName;
                        log.CallNumber = callNumber;
                        log.CallDuration = callDuration;
                        log.CallDateTick = callDate;
                        log.CallType = callType;
                        phoneContacts.Add(log);
                    }
                    catch (Exception ex)
                    {
                        //something wrong with one contact, may be display name is completely empty, decide what to do
                    }
                }
                phones.Close();
            }
            // if we get here, we can't access the contacts. Consider throwing an exception to display to the user
        }
        return phoneContacts;
    }

Это пример что вы можете посмотреть:

https://github.com/xcomar/Xamarin.CallLog/tree/master/App1

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...