게시판 답변

10 글 보임 - 1 에서 10 까지 (총 57 중에서)
  • 글쓴이
  • 답변: 비공개: [PHP 8] get Domain & path #16903
    mimoon
    키 마스터
      
      
      /***2024-06-22 for PHP 8 
       * 2024-08-11 update for disable '$HTTP_REFERER = isset($_SERVER['HTTP_REFERER']) ?  trim($_SERVER['HTTP_REFERER']) : '';ㅍ
       * '$_SERVER['HTTP_REFERER']'는 직전 url이므로 글로벌 노드(기본) 모드에서는 $_SERVER['HTTP_REFERER']가 아닌 get current url 코드로 바꿔줘야
      */
      if(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') {
      	$HTTP_REFERER = "https://";  
      	} else  {
      	$HTTP_REFERER = "http://"; 
      	}
      	// Append the host(domain name, ip) to the URL.   
      	$HTTP_REFERER.= $_SERVER['HTTP_HOST'];
      	// Append the requested resource location to the URL   
      	$HTTP_REFERER.= $_SERVER['REQUEST_URI'];
      	/** url or domain 확보 코드 끝 */
      	if (stripos($HTTP_REFERER,'powerbible.be') == false){
      	?>
      	<script>
      	$(document).ready(function(){
      		let agent= navigator.platform + " " + navigator.appVersion; //navigator.userAgent; //navigator.platform;
      		if (agent.length > 40) {
      			agent = agent.substr(0, 40 - 2) + '...';
          	}
      		//document.getElementById("demo").innerHTML=agent;
      		$.ajax({ 
      			url: "../inc/get_connect_info.php",
      			context: document.body,
      			error:function(request, status, error){
      				alert("페이지를 여는 데 실패했습니다. 접속 상태 등 점검이 필요합니다.");
      				history.back()
      			},
      			success: function(response){
      				get_connect_info.innerHTML = "<p style='font-size: 9px; margin-top: -.123em; margin-left: 15px; padding-left: 15px;'>" + response + "경로로 접속하셨습니다. 접속 도구: " + agent + "</p>";		
      			}
          	});
      	});
      	</script>
      	<?php
      	$your_path= "<span id='get_connect_info'>PowerBible engine 3.7a1</span>";
      } else {
      	$your_path= "PowerBible engine 3.7a1";
      }
      
      답변: 비공개: [Swiftui] server error handle #16898
      mimoon
      키 마스터
        mimoon
        키 마스터

          다음에 대해 고려할 것. 현재 먹히던 것이 안 먹힘.

          
          
          /**2024-07-18 Change the default-view of Media Library
           * 참조: 물리적 파일명은 'upload.php'이지만, 사용자 명시는 'admin_footer-' --> 'admin_footer-upload.php' 
           * 그외: add_action( 'restrict_manage_posts', 'media_library_filter_main'); // long.. 무한루프
           * add_action( 'admin_footer-post-new.php', 'media_library_filter' );
           * add_action( 'admin_footer-post.php', 'media_library_filter' );
           */
          add_action( 'admin_footer-upload.php', 'media_library_filter_main' );
          //add_action( 'admin_footer-post.php', 'media_library_filter' ); //에러?
          function media_library_filter_main() { 
          	?>
          	<script type="text/javascript">
          		/*
          		jQuery(document).on("DOMNodeInserted", function(){
          			//2024-07-29 changed 'select.attachment-filters' to '#media-attachment-filters' 
          				//jQuery('select#media-attachment-filters [value="uploaded"]').attr( 'selected', true ).parent().trigger('change');
          				jQuery('select#media-attachment-filters.attachment-filters [value="1"]').attr( 'selected', true ).parent().trigger('change');
          		});
          		*/
          		~function(doc, $) {
          			var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
          			var select = $('select.attachment-filters'); //var select = $('select'); // this is just DOM element, no jQuery
          			var observer = new MutationObserver(function(mutations) {
          				alert(mutations.length + " mutations happened");
          			});
          			// monitor descendant elements – changing <code>selected</code> attr on options
          			observer.observe(select, { subtree: true, attributes: true });
          			// this triggers Observer's reaction, but doesn't update select box UI
          			setTimeout(function () {
          				select.setAttribute('value', '0'); //select.setAttribute('value', 'whoa');
          			}, 1000);
          			
          			// this updates select box UI, but doesn't trigger mutation observer's callback
          			setTimeout(function () {
          				select.value = "0";	//	select.value = "whee";
          			}, 2000);
          			// this also updates the UI, but doesn't trigger mutation observer's callback
          			setTimeout(function () {
          				select.getElementsByTagName('option')[0].selected = true;
          			}, 3000);
          			
          			// neither does manual selecting of options trigger mutation observer unfortunately :(
          		}(document, function(selector) { return document.querySelector(selector); });
          
          		/*
          		function method_DOMNodeInserted() {
          			$('#method').attr('class','old').text('DOMNodeInserted');
          			$('body').on('DOMNodeInserted', '*', function(e){
          				if($(e.target).find('select').length) {
          					$(e.target).find('select').each(function(){
          						apply_select2($(this)); // Not sure why this is called twice
          					});
          				}
          			});
          		}
          		function method_MutationObserver() {
          			$('#method').attr('class','new').text('MutationObserver');
          			var observer = new MutationObserver(function(mutations) {
          				mutations.forEach(function(mutation) {
          					if ( mutation.type == 'childList' ) {
          						if (mutation.addedNodes.length >= 1) {
          							for (var i = 0; i < mutation.addedNodes.length; i++) {
          								$(mutation.addedNodes[i]).find('select').each(function(){
          									apply_select2($(this));
          								});
          							}
          						}
          					}
          				});
          			});
          			//  var observerConfig = { childList: true };
          			var observerConfig = { attributes: true, childList: true, characterData: true, subtree: true };
          			var targetNode = document.body;
          			observer.observe(targetNode, observerConfig);
          		}
          		function apply_select2($theSelect) {
          			$debugMsg = 'Detected newly-added select id: ' + $theSelect.attr('id');
          			$('#feedback').html('<span>'+$debugMsg+'</span>');
          			console.log($debugMsg);
          			// Apply select2 here
          		}
          			*/
          	</script>
          <?php 
          }
          
          답변: 비공개: [wordpress] astra에서 view count #16688
          mimoon
          키 마스터

            2024-05-04 update: 30이하일 때 배경색 띠 삭제를 위해

            
            /***2024-05-04 for jp_post_view count */
            $jp_post_view_astra = do_shortcode( '' );
            if (strpos($jp_post_view_astra,'👁')) { 
               echo "<span style='padding-right: 2px;' id='view_count' class='highlight'>&nbsp;".$jp_post_view_astra."&nbsp;</span><br>";
            } else {
               echo "";
            }
            /***2024-05-04 End of jp_post_view count */
            
            답변: 비공개: [wordpress] astra에서 view count #16646
            mimoon
            키 마스터

              2024-03-27 change code according to astra theme
              함수명이나 구조가 완전히 달라짐
              파일 구도는 그대로 \astra\Inc\blog\blog.php
              그러나 Line 571~582 쯤 다음 부분에 삽입

              
              case 'single-meta':
                do_action( 'astra_single_post_banner_meta_before' );
                $post_meta = astra_get_option( 'ast-dynamic-single-' . $post_type . '-metadata', array( 'comments', 'author', 'date' ) );
                $output    = '';
                if ( ! empty( $post_meta ) ) {
                  $output_str = astra_get_post_meta( $post_meta, '/', 'single-post' );
                      if ( ! empty( $output_str ) ) {
                          $output = apply_filters( 'astra_single_post_meta', '<div class="entry-meta">' . $output_str . '</div>' ); // WPCS: XSS OK.
                      }
                 }
              
                /***2024-03-27 for jp_post_view count */
                $jp_post_view_astra = do_shortcode( '' );
                echo "<br><span style='padding: 0 1px 0 2px;' id='view_count' class='highlight'>&nbsp;".$jp_post_view_astra."&nbsp;</span><br>";
                 /***2024-03-27 End of jp_post_view count */
              
                 echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
                 do_action( 'astra_single_post_banner_meta_after' );
              break;
              

              ‘echo $output;’의 바로 앞 줄

              답변: 비공개: [wordpress] astra에서 view count #15960
              mimoon
              키 마스터

                post-views-for-jetpack 플러그인의
                functions.jp-post-views.php 파일 내에
                다음 두 라인과

                
                $num_s = preg_replace("/[^0-9]*/s", "", $views['total']);
                if ( $num_s < 30 ) { return; }
                

                다음 라인

                
                '%s view',
                ' 👁 %s'.'명의 독자가 공감하셨습니다',
                

                이 둘을 추가/변경하지 않으면 단순 View(s)로만 게시
                전자는 30회 이하는 안 보여주는 코드.

                답변: 비공개: [wordpress] astra에서 view count #15944
                mimoon
                키 마스터

                  최신

                  
                  <!-- .post view count -->
                  <span id='view_count' class="highlight"><?php echo do_shortcode( '' ); ?></span>
                  <!-- .post view count end -->
                  
                  답변: 비공개: [Kotlin] DiffUtil 성공 #15500
                  mimoon
                  키 마스터

                    현재 이 시간 성공한 RoombibleAdapter

                    
                    
                    class RoombibleAdapter : RecyclerView.Adapter<RoombibleAdapter.Holder>(){
                    //class RoombibleAdapter : RecyclerView.Adapter<RoombibleAdapter.ArticleViewHolder>(){
                    //class RoombibleAdapter : ListAdapter<RoomPbible, RoombibleAdapter.Holder>(DiffUtils) {
                    
                        var helper:RoomHelper? = null
                        var bibleData = mutableListOf<RoomPbible>()
                        var selectedExpense = arrayListOf<RoomPbible>()
                    
                        /*
                        private val differCallback = object: DiffUtil.ItemCallback<RoomPbible>(){
                            // 이함수는 oldItem과 new Item이 같은지 확인하는 함수입니다.
                            override fun areItemsTheSame(oldItem: RoomPbible, newItem: RoomPbible): Boolean {
                                // oldItem과 newItem은 전에 만들었던 article dataclass의 타입을 가지고있음
                                // 같은아이템인지 확인하려면 두 아이템에 고유ID를 확인해줘야
                                // 기사마자 다른 url을 가지고있기때문에 data class에서 각 아이템의 url을 확인
                                return oldItem.rhv == newItem.rhv
                            }
                            @SuppressLint("DiffUtilEquals")
                            override fun areContentsTheSame(oldItem: RoomPbible, newItem: RoomPbible): Boolean {
                                //둘의 컨텐츠도 비교해줍니다.
                                return oldItem == newItem
                            }
                        }
                        */
                    
                        // 2021-12-01 Original
                        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RoombibleAdapter.Holder {
                            val roombibleBinding = ItemRoombibleBinding.inflate(LayoutInflater.from(parent.context), parent, false)
                            return Holder(roombibleBinding)
                        }
                    
                        /*
                        // 2021-12-02 Expense에서 온 것
                        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
                            Holder(ItemRoombibleBinding.inflate(LayoutInflater.from(parent.context), parent, false))
                         */
                    
                        inner class Holder(private val roombibleBinding: ItemRoombibleBinding) : RecyclerView.ViewHolder(roombibleBinding.root) {
                            private var mRoomBible:RoomPbible? = null
                    
                            /*
                            fun bind(roombible: RoomPbible) {
                                with(roombibleBinding) {
                                    bibleContent.text = roombible.rhv
                                    bibleCompare.text = roombible.cmv
                                }
                            }
                            */
                    
                            fun setRoomBible(roombible:RoomPbible) {
                                //binding.textNo.text = "${memo.no}"
                                //val str1 = roombible.rhv
                                //val trimRhv = str1.replace("[0-9\\:]".toRegex(), "")
                                //val str2 = roombible.cmv
                                //val trimCmv = str2.replace("[0-9\\:]".toRegex(), "")
                                roombibleBinding.bibleContent.text = roombible.rhv  //trimRhv
                                roombibleBinding.bibleCompare.text = roombible.cmv  //trimCmv
                                //val sdf = SimpleDateFormat("yy/MM/dd hh:mm")
                                // 날짜 포맷은 SimpleDateFormat으로 설정합니다.
                                //roombibleBinding.textDatetime.text = sdf.format(roombible.datetime)
                    
                                this.mRoomBible = roombible
                            }
                    
                        }
                    
                        override fun getItemCount(): Int {
                            return bibleData.size
                        }
                    
                        override fun getItemViewType(position: Int): Int {
                            return position % 2
                        }
                    
                        override fun getItemId(position: Int): Long {
                            //val product: Product = bibleData[position]
                            //return product.pid
                            return position.toLong()
                        }
                    
                        // 2021-12-01 Original에 Expense와 또 하나 섞은 것
                        override fun onBindViewHolder(holder: RoombibleAdapter.Holder, position: Int) {
                            val roombible = bibleData[position]
                            holder.setRoomBible(roombible)
                    
                            // 2021-12-01 실패
                            /*
                            val article = differ.currentList[position]
                            //각 리스트의 구성요소들을 UI에 연결
                            holder.itemView.apply{
                                //val bibleCompare = g.
                                 = article.rhv
                                bibleCompare.text = article.cmv
                                // 각 항목 클릭 가능하게
                                setOnClickListener{
                                    onItemClickListener?.let{
                                        it(article)
                                    }
                                }
                            }
                            */
                    
                            // holder.bind(getItem(position))   //2021-12-02 Expense에서 온 것
                    
                        }
                    
                        companion object DiffUtils : DiffUtil.ItemCallback<RoomPbible>() {
                            override fun areItemsTheSame(oldItem: RoomPbible, newItem: RoomPbible): Boolean {
                                return oldItem.rhv == newItem.rhv
                            }
                            @SuppressLint("DiffUtilEquals")
                            override fun areContentsTheSame(oldItem: RoomPbible, newItem: RoomPbible): Boolean {
                                return oldItem == newItem
                            }
                        }
                    
                        private var onItemClickListener: ((RoomPbible) -> Unit)? = null
                    
                        fun setOnItemClickListener(listener: (RoomPbible) -> Unit) {
                            onItemClickListener = listener
                        }
                    
                        // 2021-12-02
                        class DiffUtilCallback(
                            private val oldData: List<RoomPbible>,
                            private val newData: List<RoomPbible>
                        ) : DiffUtil.Callback() {
                            override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
                                val oldItem = oldData[oldItemPosition]
                                val newItem = newData[newItemPosition]
                                return oldItem.rhv == newItem.rhv
                                /*
                                return if (oldItem is Board && newItem is Board) {
                                    oldItem.rhv == newItem.rhv
                                } else {
                                    false
                                }
                                */
                            }
                            override fun getOldListSize(): Int = oldData.size
                            override fun getNewListSize(): Int = newData.size
                            override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean =
                                oldData[oldItemPosition] == newData[newItemPosition]
                        }
                    
                        /*
                        class DiffUtilCallback(
                            private val oldData: List<RoomPbible>,
                            private val newData: List<RoomPbible>
                        ) : DiffUtil.Callback() {
                            override fun areItemsTheSame(oldData: RoomPbible, newData: RoomPbible): Boolean {
                                return oldData.rhv == newData.rhv
                            }
                            override fun getOldListSize(): Int = oldData.size
                            override fun getNewListSize(): Int = newData.size
                            override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
                                TODO("Not yet implemented")
                            }
                            override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean =
                                oldData[oldItemPosition] == newData[newItemPosition]
                        }
                        */
                    
                        /*
                        // 2021-12-01    보류
                        //viewholder를 만들어줌
                        //inner class ArticleViewHolder(itemView: View): RecyclerView.ViewHolder(itemView)
                        inner class ArticleViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
                            var bibleContent : TextView = itemView.findViewById(R.id.bibleContent)
                            var bibleCompare : TextView = itemView.findViewById(R.id.bibleCompare)
                        }
                        */
                    
                        //추가시작  2021-12-01
                        //val differ = AsyncListDiffer(this, differCallback)    // 앞의 것에 달린 것
                        /*
                        override fun onBindViewHolder(holder: ArticleViewHolder, position: Int) {
                            val article = differ.currentList[position]
                            holder.itemView.apply { // apply: reference views directly
                                holder.bibleContent.text = article.rhv
                                holder.bibleCompare.text = article.cmv
                                setOnClickListener { onItemClickListener?.let { it(article) } }
                            }
                        }
                        */
                        /*
                         override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ArticleViewHolder {
                            return ArticleViewHolder(
                                LayoutInflater.from(parent.context).inflate(R.layout.item_roombible, parent,false)
                            )
                        }
                        */
                    
                        /*
                        override fun getItemCount(): Int {
                            //리사이클러뷰에서는 보통 리스트를 받아서 그 리스트 사이즈를 count하지만 리스트를 asynclistdiffer가 관리하기때문에, differ에 item갯수로 연결해주어야합니다.
                            return differ.currentList.size
                        }
                        //추가끝
                        */
                    
                        /*
                        override fun submitList(list: List<Item>?) {
                            super.submitList(list)
                        }
                        */
                    
                        fun removeSelectedExpense() = bibleData.clear()
                        //fun selectBibleSize() = differ.currentList.size
                        fun removeSelectedExpense2() {
                            bibleData.clear()
                            notifyDataSetChanged()
                            //notifyItemRangeRemoved(0, itemCount)
                        }
                        fun unselectBibleData() {
                            val sizex = bibleData.size
                            val handler = Handler(Looper.getMainLooper())
                            Log.d("Room of pentalogia", "선택사이즈 A: $sizex B: $itemCount")
                            handler.postDelayed({
                                //CoroutineScope(Dispatchers.IO).launch{
                                for (i in 0 until 30) {
                                    val sizey= bibleData[i].rhv
                                    //bibleData.removeAt(i)
                                    //if(i%2 ==1) {
                                        Log.d("Room of pentalogia", "선택 $sizey")
                                        bibleData.removeAt(i)
                                    //}
                                }
                                /*
                                for (i in bibleData.indices.reversed()) {
                                    val sizey= bibleData[i].rhv
                                    Log.d("Room of pentalogia", "선택 $sizey")
                                    //if (bibleData[i].contains("bad")) {
                                        bibleData.removeAt(i)
                                    //}
                                }
                                */
                               /*
                                val numberIterator = bibleData.iterator()
                                while (numberIterator.hasNext()) {
                                    val integer = numberIterator.next()
                                    if (integer < 3) {
                                        numberIterator.remove()
                                    }
                                }
                                */
                                //}
                            },0)
                        }
                    
                        fun refresh(data: List<RoomPbible>) {
                            //val selectedExpense: MutableList<RoomPbible> = mutableListOf()
                            /*
                            // 2021-12-02 Compleate!! Good. but lzay
                            bibleData.clear()
                            bibleData.addAll(data)
                            val handler = Handler(Looper.getMainLooper())
                            handler.postDelayed({
                                notifyDataSetChanged()
                            }, 0)
                            */
                    
                            /*
                            val oldItem = RoombibleAdapter.areItemsTheSame()
                            //val diffCallback = differCallback(this.)
                            val result = DiffUtil.calculateDiff()
                            bibleData = data as MutableList<RoomPbible>
                            result.dispatchUpdatesTo(this)
                            */
                            val diffCallback = DiffUtilCallback(this.bibleData, data)
                            val diffResult = DiffUtil.calculateDiff(diffCallback)
                            bibleData.clear()
                            bibleData.addAll(data)
                            val handler = Handler(Looper.getMainLooper())
                            handler.postDelayed({
                                diffResult.dispatchUpdatesTo(this)
                            }, 0)
                        }
                        fun loadFakeData2() {
                            //rbAdapter.bibleData.addAll(helper?.roomPbibleDao()?.getAllPbible() ?: listOf())
                            selectedExpense.addAll(helper?.roomPbibleDao()?.getAllPbible() ?: listOf())
                        }
                    
                    }
                    
                    mimoon
                    키 마스터

                      //completed version
                      // 성공

                      
                      // 2021-11-16
                          private fun startDownload() {
                              //if(Build.VERSION.SDK_INT >= 17){
                              //    val dbPATH = this.applicationInfo.dataDir+"/databases/"
                              //}else {
                                  //this.DB_PATH = "/data/data/"+context.getPackageName()+"/databases/";
                                  val dbPATH = "/data/data/" + applicationContext.packageName + "/databases/"
                                  //Log.e("Path:", DB_PATH);
                              //}
                              val dbNAME = "room_memo.db"
                              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.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI or DownloadManager.Request.NETWORK_MOBILE)
                              //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.setDestinationInExternalFilesDir(this, Environment.DIRECTORY_DOWNLOADS, filename)    // to save in cache
                              //request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename)      // to save in public download folder
                              //request.setDestinationInExternalPublicDir(Environment.getDownloadCacheDirectory().toString(), filename)
                              //val manager = getSystemService(DOWNLOAD_SERVICE) as DownloadManager   // to start download
                              //manager.enqueue(request)
                      
                              // to test by written url
                              //val target = File(strOutFile)       // 에뮬레이터에서만 효용
                              val target = File(dbPATH, dbNAME)  // 에뮬레이터에서 효용
                              if (!target.exists()) {
                                  gAlert("내부 저장소(수동 경로 $target)에 파일이 없음을 확인했습니다.")
                                  //target.createNewFile()
                              } else {
                                  val dbSize: Int = java.lang.String.valueOf(target.length() / 1024).toInt()
                                  gAlert("내부 저장소(수동 경로 $target)에 파일(크기: $dbSize)이 이미 존재합니다.")
                                  //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 currentGetDbPath: File = this.getDatabasePath("room_memo.db")     // 파일 명 포함
                              val outFileName = currentGetDbPath.path
                              //val downloadFolder = File(cacheDir.toString())
                              val downloadFolder = File(Environment.DIRECTORY_DOWNLOADS).toString()
                              //val downloadFolder = Environment.getExternalStorageDirectory()  // 에뮬레이터에서 효용
                              val dataGetExternalStorageDirectory: File = Environment.getExternalStorageDirectory()      // 에뮬레이터에서 효용
                              val dataInternalGetDataDirectory: File = Environment.getDataDirectory()
                              val dataGetDirDnld: File = File(Environment.DIRECTORY_DOWNLOADS)
                              val dataGetDnldCacheDirectory: File = Environment.getDownloadCacheDirectory()
                              val dataDownloadFilesDir = this.filesDir   // 내부 저장소 일반 파일
                              val dataDownloadCacheDir = this.cacheDir
                              val dataDirDnldGetExternalFilesDir = this.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)
                              val dataDirDnldExternalStoragePublicDirectory = getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
                              //val dataDirDnld = this.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)
                              //val dataDirDnld = this.getDatabasePath(Environment.DIRECTORY_DOWNLOADS)
                              //val dataDirDnld = File(Environment.DIRECTORY_DOWNLOADS).toString()
                              //val data: File = File(cacheDir.toString())
                              //val currentDB = File(currentDBPath)
                              val backupDB = File(downloadFolder, dbNAME)
                              //val strOutFile2 = "$currentDBPath"
                              //gAlert("내부 저장소 절대경로는$strOutFile2")
                      
                              //val target2 = File(strOutFile2)     // 에뮬과 디바이스 모두 안 됨
                              //val target2 = File(currentDBPath)       // 에뮬과 디바이스 모두 됨 (시스템에 의한 절대 경로 얻기)
                             // val target2 = File(outFileName)     // 에뮬레이터에서는 되고 디바이스에서는 안 됨
                              //val target2 = Environment.getDataDirectory()        // 에뮬레이터와 디바이스 모두 효용// 이것은 다운로드 폴더 경로
                              val target2 = File(currentGetDbPath.toString())    // 에뮬레이터에서 됨
                      
                              val target3 = File(downloadFolder, dbNAME)        // 에뮬레이터에서만 효용
                              val targetGetExternalStorageDirectory = File(dataGetExternalStorageDirectory, dbNAME)      // 외장 다운로드 메모리 경로
                              val targetInternalGetDataDirectory = File(dataInternalGetDataDirectory, dbNAME)      // 내장 메모리 다운로드 폴더 경로
                              val targetDirectDownload = File(dataGetDirDnld, dbNAME)      // 내장 다운로드 메모리 경로
                              val targetGetDownloadCacheDirectory = File(dataGetDnldCacheDirectory, dbNAME)        // 에뮬에서 효용
                              val targetDownloadFilesDir = File(dataDownloadFilesDir, dbNAME)
                              val targetDownloadCacheDir = File(dataDownloadCacheDir, dbNAME)
                              val targetDirGetExternalFilesDir = File(dataDirDnldGetExternalFilesDir, dbNAME)
                              val targetDirDnldExternalStoragePublicDirectory = File(dataDirDnldExternalStoragePublicDirectory, dbNAME)
                              //val strOutFile3 = "$data/$backupDBPath"
                              //val target3 = File(strOutFile3)
                              //gAlert("공용 저장소 파일 절대경로는 $target3")
                              //gAlert("내부 저장소 절대경로는$target2")
                              if (target2.exists()) {
                                  val dbSize: Int = java.lang.String.valueOf(target2.length() / 1024).toInt()
                                  gAlert("내장 폴더 절대경로에서 파일(크기: $dbSize) 찾음. $target2")
                                  //target.delete()
                                  //target.createNewFile()
                                  //Log.d("TAG", "==== backUpExists: " + "내장 폴더에서 백업파일 찾음");
                              } else {
                                  gAlert("내장 폴더 절대경로에서 파일 못 찾음. $target2")
                      
                              }
                              when {
                                  targetGetExternalStorageDirectory.exists() -> {
                                      gAlert("외부 저장소getExternalStorageDirectory($targetGetExternalStorageDirectory)에서 파일 찾음.")
                                      targetGetExternalStorageDirectory.delete()
                                      //targetGetExternalStorageDirectory.createNewFile()
                                      //Log.d("TAG", "==== backUpExists: " + "다운로드 폴더에서 백업파일 찾음");
                                  }
                                  targetInternalGetDataDirectory.exists() -> {
                                      gAlert("내부 저장소getDataDirectory($targetInternalGetDataDirectory)에서 파일 찾음.")
                                      targetInternalGetDataDirectory.delete()
                                  }
                                  targetDirectDownload.exists() -> {
                                      gAlert("다운로드 지정했던 함수DIRECTORY_DOWNLOADS($targetDirectDownload)에서 파일 찾음.")
                                      targetDirectDownload.delete()
                                  }
                                  targetGetDownloadCacheDirectory.exists() -> {
                                      gAlert("getDownloadCacheDirectory($targetGetDownloadCacheDirectory)에서 파일 찾음.")
                                      targetGetDownloadCacheDirectory.delete()
                                  }
                                  targetDownloadFilesDir.exists() -> {
                                      val dbSize: Int = java.lang.String.valueOf(targetDownloadFilesDir.length() / 1024).toInt()
                                      gAlert("내부 저장소 FilesDir($targetDownloadFilesDir)에서 파일(크기: $dbSize) 찾음.")
                                      //targetDownloadFilesDir.delete()
                                  }
                                  targetDownloadCacheDir.exists() -> {
                                      gAlert("내부 저장소 CacheDir($targetDownloadCacheDir)에서 파일 찾음.")
                                      targetDownloadCacheDir.delete()
                                  }
                                  targetDirGetExternalFilesDir.exists() -> {
                                      val dbSize: Int = java.lang.String.valueOf(targetDirGetExternalFilesDir.length() / 1024).toInt()
                                      gAlert("외부저장소 DirGetExternalFilesDir ($targetDirGetExternalFilesDir)에서 파일(크기: $dbSize) 찾음.")
                                      //targetDirGetExternalFilesDir.delete()
                                  }
                                  targetDirDnldExternalStoragePublicDirectory.exists() -> {
                                      val dbSize: Int = java.lang.String.valueOf(targetDirDnldExternalStoragePublicDirectory.length() / 1024).toInt()
                                      gAlert("외부 저장소 DirDnldExternalStoragePublicDirectory($targetDirDnldExternalStoragePublicDirectory)에서 파일(크기: $dbSize) 찾음.")
                                      //targetDirDnldExternalStoragePublicDirectory.delete()
                                  }
                                  target3.exists() -> {
                                      gAlert("File(Environment.DIRECTORY_DOWNLOADS)($target3)에서 파일 찾음.")
                                      target3.delete()
                                  }
                                  else -> {
                                      gAlert("아무 곳에서도 파일  못 찾음.")
                                      val manager =  getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
                                      manager.enqueue(request)
                      
                                  }
                              }
                              /*
                              val src: FileChannel = FileInputStream(currentDB).channel
                              val dst: FileChannel = FileOutputStream(backupDB).channel
                              dst.transferFrom(src, 0, src.size())
                              src.close()
                              dst.close()
                              */
                      
                              // 2021-11-20
                              // Make sure we have a path to the file
                              //currentGetDbPath.getParentFile().mkdirs()
                              // Try to copy database file
                              /* Try 부분을 제거해도 이전 가능
                              try {
                                  val inputStream: InputStream = targetDirGetExternalFilesDir.inputStream()       // 작동
                                  //val inputStream: InputStream = currentGetDbPath.inputStream()
                                  //val inputStream: InputStream = getDatabasePath("room_memo.db").inputStream()
                                  val output: OutputStream = FileOutputStream(currentGetDbPath)
                                  //val output: OutputStream = FileOutputStream(getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS))
                                  //val output: OutputStream = FileOutputStream(targetDirDnldExternalStoragePublicDirectory)
                                  //val output: OutputStream = FileOutputStream(targetDownloadFilesDir)     // 작동
                                  //val buffer = ByteArray(8192)
                                  val buffer = ByteArray(1024)
                                  var length: Int
                                  while (inputStream.read(buffer, 0, 1024).also { length = it } > 0) {
                                      output.write(buffer, 0, length)
                                  }
                                  output.flush()
                                  output.close()
                                  inputStream.close()
                      
                                  //val src: FileChannel = FileInputStream(currentGetDbPath).channel
                                  //val dst: FileChannel = FileOutputStream(targetDirDnldExternalStoragePublicDirectory).channel
                                  //dst.transferFrom(src, 0, src.size())
                                  //src.close()
                                  //dst.close()
                      
                              } catch (e: IOException) {
                                  Log.d("pentalogia", "Failed to open file", e)
                                  e.printStackTrace()
                                  //gAlert("복사 실패")
                              }
                      
                              //Try를 제거해도 createFromFile이 수행
                              */ 
                      
                              lifecycleScope.launch(Dispatchers.IO) {
                                  //.allowMainThreadQueries()
                                  // 2021-11-07
                                  //rcAdapter.setHasStableIds(true)
                                  withContext(Dispatchers.IO) {
                                      helper =
                                          Room.databaseBuilder(this@ListviewActivity, RoomHelper::class.java, "room_memo")
                                              .addMigrations(MigrateDatabase.MIGRATE_1_2)
                                              // 2021-11-16
                                              .createFromFile(File(targetDirGetExternalFilesDir.toString()))
                                                    .fallbackToDestructiveMigration()
                                              //.allowMainThreadQueries()
                                              .build()
                                      rcAdapter.helper = helper
                                      rcAdapter.listData.addAll(helper?.roomMemoDao()?.getAll() ?: listOf())
                                  }
                                  laBinding.recyclerMemo.adapter = rcAdapter
                                  laBinding.recyclerMemo.layoutManager = LinearLayoutManager(this@ListviewActivity)
                      
                                  // VerticalItemDecorator
                                  //laBinding.recyclerMemo.addItemDecoration(VerticalItemDecorator(10))
                                  //laBinding.recyclerMemo.addItemDecoration(DividerItemDecoration(this, LinearLayoutManager.VERTICAL))
                      
                                  // 2021-11-09 VerticalItemDecorator kill
                                  /*
                                  val decoDevider = CustomDecoration(3f, 10f, Color.LTGRAY)
                                  laBinding.recyclerMemo.addItemDecoration(decoDevider)
                                  */
                      
                                  (laBinding.recyclerMemo.layoutManager as LinearLayoutManager).reverseLayout = true
                                  (laBinding.recyclerMemo.layoutManager as LinearLayoutManager).stackFromEnd = true
                                  // if empty any data
                                  val emptyView: TextView = laBinding.emptyView
                                  if (rcAdapter.itemCount == 0) emptyView.visibility =
                                      View.VISIBLE else emptyView.visibility = View.GONE
                                  rcAdapter.notifyDataSetChanged()
                              }
                      
                          }
                      
                      mimoon
                      키 마스터

                        last

                        
                        private fun startDownload() {
                                val dbPATH = "/data/data/" + applicationContext.packageName + "/databases/"
                                val dbNAME = "room_memo.db"
                                val strOutFile = dbPATH + dbNAME
                                /*
                                val request = DownloadManager.Request(Uri.parse("https://mimoonchurch.net/room_memo.db"))
                                request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI or DownloadManager.Request.NETWORK_MOBILE)
                                request.setTitle("room_memo.db")
                                request.setDescription("My database is downloading.")
                                request.allowScanningByMediaScanner()
                                request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
                                request.setDestinationInExternalPublicDir(dbPATH, "room_memo.db")
                                val manager =  getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
                                manager.enqueue(request)
                                */
                                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(strOutFile)
                                if (!target.exists()) {
                                    gAlert("내부 저장소($strOutFile)에 파일이 없음을 확인했습니다.")
                                    target.createNewFile()
                                } else {
                                    gAlert("내부 저장소($strOutFile)에 파일이 이미 존재합니다.")
                                    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()
                        
                            }
                        
                      10 글 보임 - 1 에서 10 까지 (총 57 중에서)