I am trying to implement NotificationChannel and WorkManager but somehow its not working and am not seeing anything Wrong - android-jetpack

I am trying to implement a feature where you choose a date and time and the notification pops up on your phone. so after writing some code its still not working but everything seems fine
Activity code
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
public void onClick(View view) {
Calendar customCalendar = GregorianCalendar.getInstance();
DatePicker dp = findViewById(R.id.date_picker);
TimePicker picker = findViewById(R.id.time_picker);
customCalendar.set(
dp.getYear(), dp.getMonth(), dp.getDayOfMonth(), picker.getHour(), picker.getMinute(), 0);
long customTime = customCalendar.getTimeInMillis();
SimpleDateFormat sdf = new SimpleDateFormat(getString(R.string.notification_schedule_pattern), Locale.getDefault());
long currentTime = System.currentTimeMillis();
Log.d("time", "cistomTime " + customTime);
Log.d("time", "cistomTime " + currentTime);
if (customTime > currentTime) {
Data data = new Data.Builder().putInt(NOTIFICATION_ID, 0).build();
int delay = (int) (customTime - currentTime);
scheduleNotification(delay, data);
String titleNotificationSchedule = getString(R.string.notification_schedule_title);
Snackbar.make(
view,
titleNotificationSchedule + sdf
.format(customCalendar.getTime()),
LENGTH_LONG).show();
// Snackbar.make(coordinatorLayout, "Reminder set", LENGTH_LONG)
// .setAction("Action", null).show();
} else {
String errorNotificationSchedule = "Error occured";
Snackbar.make(coordinatorLayout, errorNotificationSchedule, LENGTH_LONG).show();
}
}
});
}
private void scheduleNotification(long delay, Data data) {
OneTimeWorkRequest notificationWork = new OneTimeWorkRequest.Builder(NotifyWork.class)
.setInitialDelay(delay, MILLISECONDS).setInputData(data).build();
WorkManager instanceWorkManager = WorkManager.getInstance(getApplicationContext());
instanceWorkManager.beginUniqueWork(NOTIFICATION_WORK, REPLACE, notificationWork).enqueue();
}
Worker class
public class NotifyWork extends Worker {
public static final String NOTIFICATION_ID = "notification_id";
public static final String NOTIFICATION_NAME = "Remember";
public static final String NOTIFICATION_CHANNEL = "Reminder_Channel";
public static final String NOTIFICATION_WORK = "Notification_Work";
public NotifyWork(#NonNull Context context, #NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
#NonNull
#Override
public Result doWork() {
int id = getInputData().getInt(NOTIFICATION_ID, 0);
sendNotification(id);
return Result.success();
}
private void sendNotification(int id) {
NotificationManager notificationManager = (NotificationManager) getApplicationContext()
.getSystemService(Context.NOTIFICATION_SERVICE);
Bitmap bitmap = BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.ic_done_white_24dp);
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.putExtra(NOTIFICATION_ID, id);
String titleNotification = "Reminder";
String subtitleNotification = "Time To WakeUp";
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notification = new NotificationCompat.Builder(getApplicationContext(), NOTIFICATION_CHANNEL)
.setLargeIcon(bitmap).setContentTitle(titleNotification)
.setContentText(subtitleNotification).setDefaults(IMPORTANCE_DEFAULT).setSound(getDefaultUri(TYPE_NOTIFICATION))
.setContentIntent(pendingIntent).setAutoCancel(true);
notification.setPriority(IMPORTANCE_MAX);
notificationManager.notify(id, notification.build());
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
Uri ringtoneManager = getDefaultUri(TYPE_NOTIFICATION);
AudioAttributes audioAttributes = new AudioAttributes.Builder().setUsage(USAGE_NOTIFICATION_RINGTONE)
.setContentType(CONTENT_TYPE_SONIFICATION).build();
NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL, NOTIFICATION_NAME, NotificationManager.IMPORTANCE_DEFAULT);
channel.enableLights(true);
channel.setLightColor(RED);
channel.enableVibration(true);
channel.setSound(ringtoneManager, audioAttributes);
notificationManager.createNotificationChannel(channel);
}
}
I have a DatePicker and TimePicker, when you select date and time and click on the FAB button, you get notified at that particular time

