Android - не удалось создать экземпляр BroadCastReceiver
Как следует из названия, у меня возникли проблемы с трансляцией. Я получил Службу, которая отправляет некоторые намерения в основной вид деятельности (которые получают эти сообщения с трансляцией).
Я получил этот журнал:
08-03 18:23:11.581: E/AndroidRuntime(776): FATAL EXCEPTION: main
08-03 18:23:11.581: E/AndroidRuntime(776): java.lang.RuntimeException: Unable to instantiate receiver com.example.proyectjane_smartphone.Main.$IncomingBroadcaster: java.lang.ClassNotFoundException: com.example.proyectjane_smartphone.Main.$IncomingBroadcaster in loader dalvik.system.PathClassLoader[/data/app/com.example.proyectjane_smartphone-1.apk]
08-03 18:23:11.581: E/AndroidRuntime(776): at android.app.ActivityThread.handleReceiver(ActivityThread.java:1777)
08-03 18:23:11.581: E/AndroidRuntime(776): at android.app.ActivityThread.access$2400(ActivityThread.java:117)
08-03 18:23:11.581: E/AndroidRuntime(776): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:985)
08-03 18:23:11.581: E/AndroidRuntime(776): at android.os.Handler.dispatchMessage(Handler.java:99)
08-03 18:23:11.581: E/AndroidRuntime(776): at android.os.Looper.loop(Looper.java:130)
08-03 18:23:11.581: E/AndroidRuntime(776): at android.app.ActivityThread.main(ActivityThread.java:3687)
08-03 18:23:11.581: E/AndroidRuntime(776): at java.lang.reflect.Method.invokeNative(Native Method)
08-03 18:23:11.581: E/AndroidRuntime(776): at java.lang.reflect.Method.invoke(Method.java:507)
08-03 18:23:11.581: E/AndroidRuntime(776): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
08-03 18:23:11.581: E/AndroidRuntime(776): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
08-03 18:23:11.581: E/AndroidRuntime(776): at dalvik.system.NativeStart.main(Native Method)
08-03 18:23:11.581: E/AndroidRuntime(776): Caused by: java.lang.ClassNotFoundException: com.example.proyectjane_smartphone.Main.$IncomingBroadcaster in loader dalvik.system.PathClassLoader[/data/app/com.example.proyectjane_smartphone-1.apk]
08-03 18:23:11.581: E/AndroidRuntime(776): at dalvik.system.PathClassLoader.findClass(PathClassLoader.java:240)
08-03 18:23:11.581: E/AndroidRuntime(776): at java.lang.ClassLoader.loadClass(ClassLoader.java:551)
08-03 18:23:11.581: E/AndroidRuntime(776): at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
08-03 18:23:11.581: E/AndroidRuntime(776): at android.app.ActivityThread.handleReceiver(ActivityThread.java:1768)
08-03 18:23:11.581: E/AndroidRuntime(776): ... 10 more
Вот код broadcastReceiver (он определен как внутренний класс, поэтому имя в манифесте "com.example.proyectjane_smartphone.Main. $ IncomingBroadcaster", используя "$"):
class IncomingBroadcaster extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(ACTION_CHANGE_TEXT_IO)) {
textIO.setText("OUTUT: " + intent.getStringExtra("text"));
} else if (action.equals(ACTION_SPEAK)) {
JANEvoi.speak(intent.getStringExtra("speak"));
} else if (action.equals(ACTION_CHANGE_LIGHT)) {
if (intent.getBooleanExtra("light", false)) {
connLight.setImageResource(R.drawable.lighton);
} else {
connLight.setImageResource(R.drawable.lightoff);
}
} else if (action.equals(ACTION_ENABLE_BT)) {
Intent enableBtIntent = new Intent(
BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent,
BluetoothManager.REQUEST_ENABLE_BT);
}
}
}
Мне нужно, чтобы трансляция была определена как внутренний класс, потому что он меняет некоторые тексты и называет "activityforResult", и это возможно только в основной деятельности.
Звонки для службы, вот пример, который снимает исключение:
public void enableBluetoothAdapter() {
if (blueManager.getAdapter() == null) {
Log.d("BLUETOOTHMANAGER", "There's no bluetooth adapter");
} else if (!blueManager.getAdapter().isEnabled()) {
Intent enableBTIntent = new Intent(Main.ACTION_ENABLE_BT);
sendBroadcast(enableBTIntent);
Log.d("BLUETOOTH", "BLUETOOTH ENCENDIDO");
}
}
Что я не могу понять, так это то, что (например, с "ACTION_ENABLE_BT") намерение отправляется и принимается, потому что во время сбоя действия появляется "всплывающее меню", которое активирует блютус… Итак, аварийное завершение вещания раньше использовалось (Несмотря на получение ошибки о том, что трансляция не может быть инициирована...).
Наконец, вот манифест:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.proyectjane_smartphone"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="10" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.proyectjane_smartphone.Main"
android:label="@string/app_name"
android:launchMode="singleTask"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name="com.example.proyectjane_smartphone.Main.$IncomingBroadcaster"
android:exported="false" >
<intent-filter>
<action android:name="es.jane.SpeakAction" />
<action android:name="es.jane.ChangeTextIOAction" />
<action android:name="es.jane.ChangeLight" />
<action android:name="es.jane.EnableBT" />
</intent-filter>
</receiver>
<service android:name="com.example.proyectjane_smartphone.Bluetooth.BluetoothService" >
</service>
</application>
</manifest>
Я искал, но я не нашел решения. заранее спасибо
3 ответа
Даже если вы исправите имя класса, оно все равно не будет работать, так как BroadcastReceiver
не является статическим внутренним классом. Экземпляр действия потребуется для его создания, а это невозможно из-за того, как вы можете определить его в Манифесте.
Правильный способ использовать BroadcastReceiver
который работает от имени Activity
это зарегистрировать и отменить регистрацию в Activity#onResume
а также Activity#onPause
, Таким образом, получатель прослушивает события, когда активность активна, и может правильно взаимодействовать с ней как с внутренним классом.
В onCreate()
вам нужно создать экземпляр вашего приемника, а затем в onResume()
вам нужно что-то похожее на:
final IntentFilter filter = new IntentFilter();
this.populateFilter(filter);
filter.addAction("es.jane.SpeakAction");
...
registerReceiver(this.receiver, filter);
И в onPause()
:
unregisterReceiver(this.receiver)
Вы не можете зарегистрировать внутренний класс в качестве получателя (потому что такой класс может быть создан только через экземпляр внешнего класса, т.е. такой класс не имеет конструктора по умолчанию). Однако вы можете динамически зарегистрировать экземпляр класса в своей деятельности: ссылка
Проблема была в том, что если я использую BroadcastReceiver, его не нужно объявлять в манифесте. Затем я объявляю трансляцию со следующим кодом в деятельности:
private BroadcastReceiver inBroadcast = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(ACTION_CHANGE_TEXT_IO)) {
textIO.setText("OUTUT: " + intent.getStringExtra("text"));
} else if (action.equals(ACTION_SPEAK)) {
JANEvoi.speak(intent.getStringExtra("speak"));
} else if (action.equals(ACTION_CHANGE_LIGHT)) {
if (intent.getBooleanExtra("light", false)) {
connLight.setImageResource(R.drawable.lighton);
} else {
connLight.setImageResource(R.drawable.lightoff);
}
} else if (action.equals(ACTION_ENABLE_BT)) {
Intent enableBtIntent = new Intent(
BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent,
BluetoothManager.REQUEST_ENABLE_BT);
}
}
};
И наконец, это работает!