Created class Notification : BroadcastReceiver():
const val notificationID = 0
const val channelID = "com.example.avnotification.MyUIRoom"
const val titleExtra = "titleExtra"
const val messageExtra = "messageExtra"
class Notification : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
Log.d("MyLog", "Notification: onReceive ")
val activityToOpen = intent.getSerializableExtra("activity") as Class<*>
//val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
//val pendingIntent: PendingIntent = PendingIntent.getActivity(context, 0, Intent(context, activityToOpen), PendingIntent.FLAG_IMMUTABLE)
val pendingIntent: PendingIntent = PendingIntent.getActivity(context, 0, Intent(context, activityToOpen), 0)
val notification = NotificationCompat.Builder(context, channelID)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle(intent.getStringExtra(titleExtra))
.setContentText(intent.getStringExtra(messageExtra))
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.build()
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// val channel = NotificationChannel(
// channelID,
// "Notif Channel",
// NotificationManager.IMPORTANCE_DEFAULT
// )
// notificationManager.createNotificationChannel(channel)
// }
val manager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
manager.notify(notificationID, notification)
}
}
here in this snippet I set the date and time, check permissions and try to see the notification but it doesn't come:
@RequiresApi(Build.VERSION_CODES.O)
class PanelEditTask : BottomSheetDialogFragment(), View.OnClickListener{
private var binding: PanelEditTaskBinding? = null
private var nameFormParent: String? = ""
private var taskAction: String? = ""
private var complet: String? = null
private var idTask: Int? = null
private var email: String? = "test"
private var typeTask: String? = null
private var taskRepository: TaskRepository? = null
private var taskViewModel: TaskViewModel? = null
private var taskFactory: TaskFactory? = null
private var firstStart: Boolean = true
private var currentDate = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
LocalDate.now()
} else {
TODO("VERSION.SDK_INT < O")
}
private val dateFormatter: DateTimeFormatter
init {
dateFormatter = DateTimeFormatterBuilder()
.appendValue(ChronoField.YEAR, 4)
.appendLiteral('-')
.appendValue(ChronoField.MONTH_OF_YEAR, 2)
.appendLiteral('-')
.appendValue(ChronoField.DAY_OF_MONTH, 2)
.toFormatter()
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
binding = PanelEditTaskBinding.inflate(inflater, container, false)
taskAction = arguments?.getString("taskAction").toString()
nameFormParent = arguments?.getString("nameForm").toString()
binding?.DateStartTask?.setText(arguments?.getString("dateStart").toString())
complet = arguments?.getString("completed").toString()
if (complet == "true"){
binding?.checkBoxCompleted?.isChecked = true
binding?.DateEndTask?.setText(arguments?.getString("dateEnd").toString())
}
else {
binding?.DateEndTask?.setText(getString(R.string.enter_end_start))
binding?.checkBoxCompleted?.isChecked = false}
if(taskAction == "Edit") {
idTask = arguments?.getString("idTask")?.toInt()
binding?.editNameTask?.setText(arguments?.getString("nameTask").toString())
email = arguments?.getString("email")?.toString()
typeTask = arguments?.getString("typeTask")?.toString()
binding?.editInfoTask?.setText(arguments?.getString("infoTask").toString())
}
else{
val sharedPreferences = requireContext().getSharedPreferences("MyPrefs", Context.MODE_PRIVATE)
val savedValue = sharedPreferences.getString("email", "default value")
if(savedValue != "default value") {
email = savedValue
}
}
val taskDao = Database.getInstance((context as FragmentActivity).application).taskDao
taskRepository = TaskRepository(taskDao)
taskFactory = TaskFactory(taskRepository!!)
taskViewModel = ViewModelProvider(this, taskFactory!!).get(TaskViewModel::class.java)
spinerProcessing()
// createNotification()
binding?.finishEdit?.setOnClickListener(this)
binding?.checkBoxCompleted?.setOnCheckedChangeListener{ buttonView, isChecked ->
if(isChecked){
binding?.DateEndTask?.setText(currentDate.toString())
}
else {
binding?.DateEndTask?.setText(getString(R.string.enter_end_start))}
}
binding?.DateEndTask?.setOnClickListener{
showDatePickerDialog("End")
}
binding?.DateStartTask?.setOnClickListener{
showDatePickerDialog("Start")
}
createNotification()
binding?.greateNotif?.setOnClickListener{scheduleNotification()}
return binding?.root
}
private fun createNotification() {
val name = "Notif Channel"
val desc = "A description of the Channel"
val importance = NotificationManager.IMPORTANCE_HIGH
val channel = NotificationChannel(channelID, name, importance)
channel.description = desc
// Set notification sound
channel.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION), null)
channel.enableVibration(true)
channel.enableLights(true)
val notificationManager = requireContext().getSystemService(NOTIFICATION_SERVICE) as NotificationManager
notificationManager?.createNotificationChannel(channel)
}
@RequiresApi(Build.VERSION_CODES.O)
private fun showDatePickerDialog(type:String) {
val calendar = Calendar.getInstance()
val year = calendar.get(Calendar.YEAR)
val month = calendar.get(Calendar.MONTH)
val day = calendar.get(Calendar.DAY_OF_MONTH)
var dateTextView: AppCompatTextView? = null
if(type == "End"){
dateTextView = binding?.DateEndTask as AppCompatTextView
}
else if(type == "Start"){
dateTextView = binding?.DateStartTask as AppCompatTextView
}
if(dateTextView != null) {
val datePickerDialog = DatePickerDialog(
context as FragmentActivity,
{ _, selectedYear, selectedMonth, selectedDay ->
val selectedDate = LocalDate.of(selectedYear, selectedMonth + 1, selectedDay)
val formattedDate = selectedDate.format(dateFormatter)
dateTextView.setText(formattedDate)
},
year,
month,
day
)
datePickerDialog.show()
}
// { _, selectedYear, selectedMonth, selectedDay ->
// val selectedDate = "$selectedYear-${selectedMonth + 1}-$selectedDay"
// dateTextView.setText(selectedDate)
// },
}
fun spinerProcessing(){
val taskTypeSpinner = binding?.taskTypeSpinner
val taskTypes = resources.getStringArray(R.array.type)
val adapter = ArrayAdapter(context as FragmentActivity, android.R.layout.simple_spinner_item, taskTypes)
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
taskTypeSpinner?.adapter = adapter
if (firstStart && typeTask != null){
val position = adapter.getPosition(typeTask)
taskTypeSpinner?.setSelection(position)
firstStart = false
}
taskTypeSpinner?.onItemSelectedListener = object : AdapterView.OnItemSelectedListener{
override fun onItemSelected(
parent: AdapterView<*>?,
view: View?,
position: Int,
id: Long
) {
typeTask = parent?.getItemAtPosition(position).toString()
}
override fun onNothingSelected(parent: AdapterView<*>?) {
TODO("Not yet implemented")
}
}
}
override fun onClick(view: View) {
if(binding?.checkBoxCompleted?.isChecked == true){
complet = "true"
}
else{
complet = ""
}
if(binding?.editNameTask?.text?.toString()!!.isNotEmpty() and
email.toString().isNotEmpty() and typeTask.toString().isNotEmpty() and
binding?.editInfoTask?.text?.toString()!!.isNotEmpty() and
binding?.DateStartTask?.text?.toString()!!.isNotEmpty() and
binding?.DateEndTask?.text?.toString()!!.isNotEmpty()) {
if (nameFormParent == "TaskAll" && taskAction != "Edit") {
taskViewModel?.startInsert(binding?.editNameTask?.text?.toString()!!,
email.toString(), typeTask.toString(),binding?.editInfoTask?.text?.toString()!!,binding?.DateStartTask?.text?.toString()!!,
binding?.DateEndTask?.text?.toString()!!, complet.toString())
dismiss()
(context as FragmentActivity).supportFragmentManager.beginTransaction().replace(R.id.content, TaskAll()).commit()
}
else if(nameFormParent == "TaskAll" && taskAction == "Edit"){
if(idTask != null) {
taskViewModel?.startUpdateTask(
idTask?.toInt()!!,
binding?.editNameTask?.text?.toString()!!,
email.toString(),
typeTask.toString(),
binding?.editInfoTask?.text?.toString()!!,
binding?.DateStartTask?.text?.toString()!!,
binding?.DateEndTask?.text?.toString()!!,
complet.toString()
)
}
dismiss()
(context as FragmentActivity).supportFragmentManager.beginTransaction().replace(R.id.content, TaskAll()).commit()
}
else if(nameFormParent == "TaskForType" && taskAction == "Edit"){
if(idTask != null) {
taskViewModel?.startUpdateTask(
idTask?.toInt()!!,
binding?.editNameTask?.text?.toString()!!,
email.toString(),
typeTask.toString(),
binding?.editInfoTask?.text?.toString()!!,
binding?.DateStartTask?.text?.toString()!!,
binding?.DateEndTask?.text?.toString()!!,
complet.toString()
)
}
dismiss()
(context as FragmentActivity).supportFragmentManager.beginTransaction().replace(R.id.content, TaskForType()).commit()
}
else if (nameFormParent == "TaskForType" && taskAction != "Edit") {
taskViewModel?.startInsert(binding?.editNameTask?.text?.toString()!!,
email.toString(), typeTask.toString(),binding?.editInfoTask?.text?.toString()!!,binding?.DateStartTask?.text?.toString()!!,
binding?.DateEndTask?.text?.toString()!!, complet.toString())
dismiss()
(context as FragmentActivity).supportFragmentManager.beginTransaction().replace(R.id.content, TaskForType()).commit()
}
// scheduleNotification()
}
else
Toast.makeText(context, getString(R.string.error), Toast.LENGTH_SHORT).show()
}
@RequiresApi(Build.VERSION_CODES.M)
private fun scheduleNotification() {
Log.d("MyLog", "scheduleNotification: ")
val intent = Intent(requireContext(), Notification::class.java)
val title = binding?.editNameTask?.text.toString()
val message = getString(R.string.close_task)
intent.putExtra(titleExtra, title)
intent.putExtra(messageExtra, message)
intent.putExtra("activity", MainActivity::class.java)
val pendingIntent = PendingIntent.getBroadcast(
requireContext(),
notificationID,
intent,
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
)
val alarmManager = requireContext().getSystemService(Context.ALARM_SERVICE) as AlarmManager
val time = getTime()
val result_SCHEDULE = requireContext().checkCallingOrSelfPermission("android.permission.SCHEDULE_EXACT_ALARM")
Log.d("MyLog", "test SCHEDULE_EXACT_ALARM, premission $result_SCHEDULE ")
val result_POST = requireContext().checkCallingOrSelfPermission("android.permission.POST_NOTIFICATIONS")
Log.d("MyLog", "test result_POST, premission $result_POST ")
//alarmManager.set(AlarmManager.RTC_WAKEUP, time, pendingIntent)
alarmManager.setExactAndAllowWhileIdle(
AlarmManager.RTC_WAKEUP,
time,
pendingIntent
)
showAlert(time, title, message)
}
private fun showAlert(time: Long, title: String, message: String) {
val date = Date(time)
val dateFormat = android.text.format.DateFormat.getLongDateFormat(requireContext())
val timeFormat = android.text.format.DateFormat.getTimeFormat(requireContext())
AlertDialog.Builder(context as FragmentActivity)
.setTitle("Notification Scheuled")
.setMessage(
"Title: " + title +
"\nMessage: " + message +
"\nAt: " + dateFormat.format(date) + " " + timeFormat.format(date)
)
.setPositiveButton("Okay"){_,_ ->}
.show()
}
private fun getTime(): Long {
val minute = binding?.timePicker?.minute
val hour = binding?.timePicker?.hour
val day = binding?.datePicker?.dayOfMonth
val month = binding?.datePicker?.month
val year = binding?.datePicker?.year
val calendar = Calendar.getInstance()
calendar.set(year!!, month!!,day!!,hour!!,minute!!)
return calendar.timeInMillis
}
}
AndroidManifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.myuiroom">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MyUIRoom"
tools:targetApi="31"
android:usesCleartextTraffic="true">
<receiver
android:name=".notices.Notification"/>
<activity
android:name=".MainActivity"
android:screenOrientation="portrait"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
I have set permissions for this app in my phone, help, where could be the problem?
Everything I've done : I simplified the code, just calling the notification on the button press, and removed the activity passing
private fun testNotification() {
Log.d("MyLog", "scheduleNotification: ")
val intent = Intent(requireContext(), Notification::class.java)
val title = binding?.editNameTask?.text.toString()
val message = getString(R.string.close_task)
intent.putExtra(titleExtra, title)
intent.putExtra(messageExtra, message)
requireContext().sendBroadcast(intent)
}
I wrote in BroadcastReceiver itself, the call of my fragment, but still in the log does not appear an entry on the
line Log.d("MyLog", "Notification: onReceive ").
const val notificationID = 0
const val channelID = "com.example.avnotification.MyUIRoom"
const val titleExtra = "titleExtra"
const val messageExtra = "messageExtra"
class Notification : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
Log.d("MyLog", "Notification: onReceive ")
val openFragmentIntent = Intent(context, MainActivity::class.java).apply {
putExtra("openFragment", "TaskForType")
}
val pendingIntent = PendingIntent.getActivity(
context,
0,
openFragmentIntent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
val notification = NotificationCompat.Builder(context, channelID)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle(intent.getStringExtra(titleExtra))
.setContentText(intent.getStringExtra(messageExtra))
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.build()
val manager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
manager.notify(notificationID, notification)
}
}
found the answer. Everything is fine in the code, I created a Notification class earlier for BroadcastReceiver. In the standard libraries there is the same class, instead of my class I imported it "import android.app.Notification", instead of my class I imported it "import com.example.myuiroom.Notification". And everything worked at once.