How do I get this BroadCastReceiver to work? - android

So I literally tried almost every trick in the book to get this thing running. BUT IN VAIN.
Which is why I just gonna put all that code here. I don't see why this shouldn't work.
No errors or nothing like that. Just the, receiver never fires up.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.broadcastmannankatta">
<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>
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.example.broadcastmannankatta" />
</intent-filter>
</receiver>
</application>
</manifest>
package com.example.broadcastmannankatta;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
// an Intent broadcast.
Toast.makeText(context, "YEAHA", Toast.LENGTH_LONG).show();
}
}
package com.example.broadcastmannankatta;
import androidx.appcompat.app.AppCompatActivity;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void sendbroadcast(View view) {
Intent bIntent = new Intent();
bIntent.setAction("com.example.broadcastmannankatta");
sendBroadcast(bIntent);
}
}
My UI got a button that fires the sendbroadcast method.

As explained in Android official documentation
Beginning with Android 8.0 (API level 26), the system imposes additional restrictions on manifest-declared receivers.
If your app targets Android 8.0 or higher, you cannot use the manifest to declare a receiver for most implicit broadcasts (broadcasts that don't target your app specifically). You can still use a context-registered receiver when the user is actively using your app.
So please follow instructions in the link to register to your custom receiver context-registred receiver
Don't forgot to unregister from your receiver when activity get paused or destoryed.

Related

Can't start service on boot after Android 7

I want to start a service on boot.
This code only works on Android versions that came before 7.
What should I change to make it work on newer versions? Should I use JobScheduler or maybe WorkManager instead?
For what I know Timer, Handler and AlarmManager are deprecated or have different purposes.
I suspect that after Android 7 they removed the option of starting a service on boot in order to save battery life and avoid slowing down the phone. Can you confirm that?
This is my broadcast receiver
package com.kev.boot21;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class BroadcastReceiverOnBootComplete extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("tag","xyz broadcast 1");
if (intent.getAction().equalsIgnoreCase(Intent.ACTION_BOOT_COMPLETED)) {
Intent serviceIntent = new Intent(context, AndroidServiceStartOnBoot.class);
context.startService(serviceIntent);
}
}
}
This is my service
package com.kev.boot21;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class AndroidServiceStartOnBoot extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
Log.i("tag","xyz service");
}
}
This is my manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.kev.boot21">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses-permission>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme">
<receiver
android:name="com.kev.boot21.BroadcastReceiverOnBootComplete"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service android:name="com.kev.boot21.AndroidServiceStartOnBoot"></service>
<activity
android:name="com.kev.boot21.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>
</application>
</manifest>
I found that WorkManager is the best way to handle this problem.
I managed to run a PeriodicWorkRequest after reboot on Android 7, 8 and 9 using the example code from the official documentation:
https://developer.android.com/topic/libraries/architecture/workmanager/basics
Android 10 behaves in a different way. After reboot the PeriodicWorkRequest works only after opening the app. I guess it's for performance/security reasons
You need to register your receiver in your code by calling Context.registerReceiver(), as ACTION_BOOT_COMPLETED is no longer sent to receivers registered through AndroidManifest.xml

BroadcastReceiver for incoming SMS on Samsung-Android based smartphone

I checked every stackoverflow post before posting this problem because they didn't help.
I'm using this documentation https://developer.android.com/reference/android/provider/Telephony?hl=it to understand how to build an application that listen for incoming SMS, but it seems it doesn't work in my case, so as all stackoverflow posts.
Following is what I just developed:
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="abc">
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.WRITE_SMS" />
<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>
<receiver
android:name=".IncomingSMS">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
</application>
</manifest>
MainActivity.java
package abc;
import android.Manifest;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.telephony.SmsManager;
import android.view.View;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.SEND_SMS},1);
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_SMS},2);
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.RECEIVE_SMS},3);
}
}
IncomingSMS.java
package abc;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class IncomingSMS extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
System.out.println("It works!");
}
}
Unfortunately, when I receive a new SMS, it doesn't write "It works!"
In that website there is this section:
Note: These APIs are not available on all Android-powered devices.
I'm resigning and I'm really thinking that the Samsung Galaxy A5 2017 at my disposal does not allow me to do what I want.
Is there something in the code that I forgot or really I can't develop this application on this phone?
Finally after two days of work I was able to understand the problem. If you deactivate and re-enable SMS permissions, the problem is resolved. This clearly a bug on Android Oreo.
Even better:
I modified the code as following:
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.SEND_SMS, Manifest.permission.RECEIVE_SMS, Manifest.permission.READ_SMS},1);

How to Launch an App After Rebooting / Startup

I've read some of the threads here explaining about launching an app after startup such as this one but it didn't work for me.
Here is MainActivity.java
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
AfterBootReceiver.java:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class AfterBootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("Intent.ACTION_BOOT_COMPLETED")) {
Toast.makeText(context, "AfterBootReceiver - boot", Toast.LENGTH_SHORT).show();
}
}
}
Here is the manifest with the permission code:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.liorle.startappafterboot">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="false"
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>
<receiver android:name=".AfterBootReceiver">
<intent-filter>
<action android:name= "android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
My questions is: does any of you see any problem with this code? how to make the receiver receive the boot action from within the main activity?
Thanks!
You will need to register the receiver outside of your main Activity (in your Manifest), Android will not know that your BroadcastReceiver exists until your Activity is started. You will also need to create your own BroadcastReceiver implementation for this purpose.
<receiver android:name=".BootCompletedReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
You may start yourt main Activity from inside your newly created BroadcastReceiver (BootCompletedReceiver).
Your application will also need to request the RECEIVE_BOOT_COMPLETED permission.
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
Your launcher is not listening for the BOOT_COMPLETED broadcast.
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
In your apps current state - the main activity needs to be running to listen to the BOOT_COMPLETED broadcast. Your manifest needs to have something registered that tells the ecosystem to activate the activity / receiver.