somehow changing .setLargeIcon to .setSmallIcon and referencing the image directly without converting to bitmap eg .setSmallIcon(R.drawable.ic_done_white_24dp) solved the issue

Related

Android notifications in a xamarin forms app

I'm working in a xamarin forms app, and I'm trying to develop an Android notification with two buttons:
In the first one you can write text, and this text must be retrieve to one of the ViewModels.
The second one should open a view of the app.
I have no experience with intents nor Android, and so far I can show the notification with the two buttons:
notification example
The class in charge of showing the notification is LocalNotifications : ILocalNotifications class in the Android solution:
class LocalNotifications : ILocalNotifications
{
const string channelId = "default";
const string channelName = "Default";
const string channelDescription = "The default channel for notifications.";
...
bool channelInitialized = false;
int messageId = 0;
int replyPendingIntentId = 0;
int photoPendingIntentId = 0;
NotificationManager manager;
public event EventHandler NotificationReceived;
public static LocalNotifications Instance { get; private set; }
public LocalNotifications() => Initialize();
public void Initialize()
{
if (Instance == null)
{
CreateNotificationChannel();
Instance = this;
}
}
public void SendNotification(string title, string message)
{
if (!channelInitialized)
{
CreateNotificationChannel();
}
Show(title, message);
}
public void ReceiveNotification(string title, string message)
{
var args = new NotificationEventArgs()
{
Title = title,
Message = message,
};
NotificationReceived?.Invoke(null, args);
}
private static readonly string KEY_TEXT_REPLY = "key_text_reply";
AndroidX.Core.App.RemoteInput remoteEntryInput = new AndroidX.Core.App.RemoteInput.Builder(KEY_TEXT_REPLY)
.SetLabel("Escribir entrada")
.Build();
private Intent replyIntent;
private Intent photoIntent;
public void Show(string title, string message)
{
NotificationCompat.Builder builder = new NotificationCompat.Builder(AndroidApp.Context, channelId)
.SetContentTitle(title)
.SetContentText(message)
.SetLargeIcon(BitmapFactory.DecodeResource(AndroidApp.Context.Resources, Resource.Drawable.abc_ab_share_pack_mtrl_alpha))
.SetSmallIcon(Resource.Drawable.abc_ab_share_pack_mtrl_alpha)
.SetDefaults((int)NotificationDefaults.Sound | (int)NotificationDefaults.Vibrate);
NotificationCompat.Action reply = CreateReplyIntent(title, message);
builder.AddAction(reply);
NotificationCompat.Action image = CreateImageIntent();
builder.AddAction(image);
Notification notification = builder.Build();
manager.Notify(messageId++, notification);
}
NotificationCompat.Action CreateReplyIntent(string title, string message)
{
//replyIntent = new Intent(AndroidApp.Context, typeof(MainActivity));
replyIntent = new Intent();
replyIntent.PutExtra(TitleKey, title);
replyIntent.PutExtra(MessageKey, message);
// Build a PendingIntent for the reply action to trigger.
PendingIntent replyPendingIntent =
PendingIntent.GetBroadcast(AndroidApp.Context, replyPendingIntentId++, replyIntent, PendingIntentFlags.UpdateCurrent);
// Create the reply action and add the remote input.
return new NotificationCompat.Action.Builder(Resource.Drawable.abc_ab_share_pack_mtrl_alpha,
"Escribir entrada", replyPendingIntent)
.AddRemoteInput(remoteEntryInput)
.Build();
}
NotificationCompat.Action CreateImageIntent()
{
//photoIntent = new Intent("android.media.action.IMAGE_CAPTURE");
photoIntent = new Intent(AndroidApp.Context, typeof(MainActivity));
//photoIntent.SetFlags( ActivityFlags.LaunchAdjacent | Intent.FLAG_ACTIVITY_CLEAR_TASK);
// Build a PendingIntent for the reply action to trigger.
PendingIntent phtoPendingIntent = PendingIntent.GetBroadcast(AndroidApp.Context, photoPendingIntentId++, photoIntent, PendingIntentFlags.UpdateCurrent);
return new NotificationCompat.Action.Builder(Resource.Drawable.abc_ab_share_pack_mtrl_alpha,
"Sacar foto", phtoPendingIntent)
.Build();
}
void CreateNotificationChannel()
{
manager = (NotificationManager)AndroidApp.Context.GetSystemService(AndroidApp.NotificationService);
if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
{
var channelNameJava = new Java.Lang.String(channelName);
var channel = new NotificationChannel(channelId, channelNameJava, NotificationImportance.Default)
{
Description = channelDescription
};
manager.CreateNotificationChannel(channel);
}
channelInitialized = true;
}
}
Which a don't get is how/where the app can react to those PendintIntents and how to pass the information from the android solution to the xamarin forms model.

