android - 广播接收器不能在 android oreo 中工作

标签 android broadcastreceiver android-8.0-oreo

我的广播接收器无法在 oreo 上工作,但它在 oreo 下工作正常,我对此进行了很多搜索,但找不到合适的解决方案。有没有人遇到同样的问题,这是我关于我的广播服务的代码。请建议我如何在奥利奥工作。

这是类

public int onStartCommand(Intent intent, int flags, int startId) {
        mContext = this;
        mAppPreferences = new AppPreferences(mContext);
        if (intent.getExtras() != null) {
            data = (String) intent.getExtras().get("showPopUp");
            phoneNumber= (String) intent.getExtras().get("dialNumber");
        }
        final IntentFilter intentFilter = new IntentFilter();
        if (data.equalsIgnoreCase("true")) {
            showPopup(getApplicationContext());
            Utils.ApiHit(phoneNumber,getApplicationContext());
        }
        intentFilter.setPriority(2147483647);
        intentFilter.addAction("android.intent.action.PHONE_STATE");
        callExplicitReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (intent.getAction().equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) {
                    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);
                        phoneNumber = 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, phoneNumber);
                    }
                }
            }
        };
        mContext.registerReceiver(callExplicitReceiver, intentFilter);
        return START_NOT_STICKY;
    }


    public void onIncomingCallReceived(Context ctx, String number, Date start) {
    }

    public void onIncomingCallAnswered(Context ctx, String number, Date start) {
        if (popupView.getVisibility() == View.GONE) {
            popupView.setVisibility(View.VISIBLE);
        }
    }

    public void onIncomingCallEnded(Context ctx, String number, Date start, Date end) {

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                DeleteCallLogByNumber(number);
            }
        }, 2000);
        if (popupView.getVisibility() == View.VISIBLE) {
            popupView.setVisibility(View.GONE);
        }
    }

    public void onOutgoingCallStarted(Context ctx, String number, Date start) {
//        mAppPreferences.setPrefrenceString("busy", "yes");
//        if (data.equalsIgnoreCase("true")) {
            mediaPlayer = MediaPlayer.create(ctx, R.raw.speech_audio);
//        } else {
//            mediaPlayer = MediaPlayer.create(ctx, R.raw.speech_audio);
//        }

        mediaPlayer.start();
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                if (mediaPlayer != null && mediaPlayer.isPlaying()) {
                    mediaPlayer.stop();
                    mediaPlayer.release();
                }
            }
        }, 12000);
        if (popupView.getVisibility() == View.GONE) {
            popupView.setVisibility(View.VISIBLE);
        }
    }


    public void onOutgoingCallEnded(Context ctx, String number, Date start, Date end) {
        mAppPreferences.setPrefrenceString("busy", "no");
        if (mediaPlayer != null && mediaPlayer.isPlaying()) {
            mediaPlayer.stop();
            mediaPlayer.release();
            mediaPlayer = null;
        }
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                DeleteCallLogByNumber(phoneNumber);
            }
        }, 2000);
        if (popupView.getVisibility() == View.VISIBLE) {
            popupView.setVisibility(View.GONE);
        }
    }

    public void onMissedCall(Context ctx, String number, Date start) {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                DeleteCallLogByNumber(phoneNumber);
            }
        }, 2000);
        if (popupView.getVisibility() == View.VISIBLE) {
            popupView.setVisibility(View.GONE);
        }
    }




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;
                onIncomingCallReceived(context, number, callStartTime);
                break;
            case TelephonyManager.CALL_STATE_OFFHOOK:
                if (lastState != TelephonyManager.CALL_STATE_RINGING) {
                    isIncoming = false;
                    callStartTime = new Date();
                    onOutgoingCallStarted(context, savedNumber, callStartTime);
                } else {
                    isIncoming = true;
                    callStartTime = new Date();
                    onIncomingCallAnswered(context, savedNumber, callStartTime);
                }
                break;
            case TelephonyManager.CALL_STATE_IDLE:
                if (popupView.getVisibility() == View.VISIBLE) {
                    popupView.setVisibility(View.GONE);
                }
                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;
    }

    @Override
    public void onDestroy() {
        mContext.unregisterReceiver(callExplicitReceiver);
    }

注意是在接收者内部,任何人都可以帮我解决这个问题吗?

根据讨论添加的新内容

list 数据:-

使用权限 :-

 <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

接收者:-

<receiver android:name="com.example.dialer.AppUtils.StartUpBootReceiver" android:enabled="true" android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>

我的广播接收器类:-

public class StartUpBootReceiver extends BroadcastReceiver {

    private Context mContext;

    @Override
    public void onReceive(Context context, Intent intent) {
        mContext= context;
        String action = "START";

        if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
            {
                context.startForegroundService(new Intent(context, PhoneStateService.class));
            }
            else
            {
                context.startService(new Intent(context, PhoneStateService.class));
            }
        }
    }


    private boolean isServiceRunning(Class<?> serviceClass) {
        ActivityManager manager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
        for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
            if (serviceClass.getName().equals(service.service.getClassName())) {
                return true;
            }
        }
        return false;
    }
}

休息,同样的服务会接到电话,但问题是我仍然没有接到接收器的电话。主要的一点是,服务应该只在用户点击按钮后被调用,而不是自动调用,因为我必须通过一些服务中的值(value)。

谢谢

最佳答案

广播限制

如果应用程序注册接收广播,则每次发送广播时应用程序的接收器都会消耗资源。如果太多应用程序注册接收基于系统事件的广播,这可能会导致问题;触发广播的系统事件可能会导致所有这些应用程序快速连续地消耗资源,从而损害用户体验。为缓解此问题,Android 7.0(API 级别 25)对广播进行了限制,如后台优化中所述。 Android 8.0(API 级别 26)使这些限制更加严格。

  1. 以 Android 8.0 或更高版本为目标平台的应用无法再在其 list 中为隐式广播注册广播接收器。隐式广播是不专门针对该应用程序的广播。例如,ACTION_PACKAGE_REPLACED 是一个隐式广播,因为它被发送到所有已注册的监听器,让他们知道设备上的某些包已被替换。但是,ACTION_MY_PACKAGE_REPLACED 不是隐式广播,因为它只发送到包被替换的应用程序,无论有多少其他应用程序已经为该广播注册了监听器。

  2. 应用程序可以继续在其 list 中注册显式广播。

  3. 应用程序可以在运行时使用 Context.registerReceiver() 为任何广播注册接收器,无论是隐式还是显式。

  4. 需要签名权限的广播不受此限制,因为这些广播仅发送到使用相同证书签名的应用,而不是设备上的所有应用。

来自Official Documentation

关于android - 广播接收器不能在 android oreo 中工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51221680/

相关文章:

android - Xamarin android应用程序在使用BroadcastReceiver引导时崩溃但可以启动吗?

android - 检测传入的 SMS 消息

android - 谷歌附近的通知

android - 在 Android Kotlin 的 WebView 中加载网站 URL 之前先 Ping 网站 URL

Android:有没有办法阻止在 BootReceiver 中触发 AlarmReceiver

android - Appcelerator Titanium 是否支持 Android SDK Level 26?

带有 Google Play 商店的 Android Oreo 8.0 模拟器

android - Apk 未通过 CTS 测试 : shouldNotFIndUnexpectedIntents, 不知道为什么

java - 将卡片 View 重叠在图像上

java - RxJava 2 - 你如何只为第一次点击事件做一个 Action ,然后在事件发生后重新启动?