Android broadcast is not working when the app is not running

Please don`t vote down if this is a silly question please share some light here
i want to created an app for saving call history
for that i followed
http://karanbalkar.com/2014/02/detect-incoming-call-and-call-hangup-event-in-android/
this site
but i`m not getting the event when the app is not running.Please help
i want to get the event when a incoming call is received even when the app is closed
manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.sars.broadcasttest">
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme">
<activity android:name=".Main">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".IncommingCall">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
</application>
</manifest>
class file
package com.sars.broadcasttest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;
/**
* Created by athulbabu on 18/08/15.
*/
public class IncommingCall extends BroadcastReceiver {
int i=0;
#Override
public void onReceive(Context context, Intent intent) {
Log.d("IncomingCall", "Call catched test"+i++);
Toast.makeText(context, "Calll Intent Detected. test", Toast.LENGTH_LONG).show();
}
}
For security reasons you have to run app at least once after install to get the BroadcastReceiver working.
Read this section: Launch controls on stopped applications
http://developer.android.com/about/versions/android-3.1.html

Unable to receive android.intent.action.EVENT_REMINDER broadcast

I would like to write an application that is triggered when a calendar reminder occurs. I realize there is no officially documented way of doing this, but I have seen in the log that when my calendar alarm goes off on my phone (Droid X), AlertReceiver indicates that it has received an android.intent.action.EVENT_REMINDER:
01-03 11:03:00.029 D 1523 AlertReceiver onReceive: a=android.intent.action.EVENT_REMINDER Intent { act=android.intent.action.EVENT_REMINDER dat=content://com.android.calendar/129407058000 flg=0x4 cmp=com.android.calendar/.AlertReceiver (has extras) }
So, I set up a simple BroadcastReceiver:
package com.eshayne.android;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class CalendarTest extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
android.util.Log.i("CalendarTest", "CalendarTest.onReceive called!");
}
}
with this manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.eshayne.android"
android:versionCode="1"
android:versionName="1.0">
<uses-permission android:name="android.permission.READ_CALENDAR" />
<application android:icon="#drawable/icon" android:label="#string/app_name" android:debuggable="true">
<receiver android:name="com.eshayne.android.CalendarTest">
<intent-filter>
<action android:name="android.intent.action.EVENT_REMINDER" />
</intent-filter>
</receiver>
</application>
<uses-sdk android:minSdkVersion="8" />
</manifest>
Unfortunately, when I put this on my phone and set up a calendar event with a reminder - when the reminder alerts, I still see the AlertReceiver log entry, but not mine.
I have also read here about some system intents that require registering via code rather than in the manifest. So, I tried the following instead:
package com.eshayne.android;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
public class CalendarTestDisplay extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
android.util.Log.i("CalendarTestDisplay", "received broadcast");
}
},
new IntentFilter("android.intent.action.EVENT_REMINDER"));
}
}
with this modified manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.eshayne.android"
android:versionCode="1"
android:versionName="1.0">
<uses-permission android:name="android.permission.READ_CALENDAR" />
<application android:icon="#drawable/icon" android:label="#string/app_name" android:debuggable="true">
<activity android:name=".CalendarTestDisplay"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="8" />
</manifest>
with no better result.
Any ideas what I may be missing? Or any other ideas of how I might be able to capture calendar alarm occurrences?
Thanks,
Ethan
You need to set data scheme to "content" in the intent filter.
Using manifest, add data element inside intent-filter
<receiver android:name="com.eshayne.android.CalendarTest">
<intent-filter>
<data android:scheme="content"/> <!-- this was missing -->
<action android:name="android.intent.action.EVENT_REMINDER" />
</intent-filter>
</receiver>
Using code, add datascheme in one function call
IntentFilter filter = new IntentFilter(CalendarContract.ACTION_EVENT_REMINDER);
filter.addDataScheme("content"); // this was missing
registerReceiver(myRemindersReceiver, filter);
Well, what you're trying to do is not part of the Android SDK, mostly because the calendar is not part of the operating system.
That being said, at minimum, you will need to add a <data> element to your <intent-filter>, since the Intent has a Uri.
However, I'm reasonably certain that this will not work, since the Intent also specifically identifies a component (com.android.calendar/.AlertReceiver). AFAIK, that was in the Intent at the outset, and therefore the Intent will only be delivered to that component, ignoring all other routing rules. It's conceivable the listed component only showed up after Intent resolution, but I don't think that's how those log entries work.
It is possible to make the broadcast intent "android.intent.action.EVENT_REMINDER" work by specifying DataAuthority and DataScheme in your intent filter along with your intent action.You need to specify DataAuthority as "com.android.calendar" and DataScheme as "content".
the broadcast intent "android.intent.action.EVENT_REMINDER" only gets fired when an alarm notification needs to be posted for a reminder
set a notification for your EVENT (Eg: 10 minutes before the event) in order for the broadcast intent "android.intent.action.EVENT_REMINDER" to work

Categories

Resources