Spring Kafka Unit Tests Triggers the listener, but the method cannot get the message using consumer.poll

We are using spring-kafka-test-2.2.8-RELEASE.
When I use the template to send the message, it triggers the listener correctly, but I can't get the message content in the consumer.poll. If i instantiate the KafkaTemplate without "wiring" it in a class attribute and Instantiate it based on a producer factory, it sends the message, but does not trigger the #KafkaListener, only work if I setup a Message Listener inside the #Test Method. I need to trigger the kafka listener and realize which Topic will be called next("sucess" topic when executed without errors, and "errorTopic" the listener throws an Exception) and the message content.
#RunWith(SpringRunner.class)
#SpringBootTest
#EmbeddedKafka(partitions = 1, topics = { "tp-in-gco-mao-notasfiscais" })
public class InvoicingServiceTest {
#Autowired
private NFKafkaListener nfKafkaListener;
#ClassRule
public static EmbeddedKafkaRule broker = new EmbeddedKafkaRule(1, false, "tp-in-gco-mao-
notasfiscais");
#Value("${" + EmbeddedKafkaBroker.SPRING_EMBEDDED_KAFKA_BROKERS + "}")
private String brokerAddresses;
#Autowired
private KafkaTemplate<Object, Object> template;
#BeforeClass
public static void setup() {
System.setProperty(EmbeddedKafkaBroker.BROKER_LIST_PROPERTY,
"spring.kafka.bootstrap-servers");
}
#Test
public void testTemplate() throws Exception {
NFServiceTest nfServiceTest = spy(new NFServiceTest());
nfKafkaListener.setNfServiceClient(nfServiceTest);
Map<String, Object> consumerProps = KafkaTestUtils.consumerProps("teste9", "false", broker.getEmbeddedKafka());
consumerProps.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
consumerProps.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
consumerProps.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, InvoiceDeserializer.class);
consumerProps.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, "false");
DefaultKafkaConsumerFactory<Integer, Object> cf = new DefaultKafkaConsumerFactory<Integer, Object>(
consumerProps);
Consumer<Integer, Object> consumer = cf.createConsumer();
broker.getEmbeddedKafka().consumeFromAnEmbeddedTopic(consumer, "tp-in-gco-mao-notasfiscais");
ZfifNfMao zf = new ZfifNfMao();
zf.setItItensnf(new Zfietb011());
Zfietb011 zfietb011 = new Zfietb011();
Zfie011 zfie011 = new Zfie011();
zfie011.setMatkl("TESTE");
zfietb011.getItem().add(zfie011);
zf.setItItensnf(zfietb011);
template.send("tp-in-gco-mao-notasfiscais", zf);
List<ConsumerRecord<Integer, Object>> received = new ArrayList<>();
int n = 0;
while (received.size() < 1 && n++ < 10) {
ConsumerRecords<Integer, Object> records1 = consumer.poll(Duration.ofSeconds(10));
//records1 is always empty
if (!records1.isEmpty()) {
records1.forEach(rec -> received.add(rec));
}
}
assertThat(received).extracting(rec -> {
ZfifNfMao zfifNfMaoRdesponse = (ZfifNfMao) rec.value();
return zfifNfMaoRdesponse.getItItensnf().getItem().get(0).getMatkl();
}).contains("TESTE");
broker.getEmbeddedKafka().getKafkaServers().forEach(b -> b.shutdown());
broker.getEmbeddedKafka().getKafkaServers().forEach(b -> b.awaitShutdown());
consumer.close();
}
public static class NFServiceTest implements INFServiceClient {
CountDownLatch latch = new CountDownLatch(1);
#Override
public ZfifNfMaoResponse enviarSap(ZfifNfMao zfifNfMao) {
ZfifNfMaoResponse zfifNfMaoResponse = new ZfifNfMaoResponse();
zfifNfMaoResponse.setItItensnf(new Zfietb011());
Zfietb011 zfietb011 = new Zfietb011();
Zfie011 zfie011 = new Zfie011();
zfie011.setMatkl("TESTE");
zfietb011.getItem().add(zfie011);
zfifNfMaoResponse.setItItensnf(zfietb011);
return zfifNfMaoResponse;
}
}
}
You have two brokers; one created by #EmbeddedKafka and one created by the #ClassRule.
Use one or the other; preferably the #EmbeddedKafka and simply #Autowired the broker instance.
I am guessing the consumers are listening to different brokers; you can confirm that by looking at the INFO logs put out by the consumer config.
I've followed your advice but it keeps triggering the listener, but consumer.poll does not capture the topic content.
#RunWith(SpringRunner.class)
#SpringBootTest
#EmbeddedKafka(partitions = 1, topics = { "tp-in-gco-mao-notasfiscais" })
public class InvoicingServiceTest {
#Autowired
private NFKafkaListener nfKafkaListener;
#Autowired
public EmbeddedKafkaBroker broker;
#Autowired
private KafkaTemplate<Object, Object> template;
#BeforeClass
public static void setup() {
System.setProperty(EmbeddedKafkaBroker.BROKER_LIST_PROPERTY,
"spring.kafka.bootstrap-servers");
}
#Test
public void testTemplate() throws Exception {
NFServiceTest nfServiceTest = spy(new NFServiceTest());
nfKafkaListener.setNfServiceClient(nfServiceTest);
Map<String, Object> consumerProps = KafkaTestUtils.consumerProps("teste9", "false", broker);
consumerProps.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
consumerProps.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
consumerProps.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, InvoiceDeserializer.class);
DefaultKafkaConsumerFactory<Integer, Object> cf = new DefaultKafkaConsumerFactory<Integer, Object>(
consumerProps);
Consumer<Integer, Object> consumer = cf.createConsumer();
broker.consumeFromAnEmbeddedTopic(consumer, "tp-in-gco-mao-notasfiscais");
ZfifNfMao zf = new ZfifNfMao();
zf.setItItensnf(new Zfietb011());
Zfietb011 zfietb011 = new Zfietb011();
Zfie011 zfie011 = new Zfie011();
zfie011.setMatkl("TESTE");
zfietb011.getItem().add(zfie011);
zf.setItItensnf(zfietb011);
template.send("tp-in-gco-mao-notasfiscais", zf);
List<ConsumerRecord<Integer, Object>> received = new ArrayList<>();
int n = 0;
while (received.size() < 1 && n++ < 10) {
ConsumerRecords<Integer, Object> records1 = consumer.poll(Duration.ofSeconds(10));
//records1 is always empty
if (!records1.isEmpty()) {
records1.forEach(rec -> received.add(rec));
}
}
assertThat(received).extracting(rec -> {
ZfifNfMao zfifNfMaoRdesponse = (ZfifNfMao) rec.value();
return zfifNfMaoRdesponse.getItItensnf().getItem().get(0).getMatkl();
}).contains("TESTE");
broker.getKafkaServers().forEach(b -> b.shutdown());
broker.getKafkaServers().forEach(b -> b.awaitShutdown());
consumer.close();
}
public static class NFServiceTest implements INFServiceClient {
CountDownLatch latch = new CountDownLatch(1);
#Override
public ZfifNfMaoResponse enviarSap(ZfifNfMao zfifNfMao) {
ZfifNfMaoResponse zfifNfMaoResponse = new ZfifNfMaoResponse();
zfifNfMaoResponse.setItItensnf(new Zfietb011());
Zfietb011 zfietb011 = new Zfietb011();
Zfie011 zfie011 = new Zfie011();
zfie011.setMatkl("TESTE");
zfietb011.getItem().add(zfie011);
zfifNfMaoResponse.setItItensnf(zfietb011);
return zfifNfMaoResponse;
}
}
}

