I'm creating an application that needs to read incoming SMS. Saving to a SMS provider is not required - just showing the toast at the time of receiving SMS.
<receiver android:name=".SmsHandler"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter android:priority="2147483647">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
Receiver
public class SmsHandler extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Receive sms", Toast.LENGTH_LONG).show();
}
}
Receiver working when app running, if app kill, receiver not call.
I know that with Android KitKat you need to specify the default applications for working with sms. But this is necessary if you want to save SMS to the SMS provider. This is not required if you need to catch the moment of receiving SMS.
What should I do to make the receiver work when the application is killed?
UPDATE
I tried to use the service to register BroadcastReceiver
public class AlarmService extends Service {
private static BroadcastReceiver SmsHandler;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate()
{
registerScreenOffReceiver();
}
#Override
public void onDestroy()
{
unregisterReceiver(SmsHandler);
SmsHandler = null;
}
private void registerScreenOffReceiver()
{
SmsHandler = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Receive sms", Toast.LENGTH_LONG).show();
}
};
IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
registerReceiver(SmsHandler, filter);
}
}
Related
This is my class where am getting Notification from server->
public class GCMListener_Service extends GcmListenerService {
#Override
public void onMessageReceived(String from, Bundle data) {
Intent notificationReceived = new Intent("com.example.mypackage”);
notificationReceived.putExtra(“key", fromWhere);
sendBroadcast(notificationReceived);
}
}
this i have declared in AndroidManifiestfile:
<service
android:name="com.example.pushnotification.GCMListener_Service"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
here i am trying to get Notification :
public class PushMessageReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Timber.d("Received push notification”);
}
}
here is my receiver in AndroidManifiest file->
<receiver
android:name=".notification.PushMessageReceiver"
android:exported="false">
<intent-filter>
<action android:name="com.example.mobile.pushnotification.notificationReceived" />
</intent-filter>
</receiver>
using given code below android 8 (oreo ) it working fine i am getting and receive notification message in PushMessageReceiver class in onReceive method but in android i am unable to get notification unable to send broadcast can any one please suggest me how to send broad cast in Android O .
In your Application class register and unRegister class like this:
public class YourProjectApplication extends MultiDexApplication {
private static YourProjectApplication sInstance;
public static YourProjectApplication getInstance() {
return sInstance;
}
#Override
public void onCreate() {
super.onCreate();
sInstance = this;
}
public void registerInternetConnectivityBroadCast(){
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(appInternetStatus, intentFilter);
}
public void unSetConnectivityListener(AppInternetStatus.InternetConnectivityReceiverListener listener) {
try {
unregisterReceiver(appInternetStatus);
}catch (Exception e){
e.printStackTrace();
}
try {
AppInternetStatus.internetConnectivityReceiverListener = listener;
}catch (Exception e){
e.printStackTrace();
}
}
And then in your mainActivity class (which can also be your base class) call your broadcast receiver like this:
getInstance().registerBroadCast();
getInstance().setConnectivityListener(this);
And in order to unregister your notification. In your onPause() method of your main activity class :
#Override
protected void onPause() {
super.onPause();
getInstance().unSetConnectivityListener(null);
}
I have created a BroadCast Receiver to notify the GPS state as below :
public class GpsLocationReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().matches("android.location.PROVIDERS_CHANGED")) {
Toast.makeText(context, "asdsadasdsaD", Toast.LENGTH_SHORT).show();
}
}
Receiver in Manifest as below :
<receiver android:name=".utility.GpsLocationReceiver">
<intent-filter>
<action android:name="android.location.PROVIDERS_CHANGED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
Now, the issue is that What if I want to check gps state only in single Fragment ? Right now it broadcasting for overall app.
Thanks.
ReceiverActivity.java
A Activity that watches for notifications for the event named "custom-event-name"
#Override
public void onCreate(Bundle savedInstanceState) {
...
// Register to receive messages.
// We are registering an observer (mMessageReceiver) to receive Intents
// with actions named "custom-event-name".
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
new IntentFilter("custom-event-name"));
}
// Our handler for received Intents. This will be called whenever an Intent
// with an action named "custom-event-name" is broadcasted.
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Get extra data included in the Intent
String message = intent.getStringExtra("message");
Log.d("receiver", "Got message: " + message);
}
};
#Override
protected void onDestroy() {
// Unregister since the activity is about to be closed.
LocalBroadcastManager.getInstance(this)
.unregisterReceiver(mMessageReceiver);
super.onDestroy();
}
SenderActivity.java
Intent intent = new Intent("custom-event-name");
// You can also include some extra data.
intent.putExtra("message", "This is my message!");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
in OnResume() of your fragment write
LocalBroadcastManager.getInstance(context).registerReceiver(gpsChangeReceiver , new IntentFilter("android.location.PROVIDERS_CHANGED"));
An in onPause() of your fragment write
LocalBroadcastManager.getInstance(context).unregisterReceiver(gpsChangeReceiver );
At bottom of your fragment write
private BroadcastReceiver gpsChangeReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "asdsadasdsaD", Toast.LENGTH_SHORT).show();
}
};
I want my app to be aware anytime the user changes the locale. So in my Application class, I create a receiver to listen to the system intent ACTION_LOCALE_CHANGED:
public final class MyApp extends Application {
private BroadcastReceiver myReceiver = new BroadcastReceiver() {
#Override public void onReceive(Context context, Intent intent) {
String locale = Locale.getDefault().getCountry();
Toast.makeText(context, "LOCALE CHANGED to " + locale, Toast.LENGTH_LONG).show();
}
};
#Override public void onCreate() {
IntentFilter filter = new IntentFilter(Intent.ACTION_LOCALE_CHANGED);
LocalBroadcastManager.getInstance(this).registerReceiver(myReceiver, filter);
}
}
When I press home and go to the settings app to change my locale, the Toast is not shown. Setting the breakpoint inside onReceive shows it never gets hit.
Why do you want the BroadcastReceiver in Application class. My suggestion is to have a separate class for BroadcastRecevier.
public class LocaleChangedReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction (). compareTo (Intent.ACTION_LOCALE_CHANGED) == 0)
{
Log.v("LocaleChangedRecevier", "received ACTION_LOCALE_CHANGED");
}
}
}
and register your Brodcast receiver in Manifest file.
<receiver
android:name=".LocaleChangedReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.LOCALE_CHANGED" />
</intent-filter>
</receiver>
Intent.ACTION_LOCALE_CHANGED is not a local broadcast, so it won't work when you register it with LocalBroadcastManager. LocalBroadcastManager is used for the broadcast used inside your app.
public class MyApp extends Application {
private BroadcastReceiver myReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String locale = Locale.getDefault().getCountry();
Toast.makeText(context, "LOCALE CHANGED to " + locale,
Toast.LENGTH_LONG).show();
}
};
#Override
public void onCreate() {
super.onCreate();
IntentFilter filter = new IntentFilter(Intent.ACTION_LOCALE_CHANGED);
registerReceiver(myReceiver, filter);
}
}
I am trying to set up a service that checks when a new update of an activity is installed in a device. I have already done so within an application activity, declaring the Broadcastreceiver in the manifest and it works perfectly.
However, when I try to run that receiver within a Service and dynamically declare it, my onReceive never gets called. This is my Service code:
public class UpdateService extends Service {
private static String mPackage = "com.my.package";
private static String mActivityName = "myActivity";
private BroadcastReceiver mUpdateReceiver;
#Override
public void onCreate() {
super.onCreate();
mUpdateReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("mTag","In the BroadcastReceiver onReceive()");
if (intent.getAction().equalsIgnoreCase(Intent.ACTION_PACKAGE_REPLACED)) {
// Log that a new update is has been found
Log.d("mTag","New version of the app has been installed.");
Log.d("mTag", "Intent data: " + intent.getDataString());
Log.d("mTag","My package: " + mPackage);
}
}
};
Log.d("mTag","In the service onCreate() method.");
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
filter.addAction(Intent.ACTION_PACKAGE_ADDED);
registerReceiver(mUpdateReceiver,filter);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("mTag","UpdateService started");
return Service.START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(mUpdateReceiver);
Log.d("mTag","Service destroyed");
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
}
The Log in the Service onCreate() gets called, which tells me that the service is up and running. However, after installing and replacing some apps through the adb, none of the logs in the BroadcastReceiver the method onReceive() get called.
This is my MainActivity:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService(new Intent(this, UpdateService.class));
}
}
Do you guys have any ideas why the onReceive() does not get called?
Thank you.
I based my code in these two references:
BroadcastReceiver within a Service
How to know Android app upgraded?
you should add the data schema to your IntentFilter.
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
filter.addAction(Intent.ACTION_PACKAGE_ADDED);
filter.addDataScheme("package");
registerReceiver(mUpdateReceiver,filter);
If you are trying to listen to the ACTION_PACKAGE_REPLACED broadcast, this cannot be done from service. Most probably, the replacement will happen when your application is closed. That`s why you will not listen to it.
You should register from the Manifest to let your OS know that you want to listen to this Intent then Create a class that extentsBroadcastReceiver` as the following:
Manifest:
<receiver android:name="PackageChangeReceiver" >
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<data android:scheme="package" />
</intent-filter>
</receiver>
Receiver:
public class PackageChangeReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_PACKAGE_REPLACED) && intent.getDataString().contains(context.getPackageName())) {
Log.d("Tag", "Package has been replaced");
Log.d("Tag", "Intent data: " + intent.getDataString());
Log.d("Tag", "Action: " + intent.getAction());
}
}
}
I have checked if intent.getDataString().contains(context.getPackageName()) to make sure that the replacement of the package is mine not any other application.
i want to make my app to be run in background and listens for
contact,sms deletion events.
for that i created a service in my app but i dnt how to start without activity
my code is like this
public class DeleteService extends Service {
ContentResolver cr;
MyContentObserver observer=new MyContentObserver();
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return mBinder;
}
#Override
public void onCreate() {
cpath=ContactsContract.Contacts.CONTENT_URI;
// some action
}
#Override
public void onDestroy() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Launch a background thread to do processing.
super.onStartCommand(intent, flags, startId);
cpath=ContactsContract.Contacts.CONTENT_URI;
cr=getContentResolver();
cur=cr.query(cpath, null, null, null, null);
this.getApplicationContext().getContentResolver().registerContentObserver(cpath, true, observer);
return Service.START_STICKY;
}
private class MyContentObserver extends ContentObserver {
public MyContentObserver() {
super(null);
}
#Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
nfm=(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
int NOTIFICATION_ID = 1;
Intent intent1 = new Intent();
PendingIntent pi = PendingIntent.getActivity(DeleteService.this, 1, intent1, 0);
nf=new Notification(R.drawable.ic_launcher,"Contact Database changed",System.currentTimeMillis());
nf.setLatestEventInfo(getApplicationContext(), "Delete Event", "contact name", pi);
nf.flags = nf.flags |
Notification.FLAG_ONGOING_EVENT;
}
#Override
public boolean deliverSelfNotifications()
{
super.deliverSelfNotifications();
return true;
}
}
public class LocalBinder extends Binder {
DeleteService getService() {
return DeleteService.this;
}
}
}
register ACTION_SCREEN_ON or ACTION_USER_PRESENT broadcast recivers for your Appliction in Service and start Service when screen is on or user is present. you can register ACTION_SCREEN_OFF broadcast reciver for stoping Service when phone screen is off to avoid battery drain by your app.as:
In manifest.xml:
<receiver android:name="com.my.AppStart">
<intent-filter>
<action android:name="android.intent.action.SCREEN_ON" />
<action android:name="android.intent.action.SCREEN_OFF" />
<action android:name="android.intent.action.USER_PRESENT" />
</intent-filter>
</receiver>
BroadcastReceiver :
public class AppStart extends BroadcastReceiver {
public static final String present = "android.intent.action.USER_PRESENT";
public static final String screenon = "android.intent.action.SCREEN_ON";
public static final String screenoff = "android.intent.action.SCREEN_OFF";
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(present) || intent.getAction().equals(screenon) )
{
Intent i=new Intent(context,DeleteService.class);
context.startService(i);
}
if (intent.getAction().equals(screenoff))
{
//STOP YOUR SERVICE HERE
}
}
}
A service can only by started by an Activity, or a BroadCast receiver, or a service which is already started. It can't be stand-alone(It can't start by itself). So, you would need one of the two components to start it. you can make an activity which starts the service which is the preferred way. But if you don't want to provide a user interface, implement a broadcast receiver which fires up when the phone is switched on and the boot up is completed, Inside that br, start your service. This will also help you run the service as soon as a phone starts.
for example in your manifest:
<receiver android:name="com.my.MyBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
and in the br:
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent i=new Intent(context,DeleteService.class);
context.startService(i);
}
}
In your activity .. put this code in oncreate
Intent svc=new Intent(youractivity.this,DeleteService.class);
startService(svc);