【问题标题】:Broadcast receiver inside a Service doesn't work服务内的广播接收器不起作用
【发布时间】:2017-06-28 12:35:27
【问题描述】:

我在 Service 中有一个广播接收器。该服务应该启动一个警报管理器,并且广播接收器应该接收警报。该服务在设备重启后由另一个广播接收器启动。但我的代码给出了以下异常和应用程序崩溃。我该如何解决这个问题?

06-28 17:26:20.983 6924-6924/com.example.krishan.timertest E/AndroidRuntime: FATAL EXCEPTION: main
  Process: com.example.krishan.timertest, PID: 6924
  java.lang.RuntimeException: Unable to instantiate receiver com.example.krishan.timertest.MyService$AlarmReceiver: java.lang.InstantiationException: class com.example.krishan.timertest.MyService$AlarmReceiver has no zero argument constructor
      at android.app.ActivityThread.handleReceiver(ActivityThread.java:2992)
      at android.app.ActivityThread.access$1800(ActivityThread.java:177)
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1507)
      at android.os.Handler.dispatchMessage(Handler.java:102)
      at android.os.Looper.loop(Looper.java:135)
      at android.app.ActivityThread.main(ActivityThread.java:5910)
      at java.lang.reflect.Method.invoke(Native Method)
      at java.lang.reflect.Method.invoke(Method.java:372)
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1405)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200)
   Caused by: java.lang.InstantiationException: class com.example.krishan.timertest.MyService$AlarmReceiver has no zero argument constructor
      at java.lang.Class.newInstance(Class.java:1681)
      at android.app.ActivityThread.handleReceiver(ActivityThread.java:2987)
      at android.app.ActivityThread.access$1800(ActivityThread.java:177) 
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1507) 
      at android.os.Handler.dispatchMessage(Handler.java:102) 
      at android.os.Looper.loop(Looper.java:135) 
      at android.app.ActivityThread.main(ActivityThread.java:5910) 
      at java.lang.reflect.Method.invoke(Native Method) 
      at java.lang.reflect.Method.invoke(Method.java:372) 
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1405) 
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200) 
   Caused by: java.lang.NoSuchMethodException: <init> []
      at java.lang.Class.getConstructor(Class.java:531)
      at java.lang.Class.getDeclaredConstructor(Class.java:510)
      at java.lang.Class.newInstance(Class.java:1679)
      at android.app.ActivityThread.handleReceiver(ActivityThread.java:2987) 
      at android.app.ActivityThread.access$1800(ActivityThread.java:177) 
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1507) 
      at android.os.Handler.dispatchMessage(Handler.java:102) 
      at android.os.Looper.loop(Looper.java:135) 
      at android.app.ActivityThread.main(ActivityThread.java:5910) 
      at java.lang.reflect.Method.invoke(Native Method) 
      at java.lang.reflect.Method.invoke(Method.java:372) 
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1405) 
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200)

我的服务

public class MyService extends Service {

    public MyService() {
    }

    @Override
    public void onCreate() {
        super.onCreate();

    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        Log.d("timer test", "*********************" + " Service Started " + "*********************");
        startAlert();

        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    public void startAlert() {
        Intent intent = new Intent(this, AlarmReceiver.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 0, intent, 0);
        AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), (60 * 1000), pendingIntent);
        Toast.makeText(this, "Alarm set in 60 seconds", Toast.LENGTH_LONG).show();
    }

    public class AlarmReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            Log.d("Timer Test", "*********************" + " Alarm" + "*********************");
        }
    }
}

我的广播接收器在启动完成时触发

public class BootReceiver extends BroadcastReceiver {

    private Intent ServiceIntent;

    @Override
    public void onReceive(Context context, Intent intent) {

        ServiceIntent = new Intent(context, MyService.class);
        context.startService(ServiceIntent);


        Toast.makeText(context, "Boot Receiver", Toast.LENGTH_LONG).show();
        Intent intentx = new Intent(context, MainActivity.class);
        intentx.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intentx);

    }

}

我的清单

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.krishan.timertest">

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

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service
            android:name=".MyService"
            android:enabled="true"
            android:exported="true"></service>
        <receiver android:name=".BootReceiver" >
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" >
                </action>
            </intent-filter>
        </receiver>
        <receiver android:name=".MyService$AlarmReceiver"></receiver>
    </application>

</manifest>

如果我将广播接收器声明为单独的类,这将正常工作。但我想在服务中声明它。

【问题讨论】:

  • 请检查天气您的服务是否开始。

标签: android service broadcastreceiver


【解决方案1】:

AlarmReceiver 类应该是静态的, 希望有帮助。

【讨论】:

    【解决方案2】:

    我做了类似的事情,也注册了batteryBroadcast和ScreenOn/ScreenOf Broadcast,检查代码:

    public class turnOnScreenService extends Service {
    
    
    
        private BroadcastReceiver mScreenStateReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String strAction = intent.getAction();
    
                if (strAction.equals(Intent.ACTION_SCREEN_OFF)) {
                    //do stuff
                } else if (strAction.equals(Intent.ACTION_SCREEN_ON)) {
                    //do more stuff
                }
            }
        };
    
        private BroadcastReceiver mBatteryStateReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
    
                if (intent.getAction().equals(Intent.ACTION_POWER_CONNECTED)) {
                   // more stuff
    
                } else {
                   // more stuff
                }
            }
        };
    
    
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
            IntentFilter screenStateFilter = new IntentFilter();
            screenStateFilter.addAction(Intent.ACTION_SCREEN_ON);
            screenStateFilter.addAction(Intent.ACTION_SCREEN_OFF);
            registerReceiver(mScreenStateReceiver, screenStateFilter);
    
    
            IntentFilter ifilter = new IntentFilter();
            ifilter.addAction(Intent.ACTION_POWER_CONNECTED);
            ifilter.addAction(Intent.ACTION_POWER_DISCONNECTED);
            registerReceiver(mBatteryStateReceiver, ifilter);
        }
    
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            Log.i("LocalService", "Received start id " + startId + ": " + intent);
    
            return START_NOT_STICKY;
        }
    
        @Override
        public void onDestroy() {
            unregisterReceiver(mScreenStateReceiver);
            unregisterReceiver(mBatteryStateReceiver);
        }
    
    
    }
    

    【讨论】:

    • 我应该在这里使用intentFilter.addAction()的操作是什么
    • Intent.ACTION_BOOT_COMPLETED 请为答案投票
    • Boot接收广播接收器没有问题。在服务内部创建内部类解决了我的问题。
    • 我没有足够的声望来投票回答。为此,声望必须大于 10
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-27
    • 2019-01-07
    相关资源
    最近更新 更多