Adding Entries into CalendarFX from Database

I am not sure how to add entries into the Calendar properly. I want to populate base on input from the data base.
I have tried the following but am unsure how to set the dates and entries. I am getting the data and placing into an ObserverableList . In my case the database table is CalendarData
public class CalendarController<CalendarEvent> extends Application {
private RosterService rosterService = new RosterServiceImpl();
private ObservableList<CalendarData> calendarList = FXCollections.observableArrayList();
public ObservableList<CalendarData> getCalendarDataList() {
if (!calendarList.isEmpty())
calendarList.clear();
calendarList = FXCollections.observableList((List<CalendarData>) rosterService.listCalendarData());
return calendarList;
}
#Override
public void start(Stage primaryStage) throws Exception {
CalendarView calendarView = new CalendarView();
Calendar shifts = new Calendar("ShiftRoster");
shifts.setStyle(Style.STYLE1);
CalendarSource myCalendarSource = new CalendarSource("My Calendars");
// myCalendarSource.getCalendars().addAll(shifts, holidays);
calendarView.getCalendarSources().addAll(myCalendarSource);
calendarView.setRequestedTime(LocalTime.now());
getCalendarDataList();
for(CalendarData task : calendarList){
Entry<String> entry = new Entry<String>(task.getShiftType());
LocalDate date = task.getShiftDate();
shifts.addEntries(dates);
}
CalendarSource calendarSourceTasks = new CalendarSource("Shifts");
calendarSourceTasks.getCalendars().addAll(shifts);
calendarView.getCalendarSources().setAll(calendarSourceTasks);
Solved it by doing the following code:
CalendarView calendarView = new CalendarView();
Calendar shifts = new Calendar("ShiftRoster");
shifts.setStyle(Style.STYLE1);
ZoneId id = ZoneId.of("Australia/Brisbane");
getCalendarDataList();
for (CalendarData task : calendarList) {
Entry<String> dentistAppointment = new Entry<>(task.getEmployeename());
String startTime = task.getStartTIme();
String endTime = task.getEndTime();
LocalDate date = task.getShiftDate();
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("H:mm:ss");
LocalTime start = LocalTime.parse(startTime, dtf);
LocalTime end = LocalTime.parse(endTime, dtf);
if (!start.isAfter(end)) {
dentistAppointment.setInterval(date);
dentistAppointment.setInterval(start, end);
shifts.addEntry(dentistAppointment);
}
if (!end.isAfter(start)) {
dentistAppointment.setInterval(date);
dentistAppointment.setInterval(date,start, date.plusDays(1),end);
shifts.addEntry(dentistAppointment);
}
}
CalendarSource calendarSourceTasks = new CalendarSource("Shifts");
calendarSourceTasks.getCalendars().addAll(shifts);
calendarView.getCalendarSources().setAll(calendarSourceTasks);

android with out using google cloud

how to get Notification with out using google cloud . i thought of running a thread in back ground service and update the Notification but how i can i do it.pls help me out thanks in advance
public class BackgroundThread implements Runnable {
#Override
public void run() {
List<InvoiceDetail> invoiceDetails = JsonReader.getInvoice();
if (invoiceDetails.size() > 0) {
NotificationManager nfman = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
int notifyID = 1;
NotificationCompat.Builder builder = new NotificationCompat.Builder(
LoginActivity.this).setContentTitle("WORK ASSIGNED")
.setContentText("You've received new messages.");
builder.setContentText("hai");
nfman.notify(1, builder.build());
}
}
}
public class Notifier extends BroadcastReceiver {
#SuppressWarnings("deprecation")
#Override
public void onReceive(Context context, Intent intent) {
SharedPreferences sPrefs = context.getSharedPreferences("loginData", 0);
String id = sPrefs.getString("id", "default value");
String userss = sPrefs.getString("user", "default value");
String pass = sPrefs.getString("pass", "default value");
if (id.trim().length() > 0) {
List<NotifierDetail> subjects = DataBase.notificationMethod(id);
if (subjects.size() > 0) {
User user = new User();
user.setUserName(userss);
user.setPassWord(pass);
User users = DataBase.login(user);
BaseConstants.user = users;
for (NotifierDetail sub : subjects) {
NotificationManager nm = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(
R.drawable.logo, " Notification Today",
System.currentTimeMillis());
notification.defaults=Notification.DEFAULT_SOUND;
notification.defaults=Notification.DEFAULT_VIBRATE;
DataBase.updateNotificationMethod(sub.getId());
notification.flags = Notification.FLAG_AUTO_CANCEL;
Intent in = new Intent(context, MainActivity.class);
PendingIntent pi = PendingIntent.getActivity(context, 0,
in, 0);
CharSequence name = "Notification";
CharSequence mess = name + " about " + sub.getSubject();
notification.setLatestEventInfo(context, name, mess, pi);
nm.notify(0, notification);
}
}
}
}
}

Not getting the notification from NotificationCompat.Builder

i want to generate a notification bar showing the progress via builder method but i dont know where i am going wrong.if anyone who can tell me where i am wrong and help me i will be thankful.....
public class DownloadReceiver extends ResultReceiver{
private final static String TAG = "DownloadReceiver";
public Context context;
public DownloadReceiver(Handler handler,Context context) {
super(handler);
this.context = context;
Log.d(TAG,handler.getLooper().getThread().getName());
}
#Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
super.onReceiveResult(resultCode, resultData);
Log.d(TAG,"in download receiver");
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Service.NOTIFICATION_SERVICE);
Intent notifyIntent = new Intent(android.content.Intent.ACTION_VIEW,Uri.parse("http://www.android.com"));
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, notifyIntent, 0);
if(resultCode == DownloadService.COMPLETED){
Log.d(TAG,resultCode + "");
Builder notificationBuilder = new NotificationCompat.Builder(context)
.setProgress(100, 20, false)
.addAction(R.drawable.ic_action_search, "title", pendingIntent)
.setWhen(System.currentTimeMillis());
// notification.flags = Notification.FLAG_ONGOING_EVENT;
// notification.setLatestEventInfo(context, "contentTitle", "contentText", pendingIntent);
notificationManager.notify(50, notificationBuilder.build());
}else if(resultCode == DownloadService.ALLCOMPLETED){
}
}
}
I just had to deal with this just now, the solution for me was that you have to add a notification image
.setSmallIcon(R.drawable.launcher)
otherwise it won't show anything. The old notification method didn't require you to set this yourself, as it would default to the app's icon.

Resources