public class ScreenReceiver extends BroadcastReceiver {
private boolean screenOff;
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
screenOff = true;
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
screenOff = false;
}
}
<receiver
android:name=".ScreenReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
<action android:name="android.intent.action.DREAMING_STARTED" />
<action android:name="android.intent.action.DREAMING_STOPPED" />
<action android:name="android.intent.action.CLOSE_SYSTEM_DIALOGS" />
<action android:name="android.intent.action.SCREEN_ON" />
<action android:name="android.intent.action.SCREEN_OFF" />
<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
<action android:name="android." />
</intent-filter>
</receiver>
Not getting any callback on naught and oreo devices,tried on marshmallow devices its working fine .but on oreo devices its not working and also for battery connected and network change receiver not working .
You can not register broadcast receiver in manifest.xml from Oreo.
You can see
Android 8.0 Behavior Changes
Apps cannot use their manifests to register for most implicit
broadcasts (that is, broadcasts that are not targeted specifically at
the app).
Solution
Register your receiver in your related Activity instead. Like this.
public class MainActivity extends AppCompatActivity {
BroadcastReceiver receiver;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction("android.intent.action.LOCKED_BOOT_COMPLETED");
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// todo
}
};
registerReceiver(receiver, filter);
}
#Override
protected void onDestroy() {
super.onDestroy();
if (receiver != null)
unregisterReceiver(receiver);
}
}
You can add action as string same as manifest, if you don't find relevant constant string.
Related
I am still new to Android development, but I’m creating an app that sendings an HTTP request when it receives a broadcast (from a barcode scan). I have tried to implement some other solutions that I read on here but haven't quite figured it out yet. It would be great if someone could help me get going in the right direction.
Essentially, the end goal is for the app to keep running in the background forever so that even if the app is not open and a barcode is scanned and sent to the app via broadcast signal, the HTTP request is still sent.
This is what I have so far:
MainActivity.java
public class MainActivity extends Activity implements CompoundButton.OnCheckedChangeListener {
public static final String BARCODE_BROADCAST = "...";
private final BarcodeReceiver barcodeReceiver = new BarcodeReceiver();
private TextView mTextView;
private String scannedBarcode;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(R.id.barcode);
}
#Override
public void onResume() {
super.onResume();
registerBarcodeScanner();
}
#Override
public void onPause() {
super.onPause();
unregisterBarcodeScanner();
// this code needs to keep the app running
Intent restartService = new Intent("RestartService");
this.startService(restartService);
sendBroadcast(restartService);
}
public void onDestroy() {
super.onDestroy();
// this code needs to keep the app running
Intent restartService = new Intent("RestartService");
this.startService(restartService);
sendBroadcast(restartService);
}
private void registerBarcodeScanner() {
registerReceiver(barcodeReceiver, new IntentFilter(BARCODE_BROADCAST));
}
private void unregisterBarcodeScanner() {
unregisterReceiver(barcodeReceiver);
}
private void displayBarcode() {
if (scannedBarcode == null) return;
String text = getString(R.string.barcode_scanned, scannedBarcode);
mTextView.setText(text);
/* SEND HTTP REQUEST */
}
private class BarcodeReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(BARCODE_BROADCAST)) {
String barcode = intent.getStringExtra("Barcode");
if (barcode != null) {
scannedBarcode = barcode;
displayBarcode();
}
}
}
}
}
RestartService.java
public class RestartService extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
context.startService(new Intent(context, MainActivity.class));
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="..."
android:versionCode="1">
<uses-sdk android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
tools:replace="android:label">
<activity
android:name="...MainActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name="...RestartService"
android:enabled="true"
android:exported="true"
android:label="RestartServiceWhenStopped"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="RestartService" />
</intent-filter>
</receiver>
</application>
</manifest>
I registered a BroadcastReceiver in my FragmentActivity like so:
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
setMapLocations(intent);
}
};
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
setMapLocations(intent);
}
};
and start the receiver is onStart():
public void onStart() {
super.onStart();
LocalBroadcastManager.getInstance(this).registerReceiver((mMessageReceiver),
new IntentFilter("MyNotificationData"));
}
and my broadcast sender is defined in the manifest as follows:
<service
android:name=".TrackerMessagingService"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
The problem is that onReceive() never gets hit, even though the exact same code worked fine in an AppCompatActivity in the same app. Any idea what's going on? Do broadcast services not play well with FragmentActivity?
I don't know why this worked, but I was able to get around the issue by leaving the BroadcastReceiver code in the AppCompatActivity. In that case, both BroadcastReceivers got hit.
I've some problem with Oreo and Broadcast Receiver on Boot. My method work for earlier version of Android, but with Oreo (Huawei P20 Lite with Pie) it doesn't work.
The Log.e in the Boot Receiver is not displayed in the LogCat and the action in BootService onCreate is not executed (No Log in log cat).
Boot Receiver
public class BootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.e(TAG, "Boot Receiver : Boot Start Service : AlarmNotification");
if ( Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction()) ) {
Intent myIntent = new Intent(context, BootService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(myIntent);
} else {
context.startService(myIntent);
}
}
}
}
I've set the permissions in the Manifest file
AndroidManifest.xml
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<receiver android:name=".BootReceiver"
android:enabled="true"
android:exported="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.ACTION_BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
<service
android:name=".BootService"
android:enabled="true"
android:exported="true">
</service>
BootService
The Boot Service works on earlier versions of Android
public class BootService extends Service {
public BootService() {
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
//Is fired by the Boot Receiver... on Boot !
Context context = this;
Log.e(TAG, "Start Alarm");
//Do something with the code
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_NOT_STICKY;
}
}
Perhaps I forget something, or do I something wrong ? Can somebody help me on this case, I already tested multiple solutions from StackeOverflow and read the doc, but for me it's not very clear for this case.
Thanks
I needed to restore alarm after reboot for this I added this broadcast receiver:
public class ClsRestartAlarm extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
Logging.logMessage("Broadcast");
Intent i = new Intent(context, BootService.class);
context.startService(i);
}
}
}
and registered in manifest like this:
<receiver android:name=".classes.ClsRestartAlarm"
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
and as result of broadcast I'm doing this:
public class BootService extends IntentService {
public BootService() {
super("boot service");
}
#Override
protected void onHandleIntent(Intent intent) {
AlarmManagerUtils.setStartAlarm();
AlarmManagerUtils.setEndAlarm();
}
}
I guess I'm not receiving BOOT_COMPLETE broadcast in ClsRestartAlarm class, because after restart alarm was not set and I was unable to get notification(the starting alarm start a job scheduler for sending notification and end alarm cancels job scheduler)also I have BOOT_COMPLETE permission like this:
<uses-permission android:name="ANDROID.PERMISSION.RECEIVE_BOOT_COMPLETED"/>
Use WakefulBroadcastReceiver instead. This is my workable solution:
public class BRAutoStart extends WakefulBroadcastReceiver {
private final String BOOT_COMPLETED_ACTION = "android.intent.action.BOOT_COMPLETED";
#Override
public void onReceive(Context ctx, Intent intent) {
_A.APPCTX = ctx.getApplicationContext();
if(intent.getAction().equals(BOOT_COMPLETED_ACTION)){
//code
}
}
}
<receiver android:name=".BRAutoStart">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
I am trying to start a Service that implements SensorEventListener. I am getting an error in my logcat claiming:
android.content.ActivityNotFoundException:Unable to find explicit activity class
{com.devicemoved/com.devicemoved.ShakeWakeupService};
have you declared this activity in your AndroidManifest.xml?
My Service is declared in my manifest as shown:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.devicemoved"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.devicemoved.launcherGo"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="com.devicemoved.ShakeWakeupService" />
</application>
The Activity
public class ShakeWakeupService extends Service implements SensorEventListener {
private Context mContext;
SensorManager mSensorEventManager;
Sensor mSensor;
// BroadcastReceiver for handling ACTION_SCREEN_OFF.
public BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Check action just to be on the safe side.
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
Log.v("shake mediator screen off", "trying re-registration");
// Unregisters the listener and registers it again.
mSensorEventManager.unregisterListener(ShakeWakeupService.this);
mSensorEventManager.registerListener(ShakeWakeupService.this,
mSensor, SensorManager.SENSOR_DELAY_NORMAL);
}
}
};
#Override
public void onCreate() {
super.onCreate();
Log.v("shake service startup", "registering for shake");
mContext = getApplicationContext();
// Obtain a reference to system-wide sensor event manager.
mSensorEventManager = (SensorManager) mContext
.getSystemService(Context.SENSOR_SERVICE);
// Get the default sensor for accel
mSensor = mSensorEventManager
.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
// Register for events.
mSensorEventManager.registerListener(this, mSensor,
SensorManager.SENSOR_DELAY_NORMAL);
// Register our receiver for the ACTION_SCREEN_OFF action. This will
// make our receiver
// code be called whenever the phone enters standby mode.
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
registerReceiver(mReceiver, filter);
}
#Override
public void onDestroy() {
// Unregister our receiver.
unregisterReceiver(mReceiver);
// Unregister from SensorManager.
mSensorEventManager.unregisterListener(this);
}
#Override
public IBinder onBind(Intent intent) {
// We don't need a IBinder interface.
return null;
}
public void onShake() {
// Poke a user activity to cause wake?
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// not used right now
}
// Used to decide if it is a shake
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER)
return;
Log.v("sensor", "sensor change is verifying");
}
}
The only thing I could possibly think of is that I am suppose to declare a broadcast receiver since I am using it in my class but I am not sure how to do that in this instance because I am not extending Broadcastreceiver.
I am calling this class from an activity with a button.
Any help will be great Thank You
You can already declared the package in the manifest tag, you should only need the .ShakeWakeupService part. Also make sure there is an empty constructor available for the system to construct your service