Android remote view pending Intent not working - android

I have a service that I need to stop using a pending intent from the remoteview that is showing a custom notification. I have set the pending intent and registered the broadcast receiver in the manifest. However when I am clicking the button nothing happens. The broadcast receiver is an inner class of the service class.
The inner class broadcast receiver:
public class CancelDownload extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Log.i(TAG, "onReceive: cancel intent");
if(Objects.equals(intent.getAction(), VIDEODOWNLOADACTIONS.STOP)){
stopSelf();
CustomModel model = CustomModel.getInstance();
if (model != null) {
model.changeState();
}
notificationManager.cancel(notificationId);
database.setDownloadFileAsFailed(fileID);
File emptyfile = new File(destinationPath);
if (emptyfile.exists()) {
emptyfile.delete();
}
}
}
}
Manifest:
<receiver android:name=".data.VideoDownloadService$CancelDownload"
android:exported="true"
android:enabled="true">
<intent-filter>
<action android:name="my.action.stopdownload"/>
</intent-filter>
</receiver>
Notification code:
RemoteViews downloadViews = new RemoteViews(context.getPackageName(), R.layout.notificaition_layout);
Intent cancelIntent = new Intent(context, VideoDownloadService.CancelDownload.class);
cancelIntent.setAction(VIDEODOWNLOADACTIONS.STOP);
PendingIntent cancelPendingIntent = PendingIntent.getBroadcast(context, 0, cancelIntent, PendingIntent.FLAG_ONE_SHOT);
//trying both here
downloadViews.setPendingIntentTemplate(R.id.cancel,cancelPendingIntent);
downloadViews.setOnClickPendingIntent(R.id.cancel,cancelPendingIntent);
//setting the view to the notification
builder.setContent(downloadViews)
.setCustomBigContentView(downloadViews);
When I click the button nothing happens the button id is correct. The broadcast receiver has to be an inner class because I have plenty of operations that I want to do if the user clicks cancel.
How do I make it work. Please help.

Related

Keeping the service running indefinitely

I'm trying to write a service that will run in background until removed by the user, I used this code:
Intent activityIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0,
activityIntent, 0);
Notification notification = new Notification.Builder(this).
setContentTitle(getText(R.string.app_name)).
setContentText("Doing stuff").
setContentInfo("").
setSmallIcon(R.drawable.icon).
setDeleteIntent(createOnDismissedIntent(getBaseContext(), notId)).
setContentIntent(pendingIntent).build();
notificationManager.notify(notId,notification);
return START_REDELIVER_INTENT;
The service is supposed to listen for incoming SMS and then do something once it detects an SMS.
Now it works , But if I wait for a little while and then try sending myself an SMS to see if the service is still up , the service does not do any thing implying that the service is down(I think), So my question is , Why would the service be down if i used 'START_REDELIVER_INTENT'?
-I remove the notification in onDestroy function in the service. So while the service stops working after a while the notification is still there implying that the service has not been destroyed
You need autorestart service after reboot.
Manifest:
<service android:exported="false" android:name=".service.YourService" android:enabled="true"></service>
<receiver android:name=".service.YourBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
Also permission:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
Define receiver:
public class YourBootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context arg0, Intent arg1) {
Intent serviceIntent = new Intent(arg0, YourService.class);
arg0.startService(serviceIntent);
}

register broadcastreceiver outside activity

