Broadcast Receiver in a Library Project not working - android

I have implemented Broadcast Receiver in a library project for checking the Boot Completed event , but it is not working.
Broadcast Receiver Class :
public class Reciever extends BroadcastReceiver
{
public void onReceive(Context context, Intent intent)
{
if(intent.getAction().equals("android.intent.action.BOOT_COMPLETED"))
{
Toast.makeText(context, "Device Boot Completed", Toast.LENGTH_LONG).show();
}
}
}
AndroidManifest.xml :
<receiver
android:name=".Reciever"
android:enabled="true" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
I implemented same Receiver in another application (not library project) and it is working fine.

BroadcastReceiver cannot be defined in the library project's manifest. The hosting project always needs to declare the components.
android library project and Activities
Edit:
I feel this should work with latest Android studio/ gradle based projects.

You might skipped
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
In manifest file

Override the following method
#Override
public void onReceive(Context context, Intent intent)

You should add receive tag and reboot permissions to client application manifest file which using your library jar
Like this;
<receiver android:name="com.example.library.ReceiverClass"
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>

Related

Android 10 BOOT_COMPLETED Broadcast not received to application

I have to run the service using BOOT_COMPLETED Broadcast but while the Android 10 device is booting I get the following warning.
system_process W/BroadcastQueue: Background execution not allowed: receiving Intent { act=android.intent.action.LOCKED_BOOT_COMPLETED flg=0x400010 } to com.rahul.http/.BootReceiver
Mainifest:
<service
android:name=".HttpUpdateService"
android:enabled="true"
android:directBootAware="true"
android:exported="true">
</service>
<receiver android:name=".BootReceiver"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED"
android:exported="true"
>
<intent-filter android:priority="999">
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
</intent-filter>
</receiver>
I have also added permission for receiving boot_complete broadcast.
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
I don't have any activity in my application.
try to add add android:directBootAware to your <receiver, as in DOCs
Try adding following attribute in your application tag in Manifest :
android:directBootAware="true"
When you received an intent on Broadcast receiver you have to add the check if your application target below the Android O version. Something like this:
if app build version greater than android O than you must called startForegroundService method with provided intent. otherwise you just called the method startService with provided intent.

On Android 11 Remote Bound Service binding fails when invoked from Client app

On Android 11 Remote bound Service binding fails when invoked from Client app
Problem is specific to Android 11 only.
1: Using remote bound service with AIDL interface. This service is derived from service B, which is also using AIDL interface.
public class IPCEnterpriseServicePcsc extends IPCServicePcsc {
...
protected IPCEnterpriseInterfaceLicense licenseBinder;
...
}
public class IPCEnterpriseInterfaceLicense extends IRemotePcscServiceLicense.Stub {...}
public class IPCServicePcsc extends IPCService {
...
protected IPCInterfacePcsc mBinder;
...
}
public class IPCInterfacePcsc extends IRemotePcscService.Stub{...}
2. Below is the Manifest of server application defining the service:
<service android:label="#string/pcsc_service_name" android:name=".IPCEnterpriseServicePcsc" >
<intent-filter>
<action android:name="com.baimobile.android.enterprise.credential.service.ipc.action.BIND_PCSC" />
<action android:name="com.baimobile.android.enterprise.credential.service.ipc.action.BIND_LICENSE" />
<action android:name="com.baimobile.android.enterprise.credential.service.license.action.VALIDATE_USER_LICENSE_INFO" />
</intent-filter>
</service>
server app id is "com.baimobile.android.enterprise.credential.service"
3.1 From a client app, Service 'IPCEnterpriseServicePcsc' is invoked as below:
Intent intent = new Intent("com.baimobile.android.enterprise.credential.service.ipc.action.BIND_LICENSE");
intent.setPackage("com.baimobile.android.enterprise.credential.service");
intent.putExtra("Interface","IRemotePcscServiceLicense");
boolean pcscServiceInstalled = appContext.bindService(intent, connectionToPcscInterface, Context.BIND_AUTO_CREATE);
3.2: connectionToPcscInterface is defined as:
private ServiceConnection connectionToPcscInterface = new ServiceConnection() {
public void onServiceConnected(ComponentName remoteComponent, IBinder binder) {...};
public void onServiceDisconnected(ComponentName arg0) {..};
}
3.3: With successful appContext.bindService()in step 3.1, onServiceConnected() mentoned in Step 3.2 is invoked by service. Here we are doing some validation and then binding to base class service IPCServicePcsc
Intent intent = new Intent("com.baimobile.android.pcsclite.service.ipc.action.BIND_PCSC");
intent.setPackage("com.baimobile.android.enterprise.credential.service");
intent.putExtra("Interface","IRemotePcscService"); // Request the PC/SC interface instead of the license interface.
pcscServiceInstalled = appContext.bindService(intent, connectionToPcscInterface, Context.BIND_AUTO_CREATE);
if( ! pcscServiceInstalled ){
Log.e("TAG","bindService failed.");
}
Problem Statement:
Till Android 10, client application is able to connect with these services very well however on Android 11, binding under Step 3.3 fails.
Any idea what could be the problem and looking for suggestions to troubleshoot it. Seems something broken or hardened on Android 11.
If you have not done so already, your client app needs a <queries> element in the manifest to identify the service app.
For example, in this client app, I have:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.commonsware.android.r.embed.client">
<queries>
<package android:name="com.commonsware.android.r.embed.server" />
</queries>
<application
android:name=".MainApp"
android:allowBackup="false"
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>
</application>
</manifest>
That <queries> element identifies the package of a separate app that has a bound service that the client app binds to.
Thank you CommonsWare! Your suggestion has helped fixing the issue.
In order to use queries in AndroidManifest.xml, had to upgrade,
AndroidStudio to 4.1.3 (earlier it was 3.x.x)
Gradle version to 6.5 (gradle-wrapper.properties):
distributionUrl=https://services.gradle.org/distributions/gradle-6.5-all.zip
Android gradle plugin to 4.1.0 (project build.gradle)
classpath 'com.android.tools.build:gradle:4.1.0'

