Android : IllegalArgumentException: "Component class X does not exist" in API 17 (no crash in API 8)
android, android-2.2-froyo, illegalargumentexception
Solution
TriggerMonitoringBootReceiver.class.getSimpleName();
and package
PackageManager pacman = context.getPackageManager();
which together give
di.k23b.hw3.TriggerMonitoringBootReceiver
so you are missing "/receivers/" folder prefix in class name
Problem
My emulators : When I launch the tablet emulator I get : ``` FATAL EXCEPTION: main java.lang.IllegalArgumentException: Component class TriggerMonitoringBootReceiver does not exist in di.k23b.hw3 at android.os.Parcel.readException(Parcel.java:1429) at android.os.Parcel.readException(Parcel.java:1379) at android.content.pm.IPackageManager$Stub$Proxy.setComponentEnabledSetting(IPackageManager.java:2561) at android.app.ApplicationPackageManager.setComponentEnabledSetting(ApplicationPackageManager.java:1250) at di.k23b.hw3.receivers.TriggerMonitoringBootReceiver.enable(TriggerMonitoringBootReceiver.java:81) at di.k23b.hw3.receivers.TriggerMonitoringBootReceiver.enable(TriggerMonitoringBootReceiver.java:86) at di.k23b.hw3.activities.SettingsActivity.onSharedPreferenceChanged(SettingsActivity.java:192) at android.app.SharedPreferencesImpl$EditorImpl.notifyListeners(SharedPreferencesImpl.java:475) at android.app.SharedPreferencesImpl$EditorImpl.apply(SharedPreferencesImpl.java:385) at android.preference.Preference.tryCommit(Preference.java:1349) at android.preference.Preference.persistBoolean(Preference.java:1615) at android.preference.TwoStatePreference.setChecked(TwoStatePreference.java:83) at android.preference.TwoStatePreference.onClick(TwoStatePreference.java:69) at android.preference.Preference.performClick(Preference.java:949) at android.preference.PreferenceScreen.onItemClick(PreferenceScreen.java:215) at android.widget.AdapterView.performItemClick(AdapterView.java:298) at android.widget.AbsListView.performItemClick(AbsListView.java:1100) at android.widget.AbsListView$PerformClick.run(AbsListView.java:2749) at android.widget.AbsListView$1.run(AbsListView.java:3423) at android.os.Handler.handleCallback(Handler.java:725) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:5041) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) at dalvik.system.NativeStart.main(Native Method) ``` When I launch the froyo emulator all is fine (EDIT : no it is not - the receiver is not enabled BUT still there is no crash). Is it a known issue or something ? Manifest : ``` <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="di.k23b.hw3" android:permission="android.permission.RECEIVE_BOOT_COMPLETED" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="di.k23b.hw3.activities.MainActivity" android:label="@string/title_activity_main" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="di.k23b.hw3.activities.SettingsActivity" android:label="@string/title_activity_settings" > </activity> <receiver android:name="di.k23b.hw3.receivers.TriggerMonitoringBootReceiver" android:enabled="false" > <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver> <receiver android:name="di.k23b.hw3.receivers.BatteryMonitoringReceiver" android:enabled="false"/> </application> </manifest> ``` Relevant parts from the receiver (WIP !) : ``` private static void enable(Context context, boolean enable, String className) { PackageManager pacman = context.getPackageManager(); final ComponentName componentName = new ComponentName(context, className); final int state = (enable) ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED : PackageManager.COMPONENT_ENABLED_STATE_DISABLED; pacman.setComponentEnabledSetting(componentName, state, // line 81 PackageManager.DONT_KILL_APP); } public static void enable(Context baseContext, boolean enable) { enable(baseContext, enable, // line 86 TriggerMonitoringBootReceiver.class.getSimpleName()); } ``` And in SettingsActivity: ``` @Override public void onSharedPreferenceChanged(SharedPreferences sp, String key) { if (MASTER_ENABLE.equals(key)) { TriggerMonitoringBootReceiver.enable(getBaseContext(), // line 192 sp.getBoolean(key, false)); Toast.makeText(getApplicationContext(), "CB: " + sp.getBoolean(key, false), Toast.LENGTH_SHORT) .show(); } } ``` EDIT : all clear now, using `ComponentName(Context pkg, Class<?> cls)`- as for the difference in the APIs: Calls to `PackageManager.setComponentEnabledSetting` will now throw an `IllegalArgumentException` if the given component class name does not exist in the application's manifest. - from the Android documentation