I'm trying to implement a feature which would read the notification and it seems that I've a bug in it because the onNotificationPosted() of the NotificationListenerService is never called. I configured the manifest, modified the security settings properly and even started the service manually but it did nothing. Can it be that testing it in an emulator is not the best way to proceed.
Here is the Notification getter class:
/**
* Created by laurentmeyer on 28/02/15.
*/
public class NotificationListener extends NotificationListenerService {
public NotificationListener(){
Log.d("Notification", "Created");
}
#Override
public void onNotificationPosted(StatusBarNotification sbn) {
Notification mNotification = sbn.getNotification();
Intent intent = new Intent("Msg");
Log.d("Notification", "Received");
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
}
#Override
public void onCreate() {
super.onCreate();
Log.d("Notification", "created");
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d("Notification", "destroyed");
}
#Override
public void onNotificationRemoved(StatusBarNotification sbn) {
}
}
(Sorry for the incorrect indentation)
This is my Fragment which should respond to the broadcasts:
public class VerificationFragment extends BaseFragment implements SMSReceivedCallbacks {
public void onNotificationReceived(int code) {
ed.setText("OK");
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(new Receiver(), new IntentFilter("Msg"));
}
// A bunch of other useless stuff
private class Receiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
onNotificationReceived(0);
}
}
}
The Manifest:
<service
android:name=".NotificationListener"
android:label="#string/service_name"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" >
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>
To summarise, I've:
02-28 11:40:53.236 6585-6585/com.******.laurentmeyer.****** D/Notification﹕ Created
02-28 11:40:53.236 6585-6585/com.******.laurentmeyer.****** D/Notification﹕ created
and then nothing. I already looked at all the threads on SO but maybe missing something really simple.
Enable Notification Access in your settings:
if (Settings.Secure.getString(this.getContentResolver(), "enabled_notification_listeners").contains(getApplicationContext().getPackageName())) {
//Add the code to launch the NotificationService Listener here.
} else {
//Launch notification access in the settings...
getApplicationContext().startActivity(new Intent(
"android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"));
}
Related
I am making some animation in android and I want to pause it whenever notification pops up in screen. For example sms, message from messenger, whatsApp, viber etc.
I don't need to know what is the type of notification or handle it somehow. I just need to know when it pops up so I can call my pause() method. How I can achieve this?
What you need is a notification listener service.
public class NotificationService extends NotificationListenerService {
Context context;
#Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
}
#Override
public void onNotificationPosted(StatusBarNotification sbn) {
// Send a braoadcast with some data
Intent notificationMessage = new Intent("SomeData");
notificationMessage.putExtra("Hello", "World");
LocalBroadcastManager.getInstance(context).sendBroadcast(notificationMessage);
}
#Override
public void onNotificationRemoved(StatusBarNotification sbn) {
Log.i("Msg","Notification Removed");
}
}
You can recieve the Local broadcast in you activity as follows
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LocalBroadcastManager.getInstance(this).registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String data = intent.getStringExtra("Hello");
// Do something with the data
}
}, new IntentFilter("SomeData"));
}
}
Also register the service in manifest
<service
android:name=".NotificationService"
android:label="#string/app_name"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>
</service>
you can find the official documentation here https://developer.android.com/reference/android/service/notification/NotificationListenerService
You can also find detailed demo here http://www.androiddevelopersolutions.com/2015/05/android-read-status-bar-notification.html
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 an activity which just displays a daily counter. When the day ends, i want to send a notification with last day counter, insert it in a db and if the app is running update the counters label to zero.
I think i must register a static <receiver>android.intent.action.DATE_CHANGED</receiver>. so as to get notified even if the activity is not running.
There I insert the value in DB and i send the notification.
And a dynamic created broadcast receiver which i will unregister onPause, which receives the same events, but it will only update the UI and specifically the label.
Is this the best solution?
Is there any way from a broadcastReceiver to make my Activity (if is running) to go to resume again ?
Is it possible from broadcastReceiver to call a Service, which will update my UI if my Activity is running?
Use broadcastreceiver that would catch the event
public class EventReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
ComponentName comp = new ComponentName(context.getPackageName(),
NotificationService.class.getName());
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
broadcastreceiver give event service
public class NotificationService extends IntentService {
private final ServiceBinder binder = new ServiceBinder();
private ServiceListener serviceListener;
public NotificationService() {
super("NotificationService");
}
#Override
public IBinder onBind(Intent intent) {
return binder;
}
#Override
public boolean onUnbind(Intent intent) {
serviceListener = null;
return true;
}
#Override
public void onRebind(Intent intent) {
super.onRebind(intent);
}
#Override
protected void onHandleIntent(Intent intent) {
//send notification
if(serviceListener != null){
serviceListener.updateActivity();
}
}
public void setServiceListener(ServiceListener serviceListener) {
this.serviceListener = serviceListener;
}
public class ServiceBinder extends Binder {
public NotificationService getSevice(){
return NotificationService.this;
}
}
public static interface ServiceListener{
public void updateActivity();
}
}
then you need to connect to the service in your activity
public class MainActivity extends Activity implements NotificationService.ServiceListener {
private boolean isBound;
private ServiceConnection serviceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
NotificationService.ServiceBinder binder = ((NotificationService.ServiceBinder)service);
binder.getSevice().setServiceListener(MainActivity.this);
isBound = true;
}
#Override
public void onServiceDisconnected(ComponentName name) {
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
protected void onResume() {
super.onResume();
if(!isBound) {
Intent intent = new Intent(this, NotificationService.class);
bindService(intent, serviceConnection, BIND_AUTO_CREATE);
}
}
#Override
protected void onPause() {
super.onPause();
if(isBound){
unbindService(serviceConnection);
isBound = false;
}
}
#Override
public void updateActivity() {
runOnUiThread(new Runnable() {
#Override
public void run() {
//update you list here
}
});
}
}
and do not forget to mention the service and broadcastreceiver in the manifest file and specify the intent filter
<receiver android:name="EventReceiver">
<intent-filter>
<action android:name="........." />
</intent-filter>
</receiver>
<service android:name="NotificationService"/>
You can simply use a LocalBroadcastReceiver to send events to your Activity , a working example could be found here
After more reading i found that the best solution is the above.
A static broadcast receiver for DATE_CHANGED actions. This will start a Service which will update the db and send a local custom broadcast (com.myBroadcast.WakeUpActivity)
The Activity if is running will register a receiver for the previous custom broadcast (will unregister onPause), and will update the UI.
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.
Hai i have a application using background service.its running clearly.If my mobile is switch off,my service is ound service off.when my application is started then only my background service is strated .i want to restart the service again when mobile switch off?
is it possible?
Anybody explain with code
update
public class loginForm extends Activity
{
#Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView (R.layout.login);
receiver = new ConnectionReceiver();
registerReceiver(receiver,new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
}
private class ConnectionReceiver extends BroadcastReceiver{
private Timer mTimer;
private TimerTask mTimerTask;
#Override
public void onReceive(Context context, Intent intent) {
NetworkInfo info = intent.getParcelableExtra (ConnectivityManager.EXTRA_NETWORK_INFO);
if(null != info)
{
String state = getNetworkStateString(info.getState());
if(state.equals("Connected")){
mTimer = new Timer();
mTimerTask = new TimerTask() {
#Override
public void run() {
loginForm.this.runOnUiThread(new Runnable() {
#Override
public void run() {
//Toast.makeText(getBaseContext(), "Disenabled provider " + provider,
///Toast.LENGTH_SHORT).show();
try{
insertAllGpsInformation();
}
catch(Exception e)
{
Toast.makeText(getBaseContext(), "Your Net Connected or Not Login to Net"+"", Toast.LENGTH_LONG).show();
Log.e("Upload Picture Error:",e.getMessage());
}
}
});
}
};
mTimer.scheduleAtFixedRate(mTimerTask,180000,180000);
}
}
}
}
}
Register for the ACTION_BOOT_COMPLETED (see here for details). Start your service on boot.
You should register a BroadcastReceiver and look for the BOOT_COMPLETED Intent.
Here is link with some details: http://androidgps.blogspot.com/2008/09/starting-android-service-at-boot-time.html
Did I understand your question correctly?
create Broadcast Receiver that with the Intent of BOOT COMPLETED Action.
please refer following links for more help :
http://blog.gregfiumara.com/?p=82
http://marakana.com/forums/android/examples/60.html
You can use
public class BootReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
// TODO Auto-generated method stub
Log.i("BootReceiver :: Start Booting..");
Intent i = new Intent(context, StartService.class); // Start your service class
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
and use the broadcastreciever in androidmanifest.xml as
<receiver android:name=".receiver.BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>