【问题标题】:onReceive works only once androidonReceive 仅适用于一次 android
【发布时间】:2015-12-31 15:16:29
【问题描述】:

我正在使用此代码来检测屏幕何时被锁定并调用 toast,每次屏幕被锁定时它都会起作用。但是,每当我退出应用程序时,它就会停止工作。仅当应用打开时才有效。

public class BatterySaverLiteReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
            Log.i("Check", "Screen went OFF");
            Toast.makeText(context, "screen OFF", Toast.LENGTH_LONG).show();

            task(context);
        } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
            Log.i("Check", "Screen went ON");
            Toast.makeText(context, "screen ON", Toast.LENGTH_LONG).show();
        }
    }

    private void task(Context context) {
        // Process Killer and display all package names in toast
        ActivityManager actvityManager = (ActivityManager) context
                .getApplicationContext().getSystemService(
                        context.getApplicationContext().ACTIVITY_SERVICE);
        List<RunningAppProcessInfo> procInfos = actvityManager
                .getRunningAppProcesses();
        for (int pnum = 0; pnum < procInfos.size(); pnum++) {
            actvityManager
                    .killBackgroundProcesses(procInfos.get(pnum).processName);
        }
    }
}

我就是这样注册我的接收器的

IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
mReceiver = new BatterySaverLiteReceiver();
registerReceiver(mReceiver, filter);

清单

   <receiver android:name=".BatterySaverUltraReceiver" >
        <intent-filter>
            <action android:name="android.intent.action.SCREEN_OFF" />
            <action android:name="android.intent.action.SCREEN_ON" />
        </intent-filter>
    </receiver>

我从here得到这个代码

【问题讨论】:

  • 是因为 unregisterReceiver 你的广播接收器在 onPause、onStop 或 onDestory 方法中?

标签: android


【解决方案1】:

我认为您正在杀死所有进程,包括 task() 方法中的进程。从killBackgroundProcesses() 中过滤掉你的后台服务进程。

RunningAppProcessInfo 获取进程名称并将其与您应用的进程名称进行比较。默认情况下,进程名称将等于包名称。

private void task(Context context) {
    ActivityManager actvityManager = (ActivityManager) context
            .getApplicationContext().getSystemService(
                    context.getApplicationContext().ACTIVITY_SERVICE);
    List<ActivityManager.RunningAppProcessInfo> procInfos = actvityManager
            .getRunningAppProcesses();
    for (int pnum = 0; pnum < procInfos.size(); pnum++) {
        ActivityManager.RunningAppProcessInfo info = procInfos.get(pnum);

        if (info.pid != android.os.Process.myPid()) {
            actvityManager.killBackgroundProcesses(info.processName);
        }
    }
}

【讨论】:

  • 过滤自己的包名也不是没用。它可以杀死自己的进程。阅读答案here
  • 确保你的进程名和包名相同。
【解决方案2】:

【讨论】:

  • 只是想知道,为什么这样设计的广播接收器不能在后台工作
  • BroadcastReceiver 需要唤醒权限和唤醒锁。 WakefullBroadCastReceiver 正在做你自己.. :)
【解决方案3】:

我找到了一个更有效和可靠的解决方案,我注册了一个每 5 秒工作一次的通知管理器,并在我的主要活动中调用该方法!

MainActivity.java

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // ENABLE MyReceiver SERVICE
        ComponentName receiver = new ComponentName(MainActivity.this,
                NotifyService.class);
        PackageManager pm = this.getPackageManager();
        pm.setComponentEnabledSetting(receiver,
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                PackageManager.DONT_KILL_APP);
        // Toast.makeText(this, "Enabled broadcast receiver",
        // Toast.LENGTH_SHORT)
        // .show();
        // --//

        Intent intent = new Intent(this, NotifyService.class);
        PendingIntent sender = PendingIntent.getBroadcast(this, 0, intent,
                PendingIntent.FLAG_CANCEL_CURRENT);

        AlarmManager am = (AlarmManager) this
                .getSystemService(Context.ALARM_SERVICE);
        long recurring = (1 * 1000 * 5); // in milliseconds
        am.setRepeating(AlarmManager.RTC, Calendar.getInstance()
                .getTimeInMillis(), recurring, sender);
    }

    public static void mehtodName(Context context) {
        KeyguardManager myKM = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
           if( myKM.inKeyguardRestrictedInputMode() ) {
                // it is locked
               task(context);
           } else {
                //it is not locked
           }
    }

     private static void task(Context context) {
            // Process Killer and display all package names in toast
            ActivityManager actvityManager = (ActivityManager) context
                    .getApplicationContext().getSystemService(
                            context.getApplicationContext().ACTIVITY_SERVICE);
            List<RunningAppProcessInfo> procInfos = actvityManager
                    .getRunningAppProcesses();
            for (int pnum = 0; pnum < procInfos.size(); pnum++) {
                actvityManager
                        .killBackgroundProcesses(procInfos.get(pnum).processName);
            }
        }
    }

NotifyService.java

public class NotifyService extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        MainActivity.mehtodName(context);
        // ... do what you need to do here...
    }

}

我的清单

 <receiver android:name="com.example.notifypro.NotifyService" >
 </receiver>

【讨论】:

    猜你喜欢
    • 2018-01-22
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 2013-05-26
    相关资源
    最近更新 更多