问题
I have a background service running and a notification listener. I want to call the notification listener from the background service and it does not seem to work. I have below my classes. 1. Main activity starts the service 2.MyService is the background service running 3. NLService is the notification listeners service I want to call inside the MyService
MainActivity.java
package com.example.notifyservice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.example.eg.intentserviceexample.R;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//setting button click
findViewById(R.id.btn_start_service).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Creating an intent for sending to service
Intent intent = new Intent(getApplicationContext(), MyService.class);
intent.putExtra("id", 101);
intent.putExtra("msg", "hi");
//starting service
startService(intent);
}
});
}
@Override
protected void onStart() {
super.onStart();
//register broadcast receiver for the intent MyTaskStatus
LocalBroadcastManager.getInstance(this).registerReceiver(MyReceiver, new IntentFilter("MyServiceStatus"));
}
//Defining broadcast receiver
private BroadcastReceiver MyReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String message = intent.getStringExtra("serviceMessage");
Toast.makeText(MainActivity.this, "Received : " + message, Toast.LENGTH_SHORT).show();
}
};
@Override
protected void onStop() {
super.onStop();
LocalBroadcastManager.getInstance(this).unregisterReceiver(MyReceiver);
}
}
MyService.java
package com.example.notifyservice;
import android.app.IntentService;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.widget.TextView;
public class MyService extends IntentService {
private TextView txtView;
private NotificationReceiver nReceiver;
public MyService() {
super(MyService.class.getName());
}
@Override
protected void onHandleIntent(Intent intent) {
//retrieving data from the received intent
int id = intent.getIntExtra("id",0);
String message = intent.getStringExtra("msg");
Log.i("Data ", "id : "+id+" message : "+ message );
//-----------------------------------------------
//Do your long running task here
Intent i = new Intent("com.example.notifyservice.NOTIFICATION_LISTENER_SERVICE_EXAMPLE");
i.putExtra("command","list");
sendBroadcast(i);
//------------------------------------------------
/* //Broadcasting some data
Intent myIntent = new Intent("MyServiceStatus");
myIntent.putExtra("serviceMessage", "Task done");
// Send broadcast
LocalBroadcastManager.getInstance(this).sendBroadcast(myIntent);*/
}
class NotificationReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String temp = intent.getStringExtra("notification_event") + "\n" + txtView.getText();
txtView.setText(temp);
}
}
}
NLService.java
package com.example.notifyservice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Bundle;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.support.annotation.RequiresApi;
import android.util.Log;
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
public class NLService extends NotificationListenerService {
private String TAG = this.getClass().getSimpleName();
private NLServiceReceiver nlservicereciver;
@Override
public void onCreate() {
super.onCreate();
nlservicereciver = new NLServiceReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("com.example.notify.NOTIFICATION_LISTENER_SERVICE_EXAMPLE");
registerReceiver(nlservicereciver,filter);
}
@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(nlservicereciver);
}
@Override
public void onNotificationPosted(StatusBarNotification sbn) {
String pack = sbn.getPackageName();
String text = "";
String title = "";
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
Bundle extras = sbn.getNotification().extras;
text = extras.getCharSequence("android.text").toString();
title = extras.getString("android.title");
}
Log.i("Package",pack);
Log.i("Title",title);
Log.i("Text",text);
}
@Override
public void onNotificationRemoved(StatusBarNotification sbn) {
Log.i(TAG,"********** onNOtificationRemoved");
Log.i(TAG,"ID :" + sbn.getId() + "t" + sbn.getNotification().tickerText +"\t" + sbn.getPackageName());
Intent i = new Intent("com.example.notify.NOTIFICATION_LISTENER_EXAMPLE");
i.putExtra("notification_event","onNotificationRemoved :" + sbn.getPackageName() + "\n");
sendBroadcast(i);
}
class NLServiceReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getStringExtra("command").equals("list")){
Intent i1 = new Intent("com.example.notify.NOTIFICATION_LISTENER_EXAMPLE");
i1.putExtra("notification_event","=====================");
sendBroadcast(i1);
int i=1;
for (StatusBarNotification sbn : NLService.this.getActiveNotifications()) {
Intent i2 = new Intent("com.example.notify.NOTIFICATION_LISTENER_EXAMPLE");
i2.putExtra("notification_event",i +" " + sbn.getPackageName() + "\n");
sendBroadcast(i2);
i++;
}
Intent i3 = new Intent("com.example.notify.NOTIFICATION_LISTENER_EXAMPLE");
i3.putExtra("notification_event","===== Notification List ====");
sendBroadcast(i3);
}
}
}
}
The bacgkround service starts but does not see the NLSErvice. Any help will be much appreciated!
Edit the manifest too:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.eg.intentserviceexample">
<uses-sdk android:minSdkVersion="18"
android:targetSdkVersion="18"
/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name="com.example.notifyservice.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name="com.example.notifyservice.MyService"
android:exported="false"/>
<service android:name="com.example.notifyservice.NLService"
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>
</application>
</manifest>
回答1:
So what I did wrong is that I tried to create 2 services. Instead I only needed one. Here is the code that works. What it simply does is starting the bacgrkound service and counts the notifications.When you click report it shows all the notifications, even if the user has close the app. I have put extra code for making a notification after 5 notifications.
MainActivity.java
package com.example.notifyservice;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends AppCompatActivity {
/*
protected final Timer myTimer = new Timer("MainActivityTimer", false);
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
// FIRST OF ALL
// START SERVICE AS STICKY - BY EXPLICIT INTENT
// to prevent being started by the system (without the sticky flag)
Intent intent = new Intent(getApplicationContext(), NLService.class);
// TODO: to be removed
intent.putExtra("id", 101);
intent.putExtra("msg", "hi");
//starting service
startService(intent);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent i = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
startActivity(i);
//setting button click
findViewById(R.id.btn_start_service).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Ask service (async) for its status (manually after the main activity was paused or closed and missed some NLService's broadcasts)
// the background service is sticky and the counters(added/removed) are not reset.
//Creating an intent for sending to service
//Intent intent = new Intent(getApplicationContext(), MyService.class);
Intent intent = new Intent(getApplicationContext(), NLService.class);
intent.putExtra("command", "get_status");
//starting service
startService(intent);
}
});
}
@Override
protected void onStart() {
super.onStart();
// register broadcast receiver for the intent MyTaskStatus
LocalBroadcastManager.getInstance(this).registerReceiver(MyReceiver, new IntentFilter(NLService.ACTION_STATUS_BROADCAST));
}
//Defining broadcast receiver
private BroadcastReceiver MyReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.i("MainActivity", "Broadcast Recieved: "+intent.getStringExtra("serviceMessage"));
String message = intent.getStringExtra("serviceMessage");
Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show();
}
};
@Override
protected void onStop() {
super.onStop();
LocalBroadcastManager.getInstance(this).unregisterReceiver(MyReceiver);
}
}
NLService.java
package com.example.notifyservice;
import android.app.IntentService;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.support.annotation.RequiresApi;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
// @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
public class NLService extends NotificationListenerService {
public static final String ACTION_STATUS_BROADCAST = "com.example.notifyservice.NLService_Status";
private String TAG = this.getClass().getSimpleName();
private NLServiceReceiver nlservicereciver;
/**
* The number of notifications added (since the service started)
*/
private int nAdded=0;
/**
* The number of notifications removed (since the service started)
*/
private int nRemoved=0;
int temp = 5;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//retrieving data from the received intent
if(intent.hasExtra("command")) {
Log.i("NLService", "Started for command '"+intent.getStringExtra("command"));
broadcastStatus();
} else if(intent.hasExtra("id")) {
int id = intent.getIntExtra("id", 0);
String message = intent.getStringExtra("msg");
Log.i("NLService", "Requested to start explicitly - id : " + id + " message : " + message);
}
super.onStartCommand(intent, flags, startId);
// NOTE: We return STICKY to prevent the automatic service termination
return START_STICKY;
}
private void broadcastStatus() {
Log.i("NLService", "Broadcasting status added("+nAdded+")/removed("+nRemoved+")");
Intent i1 = new Intent(ACTION_STATUS_BROADCAST);
i1.putExtra("serviceMessage","Added: "+nAdded+" | Removed: "+nRemoved);
LocalBroadcastManager.getInstance(this).sendBroadcast(i1);
// sendBroadcast(i1);
}
@Override
public void onCreate() {
super.onCreate();
Log.i("NLService", "NLService created!");
nlservicereciver = new NLServiceReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("com.example.notifyservice.NOTIFICATION_LISTENER_SERVICE_EXAMPLE");
registerReceiver(nlservicereciver,filter);
Log.i("NLService", "NLService created!");
}
@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(nlservicereciver);
Log.i("NLService", "NLService destroyed!");
}
/* > API 21
@Override
public void onListenerDisconnected() {
super.onListenerDisconnected();
Log.w("NLService", "Notification listener DISCONNECTED from the notification service! Scheduling a reconnect...");
// requestRebind(new ComponentName(this.getPackageName(), this.getClass().getCanonicalName()));
}
@Override
public void onListenerConnected() {
super.onListenerConnected();
Log.w("NLService", "Notification listener connected with the notification service!");
}
*/
@Override
public void onNotificationPosted(StatusBarNotification sbn) {
Log.i(TAG,"********** onNotificationPosted");
Log.i(TAG,"ID :" + sbn.getId() + "t" + sbn.getNotification().tickerText + "\t" + sbn.getPackageName());
Intent i = new Intent("com.example.notify.NOTIFICATION_LISTENER_EXAMPLE");
i.putExtra("notification_event","onNotificationPosted :" + sbn.getPackageName() + "\n");
sendBroadcast(i);
nAdded++;
if (nAdded == temp) {
System.out.println("reached" + temp);
temp = temp + 5;
System.out.println(temp);
NotificationManager nManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
NotificationCompat.Builder ncomp = new NotificationCompat.Builder(this);
ncomp.setContentTitle("Notification");
ncomp.setContentText("Notification Listener Service Example");
ncomp.setTicker("Notification Listener Service Example");
ncomp.setSmallIcon(R.mipmap.ic_launcher);
ncomp.setAutoCancel(true);
nManager.notify((int)System.currentTimeMillis(),ncomp.build());
}
broadcastStatus();
}
@Override
public void onNotificationRemoved(StatusBarNotification sbn) {
Log.i(TAG,"********** onNOtificationRemoved");
Log.i(TAG,"ID :" + sbn.getId() + "t" + sbn.getNotification().tickerText +"\t" + sbn.getPackageName());
Intent i = new Intent("com.example.notify.NOTIFICATION_LISTENER_EXAMPLE");
i.putExtra("notification_event","onNotificationRemoved :" + sbn.getPackageName() + "\n");
sendBroadcast(i);
nRemoved++;
broadcastStatus();
}
class NLServiceReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getStringExtra("command").equals("list")){
Intent i1 = new Intent("com.example.notify.NOTIFICATION_LISTENER_EXAMPLE");
i1.putExtra("notification_event","=====================");
sendBroadcast(i1);
int i=1;
for (StatusBarNotification sbn : NLService.this.getActiveNotifications()) {
Intent i2 = new Intent("com.example.notify.NOTIFICATION_LISTENER_EXAMPLE");
i2.putExtra("notification_event",i +" " + sbn.getPackageName() + "\n");
sendBroadcast(i2);
i++;
}
Intent i3 = new Intent("com.example.notify.NOTIFICATION_LISTENER_EXAMPLE");
i3.putExtra("notification_event","===== Notification List ====");
sendBroadcast(i3);
}
}
}
}
回答2:
Did you defined your services in your manifest. For notification service you need to write permission also.
<service
android:name=".MyService"
android:enabled="true"/>
<service android:name=".NLService"
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>
if you want to show notification in that case you need to write this code also:
NotificationManager nManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
NotificationCompat.Builder ncomp = new NotificationCompat.Builder(this);
ncomp.setContentTitle("My Notification");
ncomp.setContentText("Notification Listener Service Example");
ncomp.setTicker("Notification Listener Service Example");
ncomp.setSmallIcon(R.mipmap.ic_launcher);
ncomp.setAutoCancel(true);
nManager.notify((int)System.currentTimeMillis(),ncomp.build());
or did you provide the notification access to your app? Go to your settings and check notification access to your app provided or not?
来源:https://stackoverflow.com/questions/41425986/call-a-notification-listener-inside-a-background-service-in-android-studio