Commit fec8a048 authored by Evan W. Patton's avatar Evan W. Patton Committed by Jeffrey Schiller

Add READ_CALL_LOG permission for Android 9

Change-Id: I891d1c6f1be8cab5981c11d43aa4b80755084148
parent 4da346ef
...@@ -6,8 +6,17 @@ ...@@ -6,8 +6,17 @@
package com.google.appinventor.components.runtime; package com.google.appinventor.components.runtime;
import static android.Manifest.permission.CALL_PHONE;
import static android.Manifest.permission.PROCESS_OUTGOING_CALLS;
import static android.Manifest.permission.READ_CALL_LOG;
import static android.Manifest.permission.READ_PHONE_STATE;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri; import android.net.Uri;
import android.util.Log; import android.telephony.TelephonyManager;
import com.google.appinventor.components.annotations.DesignerComponent; import com.google.appinventor.components.annotations.DesignerComponent;
import com.google.appinventor.components.annotations.DesignerProperty; import com.google.appinventor.components.annotations.DesignerProperty;
import com.google.appinventor.components.annotations.PropertyCategory; import com.google.appinventor.components.annotations.PropertyCategory;
...@@ -22,13 +31,6 @@ import com.google.appinventor.components.common.YaVersion; ...@@ -22,13 +31,6 @@ import com.google.appinventor.components.common.YaVersion;
import com.google.appinventor.components.runtime.util.BulkPermissionRequest; import com.google.appinventor.components.runtime.util.BulkPermissionRequest;
import com.google.appinventor.components.runtime.util.PhoneCallUtil; import com.google.appinventor.components.runtime.util.PhoneCallUtil;
import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.telephony.TelephonyManager;
/** /**
* Component for making a phone call to a programatically-specified number. * Component for making a phone call to a programatically-specified number.
* *
...@@ -58,9 +60,8 @@ import android.telephony.TelephonyManager; ...@@ -58,9 +60,8 @@ import android.telephony.TelephonyManager;
nonVisible = true, nonVisible = true,
iconName = "images/phoneCall.png") iconName = "images/phoneCall.png")
@SimpleObject @SimpleObject
public class PhoneCall extends AndroidNonvisibleComponent implements Component, OnDestroyListener, ActivityResultListener { public class PhoneCall extends AndroidNonvisibleComponent implements Component, OnDestroyListener,
ActivityResultListener {
private static final String LOG_TAG = PhoneCall.class.getSimpleName();
/** /**
* Magic number "PHON" used to report when a phone call has been initiated * Magic number "PHON" used to report when a phone call has been initiated
...@@ -88,9 +89,9 @@ public class PhoneCall extends AndroidNonvisibleComponent implements Component, ...@@ -88,9 +89,9 @@ public class PhoneCall extends AndroidNonvisibleComponent implements Component,
@SuppressWarnings({"unused"}) @SuppressWarnings({"unused"})
public void Initialize() { public void Initialize() {
if (form.doesAppDeclarePermission(Manifest.permission.PROCESS_OUTGOING_CALLS)) { if (form.doesAppDeclarePermission(READ_CALL_LOG)) {
form.askPermission(new BulkPermissionRequest(this, "Initialize", form.askPermission(new BulkPermissionRequest(this, "Initialize",
Manifest.permission.PROCESS_OUTGOING_CALLS, Manifest.permission.READ_PHONE_STATE) { PROCESS_OUTGOING_CALLS, READ_PHONE_STATE, READ_CALL_LOG) {
@Override @Override
public void onGranted() { public void onGranted() {
registerCallStateMonitor(); registerCallStateMonitor();
...@@ -113,8 +114,7 @@ public class PhoneCall extends AndroidNonvisibleComponent implements Component, ...@@ -113,8 +114,7 @@ public class PhoneCall extends AndroidNonvisibleComponent implements Component,
* *
* @param phoneNumber a phone number to call * @param phoneNumber a phone number to call
*/ */
@DesignerProperty(editorType = PropertyTypeConstants.PROPERTY_TYPE_STRING, @DesignerProperty(editorType = PropertyTypeConstants.PROPERTY_TYPE_STRING)
defaultValue = "")
@SimpleProperty @SimpleProperty
public void PhoneNumber(String phoneNumber) { public void PhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber; this.phoneNumber = phoneNumber;
...@@ -134,12 +134,12 @@ public class PhoneCall extends AndroidNonvisibleComponent implements Component, ...@@ -134,12 +134,12 @@ public class PhoneCall extends AndroidNonvisibleComponent implements Component,
/** /**
* Makes a phone call using the number in the PhoneNumber property. * Makes a phone call using the number in the PhoneNumber property.
*/ */
@UsesPermissions(Manifest.permission.CALL_PHONE) @UsesPermissions(CALL_PHONE)
@SimpleFunction @SimpleFunction
public void MakePhoneCallDirect() { public void MakePhoneCallDirect() {
// Check that we have permission and ask for it if we don't // Check that we have permission and ask for it if we don't
if (!havePermission) { if (!havePermission) {
form.askPermission(Manifest.permission.CALL_PHONE, form.askPermission(CALL_PHONE,
new PermissionResultHandler() { new PermissionResultHandler() {
@Override @Override
public void HandlePermissionResponse(String permission, boolean granted) { public void HandlePermissionResponse(String permission, boolean granted) {
...@@ -147,8 +147,7 @@ public class PhoneCall extends AndroidNonvisibleComponent implements Component, ...@@ -147,8 +147,7 @@ public class PhoneCall extends AndroidNonvisibleComponent implements Component,
PhoneCall.this.havePermission = true; PhoneCall.this.havePermission = true;
PhoneCall.this.MakePhoneCallDirect(); PhoneCall.this.MakePhoneCallDirect();
} else { } else {
form.dispatchPermissionDeniedEvent(PhoneCall.this, "MakePhoneCall", form.dispatchPermissionDeniedEvent(PhoneCall.this, "MakePhoneCall", CALL_PHONE);
Manifest.permission.CALL_PHONE);
} }
} }
}); });
...@@ -170,7 +169,11 @@ public class PhoneCall extends AndroidNonvisibleComponent implements Component, ...@@ -170,7 +169,11 @@ public class PhoneCall extends AndroidNonvisibleComponent implements Component,
" If status is 1, incoming call is ringing; " + " If status is 1, incoming call is ringing; " +
"if status is 2, outgoing call is dialled. " + "if status is 2, outgoing call is dialled. " +
"phoneNumber is the incoming/outgoing phone number.") "phoneNumber is the incoming/outgoing phone number.")
@UsesPermissions({Manifest.permission.PROCESS_OUTGOING_CALLS, Manifest.permission.READ_PHONE_STATE}) @UsesPermissions({
PROCESS_OUTGOING_CALLS, // Deprecated SDK 29
READ_CALL_LOG, // minSDK 16, needed on SDK 29
READ_PHONE_STATE
})
public void PhoneCallStarted(int status, String phoneNumber) { public void PhoneCallStarted(int status, String phoneNumber) {
// invoke the application's "PhoneCallStarted" event handler. // invoke the application's "PhoneCallStarted" event handler.
EventDispatcher.dispatchEvent(this, "PhoneCallStarted", status, phoneNumber); EventDispatcher.dispatchEvent(this, "PhoneCallStarted", status, phoneNumber);
...@@ -178,9 +181,11 @@ public class PhoneCall extends AndroidNonvisibleComponent implements Component, ...@@ -178,9 +181,11 @@ public class PhoneCall extends AndroidNonvisibleComponent implements Component,
/** /**
* Event indicating that a phone call has ended. * Event indicating that a phone call has ended.
* status: 1:incoming call is missed or rejected; 2:incoming call is answered before hanging up; 3:Outgoing call is hung up. * status: 1:incoming call is missed or rejected; 2:incoming call is answered before hanging up;
* 3:Outgoing call is hung up.
* *
* @param status 1:incoming call is missed or rejected; 2:incoming call is answered before hanging up; 3:Outgoing call is hung up. * @param status 1:incoming call is missed or rejected; 2:incoming call is answered before
* hanging up; 3:Outgoing call is hung up.
* @param phoneNumber ended call phone number * @param phoneNumber ended call phone number
*/ */
@SimpleEvent( @SimpleEvent(
...@@ -190,7 +195,11 @@ public class PhoneCall extends AndroidNonvisibleComponent implements Component, ...@@ -190,7 +195,11 @@ public class PhoneCall extends AndroidNonvisibleComponent implements Component,
"if status is 2, incoming call is answered before hanging up; " + "if status is 2, incoming call is answered before hanging up; " +
"if status is 3, outgoing call is hung up. " + "if status is 3, outgoing call is hung up. " +
"phoneNumber is the ended call phone number.") "phoneNumber is the ended call phone number.")
@UsesPermissions({Manifest.permission.PROCESS_OUTGOING_CALLS, Manifest.permission.READ_PHONE_STATE}) @UsesPermissions({
PROCESS_OUTGOING_CALLS, // Deprecated SDK 29
READ_CALL_LOG, // minSDK 16, needed on SDK 29
READ_PHONE_STATE,
})
public void PhoneCallEnded(int status, String phoneNumber) { public void PhoneCallEnded(int status, String phoneNumber) {
// invoke the application's "PhoneCallEnded" event handler. // invoke the application's "PhoneCallEnded" event handler.
EventDispatcher.dispatchEvent(this, "PhoneCallEnded", status, phoneNumber); EventDispatcher.dispatchEvent(this, "PhoneCallEnded", status, phoneNumber);
...@@ -205,7 +214,11 @@ public class PhoneCall extends AndroidNonvisibleComponent implements Component, ...@@ -205,7 +214,11 @@ public class PhoneCall extends AndroidNonvisibleComponent implements Component,
description = description =
"Event indicating that an incoming phone call is answered. " + "Event indicating that an incoming phone call is answered. " +
"phoneNumber is the incoming call phone number.") "phoneNumber is the incoming call phone number.")
@UsesPermissions({Manifest.permission.PROCESS_OUTGOING_CALLS, Manifest.permission.READ_PHONE_STATE}) @UsesPermissions({
PROCESS_OUTGOING_CALLS, // Deprecated SDK 29
READ_CALL_LOG, // minSDK 16, needed on SDK 29
READ_PHONE_STATE,
})
public void IncomingCallAnswered(String phoneNumber) { public void IncomingCallAnswered(String phoneNumber) {
// invoke the application's "IncomingCallAnswered" event handler. // invoke the application's "IncomingCallAnswered" event handler.
EventDispatcher.dispatchEvent(this, "IncomingCallAnswered", phoneNumber); EventDispatcher.dispatchEvent(this, "IncomingCallAnswered", phoneNumber);
...@@ -223,7 +236,8 @@ public class PhoneCall extends AndroidNonvisibleComponent implements Component, ...@@ -223,7 +236,8 @@ public class PhoneCall extends AndroidNonvisibleComponent implements Component,
* *
*/ */
private class CallStateReceiver extends BroadcastReceiver { private class CallStateReceiver extends BroadcastReceiver {
private int status; // 0:undetermined, 1:incoming ringed, 2:outgoing dialled, 3: incoming answered private int status; // 0:undetermined, 1:incoming ringed, 2:outgoing dialled,
// 3: incoming answered
private String number; // phone call number private String number; // phone call number
public CallStateReceiver() { public CallStateReceiver() {
status = 0; status = 0;
...@@ -239,6 +253,11 @@ public class PhoneCall extends AndroidNonvisibleComponent implements Component, ...@@ -239,6 +253,11 @@ public class PhoneCall extends AndroidNonvisibleComponent implements Component,
// Incoming call rings // Incoming call rings
status = 1; status = 1;
number = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER); number = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
if (number == null) {
// This gets called first with null, then with the actual number.
// Ignore the first invocation.
return;
}
PhoneCallStarted(1, number); PhoneCallStarted(1, number);
}else if(TelephonyManager.EXTRA_STATE_OFFHOOK.equals(state)){ }else if(TelephonyManager.EXTRA_STATE_OFFHOOK.equals(state)){
// Call off-hook // Call off-hook
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment