게시판 답변

10 글 보임 - 11 에서 20 까지 (총 57 중에서)
  • 글쓴이
  • mimoon
    키 마스터

      에뮬에서는 잘 되지만, 디바이스에서는 crash

      
      /*
              //val dbPATH = "/data/data/" + applicationContext.packageName + "/databases/"
              val dbPATH : File = this.getDatabasePath("room_memo.db")
              //val dbNAME = "room_memo.db"
              val dbNAME = dbPATH.path
              //val strOutFile = dbPATH + dbNAME
              */
              val request = DownloadManager.Request(Uri.parse("https://mimoonchurch.net/room_memo.db"))
              request.setTitle("room_memo.db")
              request.setDescription("My database is downloading.")
              request.allowScanningByMediaScanner()
              request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
              val filename: String =
                  URLUtil.guessFileName("https://mimoonchurch.net/room_memo.db", null, MimeTypeMap.getFileExtensionFromUrl("https://mimoonchurch.net/room_memo.db"))
              request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename)
              //request.setDestinationInExternalPublicDir(dbPATH, filename)
              //val manager = getSystemService(DOWNLOAD_SERVICE) as DownloadManager
              //manager.enqueue(request)
      
              /*
              val target = File(dbPATH.toString())
              if (!target.exists()) {
                  gAlert("내부 저장소(${target})에 파일이 없음을 확인했습니다.")
                  target.createNewFile()
              } else {
                  gAlert("내부 저장소($target)에 파일이 이미 존재합니다.")
                  target.delete()
                  target.createNewFile()
                  val manager =  getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
                  manager.enqueue(request)
              }
              */
      
              //val currentDBPath = "\\data\\com.w_13567767\\databases\\room_memo.db"
              //val currentDBPath = "/data/data/" + applicationContext.packageName + "/databases/"
              val backupDBPath = "room_memo.db"
              val currentDBPath2: File = this.getDatabasePath("room_memo.db")
              val outFileName = currentDBPath2.path
              val downloadFolder = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString())
              //val downloadFolder = File(Environment.DIRECTORY_DOWNLOADS).toString()
              val sd = Environment.getExternalStorageDirectory()
              val data: File = Environment.getDataDirectory()
              //val currentDB = File(currentDBPath)
              //val backupDB = File(downloadFolder, backupDBPath)
              val backupDB = File(sd, backupDBPath)
              //val strOutFile2 = "$currentDBPath"
              //gAlert("내부 저장소 절대경로는$strOutFile2")
              //val target2 = File(strOutFile2)
              val target2 = File(currentDBPath2, outFileName)
              //val currentDB = File(currentDBPath2.toString())
              val currentDB = File(sd, backupDBPath)
              //val target3 = File(downloadFolder, backupDBPath)
              val strOutFile3 = "$data/$backupDBPath"
              val target3 = File(strOutFile3)
              gAlert("공용 저장소 절대경로는$strOutFile3 가 아니라 $backupDB")
              //val target = File(dbPATH.toString())
              if (!currentDB.exists()) {
                  gAlert("내부 저장소(${currentDB})에 파일이 없음을 확인했습니다.")
                  currentDB.createNewFile()
              } else {
                  gAlert("내부 저장소($currentDB)에 파일이 이미 존재합니다.")
                  currentDB.delete()
                  currentDB.createNewFile()
                  val manager =  getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
                  manager.enqueue(request)
              }
              if(currentDB.exists()){
                  gAlert("내장 폴더(${currentDB})에서 파일 찾음.")
                  currentDB.delete()
                  currentDB.createNewFile()
                  //Log.d("TAG", "==== backUpExists: " + "내장 폴더에서 백업파일 찾음");
              }
              if(backupDB.exists()){
                  gAlert("다운로드 폴더(${backupDB})에서 파일 찾음.")
                  backupDB.delete()
                  backupDB.createNewFile()
                  //Log.d("TAG", "==== backUpExists: " + "다운로드 폴더에서 백업파일 찾음");
              }
              val src: FileChannel = FileInputStream(backupDB).channel
              val dst: FileChannel = FileOutputStream(currentDB).channel
              dst.transferFrom(src, 0, src.size())
              src.close()
              dst.close()
      
      mimoon
      키 마스터

        최신 수정 상태에서 no error version

        
        //val dbPATH = "/data/data/" + applicationContext.packageName + "/databases/"
                val dbPATH : File = this.getDatabasePath("room_memo.db")
                //val dbNAME = "room_memo.db"
                val dbNAME = dbPATH.path
                //val strOutFile = dbPATH + dbNAME
                val request = DownloadManager.Request(Uri.parse("https://mimoonchurch.net/room_memo.db"))
                request.setTitle("room_memo.db")
                request.setDescription("My database is downloading.")
                request.allowScanningByMediaScanner()
                request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
                val filename: String =
                    URLUtil.guessFileName("https://mimoonchurch.net/room_memo.db", null, MimeTypeMap.getFileExtensionFromUrl("https://mimoonchurch.net/room_memo.db"))
                request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename)
                //request.setDestinationInExternalPublicDir(dbPATH, filename)
                //val manager = getSystemService(DOWNLOAD_SERVICE) as DownloadManager
                //manager.enqueue(request)
        
                val target = File(dbPATH.toString())
                if (!target.exists()) {
                    gAlert("내부 저장소(${target})에 파일이 없음을 확인했습니다.")
                    target.createNewFile()
                } else {
                    gAlert("내부 저장소($target)에 파일이 이미 존재합니다.")
                    target.delete()
                    target.createNewFile()
                    val manager =  getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
                    manager.enqueue(request)
                }
        
                //val currentDBPath = "\\data\\com.w_13567767\\databases\\room_memo.db"
                //val currentDBPath = "/data/data/" + applicationContext.packageName + "/databases/"
                val backupDBPath = "room_memo.db"
                val currentDBPath2: File = this.getDatabasePath("room_memo.db")
                val outFileName = currentDBPath2.path
                val downloadFolder = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString())
                //val downloadFolder = File(Environment.DIRECTORY_DOWNLOADS).toString()
                val data: File = Environment.getDataDirectory()
                //val currentDB = File(currentDBPath)
                val backupDB = File(downloadFolder, backupDBPath)
                //val strOutFile2 = "$currentDBPath"
                //gAlert("내부 저장소 절대경로는$strOutFile2")
                //val target2 = File(strOutFile2)
                val target2 = File(currentDBPath2, outFileName)
                val currentDB = File(currentDBPath2.toString())
                //val target3 = File(downloadFolder, backupDBPath)
                val strOutFile3 = "$data/$backupDBPath"
                val target3 = File(strOutFile3)
                gAlert("공용 저장소 절대경로는$strOutFile3")
                if(target2.exists()){
                    gAlert("내장 폴더에서 백업파일 찾음.")
                    target.delete()
                    target.createNewFile()
                    //Log.d("TAG", "==== backUpExists: " + "내장 폴더에서 백업파일 찾음");
                }
                if(target3.exists()){
                    gAlert("다운로드 폴더에서 파일 찾음.")
                    target.delete()
                    target.createNewFile()
                    //Log.d("TAG", "==== backUpExists: " + "다운로드 폴더에서 백업파일 찾음");
                }
                val src: FileChannel = FileInputStream(currentDB).channel
                val dst: FileChannel = FileOutputStream(backupDB).channel
                dst.transferFrom(src, 0, src.size())
                src.close()
                dst.close()
        
        mimoon
        키 마스터

          시간 설정이 있는 30분 단위 알람

          
           // 시간 / 분 변수화를 통해 시각 필터링
                  val HOUR_TO_SHOW_PUSH = 18
                  val MINUTE_TO_SHOW_PUSH = 30
                  val calendar = Calendar.getInstance().apply {
                      // 약정 시간 감안 무조건 30분 간격
                      if (get(Calendar.HOUR_OF_DAY) <= HOUR_TO_SHOW_PUSH)  {
                          //add(Calendar.DAY_OF_MONTH, 1)
                          if (get(Calendar.MINUTE) <= MINUTE_TO_SHOW_PUSH)  {
                              //set(Calendar.HOUR_OF_DAY, (System.currentTimeMillis() / (1000 * 60 * 60) % 24).toInt())
                              //set(Calendar.HOUR_OF_DAY, HOUR_TO_SHOW_PUSH)
                              set(Calendar.MINUTE, MINUTE_TO_SHOW_PUSH)
                          } else {
                              add(Calendar.HOUR_OF_DAY, 1)
                              set(Calendar.MINUTE, 0)
                          }
                      } else {
                          if (get(Calendar.MINUTE) <= MINUTE_TO_SHOW_PUSH)  {
                              //set(Calendar.HOUR_OF_DAY, (System.currentTimeMillis() / (1000 * 60 * 60) % 24).toInt())
                              //add(Calendar.HOUR_OF_DAY, 1)
                              set(Calendar.MINUTE, MINUTE_TO_SHOW_PUSH)
                          } else {
                              add(Calendar.HOUR_OF_DAY, 1)
                              set(Calendar.MINUTE, 0)
                          }
                      }
                  }
                  var timeDiffInMillis: Long = calendar.timeInMillis - System.currentTimeMillis()
                  //if (timeDiffInMillis <= 0 ){
                      alarmMgr?.setInexactRepeating(
                              AlarmManager.RTC_WAKEUP,
                              calendar.timeInMillis,
                              AlarmManager.INTERVAL_HALF_HOUR,
                              alarmIntent
                      )
                  //}
                  val t_dateFormat2 = SimpleDateFormat("yyyy-MM-dd kk:mm:ss E", Locale("ko", "KR"))
                  // 현재 시간을 dateFormat 에 선언한 형태의 String 으로 변환
                  var str_date2 = t_dateFormat2.format(System.currentTimeMillis())
                  var ma_cald = t_dateFormat2.format(calendar.timeInMillis)
                  val calc = (timeDiffInMillis / (1000 * 60) % 60)
                  Toast.makeText(this@MainActivity,"현재 시각은:" +str_date2 + "다음 알람은" + ma_cald + "까지이며" + timeDiffInMillis + "밀리언세컨 즉," + calc + "분 남았습니다.",Toast.LENGTH_LONG).show()
                  
          
          mimoon
          키 마스터

            알람 설정이 기존에 있을 경우 체크

            
            // 2021-08-21 Check if AlarmManager already has an alarm set?
                    val alarmUp = PendingIntent.getBroadcast(this, 0,
                            Intent("com.w_13567767.MY_UNIQUE_ACTION"),
                            PendingIntent.FLAG_NO_CREATE) != null
                            //PendingIntent.FLAG_UPDATE_CURRENT) != null
                    if (alarmUp) {
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                            val alarmManager2 = this.getSystemService(Context.ALARM_SERVICE) as AlarmManager
                            try {
                                //assert(alarmManager2 != null)
                                //val aci = alarmManager2!!.nextAlarmClock
                               // val nextAlarm = aci.getTriggerTime() //.toString()
                                //Log.w("pentalogia nextAlarm ", nextAlarm)
                                //val t_dateFormat = SimpleDateFormat("yyyy-MM-dd kk:mm:ss E", Locale("ko", "KR"))
                                // 현재 시간을 dateFormat 에 선언한 형태의 String 으로 변환
                                //val str_date = t_dateFormat.format(nextAlarm)
                                //Log.d("pentalogia", "Alarm is already active" + str_date.toString())
                                //Toast.makeText(this@MainActivity,"Alarm is already active: " + str_date,Toast.LENGTH_LONG).show()
                            } catch (e: Exception) {
                                e.printStackTrace()
                            }
                            // 시간 / 분 변수화를 통해 시각 필터링
                            val HOUR_TO_SHOW_PUSH = 18
                            val MINUTE_TO_SHOW_PUSH = 30
                            val calendar = Calendar.getInstance().apply {
                                // 약정 시간 감안 무조건 30분 간격
                                if (get(Calendar.HOUR_OF_DAY) <= HOUR_TO_SHOW_PUSH)  {
                                    //add(Calendar.DAY_OF_MONTH, 1)
                                    if (get(Calendar.MINUTE) <= MINUTE_TO_SHOW_PUSH)  {
                                        set(Calendar.HOUR_OF_DAY, HOUR_TO_SHOW_PUSH)
                                        set(Calendar.MINUTE, MINUTE_TO_SHOW_PUSH)
                                    } else {
                                        add(Calendar.HOUR_OF_DAY, 1)
                                        set(Calendar.MINUTE, 0)
                                    }
                                } else {
                                    if (get(Calendar.MINUTE) <= MINUTE_TO_SHOW_PUSH)  {
                                        //set(Calendar.HOUR_OF_DAY, hours.toInt())
                                        //add(Calendar.HOUR_OF_DAY, 1)
                                        set(Calendar.MINUTE, MINUTE_TO_SHOW_PUSH)
                                    } else {
                                        add(Calendar.HOUR_OF_DAY, 1)
                                        set(Calendar.MINUTE, 0)
                                    }
                                }
                            }
                            val timeDiffInMillis: Long = calendar.timeInMillis - System.currentTimeMillis()
                            val t_dateFormat = SimpleDateFormat("yyyy-MM-dd kk:mm:ss E", Locale("ko", "KR"))
                            val str_date = t_dateFormat.format(timeDiffInMillis)
                            Toast.makeText(this@MainActivity,"Alarm is already active: " + timeDiffInMillis,Toast.LENGTH_LONG).show()
                        } else {
                            val nextAlarm = Settings.System.NEXT_ALARM_FORMATTED
                        }
                        // 이전 알람 확인 후 새로 설정
                        //val nextAlarmTime = alarmMgr!!.getNextAlarmClock()
                        //if (System.currentTimeMillis() + 1000 * 60 * 10 < nextAlarmTime){
                            // 반복 단위
                        //}
                        //val nextAlarmTime = System.currentTimeMillis() + 1000 * 60 * 10
                        //Log.d("pentalogia", "Alarm is already active" + nextAlarmTime.toString())
                        //Toast.makeText(this@MainActivity,"Alarm is already active: " + nextAlarmTime.toString(),Toast.LENGTH_LONG).show()
                    } else {
                        // 알람 정의하고
                        // 반복 단위
                        alarmMgr = this@MainActivity.getSystemService(Context.ALARM_SERVICE) as AlarmManager
                        alarmIntent = Intent(this, AlarmReceiver::class.java).let { intent ->
                            PendingIntent.getBroadcast(this, 0, intent, 0)
                        }
                        /*
                        try {
                            //val nextAlarmTime = alarmMgr!!.nextAlarmClock.triggerTime
                            val aci = alarmMgr!!.nextAlarmClock
                            val nextAlarm = aci.getTriggerTime() //.toString()
                            val t_dateFormat = SimpleDateFormat("yyyy-MM-dd kk:mm:ss E", Locale("ko", "KR"))
                            val str_date = t_dateFormat.format(nextAlarm)
                            //Log.d("pentalogia", "Alarm is already active" + str_date.toString())
                            Toast.makeText(this@MainActivity,"Alarm is not already active: " + str_date,Toast.LENGTH_LONG).show()
                        } catch (e: Exception) {
                            e.printStackTrace()
                        }
                        alarmMgr?.setInexactRepeating(
                                AlarmManager.ELAPSED_REALTIME_WAKEUP,
                                SystemClock.elapsedRealtime() + 60 * 1000,
                                AlarmManager.INTERVAL_HALF_HOUR,
                                //1000 * 60 * 5,
                                alarmIntent
                        )
                        */
                        // 시간 / 분 변수화를 통해 시각 필터링
                        val HOUR_TO_SHOW_PUSH = 18
                        val MINUTE_TO_SHOW_PUSH = 30
                        val calendar = Calendar.getInstance().apply {
                            // 약정 시간 감안 무조건 30분 간격
                            if (get(Calendar.HOUR_OF_DAY) <= HOUR_TO_SHOW_PUSH)  {
                                //add(Calendar.DAY_OF_MONTH, 1)
                                if (get(Calendar.MINUTE) <= MINUTE_TO_SHOW_PUSH)  {
                                    set(Calendar.HOUR_OF_DAY, HOUR_TO_SHOW_PUSH)
                                    set(Calendar.MINUTE, MINUTE_TO_SHOW_PUSH)
                                } else {
                                    add(Calendar.HOUR_OF_DAY, 1)
                                    set(Calendar.MINUTE, 0)
                                }
                            } else {
                                if (get(Calendar.MINUTE) <= MINUTE_TO_SHOW_PUSH)  {
                                    //set(Calendar.HOUR_OF_DAY, hours.toInt())
                                    //add(Calendar.HOUR_OF_DAY, 1)
                                    set(Calendar.MINUTE, MINUTE_TO_SHOW_PUSH)
                                } else {
                                    add(Calendar.HOUR_OF_DAY, 1)
                                    set(Calendar.MINUTE, 0)
                                }
                            }
                        }
                        val timeDiffInMillis: Long = calendar.timeInMillis - System.currentTimeMillis()
                        val t_dateFormat = SimpleDateFormat("yyyy-MM-dd kk:mm:ss E", Locale("ko", "KR"))
                        val str_date = t_dateFormat.format(timeDiffInMillis)
                        Toast.makeText(this@MainActivity,"Alarm is not already active: " + timeDiffInMillis,Toast.LENGTH_LONG).show()
                        alarmMgr?.setInexactRepeating(
                                //alarmMgr?.set(
                                AlarmManager.RTC_WAKEUP,
                                //AlarmManager.ELAPSED_REALTIME_WAKEUP,
                                calendar.timeInMillis,
                                //AlarmManager.INTERVAL_FIFTEEN_MINUTES,
                                //AlarmManager.INTERVAL_DAY,
                                AlarmManager.INTERVAL_HALF_DAY,
                                //AlarmManager.INTERVAL_HALF_HOUR,
                                //AlarmManager.INTERVAL_HOUR,
                                //1000 * 60 * 6,
                                alarmIntent
                        )
            
                    }
            
            mimoon
            키 마스터

              // 2021-08-21 Check if AlarmManager already has an alarm set?

              
              val alarmUp = PendingIntent.getBroadcast(this, 0,
                              Intent("com.w_13567767.MY_UNIQUE_ACTION"),
                              PendingIntent.FLAG_NO_CREATE) != null
                              //PendingIntent.FLAG_UPDATE_CURRENT) != null
                      if (alarmUp) {
                          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                              val alarmManager2 = this.getSystemService(Context.ALARM_SERVICE) as AlarmManager
                              try {
                                  //assert(alarmManager2 != null)
                                  //val aci = alarmManager2!!.nextAlarmClock
                                 // val nextAlarm = aci.getTriggerTime() //.toString()
                                  //Log.w("pentalogia nextAlarm ", nextAlarm)
                                  //val t_dateFormat = SimpleDateFormat("yyyy-MM-dd kk:mm:ss E", Locale("ko", "KR"))
                                  // 현재 시간을 dateFormat 에 선언한 형태의 String 으로 변환
                                  //val str_date = t_dateFormat.format(nextAlarm)
                                  //Log.d("pentalogia", "Alarm is already active" + str_date.toString())
                                  //Toast.makeText(this@MainActivity,"Alarm is already active: " + str_date,Toast.LENGTH_LONG).show()
                              } catch (e: Exception) {
                                  e.printStackTrace()
                              }
                              // 시간 / 분 변수화를 통해 시각 필터링
                              val HOUR_TO_SHOW_PUSH = 18
                              val MINUTE_TO_SHOW_PUSH = 30
                              val calendar = Calendar.getInstance().apply {
                                  // 약정 시간 감안 무조건 30분 간격
                                  if (get(Calendar.HOUR_OF_DAY) <= HOUR_TO_SHOW_PUSH)  {
                                      //add(Calendar.DAY_OF_MONTH, 1)
                                      if (get(Calendar.MINUTE) <= MINUTE_TO_SHOW_PUSH)  {
                                          set(Calendar.HOUR_OF_DAY, HOUR_TO_SHOW_PUSH)
                                          set(Calendar.MINUTE, MINUTE_TO_SHOW_PUSH)
                                      } else {
                                          add(Calendar.HOUR_OF_DAY, 1)
                                          set(Calendar.MINUTE, 0)
                                      }
                                  } else {
                                      if (get(Calendar.MINUTE) <= MINUTE_TO_SHOW_PUSH)  {
                                          //set(Calendar.HOUR_OF_DAY, hours.toInt())
                                          //add(Calendar.HOUR_OF_DAY, 1)
                                          set(Calendar.MINUTE, MINUTE_TO_SHOW_PUSH)
                                      } else {
                                          add(Calendar.HOUR_OF_DAY, 1)
                                          set(Calendar.MINUTE, 0)
                                      }
                                  }
                              }
                              val timeDiffInMillis: Long = calendar.timeInMillis - System.currentTimeMillis()
                              val t_dateFormat = SimpleDateFormat("yyyy-MM-dd kk:mm:ss E", Locale("ko", "KR"))
                              val str_date = t_dateFormat.format(timeDiffInMillis)
                              Toast.makeText(this@MainActivity,"Alarm is already active: " + timeDiffInMillis,Toast.LENGTH_LONG).show()
                          } else {
                              val nextAlarm = Settings.System.NEXT_ALARM_FORMATTED
                          }
                          // 이전 알람 확인 후 새로 설정
                          //val nextAlarmTime = alarmMgr!!.getNextAlarmClock()
                          //if (System.currentTimeMillis() + 1000 * 60 * 10 < nextAlarmTime){
                              // 반복 단위
                          //}
                          //val nextAlarmTime = System.currentTimeMillis() + 1000 * 60 * 10
                          //Log.d("pentalogia", "Alarm is already active" + nextAlarmTime.toString())
                          //Toast.makeText(this@MainActivity,"Alarm is already active: " + nextAlarmTime.toString(),Toast.LENGTH_LONG).show()
                      } else {
                          // 알람 정의하고
                          // 반복 단위
                          alarmMgr = this@MainActivity.getSystemService(Context.ALARM_SERVICE) as AlarmManager
                          alarmIntent = Intent(this, AlarmReceiver::class.java).let { intent ->
                              PendingIntent.getBroadcast(this, 0, intent, 0)
                          }
                          /*
                          try {
                              //val nextAlarmTime = alarmMgr!!.nextAlarmClock.triggerTime
                              val aci = alarmMgr!!.nextAlarmClock
                              val nextAlarm = aci.getTriggerTime() //.toString()
                              val t_dateFormat = SimpleDateFormat("yyyy-MM-dd kk:mm:ss E", Locale("ko", "KR"))
                              val str_date = t_dateFormat.format(nextAlarm)
                              //Log.d("pentalogia", "Alarm is already active" + str_date.toString())
                              Toast.makeText(this@MainActivity,"Alarm is not already active: " + str_date,Toast.LENGTH_LONG).show()
                          } catch (e: Exception) {
                              e.printStackTrace()
                          }
                          alarmMgr?.setInexactRepeating(
                                  AlarmManager.ELAPSED_REALTIME_WAKEUP,
                                  SystemClock.elapsedRealtime() + 60 * 1000,
                                  AlarmManager.INTERVAL_HALF_HOUR,
                                  //1000 * 60 * 5,
                                  alarmIntent
                          )
                          */
                          // 시간 / 분 변수화를 통해 시각 필터링
                          val HOUR_TO_SHOW_PUSH = 18
                          val MINUTE_TO_SHOW_PUSH = 30
                          val calendar = Calendar.getInstance().apply {
                              // 약정 시간 감안 무조건 30분 간격
                              if (get(Calendar.HOUR_OF_DAY) <= HOUR_TO_SHOW_PUSH)  {
                                  //add(Calendar.DAY_OF_MONTH, 1)
                                  if (get(Calendar.MINUTE) <= MINUTE_TO_SHOW_PUSH)  {
                                      set(Calendar.HOUR_OF_DAY, HOUR_TO_SHOW_PUSH)
                                      set(Calendar.MINUTE, MINUTE_TO_SHOW_PUSH)
                                  } else {
                                      add(Calendar.HOUR_OF_DAY, 1)
                                      set(Calendar.MINUTE, 0)
                                  }
                              } else {
                                  if (get(Calendar.MINUTE) <= MINUTE_TO_SHOW_PUSH)  {
                                      //set(Calendar.HOUR_OF_DAY, hours.toInt())
                                      //add(Calendar.HOUR_OF_DAY, 1)
                                      set(Calendar.MINUTE, MINUTE_TO_SHOW_PUSH)
                                  } else {
                                      add(Calendar.HOUR_OF_DAY, 1)
                                      set(Calendar.MINUTE, 0)
                                  }
                              }
                          }
                          val timeDiffInMillis: Long = calendar.timeInMillis - System.currentTimeMillis()
                          val t_dateFormat = SimpleDateFormat("yyyy-MM-dd kk:mm:ss E", Locale("ko", "KR"))
                          val str_date = t_dateFormat.format(timeDiffInMillis)
                          Toast.makeText(this@MainActivity,"Alarm is not already active: " + timeDiffInMillis,Toast.LENGTH_LONG).show()
                          alarmMgr?.setInexactRepeating(
                                  //alarmMgr?.set(
                                  AlarmManager.RTC_WAKEUP,
                                  //AlarmManager.ELAPSED_REALTIME_WAKEUP,
                                  calendar.timeInMillis,
                                  //AlarmManager.INTERVAL_FIFTEEN_MINUTES,
                                  //AlarmManager.INTERVAL_DAY,
                                  AlarmManager.INTERVAL_HALF_DAY,
                                  //AlarmManager.INTERVAL_HALF_HOUR,
                                  //AlarmManager.INTERVAL_HOUR,
                                  //1000 * 60 * 6,
                                  alarmIntent
                          )
              
                      }
              
              mimoon
              키 마스터

                종전의 리스너

                
                todayVerse_e.setOnClickListener {
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                                //if (isNetworkAvailbale()) {         // 2021-07-07 for verification of internet
                                if (isNetworkConnected()) {         // 2021-07-07 for verification of internet
                                    //Log.d("Network_virify", "연결 정상")
                                    MydayVerse("https://mimoonchurch.net/myday3.html")
                                    //println("pentalogia Debug40 :" + today2)
                                } else {
                                    gAlert("인터넷 연결상태를 확인해주세요")
                                }
                            } else {
                                val alertVcheck = AlertDialog.Builder(this@MainActivity)
                                alertVcheck.setMessage("안드로이드 OS 6.0(마시멜로) 이상에서 사용가능한 기능입니다")
                                alertVcheck.setPositiveButton("닫기") { dialog, which -> }
                                val alertVcheck2 = alertVcheck.create()
                                alertVcheck2.show()
                            }
                        }
                

                그리고 통신 메니져

                
                @RequiresApi(Build.VERSION_CODES.M)
                    private fun isNetworkConnected(): Boolean {
                        //1
                        val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
                        //2
                        val activeNetwork = connectivityManager.activeNetwork
                        //3
                        val networkCapabilities = connectivityManager.getNetworkCapabilities(activeNetwork)
                        //4
                        return networkCapabilities != null &&
                                networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                    }
                
                mimoon
                키 마스터

                  connection sources

                  
                  /*
                      // 2021-08-15 for network 1
                      fun isOnline(context: Context): Boolean {
                          val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
                          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                              val n = cm.activeNetwork
                              if (n != null) {
                                  val nc = cm.getNetworkCapabilities(n)
                                  //It will check for both wifi and cellular network
                                  return nc!!.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) || nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
                              }
                              return false
                          } else {
                              val netInfo = cm.activeNetworkInfo
                              return netInfo != null && netInfo.isConnectedOrConnecting
                          }
                      }
                      */
                  
                      // 2021-08-15 for network 2
                      /*
                      private fun isInternetAvailable(context: Context): Boolean {
                          var result = false
                          val connectivityManager =
                                  context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
                          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                              val networkCapabilities = connectivityManager.activeNetwork ?: return false
                              val actNw =
                                      connectivityManager.getNetworkCapabilities(networkCapabilities) ?: return false
                              result = when {
                                  actNw.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
                                  actNw.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
                                  actNw.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
                                  else -> false
                              }
                          } else {
                              connectivityManager.run {
                                  connectivityManager.activeNetworkInfo?.run {
                                      result = when (type) {
                                          ConnectivityManager.TYPE_WIFI -> true
                                          ConnectivityManager.TYPE_MOBILE -> true
                                          ConnectivityManager.TYPE_ETHERNET -> true
                                          else -> false
                                      }
                  
                                  }
                              }
                          }
                          return result
                      }
                      */
                  
                      /*
                      fun  isNetworkAvailbale():Boolean{
                          val conManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
                          val internetInfo =conManager.activeNetworkInfo
                          return internetInfo!=null && internetInfo.isConnected
                      }
                      */
                  
                  mimoon
                  키 마스터

                    // 2021-05-08 Fragment_blank.xml Default

                    
                    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                        xmlns:tools="http://schemas.android.com/tools"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        tools:context=".BlankFragment">
                        <ScrollView
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:isScrollContainer="false"
                            tools:ignore="UselessParent">
                            <!-- TODO: Update blank fragment layout -->
                            <TextView
                                android:id="@+id/text_blank"
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:padding="16dp"
                                android:background="#ffffff"
                                android:text="@string/hello_blank_fragment" />
                        </ScrollView>
                        <!--WebView
                            android:id="@+id/blank_wvLayout"
                            android:layout_width="fill_parent"
                            android:layout_height="fill_parent"
                            tools:ignore="MissingConstraints" /-->
                    </RelativeLayout>
                    
                    mimoon
                    키 마스터

                      //2021-05-08 activity_crawl_main.xml

                      
                      <?xml version="1.0" encoding="utf-8"?>
                      <androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
                          xmlns:app="http://schemas.android.com/apk/res-auto"
                          xmlns:tools="http://schemas.android.com/tools"
                          android:layout_width="match_parent"
                          android:layout_height="match_parent"
                          tools:openDrawer="start"
                          tools:context=".CrawlActivity">
                          <RelativeLayout
                              android:layout_width="match_parent"
                              android:layout_height="match_parent">
                          <WebView
                              android:id="@+id/crawl_wvLayout"
                              android:layout_width="fill_parent"
                              android:layout_height="fill_parent"
                              android:layout_marginTop="27dp"
                              tools:ignore="MissingConstraints" />
                          <LinearLayout
                              android:orientation="horizontal"
                              android:layout_width="match_parent"
                              android:layout_height="match_parent">
                             <FrameLayout
                                 android:id="@+id/fl_activity_main"
                                 android:layout_width="match_parent"
                                 android:layout_height="match_parent"
                                 tools:ignore="UselessParent">
                              <Button
                                  android:id="@+id/btn"
                                  android:layout_width="wrap_content"
                                  android:layout_height="wrap_content"
                                  android:layout_gravity="right"
                                  android:text="@string/btn1"
                                  tools:ignore="RtlHardcoded" />
                              </FrameLayout>
                          </LinearLayout>
                          </RelativeLayout>
                          <com.google.android.material.navigation.NavigationView
                              android:id="@+id/nav_view"
                              android:layout_width="wrap_content"
                              android:layout_height="match_parent"
                              android:layout_gravity="start"
                              android:fitsSystemWindows="true"
                              app:headerLayout="@layout/nav_header_main"
                              app:menu="@menu/activity_main_drawer" />
                      
                      </androidx.drawerlayout.widget.DrawerLayout>
                      
                      mimoon
                      키 마스터

                        안정적인 fragment 리스너

                        
                        private static final String FRAGMENT_TAG = "FRAGMENT_TAG";
                            private static final String KEY_NUMBER = "KEY_NUMBER";
                            private int mNumber = 0;
                            private FragmentManager.OnBackStackChangedListener mListener = new FragmentManager.OnBackStackChangedListener() {
                                @Override
                                public void onBackStackChanged() {
                                    FragmentManager fragmentManager = getSupportFragmentManager();
                                    int count = 0;
                                    for (Fragment f: fragmentManager.getFragments()) {
                                        if (f != null) {
                                            count++;
                                        }
                                    }
                                    mNumber = count;
                                    Log.d("MainActivity", "onBackStackChanged mNumber=" + mNumber);
                                }
                            };
                        
                      10 글 보임 - 11 에서 20 까지 (총 57 중에서)