What is the correct setting of BroadcastReceiver with BOOT_COMPLETED action in Xamarin project?

I created a simple sample to test the BroadcastReceiver reacting to the action BOOT_COMPLETED see. below, but it is not working. After starting the tablet is no activity / app is running and in the logocat is nothing. I'm probably a mistake in the settings, but I can not find out what
I use a tablet alps 874v3 android 4.4.2 and Visual Studio 2010 with Xamarin to write Android app in .net
On SO I found some additional information:
1 Registration BroadcastReceiver have not be inside AndroidManifest.xml but must use class attributes.
2 Applications must contain BroadcastReceiverand activity otherwise the will not run on later versions of Android (for safety)
3 Once installed the application is in stopped state so i started it (system verifies that the user wants the application) and then kill and then I try to reboot.
[BroadcastReceiver(Enabled = true, Exported = true, Permission = "RECEIVE_BOOT_COMPLETED")]
[IntentFilter(new string[] { "android.intent.action.BOOT_COMPLETED"})]
public class BootBroadcastReceiver : BroadcastReceiver
{
public BootBroadcastReceiver()
{
}
public override void OnReceive(Context context, Intent intent)
{
Log.Debug("TestBoot", "BootBroadcastReceiver.OnReceive()");
context.StartActivity(typeof(UsbMainActivity));
Log.Debug("TestBoot", "BootBroadcastReceiver.OnReceive() after start activity");
}
}
[Activity(Label = "UsbMainActivity", Icon = "#drawable/icon", MainLauncher = true, Permission = "RECEIVE_BOOT_COMPLETED")]
[IntentFilter(new string[] { "android.intent.action.BOOT_COMPLETED" })]
public class UsbMainActivity : Activity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
Utils.MyLog("TestBoot", 1, "UsbMainActivity.OnCreate()");
}
}
There is a AndroidMainfest.xml which was generated by xamarin :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="TestBoot.TestBoot" android:versionCode="1" android:versionName="1.0">
<uses-sdk android:minSdkVersion="15" android:targetSdkVersion="19" />
<application android:label="TestBoot" android:icon="#drawable/icon" android:name="mono.android.app.Application" android:debuggable="true">
<activity android:icon="#drawable/icon" android:label="UsbMainActivity" android:permission="RECEIVE_BOOT_COMPLETED" android:name="md5e98891b9b152ca725e5cab653b1387f3.UsbMainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</activity>
<receiver android:enabled="true" android:exported="true" android:permission="RECEIVE_BOOT_COMPLETED" android:name="md5e98891b9b152ca725e5cab653b1387f3.BootBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<provider android:name="mono.MonoRuntimeProvider" android:exported="false" android:initOrder="2147483647" android:authorities="TestBoot.TestBoot.mono.MonoRuntimeProvider.__mono_init__" />
<receiver android:name="mono.android.Seppuku">
<intent-filter>
<action android:name="mono.android.intent.action.SEPPUKU" />
<category android:name="mono.android.intent.category.SEPPUKU.TestBoot.TestBoot" />
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
</manifest>
The problem was that after installing application i stopped via Settings- "Force Quit" and then tried to reboot. If I'm after installing stopped only a activity, so after the restart boot_completed arrived. So it seems that the application must running before the reboot and then the boot_completed arrived.
Note: Test reboot via adb console, type :
adb shell
am broadcast -a android.intent.action.BOOT_COMPLETED
add this permission to manifest
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
On some devices declaring the permission twice, once in the manifest and second as attribute to the receiver will make the receiver not working. You can leave only the permission declared inside the manifest. Check my comment (GeorgiZ) in this thread: https://forums.xamarin.com/discussion/80876/open-an-app-on-startup-after-booting-not-working.

