7 package com.google.appinventor.components.runtime;
9 import static android.Manifest.permission.CALL_PHONE;
10 import static android.Manifest.permission.PROCESS_OUTGOING_CALLS;
11 import static android.Manifest.permission.READ_CALL_LOG;
12 import static android.Manifest.permission.READ_PHONE_STATE;
14 import android.content.BroadcastReceiver;
15 import android.content.Context;
16 import android.content.Intent;
17 import android.content.IntentFilter;
18 import android.net.Uri;
19 import android.telephony.TelephonyManager;
61 @DesignerComponent(version = YaVersion.PHONECALL_COMPONENT_VERSION,
62 description =
"<p>A non-visible component that makes a phone call to " +
63 "the number specified in the <code>PhoneNumber</code> property, which " +
64 "can be set either in the Designer or Blocks Editor. The component " +
65 "has a <code>MakePhoneCall</code> method, enabling the program to launch " +
67 "<p>Often, this component is used with the <code>ContactPicker</code> " +
68 "component, which lets the user select a contact from the ones stored " +
69 "on the phone and sets the <code>PhoneNumber</code> property to the " +
70 "contact's phone number.</p>" +
71 "<p>To directly specify the phone number (e.g., 650-555-1212), set " +
72 "the <code>PhoneNumber</code> property to a Text with the specified " +
73 "digits (e.g., \"6505551212\"). Dashes, dots, and parentheses may be " +
74 "included (e.g., \"(650)-555-1212\") but will be ignored; spaces may " +
75 "not be included.</p>",
76 category = ComponentCategory.SOCIAL,
78 iconName =
"images/phoneCall.png")
86 private static final int PHONECALL_REQUEST_CODE = 0x50484F4E;
87 private String phoneNumber;
88 private final Context context;
89 private final CallStateReceiver callStateReceiver;
90 private boolean havePermission =
false;
91 private boolean didRegisterReceiver =
false;
99 super(container.
$form());
104 callStateReceiver =
new CallStateReceiver();
107 @SuppressWarnings({
"unused"})
111 PROCESS_OUTGOING_CALLS, READ_PHONE_STATE, READ_CALL_LOG) {
113 public void onGranted() {
114 registerCallStateMonitor();
137 this.phoneNumber = phoneNumber;
144 @
SimpleFunction(description =
"Launches the default dialer app set to start a phone call using"
145 +
"the number in the PhoneNumber property.")
147 Intent i =
new Intent(Intent.ACTION_DIAL, Uri.fromParts(
"tel",
this.phoneNumber,
null));
148 if (i.resolveActivity(
form.getPackageManager()) !=
null) {
149 form.startActivityForResult(i, PHONECALL_REQUEST_CODE);
159 @
SimpleFunction(description =
"Directly initiates a phone call using the number in the "
160 +
"PhoneNumber property.")
163 if (!havePermission) {
167 public void HandlePermissionResponse(String permission,
boolean granted) {
192 "Event indicating that a phonecall has started." +
193 " If status is 1, incoming call is ringing; " +
194 "if status is 2, outgoing call is dialled. " +
195 "phoneNumber is the incoming/outgoing phone number.")
197 PROCESS_OUTGOING_CALLS,
219 "Event indicating that a phone call has ended. " +
220 "If status is 1, incoming call is missed or rejected; " +
221 "if status is 2, incoming call is answered before hanging up; " +
222 "if status is 3, outgoing call is hung up. " +
223 "phoneNumber is the ended call phone number.")
225 PROCESS_OUTGOING_CALLS,
242 "Event indicating that an incoming phone call is answered. " +
243 "phoneNumber is the incoming call phone number.")
245 PROCESS_OUTGOING_CALLS,
256 if (requestCode == PHONECALL_REQUEST_CODE) {
265 private class CallStateReceiver
extends BroadcastReceiver {
268 private String number;
269 public CallStateReceiver() {
275 public void onReceive(Context context, Intent intent) {
276 String action = intent.getAction();
277 if(TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)){
278 String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
279 if(TelephonyManager.EXTRA_STATE_RINGING.equals(state)){
282 number = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
283 if (number ==
null) {
289 }
else if(TelephonyManager.EXTRA_STATE_OFFHOOK.equals(state)){
296 }
else if(TelephonyManager.EXTRA_STATE_IDLE.equals(state)){
301 }
else if(status == 3){
304 }
else if(status == 2){
311 }
else if(Intent.ACTION_NEW_OUTGOING_CALL.equals(action)){
314 number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
323 private void registerCallStateMonitor(){
324 IntentFilter intentFilter =
new IntentFilter();
325 intentFilter.addAction(Intent.ACTION_NEW_OUTGOING_CALL);
326 intentFilter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
327 context.registerReceiver(callStateReceiver, intentFilter);
328 didRegisterReceiver =
true;
334 private void unregisterCallStateMonitor() {
335 if (didRegisterReceiver) {
336 context.unregisterReceiver(callStateReceiver);
337 didRegisterReceiver =
false;
343 unregisterCallStateMonitor();