I have a widget that is updated by a service. The service also sets an OnClick event for an ImageButton that is in the widget layout. The way I do this is by setting a PendingIntent that is supposed to open the service.
However, when I click the refresh button, nothing happens.
public void setRefreshButton(Context context, RemoteViews views) {
Intent widgetUpdateIntent = new Intent(context, UpdateService.class);
PendingIntent pendingRefreshIntent = PendingIntent.getActivity(
context, 0, widgetUpdateIntent, 0);
}
views.setOnClickPendingIntent(R.id.widget_button_refresh,
pendingRefreshIntent);
}
I have a log at the first line of onStart() of my service, but that doesn't even show up in LogCat. What am I doing wrong?
Your PendingIntent attempts to starts an Activity, not a Service. Try with PendingIntent.getService.
Related
I want to know how to link widget and activity in android so that by clicking the widget only call some functios to do work but Not launch the activity something like when we click bluetooth in notification bar it just open bluetooth or close bluetooth without entering to that bluetooth app......
Thanks in advance :)
UPDATED ::
Below is Main Activity Code.
imageFlashlight.setOnClickListener(new View.OnClickListener() {
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
#Override
public void onClick(View view) {
if (finalHasCameraFlash) {
if (flashLightStatus)
flashLightOff();
else
flashLightOn();
} else {
Toast.makeText(MainActivity.this, "No flash available on your device",
Toast.LENGTH_SHORT).show();
}
}
});
The Code below is my widget code...
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {
// Construct the RemoteViews object
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.app_widget);
// Construct an Intent object includes web adresss.
Intent intent = new Intent(context, MainActivity.class);
// In widget we are not allowing to use intents as usually. We have to use PendingIntent instead of 'startActivity'
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
// Here the basic operations the remote view can do.
views.setOnClickPendingIntent(R.id.tvWidget, pendingIntent);
// Instruct the widget manager to update the widget
appWidgetManager.updateAppWidget(appWidgetId, views);
}
UPDATED : As you can see i want to handle two functions by clicking the widget Without Entering to the activity just by tapping..
You can try sending Broadcast as
Intent broadcastIntent=new Intent(this,BroadcastReceiver.class);
//use .getBroadcast instead of getActivity and start a service when u receive this
//broadcast
PendingIntent pendingBroadcastIntent = PendingIntent.getBroadcast(context, 7, broadcastIntent, 0)
//set this pendingIntent on widget
the PendingIntent.getBroadcast() method will do the trick.
Remember to start the service when you receive this broadcast you can also set action on the intent using broadcastIntent.setAction(YOUR_ACTION).
Regards,
Karya
Having quite a bit of trouble getting my foreground service to simply dismiss on swipe or by the clear all notifications button. I know there are several questions like this, but I have read them and will list some of what I've already tried. I tried this method, where you pass a simple intent with an extra into a pending intent, then add that pending intent to setDeleteIntent(). That didn't work, it never gets called.
I also tried this (second highest answer, "fully fleshed out" version), with the same results. Which ties in to the "answer" of this question as well. With how many apps have notifications that are dismissible with a swipe or clear all button, I must be missing something very obvious and I can't figure out what.
What my current code looks like (all of this inside of my service class).
BroadcastReceiver class
public class NotificationDismissedReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// this is never called
stopSelf();
}
}
// in the manifest for that BroadcastReceiver, have also tried it with these values false
android:exported="true"
android:enabled="true"
Pending intent
private PendingIntent createOnDismissedIntent(Context context, int notificationId) {
Intent intent = new Intent(context.getApplicationContext(), NotificationDismissedReceiver.class);
PendingIntent pendingIntent =
PendingIntent.getBroadcast(context.getApplicationContext(),
notificationId, intent, 0);
return pendingIntent;
}
In the notification builder (101 is what I startForeground with)
.setDeleteIntent(createOnDismissedIntent(this, 101))
Edit:
Separate file receiver used instead of the inner class version.
public class NotificationDismissedReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
int notificationId = intent.getExtras().getInt("notificationId");
/* Your code to handle the event here */
if(notificationId == 101){
Intent stopIntent = new Intent(context, AssistorServiceClass.class);
context.stopService(stopIntent);
}
}
}
Edit2
To be clear, I'm not trying to stop the foreground notification and keep the service alive. I want them both just gone, as if I called stopSelf within the service class.
I want to know is there a way for the NotificationListenerService to know if a Notification has been clicked or it has been dismissed. I can see that the Inner class NotificationListenerWrapper in NotificationListenerService has a onNotificationClick() method , but since the NotificationListenerWrapper is hidden with #hide annotation I'm not able to use that.
My question is Can I write a Listener which basically keeps track of whether a notification has been clicked or dismissed.
Basically I want to track if the notifications of my App is being dismissed or they are clicked without any intrusive code in each and every Notification.
P.S. NotificationListenerService provides only onNotificationPosted() and onNotificationRemoved(), but my requirement is to know if notifications are clicked or Removed.
Thanks
When you create and show a notification, you provide a PendingIntent for when it is clicked (using .setContentIntent). You can also define a PendingIntent for when it gets dismissed(using .setDeleteIntent(PendingIntent).
If you want to be able to track your Notifications, you need to pass a PendingIntent (like a BroadcastReceiver or IntentService) and pass a few parameters like notificationId and isDismissed and do your work in the BroadcastReceiver.
You can see the complete code in this answer.
I don't think there is a listener for this. But you can implement this logic in another way using PendingIntent and BroadcastReceiver
For OnClick
add a ContentIntent and BroadcastReceiver. So you will know that your notification is clicked or not in the BroadcastReceiver
Intent onClickIntent = new Intent(this, OnClickBroadcastReceiver.class);
PendingIntent onClickPendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 0, onClickIntent, 0);
mBuilder.setContentIntent(onClickPendingIntent);
And inside the BroadcastReceiver you can write your logic
public class OnClickBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//Open your activity here
Intent mainIntent = new Intent(context, YourActivity.class);
context.startActivity(mainIntent);
// Do your onClick related logic here
}
}
For onDismiss
For this you need to add a DeleteIntent into your notification builder
Intent onCancelIntent = new Intent(this, OnCancelBroadcastReceiver.class);
PendingIntent onDismissPendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 0, onCancelIntent, 0);
mBuilder.setDeleteIntent(onDismissPendingIntent);
and BroadcastReceiver for this is
public class OnCancelBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//Do your logic here
}
}
Don't forget to register these BroadcastReceiver to AndroidManifest
I have a notification layout which is something like this:
My service is ongoing. I want a notification/event sent to my service when stop button is pressed. Click event on notification view is not required.
When the button is pressed, I want my service to stop.
Currently, I'm trying to do this by sending broadcast to an activity (as I did not find a way to directly inform service of the button press).
My current code is:
Intent intent = new Intent(this, MediaEventsReceiver.class);
PendingIntent pending = PendingIntent.getActivity(this, 1, intent, 0);
contentView.setOnClickPendingIntent(R.id.btnStop, pending);
I've also added the reciver in my manifest:
<receiver android:name=".activities.SplashActivity$MediaEventsReceiver" />
Please use code example(s) to explain.
I'm developing a music player app using SINGLE activity. You can add listener to your button like this:
Bind intent
Intent intent = new Intent("ACTION_NAME");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.previousImageView, pendingIntent);
Implement a custom BroadcastReceiver
private class ActionBroadcastReceiver extends BroadcastReceiver
{
public void onReceive(Context context, Intent intent)
{
switch (intent.getAction())
{
case "ACTION_NAME":
{
doSomething();
break;
}
}
}
}
Register your BroadcastReceiver
IntentFilter filter = new IntentFilter();
filter.addAction("ACTION_NAME");
ActionBroadcastReceiver actionBroadcastReceiver = new ActionBroadcastReceiver();
registerReceiver(actionBroadcastReceiver, filter);
SOLVED:
I've used another activity which is called on button click by PendingIntent.
The new activity binds the service and sends it a stop message.
Right after it, it unbinds itself and finishes.
STILL:
I want a solution which does not involve a third activity. There SHOULD be a way where the button click in notification directly informs service and service stops itself. There is NO NEED of an activity for this task.
After lots of efforts in doing this, i finally asking. I have widget with textview, button and imageview. both views are loaded from preference. I am able to start myActivityA when user clicks textview and myActivityB when user clicks imageview from widget. But not able to receive onclick event (in service) for button. I am doing this in following manner.
MyWidgetProvider class
final ComponentName serviceName = new ComponentName(context, "com.mypkg.MyService");
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_main);
Intent intent = new Intent(Service.TOGGLE_ACTION);
intent.setComponent(serviceName);
PendingIntent pendingIntent = PendingIntent.getService(context,0 /* no requestCode */, intent, 0 /* no flags */);
remoteViews.setOnClickPendingIntent(R.id.widget_button1, pendingIntent);
In MyService class,
// broadcast message receiver for commands to service.
private BroadcastReceiver mIntentReceiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
String cmd = intent.getStringExtra("Command");
if (TOGGLE_ACTION.equals(action))
{
m_iKey = intent.getIntExtra("MyService.MyKey", 0);
// call functions defined in MyService.
}
}
};
My problem is i am not able to receive TOGGLE_ACTION in service at all. OnStartCommand is called in MyService,
Can any one suggest what could be issue?
What exactly i want from button click event is....
If service is not started (service is started in first activity, life span is now limited to activity) then start it... and TOGGLE_ACTION should be executed.
IF service is already started(means my activity is minimized) then TOGGLE_ACTION should be executed.
Is there any other way to achieve this?
Or other way to pass some data and call some routine of service from widget?
try this,
Intent intent= new Intent(context, myActivityB.class);
PendingIntent pending=PendingIntent.getActivity(context, 0 , intent,PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.button, pending);
R.id.button this is your button Id.