I want to add reminder functionality to my Application.
I have Activity with a Button "Remind in 5 minutes". When I press this Button method setReminderInMinutes calls and in 5 minutes I will get a Dialog Fragment.
public void setReminderInMinutes(int timeInMinutes){
BroadcastReceiver receiver = new BroadcastReceiver() {
#Override public void onReceive(Context context, Intent intent){
ReasonsNonDeliveryDlgFragment cityDlg = ReasonsNonDeliveryDlgFragment.newinstance();
cityDlg.show(getSupportFragmentManager(), CityDlgFragment.TAG);
((Vibrator)getSystemService(VIBRATOR_SERVICE)).vibrate(800);
context.unregisterReceiver(this);
}
};
this.registerReceiver(receiver, new IntentFilter("somemessage"));
PendingIntent pintent = PendingIntent.getBroadcast( this, 0, new Intent("somemessage"), 0 );
AlarmManager manager = (AlarmManager)(this.getSystemService(Context.ALARM_SERVICE));
manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 1000*60*timeInMinutes, pintent);
}
It works well until I stay on this Activity, but when I press back Button Activity destroys, onReceive method never fire and I receive exception:
" android.app.IntentReceiverLeaked: Activity MyActivity has leaked
IntentReceiver MyActivity$1#42136488 that was originally registered
here. Are you missing a call to unregisterReceiver()?"
So, is there anyway to register BroadcastReceiver outside my Activity?
P.S. I have tried to register it in manifest file:
<receiver android:name=".receivers.ReminderReceiver">
<intent-filter>
<action android:name="name"/>
</intent-filter>
</receiver>
But still nothing works. What am I doing wrong?
In your case it will not work because in manifest file you given the action as "name" but while creating intent you given the action as "somemessage". So how it works. Give the same action name in manifest and intent.
Change your code like below
<receiver android:name=".receivers.ReminderReceiver">
<intent-filter>
<action android:name="some_action"/>
</intent-filter>
</receiver>
And in setReminder() method
PendingIntent pintent = PendingIntent.getBroadcast( this, 0, new Intent("some_action"), 0 );
AlarmManager manager = (AlarmManager)(this.getSystemService(Context.ALARM_SERVICE));
manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 1000*60*timeInMinutes, pintent)
The only way to register reciever outside of Activity - register it inside manifest of application. In you case it should look like following:
<receiver android:name=".receivers.ReminderReceiver" >
<intent-filter>
<action android:name="somemessage" />
</intent-filter>
</receiver>
Important to set name in <intent-filter> same as action of your Intent inside sended broadcast.
Try this out
#Override
public void onResume() {
super.onResume();
// Register mMessageReceiver to receive messages.
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
new IntentFilter("my-event"));
}
// handler for received Intents for the "my-event" event
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Extract data included in the Intent
String message = intent.getStringExtra("message");
Log.d("receiver", "Got message: " + message);
}
};
#Override
protected void onPause() {
// Unregister since the activity is not visible
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
super.onPause();
}
It is not necessary to pass a reference of BroadCastReceiver to pending intent. You can also pass the reference of your activity so that it will be called for you when the pending intent goes of.
If you want to use BroadCastReceiver outside of your activity you can declare it in manifest like this
<receiver android:name=".MyReceiver"
android:exported="true">
</receiver>
Then in your activity do this to register it with alarm manager
PendingIntent pintent = PendingIntent.getBroadcast(this, 0, new Intent(this, MyReceiver.class), 0 );
AlarmManager manager = (AlarmManager)(this.getSystemService(Context.ALARM_SERVICE));
manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 1000*60*timeInMinutes, pintent);

Broadcast result is always zero

I'm trying to create an external broadcast service which sends a number. A client (external application) trying to send a request to my service and the service sends back a number. I registered my service and broadcast resiever in AndroidManifest.xml:
<service android:exported="true" android:enabled="true" android:name=".MyService"/>
<receiver android:exported="true" android:enabled="true" android:name=".MyStartServiceReceiver">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>
my broadcast class:
public class MyStartServiceReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent intent1 = new Intent(context, MyService.class);
context.startService(intent1);
}
}
in MyService class I'm trying to put extra data
public void onStart(Intent intent, int startId) {
Log.i(TAG, "service started");
intent.setClass(getApplicationContext(), MyService.class);
intent.setAction(Intent.ACTION_SEND);
intent.putExtra("result", 10);
sendBroadcast(intent);
}
and send it back, but I keep getting zero. To check my service I use adb shell:
adb shell am broadcast -a android.intent.action.SEND
Broadcasting: Intent { act=android.intent.action.SEND }
Broadcast completed: result=0
Does anybody know what's wrong in my service?
You can see here:
http://developer.android.com/reference/android/content/Intent.html
that ACTION_SEND is activity action, it cannot be used with receiver.
So you must switch from receiver to activity, you can make it a hidden activity using Theme.NoDisplay
[edit]
some more explanation: BroadcastReceiver with intent-filter for them?
Try something like this.
Method to send broadcast, used within the MyService
public static void sendSomeBroadcast(Context context, String topic) {
Intent actionIntent = new Intent();
// I would use Constants for these Action/Extra values
actionIntent.setAction(ConstantClass.SEND_SOME_BROADCAST);
actionIntent.putExtra(ConstantClas.BROADCAST_RESULT, 10);
LocalBroadcastManager.getInstance(context).sendBroadcast(actionIntent);
}
In action
public void onStart(Intent intent, int startId) {
sendSomeBroadcast();
}
BroadcastReceiver
public class MyStartServiceReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// do what you want with the intent, for example intent.getExtras()..
Intent intent1 = new Intent(context, MyService.class);
context.startService(intent1);
}
}
Binding the receiver and listening for specific Action
private void bindStartServiceReceiver() {
MyStartServiceReceiver startServiceReceiver = new MyStartServiceReceiver();
//This may need to be changed to fit your application
LocalBroadcastManager.getInstance(this).registerReceiver(subscribeTopicReceiver,
new IntentFilter(ConstantClass.SEND_SOME_BROADCAST));
}

