
اولین کار برای اینکه بتونیم به تماس های ورودی و خروجی در اندروید دسترسی داشته باشیم اضافه کردن مجوز دسترسی به تماس ها در فایل AndroidManifest.xml است :
1 2 |
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" /> |
ساخت کلاس CallReceiver :
برای دریافت تماس های ورودی و خروجی در اندروید باید یک رسیور تعریف کنیم تا حالت های مختلف تماس رو بتونیم کنترل کنیم . اسم کلاس رو CallReceiver میذارم :
1 2 3 4 5 6 |
public class CallReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { } } |
برای اینکه این کلاس رسیور ما بتونه تغییرات رو دریافت کنه باید اون رو به عنوان رسیور در فایل AndroidManifest.xml اضافه کنیم :
1 2 3 4 5 6 7 8 9 |
<receiver android:name=".CallReceiver" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="android.intent.action.PHONE_STATE" /> <action android:name="android.intent.action.NEW_OUTGOING_CALL" /> </intent-filter> </receiver> |
دوتا action برای این رسیور تعریف کردیم . این دوتا action مشخص میکنن که این رسیور چه رویدادهایی رو باید دریافت کنه یا بهشون پاسخ بده .
تماس ها در اندروید سه حالت دارند :
- در حال زنگ خودرن : Ringing
- در حال مکالمه یا جواب دادن تماس : Offhook
البته حالت Offhook برای این موارد هم اتفاق میفته : dialing, active, or on hold, and no calls are ringing or waiting
3.قطع شدن تماس یا رد تماس :Idle
برای اینکه بتونیم تشخصی بدیم که کدوم یکی از حالت های بالا اتفاق افتاده به صورت زیر عمل میکنیم :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public class CallReceiver extends BroadcastReceiver { private String currentState; @Override public void onReceive(Context context, Intent intent) { currentState = intent.getStringExtra(TelephonyManager.EXTRA_STATE); if (currentState!=null && currentState.equals(TelephonyManager.EXTRA_STATE_RINGING)){ //تلفن در حال زنگ خوردن است و کدهای خودتونو اینجا وارد کنید } if (currentState!=null && currentState.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)){ //در حال مکالمه یا تماس جواب داده شده است } if (currentState!=null && currentState.equals(TelephonyManager.EXTRA_STATE_IDLE)){ //تماس قطع شد } } } |
تشخیص تماس های خروجی با دریافت تماس های ورودی فرق داره . برای تشخصی تماس های خروجی نیاز به مجوز PROCESS_OUTGOING_CALLS در فایل AndroidManifast.xml داریم که در ابتدای این آموزش این کار رو انجام دادیم . حالا باید ببینیم که چطوری میشه فهمید که تماس خروجی گرفته شده ؟ ینی یوزر خودش با یک شماره تماس گرفته :
1 2 3 4 5 6 7 8 9 10 |
public class CallReceiver extends BroadcastReceiver { private String action; @Override public void onReceive(Context context, Intent intent) { action=intent.getAction(); if (action!=null && action.equals(Intent.ACTION_NEW_OUTGOING_CALL)) { //تو این حالت تماس خروجی رو تشخصی دادیم و میتونیم کد های خودمونو اینجا بنویسیم } } } |
از سه حالتی که برای تماس های ورودی گفتم فقط دو حالتش برای تماس خروجی قابل استفاده است و حالت Ringing برای تماس های خروجی کاربرد نداره.
حالا سوال اینجاست که چطوری بفهمیم این دو حالت برای کدوم یکی از تماس هاست ؟ مثلا وقتی حالت Idle اتفاق افتاد ینی تماس قطع شد برای تماس دریافتی بوده یا تماس خروجی ؟!
برای تشخیص این حالت باید دو نوع state تعریف کنیم ، currenState و firstState .
firstState مشخص میکنه که اولین state ی که اتفاق اتفاده چی بوده مثلا تلفن درحال زنگ خوردنه یا اینکه یوزر داره تماس میگیره .
currenState هم حالت های offhook و Idle رو مشخص میکنه .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
public class CallReceiver extends BroadcastReceiver { private static String currentState; private static String firstState; private final String OUTGOING_CALL="outgoing_call"; private final String INCOMING_CALL="incoming_call"; private String action; @Override public void onReceive(Context context, Intent intent) { action=intent.getAction(); currentState = intent.getStringExtra(TelephonyManager.EXTRA_STATE); if (action!=null && action.equals(Intent.ACTION_NEW_OUTGOING_CALL)) { firstState=OUTGOING_CALL; } if (currentState!=null && currentState.equals(TelephonyManager.EXTRA_STATE_RINGING)){ firstState=INCOMING_CALL; } if (currentState != null && firstState != null ){ if (firstState.equals(INCOMING_CALL)) { if (currentState.equals(TelephonyManager.EXTRA_STATE_RINGING)){ //تلفن در حال زنگ خوردن است و کدهای خودتونو اینجا وارد کنید } if ( currentState.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)){ //در حال مکالمه یا تماس ورودی جواب داده شده است } if (currentState.equals(TelephonyManager.EXTRA_STATE_IDLE)){ //تماس ورودی قطع شد } } if (firstState.equals(OUTGOING_CALL)) { if (currentState.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)){ //در حال زنگ خوردن ، مکالمه یا تماس خروجی جواب داده شده است } if (currentState.equals(TelephonyManager.EXTRA_STATE_IDLE)){ //تماس خروجی قطع شد } } } } |
فقط نکته ای که اینجا وجود داره اینه که برای تماس های خروجی حالت offhook از موقعی که تماس گرفته میشه اتفاق میفته و تفاوت بین جواب دادن تماس خروجی و یا در حال تماس بودن قابل تشخیص نیست .
سلام خسته نباشید . ببخشی اگه بخوایم زنگ بزنیم به کسی باید چیکارکنیم
سلام مرسی.
برای تماس گرفتن از طریق کد نویسی به صورت زیر عمل کنید :
در ضمن باید اجازه تماس رو هم تو فایل AndroidManifast.xml داده باشید .
همینطور اگه اندروید 6 به بالا باشه باید به صورت ران تایم اجازه دسترسی رو از یوزر بگیرید.
خواهش میکنم این مطالب رو به پستتون اضاف کنید
خیلی جالب و خوب نوشتین
1. اگه بخوايم کدی بنویسم که زمان مکالمه رو محاسبه کنه
و زمان رو به شماره تلفن تماس گیرنده یا تماس شونده نسبت داد
2. در آخر آماری از مکالمات با شماره رو داشته باشیم ( جمع زد مکالمات رو)
3. چطور میشه اولین تاریخ تماس و آخرین تاریخ تماس رو برای شماره مورد نظر ثبت کرد
4. و اینکه از مخاطبین نام شماره مورد نظر رو دریافت کرد
در مورد محاسبه زمان مکالمه میتونید وقتی حالت
OFFHOOK
اتفاق افتاد زمان فعلی رو ثبت کنید با استفاده از کدSystem.currentTimeMillis
و پس از اینکه تماس قطع شده یا حالتIDLE
اتفاق افتاد دوباره زمان فعلی سیستم رو ثبت کنید و با کم کردن زمان قطع از زمان شروع تماس، مدت زمان تماس رو محاسبه کنید . در مورد مخاطبین هم به زودی آموزشی تهیه میکنم.خوب درباره تماس خروجی چی؟چون فرقی بین حالت offhook و ringing نیست نمیشه ازین روش استفاده کرد که
من که متوجه منظورتون نشدم . حالت offhook که کلا با حالت ringing فرق داره و این مورد رو تو قسمت تشخیص حالت های مختلف تماس در اندروید توضیح دادم . و این که توی تماس خروجی دیگه حالت ringing وجود نداره . ولی اگه منظورتون اینه که چطور تشخیص بدین حالت offhook زمانی که تلفن داره زنگ میخوره اتفاق افتاده یا زمانی که شما دارید زنگ میزنید اتفاق اتفاده رو هم توی قسمت آخر همین آموزش توضیح دادم
سپاسگزار که سریع پاسخ دادید.من منظورم pickup کردن گوشی هنگام تماس خروجی بود.هنگامی که تماس خروجی باشه از لحظه ای که تماس شروع به گرفتن میکنه حتی اگه جوابی به تماس داده نشه یعنی گوشی برداشته نشه ، حالت off hook هست.یعنی حالت آف هوک در تماس خروجی به معنی جواب دادن و برقراری مکالمه نیست فقط اینکه یه تماسی برقرار شده رو نشون میده.من خیلی فوری به روشی احتیاج دارم که نشون بده تماسی که گوشی من میگیره پاسخ داده شده.اگه راهی هست یا من جایی اشتباه میکنم ممنون میشم بگید.
موفق باشید
درسته در تماس خروجی به این صورته که شما گفتید . برای فهمیدن این که گوشی برداشته شده وقتی که تماس میگیریم برای برنامه ای غیر از برنامه ای که به عنوان برنامه تماس پیشفرض سیستم عامل تعریف شده روش معمولی وجود نداره . و حالت offhook هم طبق گفته خود گوگل برای حالت های مختلفی اتفاق میفته که حالت هاش اینها هستن : dialing, active, or on hold, and no calls are ringing or waiting البته یک سری روش های غیر معمولی وجود داره که پیشنهاد نمیکنم . چون ممکنه توی بعضی گوشی ها کار کنه و تو بعضی… بیشتر »
ممنون که وقت گذاشتید.اگه پیدا کردید که لطف میکنید پست کنید.موفق و پیروز باشید
سلام.من دوباره مشکل خوردم…بخشید فکر میکنم شما بتونبد کمکم کنید….این مطالبی که اینجا گفتید برای اندروید ۸ و بالاتر کار نمیکنه.بدجور گیر کردم. رانتایم پرمیژن اضافه هم تا حد ممکن میخوام ندم…میتونید کمکم کنید؟
سلام . کدوم قسمتش کار نمیکنه ؟ تا اونجایی که اطلاع دارم فقط ACTION_NEW_OUTGOING_CALL برای اندروید 10 و بالاتر منسوخ شده .و اگه در حال ساخت appی برای مدیریت تماس هستید باید از api جدید android.telecom استفاده کنید . که البته این api هم از اندروید 6 به بالا به سیستم عامل اضافه شده . شاید این لینک بتونه بهتون کمک کنه