我在应用中使用了广播接收器,在通话断开后,可以通过该接收器获得每次来电的电话号码。在android Pie下所有工作都很好。我想在通话中断后立即得到号码。但是在Android Pie中,它没有获取电话号码。始终为null。所有其他版本都运行良好。搜索之后,我发现我必须授予READ_CALL_LOG的运行时权限。所以我做到了。但是什么都没有改变。它不适用于android Pie。 这是我的代码的简介:
清单:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ttff.phonemanager">
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_CALL_LOG"/>
<uses-permission android:name="android.permission.WRITE_CALL_LOG"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.ACTION_MANAGE_OVERLAY_PERMISSION" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="@drawable/calllogo"
android:label="@string/app_name"
android:roundIcon="@drawable/calllogo"
android:supportsRtl="true"
android:usesCleartextTraffic="true"
android:theme="@style/AppTheme">
<activity android:name="com.ttff.phonemanager.activities.IgnoredNumbersActivity"/>
<activity android:name="com.ttff.phonemanager.activities.IContactsActivity" />
<activity android:name="com.ttff.phonemanager.activities.SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.ttff.phonemanager.activities.CategoryPhoneActivity" />
<activity
android:name="com.ttff.phonemanager.activities.LogsActivity"
android:label="@string/title_activity_logs"
android:theme="@style/AppTheme.NoActionBar" />
<activity
android:name="com.ttff.phonemanager.activities.CategoryActivity"
android:label="@string/title_activity_category"
android:theme="@style/AppTheme.NoActionBar" />
<activity android:name="com.ttff.phonemanager.MainActivity" />
<receiver
android:name="com.ttff.phonemanager.callhelpers.CallReciever"
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
我的BroastCast接收器类:
public abstract class PhoneCallReceiver extends BroadcastReceiver {
private static int lastState = TelephonyManager.CALL_STATE_IDLE;
private static Date callStartTime;
private static boolean isIncoming;
private static String savedNumber;
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL")) {
savedNumber = intent.getExtras().getString("android.intent.extra.PHONE_NUMBER");
}
else{
String stateStr = intent.getExtras().getString(TelephonyManager.EXTRA_STATE);
String number = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
int state = 0;
if(stateStr.equals(TelephonyManager.EXTRA_STATE_IDLE)){
state = TelephonyManager.CALL_STATE_IDLE;
}
else if(stateStr.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)){
state = TelephonyManager.CALL_STATE_OFFHOOK;
}
else if(stateStr.equals(TelephonyManager.EXTRA_STATE_RINGING)){
state = TelephonyManager.CALL_STATE_RINGING;
}
onCallStateChanged(context, state, number);
}
}
protected void onIncomingCallStarted(Context ctx, String number, Date start){}
protected void onOutgoingCallStarted(Context ctx, String number, Date start){}
protected void onIncomingCallEnded(Context ctx, String number, Date start, Date end){}
protected void onOutgoingCallEnded(Context ctx, String number, Date start, Date end){}
protected void onMissedCall(Context ctx, String number, Date start){}
public void onCallStateChanged(Context context, int state, String number) {
if(lastState == state){
return;
}
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
isIncoming = true;
callStartTime = new Date();
savedNumber = number;
onIncomingCallStarted(context, number, callStartTime);
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
if(lastState != TelephonyManager.CALL_STATE_RINGING){
isIncoming = false;
callStartTime = new Date();
onOutgoingCallStarted(context, savedNumber, callStartTime);
}
break;
case TelephonyManager.CALL_STATE_IDLE:
if(lastState == TelephonyManager.CALL_STATE_RINGING){
onMissedCall(context, savedNumber, callStartTime);
}
else if(isIncoming){
onIncomingCallEnded(context, savedNumber, callStartTime, new Date());
}
else{
onOutgoingCallEnded(context, savedNumber, callStartTime, new Date());
}
break;
}
lastState = state;
}
}
CallReciever类别:
public class CallReciever extends PhoneCallReceiver {
DatabaseHelper databaseHelper ;
@Override
protected void onIncomingCallEnded(final Context ctx, final String number, Date start, Date end) {
SharedPreferences preferencesUnknown = PreferenceManager.getDefaultSharedPreferences(ctx);
final SharedPreferences.Editor editorUnknown = preferencesUnknown.edit();
boolean checkedUnknown = preferencesUnknown.getBoolean("checkedunknown", false);
if (checkedUnknown) {
boolean isUnknown = contactExists(ctx, number);
if (isUnknown == false) {
AlertDialog.Builder alerDialog = new AlertDialog.Builder(ctx);
alerDialog.setIcon(R.drawable.calllogo);
alerDialog.setTitle(number);
alerDialog.setMessage("Save this number ?");
alerDialog.setCancelable(false);
alerDialog.setPositiveButton("YES", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(ctx, CategoryPhoneActivity.class);
intent.putExtra("Phone", number);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ctx.startActivity(intent);
}
});
alerDialog.setNegativeButton("NO", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
AlertDialog aldialog = alerDialog.create();
aldialog.setCanceledOnTouchOutside(false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
aldialog.getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY); } else {
aldialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
}
aldialog.show(); } else {
Toast.makeText(ctx, "Number is already saved", Toast.LENGTH_SHORT).show(); }
}else{
AlertDialog.Builder alerDialog = new AlertDialog.Builder(ctx);
alerDialog.setTitle(number);
alerDialog.setMessage("Save this number ?");
alerDialog.setPositiveButton("YES", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(ctx, CategoryPhoneActivity.class);
intent.putExtra("Phone", number);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ctx.startActivity(intent);
}
});
AlertDialog aldialog = alerDialog.create();
aldialog.setCanceledOnTouchOutside(false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
aldialog.getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY); } else {
aldialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
}
aldialog.show(); }
}
MainActivity中的权限:
private void requestCallLogPermission() {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_CALL_LOG)){
new AlertDialog.Builder(this).setTitle("Permission Needed")
.setMessage("This permission is needed by App to work properly !")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(MainActivity.this, new String[] {Manifest.permission.READ_CALL_LOG},
CALL_LOG_PERMISSION);
}
}).setCancelable(false)
.create().show();
}else {
ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.READ_CALL_LOG},
CALL_LOG_PERMISSION);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch(requestCode){
case MY_PERMISSIONS_REQUEST_READ_PHONE_STATE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
}else {
return;
}
case CALL_LOG_PERMISSION:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Call Log Permission Granted !", Toast.LENGTH_SHORT).show();
}
}
}
现在请帮助某人!