How to bring an Activity to foreground? Nothing work from inside a BroadcastReceiver

I have an activity that receives SMS and I would like it to be brought to the foreground when that happens. It doesn't matter if it is the same instance or a new one. I've tried everything I found in this site, even other flags like FLAG_ACTIVITY_NEW_TASK works fine, but [so far] NOTHING brings the Activity to the foreground.
public class SMSMessenger extends Activity {
private static final String ACTION = "android.provider.Telephony.SMS_RECEIVED";
private BroadcastReceiver yourReceiver;
#Override
public void onCreate(Bundle savedInstanceState) {
final IntentFilter theFilter = new IntentFilter();
theFilter.addAction(ACTION);
this.yourReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Bring activity to the foreground - doesn't work
Intent I = new Intent(context, SMSMessenger.class);
I.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
context.startActivity(I);
//------------------------------------------------
}
};
this.registerReceiver(this.yourReceiver, theFilter);
}
}
I believe what you are looking for is this. Create your receiver as a seperate file (MyBroadcastReceiver.java) and have it launch the activity or popup a notification or whatever. In your AndroidManifest try putting this:
<receiver android:name=".MyBroadcastReceiver">
<intent-filter>
<action android:name=
"android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
Also make sure you include the SMS permission in your AndroidManifest:
<uses-permission android:name="android.permission.RECEIVE_SMS" />
Try this one..
myManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
myNotification = new Notification(R.drawable.alert1, "ALERT...!!", System.currentTimeMillis());
myIntent = new Intent(context, SmsMessanger.class);
myPendingIntent = PendingIntent.getActivity(context, 0, myIntent, 0);
myNotification.setLatestEventInfo(context, "NEW SMS ALERT...!!", "You have a new SMS alert..!! Click here to stop the alert tone...!!", myPendingIntent);
myManager.notify(0, myNotification);
It worked for me..!
when we click on the notification, the activity is brought to front.

How to define an IntentFilter for a Broadcast Receiver

So I am attempting to make an application that will show a toast message when every a text message is received. I want the application to only show the toast, and I currently using this code to show it, but I get an exception error when the application runs. I am using this code
BroadcastReceiver BR = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText( context, "testing", Toast.LENGTH_SHORT ).show();
}
};
IntentFilter filter = new IntentFilter();
registerReceiver(BR, filter);
I'm pretty sure it's the intent filter, but I'm not sure.
You have to make the entry of your broadcastreceiver in manifest then add the intent filter as we add for our activities.It is possible on runtime too.
You should create seperate class which extends BroadcastReceiver
and then override onRecieve method.
Here, AlarmMain.this is main class and
OneShotAlarm.class which extends BroadcaseReceiver :
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText( context, "testing", Toast.LENGTH_SHORT ).show();
}
You can call onRecieve() as per following:
Intent intentAlarm = new Intent(AlarmMain.this, OneShotAlarm.class);
operation = PendingIntent.getBroadcast(AlarmMain.this, 0, intentAlarm, 0);
alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, objDate.getTime(), operation);
You can try following but it is optional (include following tag into AndroidManifest.xml)
<receiver
android:name="com.android.alarm.OneShotAlarm"
android:exported="true">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>

Categories

Resources