WakefulBroadcastReceiver get java.lang.ClassNotFoundException

In my Android project, I have a Service class:
public class MyService extends Service{
...
//Defined a WakefulBroadcastReceiver as a inner static class
public static class DeviceRebootReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//Do something when user reboot the device
}
}
}
As you see above, I have defined a WakefulBroadcastReceiver as a inner static class in MyService class. This receiver receives the broadcast when user reboot his/her device.
My AndroidManifest.xml looks like this:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.my.project"
android:versionCode="1"
android:versionName="2.1" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
...>
<activity ...> ... </activity>
<service android:name="com.my.project.MyService"
android:exported="false"/>
<receiver
android:name="com.my.project.MyService$DeviceRebootReceiver"
>
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
But when I run my app & after rebooted the device, my logcat shows me error:
Unable to instantiate receiver com.my.project.MyService$DeviceRebootReceiver:
java.lang.ClassNotFoundException: com.my.project.MyService$DeviceRebootReceiver in loader dalvik.system.PathClassLoader[/data/app/com.my.project-1.apk]
Why my receiver class is not able to be loaded by system?
=====Update======
I also tried to make my DeviceRebootReceiver as a separate class (DeviceRebootReceiver.java), and made the AndroidManifest.xml changed to :
<application...>
<receiver
android:name="com.my.project.DeviceRebootReceiver"
>
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
But I still get the similar error in logcat:
java.lang.RuntimeException: Unable to instantiate receiver com.my.project.DeviceRebootReceiver: java.lang.ClassNotFoundException
I had the same problem and solved it.
It's about the android-support-v4.jar library, you should only have the official and updated library (copied from ANDROID_SDK/extras/android/support/) under the libs folder in your project and Android Private Libraries checked in the Java Build Path of your project. For example, I also had a ClassNotFoundException because of my project was using the android-support-v4.jar of another library (ActionBarSherlock) even with the official android-support-v4.jar included in my java build path, so I unchecked the Android Private Libraries of the ActionBarSherlock project to avoid this redundancy.

JAR register BroadcastReceiver

My BroadcastReceiver class name is net.push.MyReceiver
and the Mainfest in JAR:
<receiver android:name="net.push.MyReceiver" >
<intent-filter>
<action android:name="MyReceiver_Action" />
</intent-filter>
</receiver>
and the register BroadcastReceiver,Receiver can not receive broadcast.
if i change the Mainfest like below:
<receiver android:name="net.push.MyReceiver" >
<intent-filter>
<action android:name="MyReceiver_Action" />
</intent-filter>
</receiver>
then it can Receive the broadcast.
I wonder how can i Receive the broadcast while register the mainFest in JAR.
AndroidManifest.xml is specified for an application not for a jar.
So, if you want your receiver to actually work, you need to put that declaration in application manifest which should be located in the root of your application project folder.
Every application must have an AndroidManifest.xml file (with
precisely that name) in its root directory
More to read here: http://developer.android.com/guide/topics/manifest/manifest-intro.html

Categories

Resources