<?xml version="1.0" encoding="utf-8" ?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<title>다국어 홈페이지 제작 관리 - 제로나라 &amp;gt; 오픈지식 &amp;gt; 팁앤테크</title>
<link>https://zeronara.com/tipntech</link>
<language>ko</language>
<description>팁앤테크 (2026-03-21 22:20:39)</description>

<item>
<title>[php] 안드로이드 웹뷰 정리 2026-03-21Webサイト</title>
<link>https://zeronara.com/tipntech/1106</link>
<description><![CDATA[<img src="https://zeronara.net/data/editor/2602/9bd8344ae4448c715b78624d2c4d2ffe_1771850258_1827.png" title="9bd8344ae4448c715b78624d2c4d2ffe_1771850258_1827.png" alt="9bd8344ae4448c715b78624d2c4d2ffe_1771850258_1827.png" /><br style="clear:both;" /><p><br /></p><p><br /></p><p><img src="https://zeronara.net/data/editor/2602/9bd8344ae4448c715b78624d2c4d2ffe_1771850300_1786.png" title="9bd8344ae4448c715b78624d2c4d2ffe_1771850300_1786.png" alt="9bd8344ae4448c715b78624d2c4d2ffe_1771850300_1786.png" /><br style="clear:both;" /> </p><img src="https://zeronara.net/data/editor/2602/9bd8344ae4448c715b78624d2c4d2ffe_1771854235_0291.png" title="9bd8344ae4448c715b78624d2c4d2ffe_1771854235_0291.png" alt="9bd8344ae4448c715b78624d2c4d2ffe_1771854235_0291.png" /><br style="clear:both;" /><br style="clear:both;" /><br style="clear:both;" /><br /><p><b>manifests/AndroidManifest.xml</b></p><div style="background-color:#1e1f22;color:#bcbec4;"><pre style="font-family:'JetBrains Mono', monospace;font-size:9.8pt;"><span style="color:#d5b778;">&lt;?</span>xml version<span style="color:#6aab73;">="1.0" </span>encoding<span style="color:#6aab73;">="utf-8"</span><span style="color:#d5b778;">?&gt;<br /></span><span style="color:#d5b778;">&lt;manifest </span>xmlns:<span style="color:#c77dbb;">android</span><span style="color:#6aab73;">="http://schemas.android.com/apk/res/android"<br /></span><span style="color:#6aab73;">    </span>package<span style="color:#6aab73;">="zeronara.net"</span><span style="color:#d5b778;">&gt;<br /></span><span style="color:#d5b778;"><br /></span><span style="color:#d5b778;">    &lt;uses-permission </span><span style="color:#c77dbb;">android</span>:name<span style="color:#6aab73;">="android.permission.INTERNET" </span><span style="color:#d5b778;">/&gt;<br /></span><span style="color:#d5b778;"><br /></span><span style="color:#d5b778;">    &lt;application<br /></span><span style="color:#d5b778;">        </span><span style="color:#c77dbb;">android</span>:allowBackup<span style="color:#6aab73;">="true"<br /></span><span style="color:#6aab73;">        </span><span style="color:#c77dbb;">android</span>:icon<span style="color:#6aab73;">="@mipmap/ic_launcher"<br /></span><span style="color:#6aab73;">        </span><span style="color:#c77dbb;">android</span>:label<span style="color:#6aab73;">="@string/app_name"<br /></span><span style="color:#6aab73;">        </span><span style="color:#c77dbb;">android</span>:roundIcon<span style="color:#6aab73;">="@mipmap/ic_launcher_round"<br /></span><span style="color:#6aab73;">        </span><span style="color:#c77dbb;">android</span>:supportsRtl<span style="color:#6aab73;">="true"<br /></span><span style="color:#6aab73;">        </span><span style="color:#c77dbb;">android</span>:theme<span style="color:#6aab73;">="@style/Theme.App.Transparent"<br /></span><span style="color:#6aab73;">        </span><span style="color:#c77dbb;">android</span>:usesCleartextTraffic<span style="color:#6aab73;">="true"</span><span style="color:#d5b778;">&gt;<br /></span><span style="color:#d5b778;"><br /></span><span style="color:#d5b778;">        &lt;activity<br /></span><span style="color:#d5b778;">            </span><span style="color:#c77dbb;">android</span>:name<span style="color:#6aab73;">=".MainActivity"<br /></span><span style="color:#6aab73;">            </span><span style="color:#c77dbb;">android</span>:exported<span style="color:#6aab73;">="true"<br /></span><span style="color:#6aab73;">            </span><span style="color:#c77dbb;">android</span>:windowSoftInputMode<span style="color:#6aab73;">="adjustResize"</span><span style="color:#d5b778;">&gt;<br /></span><span style="color:#d5b778;">            &lt;intent-filter&gt;<br /></span><span style="color:#d5b778;">                &lt;action </span><span style="color:#c77dbb;">android</span>:name<span style="color:#6aab73;">="android.intent.action.MAIN" </span><span style="color:#d5b778;">/&gt;<br /></span><span style="color:#d5b778;">                &lt;category </span><span style="color:#c77dbb;">android</span>:name<span style="color:#6aab73;">="android.intent.category.LAUNCHER" </span><span style="color:#d5b778;">/&gt;<br /></span><span style="color:#d5b778;">            &lt;/intent-filter&gt;<br /></span><span style="color:#d5b778;">        &lt;/activity&gt;<br /></span><span style="color:#d5b778;"><br /></span><span style="color:#d5b778;">    &lt;/application&gt;<br /></span><span style="color:#d5b778;"><br /></span><span style="color:#d5b778;">&lt;/manifest&gt;</span></pre></div><br /><p><b>kotlin+java/zeronara.net/MainActivity.java</b></p><p><b><br /></b></p><div style="background-color:#1e1f22;color:#bcbec4;"><pre style="font-family:'JetBrains Mono', monospace;font-size:9.8pt;"><span style="color:#cf8e6d;">package </span>zeronara.net;<br /><br /><span style="color:#cf8e6d;">import </span>android.app.AlertDialog;<br /><span style="color:#cf8e6d;">import </span>android.annotation.<span style="color:#b3ae60;">SuppressLint</span>;<br /><span style="color:#cf8e6d;">import </span>android.content.ActivityNotFoundException;<br /><span style="color:#cf8e6d;">import </span>android.content.Intent;<br /><span style="color:#cf8e6d;">import </span>android.graphics.Color;<br /><span style="color:#cf8e6d;">import </span>android.net.Uri;<br /><span style="color:#cf8e6d;">import </span>android.os.Bundle;<br /><span style="color:#cf8e6d;">import </span>android.util.Log;<br /><span style="color:#cf8e6d;">import </span>android.view.Window;<br /><span style="color:#cf8e6d;">import </span>android.widget.FrameLayout;<br /><span style="color:#cf8e6d;">import </span>android.webkit.SslErrorHandler;<br /><span style="color:#cf8e6d;">import </span>android.webkit.WebChromeClient;<br /><span style="color:#cf8e6d;">import </span>android.webkit.WebResourceError;<br /><span style="color:#cf8e6d;">import </span>android.webkit.WebResourceRequest;<br /><span style="color:#cf8e6d;">import </span>android.webkit.WebSettings;<br /><span style="color:#cf8e6d;">import </span>android.webkit.WebView;<br /><span style="color:#cf8e6d;">import </span>android.webkit.WebViewClient;<br /><span style="color:#cf8e6d;">import </span>android.net.http.SslError;<br /><br /><span style="color:#cf8e6d;">import </span>androidx.activity.EdgeToEdge;<br /><span style="color:#cf8e6d;">import </span>androidx.appcompat.app.AppCompatActivity;<br /><span style="color:#cf8e6d;">import </span>androidx.activity.OnBackPressedCallback;<br /><span style="color:#cf8e6d;">import </span>androidx.core.graphics.Insets;<br /><span style="color:#cf8e6d;">import </span>androidx.core.view.ViewCompat;<br /><span style="color:#cf8e6d;">import </span>androidx.core.view.WindowInsetsCompat;<br /><span style="color:#cf8e6d;">import </span>androidx.core.view.WindowInsetsControllerCompat;<br /><span style="color:#cf8e6d;">import </span>androidx.swiperefreshlayout.widget.SwipeRefreshLayout;<br /><br /><span style="color:#cf8e6d;">public class </span>MainActivity <span style="color:#cf8e6d;">extends </span>AppCompatActivity {<br />    <span style="color:#cf8e6d;">private static final </span>String <span style="color:#c77dbb;font-style:italic;">TAG </span>= <span style="color:#6aab73;">"MainActivity"</span>;<br />    <span style="color:#cf8e6d;">public </span>WebView <span style="color:#c77dbb;">webView</span>;<br />    <span style="color:#cf8e6d;">private </span>SwipeRefreshLayout <span style="color:#c77dbb;">swipeRefresh</span>;<br /><br />    <span style="color:#b3ae60;">@Override<br /></span><span style="color:#b3ae60;">    @SuppressLint</span>(<span style="color:#6aab73;">"SetJavaScriptEnabled"</span>)<br />    <span style="color:#cf8e6d;">protected void </span><span style="color:#56a8f5;">onCreate</span>(Bundle savedInstanceState) {<br />        <span style="color:#7a7e85;">// EdgeToEdge: </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">システムバー領域までコンテンツを拡張（</span><span style="color:#7a7e85;">API 36</span><span style="color:#7a7e85;font-family:'Courier New', monospace;">対応）<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">        </span>EdgeToEdge.<span style="font-style:italic;">enable</span>(<span style="color:#cf8e6d;">this</span>);<br /><br />        <span style="color:#cf8e6d;">super</span>.onCreate(savedInstanceState);<br />        requestWindowFeature(Window.<span style="color:#c77dbb;font-style:italic;">FEATURE_NO_TITLE</span>);<br />        setContentView(R.layout.<span style="color:#c77dbb;font-style:italic;">activity_main</span>);<br /><br />        <span style="color:#7a7e85;">// </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">ウィンドウ背景を透明に設定<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">        </span>getWindow().setBackgroundDrawable(<span style="color:#cf8e6d;">null</span>);<br /><br />        <span style="color:#7a7e85;">// </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">ステータスバー</span><span style="color:#7a7e85;"> / </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">ナビゲーションバーを完全透明に設定<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">        </span>getWindow().setStatusBarColor(Color.<span style="color:#c77dbb;font-style:italic;">TRANSPARENT</span>);<br />        getWindow().setNavigationBarColor(Color.<span style="color:#c77dbb;font-style:italic;">TRANSPARENT</span>);<br /><br />        <span style="color:#7a7e85;">// </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">システムバーアイコンの色を設定<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">        </span><span style="color:#7a7e85;">// false = </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">白いアイコン（暗い背景用）</span><span style="color:#7a7e85;"> / true = </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">黒いアイコン（明るい背景用）<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">        </span>WindowInsetsControllerCompat insetsController =<br />                <span style="color:#cf8e6d;">new </span>WindowInsetsControllerCompat(getWindow(), getWindow().getDecorView());<br />        insetsController.setAppearanceLightStatusBars(<span style="color:#cf8e6d;">false</span>);<br />        insetsController.setAppearanceLightNavigationBars(<span style="color:#cf8e6d;">false</span>);<br /><br />        <span style="color:#c77dbb;">webView </span>= findViewById(R.id.<span style="color:#c77dbb;font-style:italic;">webView</span>);<br />        <span style="color:#c77dbb;">swipeRefresh </span>= findViewById(R.id.<span style="color:#c77dbb;font-style:italic;">swipeRefresh</span>);<br /><br />        <span style="color:#7a7e85;">// WebView</span><span style="color:#7a7e85;font-family:'Courier New', monospace;">の背景を透明に設定<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">        </span><span style="color:#c77dbb;">webView</span>.setBackgroundColor(Color.<span style="color:#c77dbb;font-style:italic;">TRANSPARENT</span>);<br /><br />        <span style="color:#7a7e85;">// SwipeRefreshLayout </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">インジケーターの色設定<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">        </span><span style="color:#c77dbb;">swipeRefresh</span>.setColorSchemeColors(<br />                Color.<span style="font-style:italic;">parseColor</span>(<span style="color:#6aab73;">"#4A90E2"</span>),<br />                Color.<span style="font-style:italic;">parseColor</span>(<span style="color:#6aab73;">"#50C878"</span>),<br />                Color.<span style="font-style:italic;">parseColor</span>(<span style="color:#6aab73;">"#FF6B6B"</span>)<br />        );<br />        <span style="color:#7a7e85;">// </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">インジケーターの背景色（透明背景に合わせて白）<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">        </span><span style="color:#c77dbb;">swipeRefresh</span>.setProgressBackgroundColorSchemeColor(Color.<span style="color:#c77dbb;font-style:italic;">WHITE</span>);<br /><br />        <span style="color:#7a7e85;">// </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">下にスワイプしたときにページを再読み込み<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">        </span><span style="color:#c77dbb;">swipeRefresh</span>.setOnRefreshListener(() -&gt; <span style="color:#c77dbb;">webView</span>.reload());<br /><br />        <span style="color:#7a7e85;">// WebView</span><span style="color:#7a7e85;font-family:'Courier New', monospace;">ではなくコンテナ（</span><span style="color:#7a7e85;">FrameLayout</span><span style="color:#7a7e85;font-family:'Courier New', monospace;">）にパディングを適用<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">        </span><span style="color:#7a7e85;">// → WebView</span><span style="color:#7a7e85;font-family:'Courier New', monospace;">のスクロール領域はそのままで、システムバー分のマージンを確保<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">        </span>FrameLayout container = findViewById(R.id.<span style="color:#c77dbb;font-style:italic;">container</span>);<br />        ViewCompat.<span style="font-style:italic;">setOnApplyWindowInsetsListener</span>(container, (v, insets) -&gt; {<br />            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.<span style="font-style:italic;">systemBars</span>());<br />            v.setPadding(<br />                    systemBars.<span style="color:#c77dbb;">left</span>,   <span style="color:#7a7e85;">// </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">左（横向きモード対応）<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">                    </span>systemBars.<span style="color:#c77dbb;">top</span>,    <span style="color:#7a7e85;">// </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">ステータスバーの高さ<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">                    </span>systemBars.<span style="color:#c77dbb;">right</span>,  <span style="color:#7a7e85;">// </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">右（横向きモード対応）<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">                    </span>systemBars.<span style="color:#c77dbb;">bottom  </span><span style="color:#7a7e85;">// </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">ナビゲーションバーの高さ<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">            </span>);<br />            <span style="color:#cf8e6d;">return </span>WindowInsetsCompat.<span style="color:#c77dbb;font-style:italic;">CONSUMED</span>;<br />        });<br /><br />        WebSettings webSettings = <span style="color:#c77dbb;">webView</span>.getSettings();<br /><br />        <span style="color:#7a7e85;">// JavaScript</span><span style="color:#7a7e85;font-family:'Courier New', monospace;">はWebサイト</span><span style="color:#7a7e85;font-family:'Courier New', monospace;">の正常動作に必須<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">        </span><span style="color:#7a7e85;">// </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">信頼できる自社ドメインのコンテンツのみを読み込むため、</span><span style="color:#7a7e85;">XSS</span><span style="color:#7a7e85;font-family:'Courier New', monospace;">リスクは最小限<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">        </span>webSettings.setJavaScriptEnabled(<span style="color:#cf8e6d;">true</span>);<br />        webSettings.setDomStorageEnabled(<span style="color:#cf8e6d;">true</span>);<br />        webSettings.setUseWideViewPort(<span style="color:#cf8e6d;">true</span>);<br />        webSettings.setLoadWithOverviewMode(<span style="color:#cf8e6d;">true</span>);<br />        webSettings.setCacheMode(WebSettings.<span style="color:#c77dbb;font-style:italic;">LOAD_DEFAULT</span>);<br /><br />        <span style="color:#7a7e85;">// </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">ユーザーエージェント設定<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">        </span>String defaultUA = webSettings.getUserAgentString();<br />        webSettings.setUserAgentString(defaultUA + <span style="color:#6aab73;">" webviewApp/1.0 (Android)"</span>);<br /><br />        <span style="color:#c77dbb;">webView</span>.setWebViewClient(<span style="color:#cf8e6d;">new </span>WebViewClient() {<br /><br />            <span style="color:#b3ae60;">@Override<br /></span><span style="color:#b3ae60;">            </span><span style="color:#cf8e6d;">public boolean </span><span style="color:#56a8f5;">shouldOverrideUrlLoading</span>(WebView view, WebResourceRequest request) {<br />                String url = request.getUrl().toString();<br /><br />                <span style="color:#7a7e85;">// Google Play</span><span style="color:#7a7e85;font-family:'Courier New', monospace;">ストアリンクの処理<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">                </span><span style="color:#cf8e6d;">if </span>(url.startsWith(<span style="color:#6aab73;">"market://"</span>) || url.contains(<span style="color:#6aab73;">"play.google.com/store"</span>)) {<br />                    <span style="color:#cf8e6d;">try </span>{<br />                        Intent intent = <span style="color:#cf8e6d;">new </span>Intent(Intent.<span style="color:#c77dbb;font-style:italic;">ACTION_VIEW</span>, Uri.<span style="font-style:italic;">parse</span>(url));<br />                        startActivity(intent);<br />                    } <span style="color:#cf8e6d;">catch </span>(ActivityNotFoundException e) {<br />                        <span style="color:#7a7e85;">// Play</span><span style="color:#7a7e85;font-family:'Courier New', monospace;">ストアアプリが存在しない場合はブラウザへフォールバック<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">                        </span>String fallbackUrl = url.replace(<span style="color:#6aab73;">"market://"</span>, <span style="color:#6aab73;">"https://play.google.com/store/apps/"</span>);<br />                        startActivity(<span style="color:#cf8e6d;">new </span>Intent(Intent.<span style="color:#c77dbb;font-style:italic;">ACTION_VIEW</span>, Uri.<span style="font-style:italic;">parse</span>(fallbackUrl)));<br />                    }<br />                    <span style="color:#cf8e6d;">return true</span>;<br />                }<br /><br />                <span style="color:#7a7e85;">// </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">外部ブラウザで開くべきスキームの処理（</span><span style="color:#7a7e85;">tel</span><span style="color:#7a7e85;font-family:'Courier New', monospace;">、</span><span style="color:#7a7e85;">mailto</span><span style="color:#7a7e85;font-family:'Courier New', monospace;">など）<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">                </span><span style="color:#cf8e6d;">if </span>(url.startsWith(<span style="color:#6aab73;">"tel:"</span>) || url.startsWith(<span style="color:#6aab73;">"mailto:"</span>) || url.startsWith(<span style="color:#6aab73;">"intent:"</span>)) {<br />                    <span style="color:#cf8e6d;">try </span>{<br />                        startActivity(<span style="color:#cf8e6d;">new </span>Intent(Intent.<span style="color:#c77dbb;font-style:italic;">ACTION_VIEW</span>, Uri.<span style="font-style:italic;">parse</span>(url)));<br />                    } <span style="color:#cf8e6d;">catch </span>(ActivityNotFoundException e) {<br />                        Log.<span style="font-style:italic;">e</span>(<span style="color:#c77dbb;font-style:italic;">TAG</span>, <span style="color:#6aab73;">"</span><span style="color:#6aab73;font-family:'Courier New', monospace;">指定された</span><span style="color:#6aab73;">URL</span><span style="color:#6aab73;font-family:'Courier New', monospace;">に対応するアクティビティが見つかりません</span><span style="color:#6aab73;">: " </span>+ url, e);<br />                    }<br />                    <span style="color:#cf8e6d;">return true</span>;<br />                }<br /><br />                <span style="color:#cf8e6d;">return false</span>; <span style="color:#7a7e85;">// </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">その他の</span><span style="color:#7a7e85;">URL</span><span style="color:#7a7e85;font-family:'Courier New', monospace;">は</span><span style="color:#7a7e85;">WebView</span><span style="color:#7a7e85;font-family:'Courier New', monospace;">で処理<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">            </span>}<br /><br />            <span style="color:#b3ae60;">@Override<br /></span><span style="color:#b3ae60;">            </span><span style="color:#cf8e6d;">public void </span><span style="color:#56a8f5;">onPageFinished</span>(WebView view, String url) {<br />                <span style="color:#cf8e6d;">super</span>.onPageFinished(view, url);<br />                <span style="color:#7a7e85;">// </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">ページ読み込み完了時にインジケーターを非表示<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">                </span><span style="color:#c77dbb;">swipeRefresh</span>.setRefreshing(<span style="color:#cf8e6d;">false</span>);<br />            }<br /><br />            <span style="color:#b3ae60;">@Override<br /></span><span style="color:#b3ae60;">            </span><span style="color:#cf8e6d;">public void </span><span style="color:#56a8f5;">onReceivedError</span>(WebView view, WebResourceRequest request, WebResourceError error) {<br />                <span style="color:#cf8e6d;">super</span>.onReceivedError(view, request, error);<br />                <span style="color:#7a7e85;">// </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">エラー時もインジケーターを非表示<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">                </span><span style="color:#c77dbb;">swipeRefresh</span>.setRefreshing(<span style="color:#cf8e6d;">false</span>);<br />            }<br /><br />            <span style="color:#b3ae60;">@Override<br /></span><span style="color:#b3ae60;">            </span><span style="color:#cf8e6d;">public void </span><span style="color:#56a8f5;">onReceivedSslError</span>(WebView view, SslErrorHandler handler, SslError error) {<br />                <span style="color:#7a7e85;">// </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">【セキュリティ修正】すべての</span><span style="color:#7a7e85;">SSL</span><span style="color:#7a7e85;font-family:'Courier New', monospace;">エラーを無視する</span><span style="color:#7a7e85;"> handler.proceed() </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">を削除<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">                </span><span style="color:#7a7e85;">// SSL</span><span style="color:#7a7e85;font-family:'Courier New', monospace;">証明書エラー時は接続をブロックし、ユーザーに通知する<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">                </span>handler.cancel();<br />                <span style="color:#c77dbb;">swipeRefresh</span>.setRefreshing(<span style="color:#cf8e6d;">false</span>);<br /><br />                String errorMessage;<br />                <span style="color:#cf8e6d;">switch </span>(error.getPrimaryError()) {<br />                    <span style="color:#cf8e6d;">case </span>SslError.<span style="color:#c77dbb;font-style:italic;">SSL_EXPIRED</span>:<br />                        errorMessage = <span style="color:#6aab73;">"</span><span style="color:#6aab73;font-family:'Courier New', monospace;">セキュリティ証明書の有効期限が切れています。</span><span style="color:#6aab73;">"</span>;<br />                        <span style="color:#cf8e6d;">break</span>;<br />                    <span style="color:#cf8e6d;">case </span>SslError.<span style="color:#c77dbb;font-style:italic;">SSL_IDMISMATCH</span>:<br />                        errorMessage = <span style="color:#6aab73;">"</span><span style="color:#6aab73;font-family:'Courier New', monospace;">セキュリティ証明書のドメインが一致しません。</span><span style="color:#6aab73;">"</span>;<br />                        <span style="color:#cf8e6d;">break</span>;<br />                    <span style="color:#cf8e6d;">case </span>SslError.<span style="color:#c77dbb;font-style:italic;">SSL_NOTYETVALID</span>:<br />                        errorMessage = <span style="color:#6aab73;">"</span><span style="color:#6aab73;font-family:'Courier New', monospace;">セキュリティ証明書はまだ有効ではありません。</span><span style="color:#6aab73;">"</span>;<br />                        <span style="color:#cf8e6d;">break</span>;<br />                    <span style="color:#cf8e6d;">case </span>SslError.<span style="color:#c77dbb;font-style:italic;">SSL_UNTRUSTED</span>:<br />                        errorMessage = <span style="color:#6aab73;">"</span><span style="color:#6aab73;font-family:'Courier New', monospace;">信頼できないセキュリティ証明書です。</span><span style="color:#6aab73;">"</span>;<br />                        <span style="color:#cf8e6d;">break</span>;<br />                    <span style="color:#cf8e6d;">default</span>:<br />                        errorMessage = <span style="color:#6aab73;">"</span><span style="color:#6aab73;font-family:'Courier New', monospace;">不明な</span><span style="color:#6aab73;">SSL</span><span style="color:#6aab73;font-family:'Courier New', monospace;">証明書エラーが発生しました。</span><span style="color:#6aab73;">"</span>;<br />                        <span style="color:#cf8e6d;">break</span>;<br />                }<br /><br />                <span style="color:#cf8e6d;">new </span>AlertDialog.Builder(MainActivity.<span style="color:#cf8e6d;">this</span>)<br />                        .setTitle(<span style="color:#6aab73;">"</span><span style="color:#6aab73;font-family:'Courier New', monospace;">セキュリティ警告</span><span style="color:#6aab73;">"</span>)<br />                        .setMessage(errorMessage + <span style="color:#6aab73;">"</span><span style="color:#cf8e6d;">\n\n</span><span style="color:#6aab73;font-family:'Courier New', monospace;">このページは安全ではないため、接続がブロックされました。</span><span style="color:#6aab73;">"</span>)<br />                        .setPositiveButton(<span style="color:#6aab73;">"</span><span style="color:#6aab73;font-family:'Courier New', monospace;">確認</span><span style="color:#6aab73;">"</span>, (dialog, which) -&gt; dialog.dismiss())<br />                        .setCancelable(<span style="color:#cf8e6d;">false</span>)<br />                        .show();<br />            }<br />        });<br /><br />        <span style="color:#c77dbb;">webView</span>.setWebChromeClient(<span style="color:#cf8e6d;">new </span>WebChromeClient() {<br />            <span style="color:#b3ae60;">@Override<br /></span><span style="color:#b3ae60;">            </span><span style="color:#cf8e6d;">public void </span><span style="color:#56a8f5;">onReceivedTitle</span>(WebView view, String title) {<br />                <span style="color:#cf8e6d;">super</span>.onReceivedTitle(view, title);<br />            }<br />        });<br /><br />        <span style="color:#7a7e85;">// OnBackPressedDispatcher</span><span style="color:#7a7e85;font-family:'Courier New', monospace;">を使用した戻るボタンの処理<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">        </span>OnBackPressedCallback callback = <span style="color:#cf8e6d;">new </span>OnBackPressedCallback(<span style="color:#cf8e6d;">true</span>) {<br />            <span style="color:#b3ae60;">@Override<br /></span><span style="color:#b3ae60;">            </span><span style="color:#cf8e6d;">public void </span><span style="color:#56a8f5;">handleOnBackPressed</span>() {<br />                <span style="color:#cf8e6d;">if </span>(<span style="color:#c77dbb;">webView</span>.canGoBack()) {<br />                    <span style="color:#7a7e85;">// WebView</span><span style="color:#7a7e85;font-family:'Courier New', monospace;">の履歴を一つ戻る<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">                    </span><span style="color:#c77dbb;">webView</span>.goBack();<br />                } <span style="color:#cf8e6d;">else </span>{<br />                    <span style="color:#7a7e85;">// </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">履歴がない場合はシステムの戻る動作に委譲<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">                    </span>setEnabled(<span style="color:#cf8e6d;">false</span>);<br />                    getOnBackPressedDispatcher().onBackPressed();<br />                    setEnabled(<span style="color:#cf8e6d;">true</span>);<br />                }<br />            }<br />        };<br />        getOnBackPressedDispatcher().addCallback(<span style="color:#cf8e6d;">this</span>, callback);<br /><br />        <span style="color:#7a7e85;">// </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">アプリ起動時に</span><span style="color:#7a7e85;">Webサイト</span><span style="color:#7a7e85;font-family:'Courier New', monospace;">を読み込む<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">        </span><span style="color:#c77dbb;">webView</span>.loadUrl(<span style="color:#6aab73;">"https://zeronara.net"</span>);<br />    }<br /><br />    <span style="color:#b3ae60;">@Override<br /></span><span style="color:#b3ae60;">    </span><span style="color:#cf8e6d;">protected void </span><span style="color:#56a8f5;">onPause</span>() {<br />        <span style="color:#cf8e6d;">super</span>.onPause();<br />        <span style="color:#c77dbb;">webView</span>.onPause(); <span style="color:#7a7e85;">// WebView</span><span style="color:#7a7e85;font-family:'Courier New', monospace;">の描画を一時停止<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">    </span>}<br /><br />    <span style="color:#b3ae60;">@Override<br /></span><span style="color:#b3ae60;">    </span><span style="color:#cf8e6d;">protected void </span><span style="color:#56a8f5;">onResume</span>() {<br />        <span style="color:#cf8e6d;">super</span>.onResume();<br />        <span style="color:#c77dbb;">webView</span>.onResume(); <span style="color:#7a7e85;">// WebView</span><span style="color:#7a7e85;font-family:'Courier New', monospace;">の描画を再開<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">    </span>}<br /><br />    <span style="color:#b3ae60;">@Override<br /></span><span style="color:#b3ae60;">    </span><span style="color:#cf8e6d;">protected void </span><span style="color:#56a8f5;">onDestroy</span>() {<br />        <span style="color:#cf8e6d;">super</span>.onDestroy();<br />        <span style="color:#c77dbb;">webView</span>.destroy(); <span style="color:#7a7e85;">// WebView</span><span style="color:#7a7e85;font-family:'Courier New', monospace;">リソースを解放<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">    </span>}<br />}</pre></div><br /><p><b>res/layout/activity_main.xml</b></p><div style="background-color:#1e1f22;color:#bcbec4;"><pre style="font-family:'JetBrains Mono', monospace;font-size:9.8pt;"><span style="color:#d5b778;">&lt;?</span>xml version<span style="color:#6aab73;">="1.0" </span>encoding<span style="color:#6aab73;">="utf-8"</span><span style="color:#d5b778;">?&gt;<br /></span><span style="color:#d5b778;">&lt;FrameLayout<br /></span><span style="color:#d5b778;">    </span>xmlns:<span style="color:#c77dbb;">android</span><span style="color:#6aab73;">="http://schemas.android.com/apk/res/android"<br /></span><span style="color:#6aab73;">    </span><span style="color:#c77dbb;">android</span>:id<span style="color:#6aab73;">="@+id/container"<br /></span><span style="color:#6aab73;">    </span><span style="color:#c77dbb;">android</span>:layout_width<span style="color:#6aab73;">="match_parent"<br /></span><span style="color:#6aab73;">    </span><span style="color:#c77dbb;">android</span>:layout_height<span style="color:#6aab73;">="match_parent"<br /></span><span style="color:#6aab73;">    </span><span style="color:#c77dbb;">android</span>:fitsSystemWindows<span style="color:#6aab73;">="false"</span><span style="color:#d5b778;">&gt;<br /></span><span style="color:#d5b778;"><br /></span><span style="color:#d5b778;">    &lt;androidx.swiperefreshlayout.widget.SwipeRefreshLayout<br /></span><span style="color:#d5b778;">        </span><span style="color:#c77dbb;">android</span>:id<span style="color:#6aab73;">="@+id/swipeRefresh"<br /></span><span style="color:#6aab73;">        </span><span style="color:#c77dbb;">android</span>:layout_width<span style="color:#6aab73;">="match_parent"<br /></span><span style="color:#6aab73;">        </span><span style="color:#c77dbb;">android</span>:layout_height<span style="color:#6aab73;">="match_parent"</span><span style="color:#d5b778;">&gt;<br /></span><span style="color:#d5b778;"><br /></span><span style="color:#d5b778;">        &lt;WebView<br /></span><span style="color:#d5b778;">            </span><span style="color:#c77dbb;">android</span>:id<span style="color:#6aab73;">="@+id/webView"<br /></span><span style="color:#6aab73;">            </span><span style="color:#c77dbb;">android</span>:layout_width<span style="color:#6aab73;">="match_parent"<br /></span><span style="color:#6aab73;">            </span><span style="color:#c77dbb;">android</span>:layout_height<span style="color:#6aab73;">="match_parent"<br /></span><span style="color:#6aab73;">            </span><span style="color:#c77dbb;">android</span>:fitsSystemWindows<span style="color:#6aab73;">="false" </span><span style="color:#d5b778;">/&gt;<br /></span><span style="color:#d5b778;"><br /></span><span style="color:#d5b778;">    &lt;/androidx.swiperefreshlayout.widget.SwipeRefreshLayout&gt;<br /></span><span style="color:#d5b778;"><br /></span><span style="color:#d5b778;">&lt;/FrameLayout&gt;</span></pre></div><p><b><br /></b></p><p><b>app/Gradle Scripts/build.radle.kts (Module :app)</b></p><div style="background-color:#1e1f22;color:#bcbec4;"><pre style="font-family:'JetBrains Mono', monospace;font-size:9.8pt;"><span style="color:#b3ae60;">plugins </span><span style="font-weight:bold;">{<br /></span><span style="font-weight:bold;">    </span><span style="color:#b3ae60;">alias</span>(<span style="color:#c77dbb;font-style:italic;">libs</span>.<span style="color:#c77dbb;font-style:italic;">plugins</span>.<span style="color:#c77dbb;font-style:italic;">android</span>.<span style="color:#c77dbb;font-style:italic;">application</span>)<br /><span style="font-weight:bold;">}<br /></span><span style="font-weight:bold;"><br /></span><span style="color:#57aaf7;font-style:italic;">android </span><span style="font-weight:bold;">{<br /></span><span style="font-weight:bold;">    </span><span style="color:#c77dbb;">namespace </span>= <span style="color:#6aab73;">"zeronara.net"<br /></span><span style="color:#6aab73;">    </span>compileSdk <span style="font-weight:bold;">{<br /></span><span style="font-weight:bold;">        </span><span style="color:#c77dbb;">version </span>= release(<span style="color:#2aacb8;">36</span>) <span style="font-weight:bold;">{<br /></span><span style="font-weight:bold;">            </span><span style="color:#c77dbb;">minorApiLevel </span>= <span style="color:#2aacb8;">1<br /></span><span style="color:#2aacb8;">        </span><span style="font-weight:bold;">}<br /></span><span style="font-weight:bold;">    }<br /></span><span style="font-weight:bold;"><br /></span><span style="font-weight:bold;">    </span>defaultConfig <span style="font-weight:bold;">{<br /></span><span style="font-weight:bold;">        </span><span style="color:#c77dbb;">applicationId </span>= <span style="color:#6aab73;">"zeronara.net"<br /></span><span style="color:#6aab73;">        </span><span style="color:#c77dbb;">minSdk </span>= <span style="color:#2aacb8;">24<br /></span><span style="color:#2aacb8;">        </span><span style="color:#c77dbb;">targetSdk </span>= <span style="color:#2aacb8;">36<br /></span><span style="color:#2aacb8;">        </span><span style="color:#c77dbb;">versionCode </span>= <span style="color:#2aacb8;">2026032102<br /></span><span style="color:#2aacb8;">        </span><span style="color:#c77dbb;">versionName </span>= <span style="color:#6aab73;">"2.0"<br /></span><span style="color:#6aab73;"><br /></span><span style="color:#6aab73;">        </span><span style="color:#c77dbb;">testInstrumentationRunner </span>= <span style="color:#6aab73;">"androidx.test.runner.AndroidJUnitRunner"<br /></span><span style="color:#6aab73;">    </span><span style="font-weight:bold;">}<br /></span><span style="font-weight:bold;"><br /></span><span style="font-weight:bold;">    </span>buildTypes <span style="font-weight:bold;">{<br /></span><span style="font-weight:bold;">        </span><span style="color:#57aaf7;font-style:italic;">release </span><span style="font-weight:bold;">{<br /></span><span style="font-weight:bold;">            </span><span style="color:#c77dbb;">isMinifyEnabled </span>= <span style="color:#cf8e6d;">false<br /></span><span style="color:#cf8e6d;">            </span>proguardFiles(<br />                getDefaultProguardFile(<span style="color:#6aab73;">"proguard-android-optimize.txt"</span>),<br />                <span style="color:#6aab73;">"proguard-rules.pro"<br /></span><span style="color:#6aab73;">            </span>)<br />        <span style="font-weight:bold;">}<br /></span><span style="font-weight:bold;">    }<br /></span><span style="font-weight:bold;">    </span>compileOptions <span style="font-weight:bold;">{<br /></span><span style="font-weight:bold;">        </span><span style="color:#c77dbb;">sourceCompatibility </span>= JavaVersion.<span style="color:#c77dbb;font-style:italic;">VERSION_11<br /></span><span style="color:#c77dbb;font-style:italic;">        </span><span style="color:#c77dbb;">targetCompatibility </span>= JavaVersion.<span style="color:#c77dbb;font-style:italic;">VERSION_11<br /></span><span style="color:#c77dbb;font-style:italic;">    </span><span style="font-weight:bold;">}<br /></span><span style="font-weight:bold;">}<br /></span><span style="font-weight:bold;"><br /></span><span style="color:#57aaf7;font-style:italic;">dependencies </span><span style="font-weight:bold;">{<br /></span><span style="font-weight:bold;">    </span><span style="color:#57aaf7;font-style:italic;">implementation</span>(<span style="color:#c77dbb;font-style:italic;">libs</span>.<span style="color:#c77dbb;font-style:italic;">appcompat</span>)<br />    <span style="color:#57aaf7;font-style:italic;">implementation</span>(<span style="color:#c77dbb;font-style:italic;">libs</span>.<span style="color:#c77dbb;font-style:italic;">material</span>)<br />    <span style="color:#57aaf7;font-style:italic;">implementation</span>(<span style="color:#c77dbb;font-style:italic;">libs</span>.<span style="color:#c77dbb;font-style:italic;">activity</span>)<br />    <span style="color:#57aaf7;font-style:italic;">implementation</span>(<span style="color:#c77dbb;font-style:italic;">libs</span>.<span style="color:#c77dbb;font-style:italic;">constraintlayout</span>)<br />    <span style="color:#57aaf7;font-style:italic;">implementation</span>(<span style="color:#c77dbb;font-style:italic;">libs</span>.<span style="color:#c77dbb;font-style:italic;">swiperefreshlayout</span>)<br />    <span style="color:#57aaf7;font-style:italic;">testImplementation</span>(<span style="color:#c77dbb;font-style:italic;">libs</span>.<span style="color:#c77dbb;font-style:italic;">junit</span>)<br />    <span style="color:#57aaf7;font-style:italic;">androidTestImplementation</span>(<span style="color:#c77dbb;font-style:italic;">libs</span>.<span style="color:#c77dbb;font-style:italic;">ext</span>.<span style="color:#c77dbb;font-style:italic;">junit</span>)<br />    <span style="color:#57aaf7;font-style:italic;">androidTestImplementation</span>(<span style="color:#c77dbb;font-style:italic;">libs</span>.<span style="color:#c77dbb;font-style:italic;">espresso</span>.<span style="color:#c77dbb;font-style:italic;">core</span>)<br /><span style="font-weight:bold;">}</span></pre></div><br /><p><b>gradle/libs.versions.toml</b></p><div style="background-color:#1e1f22;color:#bcbec4;"><pre style="font-family:'JetBrains Mono', monospace;font-size:9.8pt;">[<span style="color:#cf8e6d;">versions</span>]<br /><span style="color:#cf8e6d;">agp </span>= <span style="color:#6aab73;">"9.1.0"<br /></span><span style="color:#cf8e6d;">junit </span>= <span style="color:#6aab73;">"4.13.2"<br /></span><span style="color:#cf8e6d;">junitVersion </span>= <span style="color:#6aab73;">"1.3.0"<br /></span><span style="color:#cf8e6d;">espressoCore </span>= <span style="color:#6aab73;">"3.7.0"<br /></span><span style="color:#cf8e6d;">appcompat </span>= <span style="color:#6aab73;">"1.7.1"<br /></span><span style="color:#cf8e6d;">material </span>= <span style="color:#6aab73;">"1.13.0"<br /></span><span style="color:#cf8e6d;">activity </span>= <span style="color:#6aab73;">"1.13.0"<br /></span><span style="color:#cf8e6d;">constraintlayout </span>= <span style="color:#6aab73;">"2.2.1"<br /></span><span style="color:#cf8e6d;">swiperefreshlayout </span>= <span style="color:#6aab73;">"1.2.0"<br /></span><span style="color:#6aab73;"><br /></span>[<span style="color:#cf8e6d;">libraries</span>]<br /><span style="color:#cf8e6d;">junit </span>= { <span style="color:#cf8e6d;">group </span>= <span style="color:#6aab73;">"junit"</span>, <span style="color:#cf8e6d;">name </span>= <span style="color:#6aab73;">"junit"</span>, <span style="color:#cf8e6d;">version</span>.<span style="color:#cf8e6d;">ref </span>= <span style="color:#6aab73;">"junit" </span>}<br /><span style="color:#cf8e6d;">ext-junit </span>= { <span style="color:#cf8e6d;">group </span>= <span style="color:#6aab73;">"androidx.test.ext"</span>, <span style="color:#cf8e6d;">name </span>= <span style="color:#6aab73;">"junit"</span>, <span style="color:#cf8e6d;">version</span>.<span style="color:#cf8e6d;">ref </span>= <span style="color:#6aab73;">"junitVersion" </span>}<br /><span style="color:#cf8e6d;">espresso-core </span>= { <span style="color:#cf8e6d;">group </span>= <span style="color:#6aab73;">"androidx.test.espresso"</span>, <span style="color:#cf8e6d;">name </span>= <span style="color:#6aab73;">"espresso-core"</span>, <span style="color:#cf8e6d;">version</span>.<span style="color:#cf8e6d;">ref </span>= <span style="color:#6aab73;">"espressoCore" </span>}<br /><span style="color:#cf8e6d;">appcompat </span>= { <span style="color:#cf8e6d;">group </span>= <span style="color:#6aab73;">"androidx.appcompat"</span>, <span style="color:#cf8e6d;">name </span>= <span style="color:#6aab73;">"appcompat"</span>, <span style="color:#cf8e6d;">version</span>.<span style="color:#cf8e6d;">ref </span>= <span style="color:#6aab73;">"appcompat" </span>}<br /><span style="color:#cf8e6d;">material </span>= { <span style="color:#cf8e6d;">group </span>= <span style="color:#6aab73;">"com.google.android.material"</span>, <span style="color:#cf8e6d;">name </span>= <span style="color:#6aab73;">"material"</span>, <span style="color:#cf8e6d;">version</span>.<span style="color:#cf8e6d;">ref </span>= <span style="color:#6aab73;">"material" </span>}<br /><span style="color:#cf8e6d;">activity </span>= { <span style="color:#cf8e6d;">group </span>= <span style="color:#6aab73;">"androidx.activity"</span>, <span style="color:#cf8e6d;">name </span>= <span style="color:#6aab73;">"activity"</span>, <span style="color:#cf8e6d;">version</span>.<span style="color:#cf8e6d;">ref </span>= <span style="color:#6aab73;">"activity" </span>}<br /><span style="color:#cf8e6d;">constraintlayout </span>= { <span style="color:#cf8e6d;">group </span>= <span style="color:#6aab73;">"androidx.constraintlayout"</span>, <span style="color:#cf8e6d;">name </span>= <span style="color:#6aab73;">"constraintlayout"</span>, <span style="color:#cf8e6d;">version</span>.<span style="color:#cf8e6d;">ref </span>= <span style="color:#6aab73;">"constraintlayout" </span>}<br /><span style="color:#cf8e6d;">swiperefreshlayout </span>= { <span style="color:#cf8e6d;">group </span>= <span style="color:#6aab73;">"androidx.swiperefreshlayout"</span>, <span style="color:#cf8e6d;">name </span>= <span style="color:#6aab73;">"swiperefreshlayout"</span>, <span style="color:#cf8e6d;">version</span>.<span style="color:#cf8e6d;">ref </span>= <span style="color:#6aab73;">"swiperefreshlayout" </span>}<br /><br />[<span style="color:#cf8e6d;">plugins</span>]<br /><span style="color:#cf8e6d;">android-application </span>= { <span style="color:#cf8e6d;">id </span>= <span style="color:#6aab73;">"com.android.application"</span>, <span style="color:#cf8e6d;">version</span>.<span style="color:#cf8e6d;">ref </span>= <span style="color:#6aab73;">"agp" </span>}<br /><br /> </pre></div><p><br /></p><p><b>res/values/themes.xml</b></p><div style="background-color:#1e1f22;color:#bcbec4;"><pre style="font-family:'JetBrains Mono', monospace;font-size:9.8pt;"><span style="color:#d5b778;">&lt;?</span>xml version<span style="color:#6aab73;">="1.0" </span>encoding<span style="color:#6aab73;">="utf-8"</span><span style="color:#d5b778;">?&gt;<br /></span><span style="color:#d5b778;">&lt;resources&gt;<br /></span><span style="color:#d5b778;"><br /></span><span style="color:#d5b778;">    </span><span style="color:#7a7e85;">&lt;!-- </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">透明背景</span><span style="color:#7a7e85;"> + Edge-to-Edge </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">テーマ </span><span style="color:#7a7e85;">--&gt;<br /></span><span style="color:#7a7e85;">    </span><span style="color:#d5b778;">&lt;style </span>name<span style="color:#6aab73;">="Theme.App.Transparent" </span>parent<span style="color:#6aab73;">="Theme.AppCompat.NoActionBar"</span><span style="color:#d5b778;">&gt;<br /></span><span style="color:#d5b778;">        </span><span style="color:#7a7e85;">&lt;!-- </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">ウィンドウ背景を透明に設定 </span><span style="color:#7a7e85;">--&gt;<br /></span><span style="color:#7a7e85;">        </span><span style="color:#d5b778;">&lt;item </span>name<span style="color:#6aab73;">="android:windowBackground"</span><span style="color:#d5b778;">&gt;</span>@android:color/transparent<span style="color:#d5b778;">&lt;/item&gt;<br /></span><span style="color:#d5b778;">        &lt;item </span>name<span style="color:#6aab73;">="android:colorBackground"</span><span style="color:#d5b778;">&gt;</span>@android:color/transparent<span style="color:#d5b778;">&lt;/item&gt;<br /></span><span style="color:#d5b778;"><br /></span><span style="color:#d5b778;">        </span><span style="color:#7a7e85;">&lt;!-- </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">ステータスバー</span><span style="color:#7a7e85;"> / </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">ナビゲーションバーを完全透明に設定 </span><span style="color:#7a7e85;">--&gt;<br /></span><span style="color:#7a7e85;">        </span><span style="color:#d5b778;">&lt;item </span>name<span style="color:#6aab73;">="android:statusBarColor"</span><span style="color:#d5b778;">&gt;</span>@android:color/transparent<span style="color:#d5b778;">&lt;/item&gt;<br /></span><span style="color:#d5b778;">        &lt;item </span>name<span style="color:#6aab73;">="android:navigationBarColor"</span><span style="color:#d5b778;">&gt;</span>@android:color/transparent<span style="color:#d5b778;">&lt;/item&gt;<br /></span><span style="color:#d5b778;"><br /></span><span style="color:#d5b778;">        </span><span style="color:#7a7e85;">&lt;!-- </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">システムバーの背景をアプリ側で描画 </span><span style="color:#7a7e85;">--&gt;<br /></span><span style="color:#7a7e85;">        </span><span style="color:#d5b778;">&lt;item </span>name<span style="color:#6aab73;">="android:windowDrawsSystemBarBackgrounds"</span><span style="color:#d5b778;">&gt;</span>true<span style="color:#d5b778;">&lt;/item&gt;<br /></span><span style="color:#d5b778;"><br /></span><span style="color:#d5b778;">        </span><span style="color:#7a7e85;">&lt;!-- </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">半透明モードを無効化（完全透明のため） </span><span style="color:#7a7e85;">--&gt;<br /></span><span style="color:#7a7e85;">        </span><span style="color:#d5b778;">&lt;item </span>name<span style="color:#6aab73;">="android:windowTranslucentStatus"</span><span style="color:#d5b778;">&gt;</span>false<span style="color:#d5b778;">&lt;/item&gt;<br /></span><span style="color:#d5b778;">        &lt;item </span>name<span style="color:#6aab73;">="android:windowTranslucentNavigation"</span><span style="color:#d5b778;">&gt;</span>false<span style="color:#d5b778;">&lt;/item&gt;<br /></span><span style="color:#d5b778;"><br /></span><span style="color:#d5b778;">        </span><span style="color:#7a7e85;">&lt;!-- </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">ノッチ</span><span style="color:#7a7e85;"> / </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">パンチホール領域までコンテンツを拡張</span><span style="color:#7a7e85;"> (API 28+) --&gt;<br /></span><span style="color:#7a7e85;">        </span><span style="color:#d5b778;">&lt;item </span>name<span style="color:#6aab73;">="android:windowLayoutInDisplayCutoutMode"</span><span style="color:#d5b778;">&gt;</span>shortEdges<span style="color:#d5b778;">&lt;/item&gt;<br /></span><span style="color:#d5b778;"><br /></span><span style="color:#d5b778;">        </span><span style="color:#7a7e85;">&lt;!-- </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">ソフトキーボード表示時のレイアウト調整 </span><span style="color:#7a7e85;">--&gt;<br /></span><span style="color:#7a7e85;">        </span><span style="color:#d5b778;">&lt;item </span>name<span style="color:#6aab73;">="android:windowSoftInputMode"</span><span style="color:#d5b778;">&gt;</span>adjustResize<span style="color:#d5b778;">&lt;/item&gt;<br /></span><span style="color:#d5b778;">    &lt;/style&gt;<br /></span><span style="color:#d5b778;"><br /></span><span style="color:#d5b778;">&lt;/resources&gt;</span></pre></div><p><b><br /></b></p><p><b>res/values/strings.xml</b></p><div style="background-color:#1e1f22;color:#bcbec4;"><pre style="font-family:'JetBrains Mono', monospace;font-size:9.8pt;"><span style="color:#d5b778;">&lt;resources&gt;<br /></span><span style="color:#d5b778;">    &lt;string </span>name<span style="color:#6aab73;">="app_name"</span><span style="color:#d5b778;">&gt;</span>ZERONARA<span style="color:#d5b778;">&lt;/string&gt;<br /></span><span style="color:#d5b778;">&lt;/resources&gt;</span></pre></div><p><br /></p><p><b>아이콘 생성</b></p><p><b>***.png준비 640*640</b></p><p><img src="https://zeronara.net/data/editor/2602/9bd8344ae4448c715b78624d2c4d2ffe_1771854283_2008.png" title="9bd8344ae4448c715b78624d2c4d2ffe_1771854283_2008.png" alt="9bd8344ae4448c715b78624d2c4d2ffe_1771854283_2008.png" /><br style="clear:both;" /> </p><p><br /></p><p><br /></p><p>1. 안드로이드 뒤로가기 버튼 사용</p><p>2. API 36에서 상단바 숨김현상 처리</p><p>3. 아래 스크롤시 새로고침</p><p>4. 어플접속확인 agent 추가 - webviewApp/1.0 (Android)</p><p><br /></p>]]></description>
<dc:creator>제로</dc:creator>
<dc:date>2026-03-21T22:20:39+09:00</dc:date>
</item>


<item>
<title>[php] 안드로이드 웹뷰 정리 2026-02-23</title>
<link>https://zeronara.com/tipntech/1105</link>
<description><![CDATA[<img src="https://zeronara.net/data/editor/2602/9bd8344ae4448c715b78624d2c4d2ffe_1771850258_1827.png" title="9bd8344ae4448c715b78624d2c4d2ffe_1771850258_1827.png" alt="9bd8344ae4448c715b78624d2c4d2ffe_1771850258_1827.png" /><br style="clear:both;" /><p><br /></p><p><br /></p><p><img src="https://zeronara.net/data/editor/2602/9bd8344ae4448c715b78624d2c4d2ffe_1771850300_1786.png" title="9bd8344ae4448c715b78624d2c4d2ffe_1771850300_1786.png" alt="9bd8344ae4448c715b78624d2c4d2ffe_1771850300_1786.png" /><br style="clear:both;" /> </p><img src="https://zeronara.net/data/editor/2602/9bd8344ae4448c715b78624d2c4d2ffe_1771854235_0291.png" title="9bd8344ae4448c715b78624d2c4d2ffe_1771854235_0291.png" alt="9bd8344ae4448c715b78624d2c4d2ffe_1771854235_0291.png" /><br style="clear:both;" /><br style="clear:both;" /><br style="clear:both;" /><br /><p><b>manifests/AndroidManifest.xml</b></p><div style="background-color:#1e1f22;color:#bcbec4;"><pre style="font-family:'JetBrains Mono', monospace;font-size:9.8pt;"><span style="color:#d5b778;">&lt;?</span>xml version<span style="color:#6aab73;">="1.0" </span>encoding<span style="color:#6aab73;">="utf-8"</span><span style="color:#d5b778;">?&gt;<br /></span><span style="color:#d5b778;">&lt;manifest </span>xmlns:<span style="color:#c77dbb;">android</span><span style="color:#6aab73;">="http://schemas.android.com/apk/res/android"<br /></span><span style="color:#6aab73;">    </span>xmlns:<span style="color:#c77dbb;">tools</span><span style="color:#6aab73;">="http://schemas.android.com/tools"</span><span style="color:#d5b778;">&gt;<br /></span><span style="color:#d5b778;"><br /></span><span style="color:#d5b778;">    &lt;uses-permission </span><span style="color:#c77dbb;">android</span>:name<span style="color:#6aab73;">="android.permission.INTERNET" </span><span style="color:#d5b778;">/&gt;<br /></span><span style="color:#d5b778;"><br /></span><span style="color:#d5b778;">    &lt;application<br /></span><span style="color:#d5b778;">        </span><span style="color:#c77dbb;">android</span>:allowBackup<span style="color:#6aab73;">="true"<br /></span><span style="color:#6aab73;">        </span><span style="color:#c77dbb;">android</span>:dataExtractionRules<span style="color:#6aab73;">="@xml/data_extraction_rules"<br /></span><span style="color:#6aab73;">        </span><span style="color:#c77dbb;">android</span>:fullBackupContent<span style="color:#6aab73;">="@xml/backup_rules"<br /></span><span style="color:#6aab73;">        </span><span style="color:#c77dbb;">android</span>:icon<span style="color:#6aab73;">="@mipmap/ic_launcher"<br /></span><span style="color:#6aab73;">        </span><span style="color:#c77dbb;">android</span>:label<span style="color:#6aab73;">="@string/app_name"<br /></span><span style="color:#6aab73;">        </span><span style="color:#c77dbb;">android</span>:roundIcon<span style="color:#6aab73;">="@mipmap/ic_launcher_round"<br /></span><span style="color:#6aab73;">        </span><span style="color:#c77dbb;">android</span>:supportsRtl<span style="color:#6aab73;">="true"<br /></span><span style="color:#6aab73;">        </span><span style="color:#c77dbb;">android</span>:theme<span style="color:#6aab73;">="@style/Theme.AppCompat.Light.NoActionBar"<br /></span><span style="color:#6aab73;">        </span><span style="color:#c77dbb;">android</span>:usesCleartextTraffic<span style="color:#6aab73;">="true"</span><span style="color:#d5b778;">&gt;<br /></span><span style="color:#d5b778;">        &lt;activity<br /></span><span style="color:#d5b778;">            </span><span style="color:#c77dbb;">android</span>:name<span style="color:#6aab73;">=".MainActivity"<br /></span><span style="color:#6aab73;">            </span><span style="color:#c77dbb;">android</span>:exported<span style="color:#6aab73;">="true"</span><span style="color:#d5b778;">&gt;<br /></span><span style="color:#d5b778;">            &lt;intent-filter&gt;<br /></span><span style="color:#d5b778;">                &lt;action </span><span style="color:#c77dbb;">android</span>:name<span style="color:#6aab73;">="android.intent.action.MAIN" </span><span style="color:#d5b778;">/&gt;<br /></span><span style="color:#d5b778;"><br /></span><span style="color:#d5b778;">                &lt;category </span><span style="color:#c77dbb;">android</span>:name<span style="color:#6aab73;">="android.intent.category.LAUNCHER" </span><span style="color:#d5b778;">/&gt;<br /></span><span style="color:#d5b778;">            &lt;/intent-filter&gt;<br /></span><span style="color:#d5b778;">        &lt;/activity&gt;<br /></span><span style="color:#d5b778;">    &lt;/application&gt;<br /></span><span style="color:#d5b778;"><br /></span><span style="color:#d5b778;">&lt;/manifest&gt;</span></pre></div><p><br /></p><p><b>kotlin+java/zeronara.net/MainActivity.java</b></p><div style="background-color:#1e1f22;color:#bcbec4;"><pre style="font-family:'JetBrains Mono', monospace;font-size:9.8pt;"><span style="color:#cf8e6d;">package </span>zeronara.net;<br /><br /><span style="color:#cf8e6d;">import </span>android.content.ActivityNotFoundException;<br /><span style="color:#cf8e6d;">import </span>android.content.Intent;<br /><span style="color:#cf8e6d;">import </span>android.net.Uri;<br /><span style="color:#cf8e6d;">import </span>android.os.Bundle;<br /><span style="color:#cf8e6d;">import </span>android.view.Window;<br /><span style="color:#cf8e6d;">import </span>android.webkit.SslErrorHandler;<br /><span style="color:#cf8e6d;">import </span>android.webkit.WebChromeClient;<br /><span style="color:#cf8e6d;">import </span>android.webkit.WebResourceError;<br /><span style="color:#cf8e6d;">import </span>android.webkit.WebResourceRequest;<br /><span style="color:#cf8e6d;">import </span>android.webkit.WebSettings;<br /><span style="color:#cf8e6d;">import </span>android.webkit.WebView;<br /><span style="color:#cf8e6d;">import </span>android.webkit.WebViewClient;<br /><span style="color:#cf8e6d;">import </span>android.net.http.SslError;<br /><br /><span style="color:#cf8e6d;">import </span>androidx.appcompat.app.AppCompatActivity;<br /><br /><span style="color:#cf8e6d;">public class </span>MainActivity <span style="color:#cf8e6d;">extends </span>AppCompatActivity {<br />    <span style="color:#cf8e6d;">public </span>WebView <span style="color:#c77dbb;">webView</span>;<br /><br />    <span style="color:#b3ae60;">@Override<br /></span><span style="color:#b3ae60;">    </span><span style="color:#cf8e6d;">protected void </span><span style="color:#56a8f5;">onCreate</span>(Bundle savedInstanceState) {<br />        <span style="color:#cf8e6d;">super</span>.onCreate(savedInstanceState);<br />        requestWindowFeature(Window.<span style="color:#c77dbb;font-style:italic;">FEATURE_NO_TITLE</span>);<br />        setContentView(R.layout.<span style="color:#c77dbb;font-style:italic;">activity_main</span>);<br /><br />        <span style="color:#c77dbb;">webView </span>= (WebView) findViewById(R.id.<span style="color:#c77dbb;font-style:italic;">webView</span>);<br />        WebSettings webSettings = <span style="color:#c77dbb;">webView</span>.getSettings();<br /><br />        webSettings.setJavaScriptEnabled(<span style="color:#cf8e6d;">true</span>);<br />        webSettings.setDomStorageEnabled(<span style="color:#cf8e6d;">true</span>);<br />        webSettings.setUseWideViewPort(<span style="color:#cf8e6d;">true</span>);<br />        webSettings.setLoadWithOverviewMode(<span style="color:#cf8e6d;">true</span>);<br />        webSettings.setCacheMode(WebSettings.<span style="color:#c77dbb;font-style:italic;">LOAD_DEFAULT</span>);<br /><br />        <span style="color:#7a7e85;">// User-Agent<br /></span><span style="color:#7a7e85;">        </span>String defaultUA = webSettings.getUserAgentString();<br />        webSettings.setUserAgentString(defaultUA + <span style="color:#6aab73;">" zeronaraApp/1.0 (Android)"</span>);<br /><br />        <span style="color:#c77dbb;">webView</span>.setWebViewClient(<span style="color:#cf8e6d;">new </span>WebViewClient() {<br /><br />            <span style="color:#b3ae60;">@Override<br /></span><span style="color:#b3ae60;">            </span><span style="color:#cf8e6d;">public boolean </span><span style="color:#56a8f5;">shouldOverrideUrlLoading</span>(WebView view, WebResourceRequest request) {<br />                String url = request.getUrl().toString();<br /><br />                <span style="color:#7a7e85;">// </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">구글 플레이스토어 링크 처리<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">                </span><span style="color:#cf8e6d;">if </span>(url.startsWith(<span style="color:#6aab73;">"market://"</span>) || url.contains(<span style="color:#6aab73;">"play.google.com/store"</span>)) {<br />                    <span style="color:#cf8e6d;">try </span>{<br />                        Intent intent = <span style="color:#cf8e6d;">new </span>Intent(Intent.<span style="color:#c77dbb;font-style:italic;">ACTION_VIEW</span>, Uri.<span style="font-style:italic;">parse</span>(url));<br />                        startActivity(intent);<br />                    } <span style="color:#cf8e6d;">catch </span>(ActivityNotFoundException e) {<br />                        <span style="color:#7a7e85;">// </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">플레이스토어 앱이 없으면 브라우저로 폴백<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">                        </span>String fallbackUrl = url.replace(<span style="color:#6aab73;">"market://"</span>, <span style="color:#6aab73;">"https://play.google.com/store/apps/"</span>);<br />                        startActivity(<span style="color:#cf8e6d;">new </span>Intent(Intent.<span style="color:#c77dbb;font-style:italic;">ACTION_VIEW</span>, Uri.<span style="font-style:italic;">parse</span>(fallbackUrl)));<br />                    }<br />                    <span style="color:#cf8e6d;">return true</span>;<br />                }<br /><br />                <span style="color:#7a7e85;">// </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">외부 브라우저로 열어야 할 스킴 처리</span><span style="color:#7a7e85;"> (tel, mailto </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">등</span><span style="color:#7a7e85;">)<br /></span><span style="color:#7a7e85;">                </span><span style="color:#cf8e6d;">if </span>(url.startsWith(<span style="color:#6aab73;">"tel:"</span>) || url.startsWith(<span style="color:#6aab73;">"mailto:"</span>) || url.startsWith(<span style="color:#6aab73;">"intent:"</span>)) {<br />                    <span style="color:#cf8e6d;">try </span>{<br />                        startActivity(<span style="color:#cf8e6d;">new </span>Intent(Intent.<span style="color:#c77dbb;font-style:italic;">ACTION_VIEW</span>, Uri.<span style="font-style:italic;">parse</span>(url)));<br />                    } <span style="color:#cf8e6d;">catch </span>(ActivityNotFoundException e) {<br />                        e.printStackTrace();<br />                    }<br />                    <span style="color:#cf8e6d;">return true</span>;<br />                }<br /><br />                <span style="color:#cf8e6d;">return false</span>; <span style="color:#7a7e85;">// </span><span style="color:#7a7e85;font-family:'Courier New', monospace;">그 외</span><span style="color:#7a7e85;"> URL</span><span style="color:#7a7e85;font-family:'Courier New', monospace;">은 웹뷰에서 처리<br /></span><span style="color:#7a7e85;font-family:'Courier New', monospace;">            </span>}<br /><br />            <span style="color:#b3ae60;">@Override<br /></span><span style="color:#b3ae60;">            </span><span style="color:#cf8e6d;">public void </span><span style="color:#56a8f5;">onPageFinished</span>(WebView view, String url) {<br />                <span style="color:#cf8e6d;">super</span>.onPageFinished(view, url);<br />            }<br /><br />            <span style="color:#b3ae60;">@Override<br /></span><span style="color:#b3ae60;">            </span><span style="color:#cf8e6d;">public void </span><span style="color:#56a8f5;">onReceivedError</span>(WebView view, WebResourceRequest request, WebResourceError error) {<br />                <span style="color:#cf8e6d;">super</span>.onReceivedError(view, request, error);<br />            }<br /><br />            <span style="color:#b3ae60;">@Override<br /></span><span style="color:#b3ae60;">            </span><span style="color:#cf8e6d;">public void </span><span style="color:#56a8f5;">onReceivedSslError</span>(WebView view, SslErrorHandler handler, SslError error) {<br />                handler.proceed();<br />            }<br />        });<br /><br />        <span style="color:#c77dbb;">webView</span>.setWebChromeClient(<span style="color:#cf8e6d;">new </span>WebChromeClient() {<br />            <span style="color:#b3ae60;">@Override<br /></span><span style="color:#b3ae60;">            </span><span style="color:#cf8e6d;">public void </span><span style="color:#56a8f5;">onReceivedTitle</span>(WebView view, String title) {<br />                <span style="color:#cf8e6d;">super</span>.onReceivedTitle(view, title);<br />            }<br />        });<br /><br />        <span style="color:#c77dbb;">webView</span>.loadUrl(<span style="color:#6aab73;">"https://zeronara.net"</span>);<br />    }<br /><br />    <span style="color:#b3ae60;">@Override<br /></span><span style="color:#b3ae60;">    </span><span style="color:#cf8e6d;">public void </span><span style="color:#56a8f5;">onBackPressed</span>() {<br />        <span style="color:#cf8e6d;">if </span>(<span style="color:#c77dbb;">webView</span>.canGoBack()) {<br />            <span style="color:#c77dbb;">webView</span>.goBack();<br />        } <span style="color:#cf8e6d;">else </span>{<br />            getOnBackPressedDispatcher().onBackPressed();<br />        }<br />    }<br /><br />    <span style="color:#b3ae60;">@Override<br /></span><span style="color:#b3ae60;">    </span><span style="color:#cf8e6d;">protected void </span><span style="color:#56a8f5;">onPause</span>() {<br />        <span style="color:#cf8e6d;">super</span>.onPause();<br />        <span style="color:#c77dbb;">webView</span>.onPause();<br />    }<br /><br />    <span style="color:#b3ae60;">@Override<br /></span><span style="color:#b3ae60;">    </span><span style="color:#cf8e6d;">protected void </span><span style="color:#56a8f5;">onResume</span>() {<br />        <span style="color:#cf8e6d;">super</span>.onResume();<br />        <span style="color:#c77dbb;">webView</span>.onResume();<br />    }<br /><br />    <span style="color:#b3ae60;">@Override<br /></span><span style="color:#b3ae60;">    </span><span style="color:#cf8e6d;">protected void </span><span style="color:#56a8f5;">onDestroy</span>() {<br />        <span style="color:#cf8e6d;">super</span>.onDestroy();<br />        <span style="color:#c77dbb;">webView</span>.destroy();<br />    }<br />}</pre></div><br /><p><b>res/layout/activity_main.xml</b></p><div style="background-color:#1e1f22;color:#bcbec4;"><pre style="font-family:'JetBrains Mono', monospace;font-size:9.8pt;"><span style="color:#d5b778;">&lt;?</span>xml version<span style="color:#6aab73;">="1.0" </span>encoding<span style="color:#6aab73;">="utf-8"</span><span style="color:#d5b778;">?&gt;<br /></span><span style="color:#d5b778;">&lt;androidx.constraintlayout.widget.ConstraintLayout </span>xmlns:<span style="color:#c77dbb;">android</span><span style="color:#6aab73;">="http://schemas.android.com/apk/res/android"<br /></span><span style="color:#6aab73;">    </span>xmlns:<span style="color:#c77dbb;">app</span><span style="color:#6aab73;">="http://schemas.android.com/apk/res-auto"<br /></span><span style="color:#6aab73;">    </span>xmlns:<span style="color:#c77dbb;">tools</span><span style="color:#6aab73;">="http://schemas.android.com/tools"<br /></span><span style="color:#6aab73;">    </span><span style="color:#c77dbb;">android</span>:id<span style="color:#6aab73;">="@+id/main"<br /></span><span style="color:#6aab73;">    </span><span style="color:#c77dbb;">android</span>:layout_width<span style="color:#6aab73;">="match_parent"<br /></span><span style="color:#6aab73;">    </span><span style="color:#c77dbb;">android</span>:layout_height<span style="color:#6aab73;">="match_parent"<br /></span><span style="color:#6aab73;">    </span><span style="color:#c77dbb;">tools</span>:context<span style="color:#6aab73;">=".MainActivity"</span><span style="color:#d5b778;">&gt;<br /></span><span style="color:#d5b778;"><br /></span><span style="color:#d5b778;">    &lt;WebView<br /></span><span style="color:#d5b778;">        </span><span style="color:#c77dbb;">android</span>:id<span style="color:#6aab73;">="@+id/webView"<br /></span><span style="color:#6aab73;">        </span><span style="color:#c77dbb;">android</span>:layout_width<span style="color:#6aab73;">="match_parent"<br /></span><span style="color:#6aab73;">        </span><span style="color:#c77dbb;">android</span>:layout_height<span style="color:#6aab73;">="match_parent" </span><span style="color:#d5b778;">/&gt;<br /></span><span style="color:#d5b778;"><br /></span><span style="color:#d5b778;">&lt;/androidx.constraintlayout.widget.ConstraintLayout&gt;</span></pre></div><b><br /></b><p><b>res/values/strings.xml</b></p><div style="background-color:#1e1f22;color:#bcbec4;"><pre style="font-family:'JetBrains Mono', monospace;font-size:9.8pt;"><span style="color:#d5b778;">&lt;resources&gt;<br /></span><span style="color:#d5b778;">    &lt;string </span>name<span style="color:#6aab73;">="app_name"</span><span style="color:#d5b778;">&gt;</span>ZERONARA<span style="color:#d5b778;">&lt;/string&gt;<br /></span><span style="color:#d5b778;">&lt;/resources&gt;</span></pre></div><p><br /></p><p><b>아이콘 생성</b></p><p><b>***.png준비 640*640</b></p><p><img src="https://zeronara.net/data/editor/2602/9bd8344ae4448c715b78624d2c4d2ffe_1771854283_2008.png" title="9bd8344ae4448c715b78624d2c4d2ffe_1771854283_2008.png" alt="9bd8344ae4448c715b78624d2c4d2ffe_1771854283_2008.png" /><br style="clear:both;" /> </p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p>]]></description>
<dc:creator>제로</dc:creator>
<dc:date>2026-02-23T21:38:26+09:00</dc:date>
</item>


<item>
<title>[php] 안드로이드 웹뷰 정리</title>
<link>https://zeronara.com/tipntech/1103</link>
<description><![CDATA[<p>res/layout/activity_main.xml</p><pre style="background-color:#2b2b2b;color:#a9b7c6;font-family:'JetBrains Mono', monospace;font-size:9.8pt;"><span style="color:#e8bf6a;">&lt;?</span><span style="color:#bababa;">xml version</span><span style="color:#6a8759;">="1.0" </span><span style="color:#bababa;">encoding</span><span style="color:#6a8759;">="utf-8"</span><span style="color:#e8bf6a;">?&gt;<br /></span><span style="color:#e8bf6a;">&lt;androidx.constraintlayout.widget.ConstraintLayout </span><span style="color:#bababa;">xmlns:</span><span style="color:#9876aa;">android</span><span style="color:#6a8759;">="http://schemas.android.com/apk/res/android"<br /></span><span style="color:#6a8759;">    </span><span style="color:#bababa;">xmlns:</span><span style="color:#9876aa;">app</span><span style="color:#6a8759;">="http://schemas.android.com/apk/res-auto"<br /></span><span style="color:#6a8759;">    </span><span style="color:#bababa;">xmlns:</span><span style="color:#9876aa;">tools</span><span style="color:#6a8759;">="http://schemas.android.com/tools"<br /></span><span style="color:#6a8759;">    </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:layout_width</span><span style="color:#6a8759;">="match_parent"<br /></span><span style="color:#6a8759;">    </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:layout_height</span><span style="color:#6a8759;">="match_parent"<br /></span><span style="color:#6a8759;">    </span><span style="color:#9876aa;">tools</span><span style="color:#bababa;">:context</span><span style="color:#6a8759;">=".MainActivity"</span><span style="color:#e8bf6a;">&gt;<br /></span><span style="color:#e8bf6a;"><br /></span><span style="color:#e8bf6a;">    &lt;WebView<br /></span><span style="color:#e8bf6a;">        </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:id</span><span style="color:#6a8759;">="@+id/webView"<br /></span><span style="color:#6a8759;">        </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:layout_width</span><span style="color:#6a8759;">="match_parent"<br /></span><span style="color:#6a8759;">        </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:layout_height</span><span style="color:#6a8759;">="match_parent"<br /></span><span style="color:#6a8759;">        </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:visibility</span><span style="color:#6a8759;">="visible"<br /></span><span style="color:#6a8759;">        </span><span style="color:#9876aa;">tools</span><span style="color:#bababa;">:layout_editor_absoluteX</span><span style="color:#6a8759;">="8dp"<br /></span><span style="color:#6a8759;">        </span><span style="color:#9876aa;">tools</span><span style="color:#bababa;">:layout_editor_absoluteY</span><span style="color:#6a8759;">="8dp" </span><span style="color:#e8bf6a;">/&gt;<br /></span><span style="color:#e8bf6a;"><br /></span><span style="color:#e8bf6a;">&lt;/androidx.constraintlayout.widget.ConstraintLayout&gt;</span><span style="color:#e8bf6a;"></span></pre><p><br /></p><p>java/com.zeronara.webview/SplashActivity.java</p><pre style="background-color:#2b2b2b;color:#a9b7c6;font-family:'JetBrains Mono', monospace;font-size:9.8pt;"><span style="color:#cc7832;">package </span>com.zeronara.webview<span style="color:#cc7832;">;<br /></span><span style="color:#cc7832;"><br /></span><span style="color:#cc7832;">import </span>androidx.appcompat.app.AppCompatActivity<span style="color:#cc7832;">;<br /></span><span style="color:#cc7832;">import </span>android.content.Intent<span style="color:#cc7832;">;<br /></span><span style="color:#cc7832;">import </span>android.os.Handler<span style="color:#cc7832;">;<br /></span><span style="color:#cc7832;">import </span>android.os.Bundle<span style="color:#cc7832;">;<br /></span><span style="color:#cc7832;">public class </span>SplashActivity <span style="color:#cc7832;">extends </span>AppCompatActivity {<br />    <span style="color:#bbb529;">@Override<br /></span><span style="color:#bbb529;">    </span><span style="color:#cc7832;">protected void </span><span style="color:#ffc66d;">onCreate</span>(Bundle savedInstanceState) {<br />        <span style="color:#cc7832;">super</span>.onCreate(savedInstanceState)<span style="color:#cc7832;">;<br /></span><span style="color:#cc7832;">        </span>setContentView(R.layout.<span style="color:#9876aa;font-style:italic;">activity_splash</span>)<span style="color:#cc7832;">;<br /></span><span style="color:#cc7832;"><br /></span><span style="color:#cc7832;">        </span>Handler handler = <span style="color:#cc7832;">new </span>Handler()<span style="color:#cc7832;">;<br /></span><span style="color:#cc7832;">        </span>handler.postDelayed(<span style="color:#cc7832;">new </span>Runnable() {<br />            <span style="color:#bbb529;">@Override<br /></span><span style="color:#bbb529;">            </span><span style="color:#cc7832;">public void </span><span style="color:#ffc66d;">run</span>() {<br />                Intent intent = <span style="color:#cc7832;">new </span>Intent(getBaseContext()<span style="color:#cc7832;">, </span>MainActivity.<span style="color:#cc7832;">class</span>)<span style="color:#cc7832;">;<br /></span><span style="color:#cc7832;">                </span>startActivity(intent)<span style="color:#cc7832;">;<br /></span><span style="color:#cc7832;">                </span>finish()<span style="color:#cc7832;">;<br /></span><span style="color:#cc7832;">            </span>}<br /><br />        }<span style="color:#cc7832;">, </span><span style="color:#6897bb;">2000</span>)<span style="color:#cc7832;">;<br /></span><span style="color:#cc7832;">    </span>}<br />}<br /></pre><p><br /></p><p>manifests/AndroidManifest.xml<br /></p><pre style="background-color:#2b2b2b;color:#a9b7c6;font-family:'JetBrains Mono', monospace;font-size:9.8pt;"><span style="color:#e8bf6a;">&lt;?</span><span style="color:#bababa;">xml version</span><span style="color:#6a8759;">="1.0" </span><span style="color:#bababa;">encoding</span><span style="color:#6a8759;">="utf-8"</span><span style="color:#e8bf6a;">?&gt;<br /></span><span style="color:#e8bf6a;">&lt;manifest </span><span style="color:#bababa;">xmlns:</span><span style="color:#9876aa;">android</span><span style="color:#6a8759;">="http://schemas.android.com/apk/res/android"<br /></span><span style="color:#6a8759;">    </span><span style="color:#bababa;">package</span><span style="color:#6a8759;">="</span>com.zeronara.webview"<span style="font-size:9.8pt;color:rgb(232,191,106);">&gt;</span><br /><span style="color:#e8bf6a;"><br /></span><span style="color:#e8bf6a;">    &lt;uses-permission </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:name</span><span style="color:#6a8759;">="android.permission.INTERNET" </span><span style="color:#e8bf6a;">/&gt;<br /></span><span style="color:#e8bf6a;"><br /></span><span style="color:#e8bf6a;">    &lt;application<br /></span><span style="color:#e8bf6a;">        </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:allowBackup</span><span style="color:#6a8759;">="true"<br /></span><span style="color:#6a8759;">        </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:fullBackupContent</span><span style="color:#6a8759;">="true"<br /></span><span style="color:#6a8759;">        </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:icon</span><span style="color:#6a8759;">="@drawable/splash"<br /></span><span style="color:#6a8759;">        </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:label</span><span style="color:#6a8759;">="@string/app_name"<br /></span><span style="color:#6a8759;">        </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:roundIcon</span><span style="color:#6a8759;">="@drawable/splash"<br /></span><span style="color:#6a8759;">        </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:supportsRtl</span><span style="color:#6a8759;">="true"<br /></span><span style="color:#6a8759;">        </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:theme</span><span style="color:#6a8759;">="@style/Theme.AppCompat.Light.NoActionBar.FullScreen"<br /></span><span style="color:#6a8759;">        </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:usesCleartextTraffic</span><span style="color:#6a8759;">="true"<br /></span><span style="color:#6a8759;">        </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:hardwareAccelerated</span><span style="color:#6a8759;">="true"</span><span style="color:#e8bf6a;">&gt;<br /></span><span style="color:#e8bf6a;">        &lt;activity<br /></span><span style="color:#e8bf6a;">            </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:name</span><span style="color:#6a8759;">=".MainActivity"<br /></span><span style="color:#6a8759;">            </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:exported</span><span style="color:#6a8759;">="true"</span><span style="color:#e8bf6a;">&gt;<br /></span><span style="color:#e8bf6a;">            &lt;intent-filter&gt;<br /></span><span style="color:#e8bf6a;">                &lt;action </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:name</span><span style="color:#6a8759;">="android.intent.action.MAIN" </span><span style="color:#e8bf6a;">/&gt;<br /></span><span style="color:#e8bf6a;"><br /></span><span style="color:#e8bf6a;">                &lt;category </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:name</span><span style="color:#6a8759;">="android.intent.category.LAUNCHER" </span><span style="color:#e8bf6a;">/&gt;<br /></span><span style="color:#e8bf6a;">            &lt;/intent-filter&gt;<br /></span><span style="color:#e8bf6a;">        &lt;/activity&gt;<br /></span><span style="color:#e8bf6a;">    &lt;/application&gt;<br /></span><span style="color:#e8bf6a;"><br /></span><span style="color:#e8bf6a;">&lt;/manifest&gt;</span></pre><p><br /></p><p>res/layout/activity_splash.xml</p><pre style="background-color:#2b2b2b;color:#a9b7c6;font-family:'JetBrains Mono', monospace;font-size:9.8pt;"><span style="color:#e8bf6a;">&lt;?</span><span style="color:#bababa;">xml version</span><span style="color:#6a8759;">="1.0" </span><span style="color:#bababa;">encoding</span><span style="color:#6a8759;">="utf-8"</span><span style="color:#e8bf6a;">?&gt;<br /></span><span style="color:#e8bf6a;">&lt;LinearLayout </span><span style="color:#bababa;">xmlns:</span><span style="color:#9876aa;">android</span><span style="color:#6a8759;">="http://schemas.android.com/apk/res/android"<br /></span><span style="color:#6a8759;">    </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:layout_width</span><span style="color:#6a8759;">="match_parent"<br /></span><span style="color:#6a8759;">    </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:layout_height</span><span style="color:#6a8759;">="match_parent"<br /></span><span style="color:#6a8759;">    </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:orientation</span><span style="color:#6a8759;">="vertical"<br /></span><span style="color:#6a8759;">    </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:background</span><span style="color:#6a8759;">="#fff"<br /></span><span style="color:#6a8759;">    </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:weightSum</span><span style="color:#6a8759;">="1"</span><span style="color:#e8bf6a;">&gt;<br /></span><span style="color:#e8bf6a;"><br /></span><span style="color:#e8bf6a;">    &lt;ImageView<br /></span><span style="color:#e8bf6a;">        </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:src</span><span style="color:#6a8759;">="@drawable/splash"<br /></span><span style="color:#6a8759;">        </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:layout_width</span><span style="color:#6a8759;">="match_parent"<br /></span><span style="color:#6a8759;">        </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:layout_height</span><span style="color:#6a8759;">="wrap_content"<br /></span><span style="color:#6a8759;">        </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:id</span><span style="color:#6a8759;">="@+id/imageView"<br /></span><span style="color:#6a8759;">        </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:layout_weight</span><span style="color:#6a8759;">="0.82" </span><span style="color:#e8bf6a;">/&gt;<br /></span><span style="color:#e8bf6a;">&lt;/LinearLayout&gt;</span></pre><p><br /></p><p>res/values/styles.xml</p><pre style="background-color:#2b2b2b;color:#a9b7c6;font-family:'JetBrains Mono', monospace;font-size:9.8pt;"></pre><pre style="font-family:'JetBrains Mono', monospace;font-size:9.8pt;"><br /></pre><pre style="background-color:#2b2b2b;color:#a9b7c6;font-family:'JetBrains Mono', monospace;font-size:9.8pt;"><span style="color:#e8bf6a;">&lt;resources&gt;<br /></span><span style="color:#e8bf6a;">    </span><span style="color:#808080;">&lt;!-- Base application theme. --&gt;<br /></span><span style="color:#808080;">    </span><span style="color:#e8bf6a;">&lt;style </span><span style="color:#bababa;">name</span><span style="color:#6a8759;">="Theme.AppCompat.Light.NoActionBar.FullScreen" </span><span style="color:#bababa;">parent</span><span style="color:#6a8759;">="@style/Theme.AppCompat.Light"</span><span style="color:#e8bf6a;">&gt;<br /></span><span style="color:#e8bf6a;">        </span><span style="color:#808080;">&lt;!-- Customize your theme here. --&gt;<br /></span><span style="color:#808080;">        </span><span style="color:#e8bf6a;">&lt;item </span><span style="color:#bababa;">name</span><span style="color:#6a8759;">="colorPrimary"</span><span style="color:#e8bf6a;">&gt;</span>@color/colorPrimary<span style="color:#e8bf6a;">&lt;/item&gt;<br /></span><span style="color:#e8bf6a;">        &lt;item </span><span style="color:#bababa;">name</span><span style="color:#6a8759;">="colorPrimaryDark"</span><span style="color:#e8bf6a;">&gt;</span>@color/colorPrimaryDark<span style="color:#e8bf6a;">&lt;/item&gt;<br /></span><span style="color:#e8bf6a;">        &lt;item </span><span style="color:#bababa;">name</span><span style="color:#6a8759;">="colorAccent"</span><span style="color:#e8bf6a;">&gt;</span>@color/colorAccent<span style="color:#e8bf6a;">&lt;/item&gt;<br /></span><span style="color:#e8bf6a;">        </span><span style="color:#808080;">&lt;!-- add Style --&gt;<br /></span><span style="color:#808080;">        </span><span style="color:#e8bf6a;">&lt;item </span><span style="color:#bababa;">name</span><span style="color:#6a8759;">="windowNoTitle"</span><span style="color:#e8bf6a;">&gt;</span>true<span style="color:#e8bf6a;">&lt;/item&gt;<br /></span><span style="color:#e8bf6a;">        &lt;item </span><span style="color:#bababa;">name</span><span style="color:#6a8759;">="windowActionBar"</span><span style="color:#e8bf6a;">&gt;</span>false<span style="color:#e8bf6a;">&lt;/item&gt;<br /></span><span style="color:#e8bf6a;">        &lt;item </span><span style="color:#bababa;">name</span><span style="color:#6a8759;">="android:windowFullscreen"</span><span style="color:#e8bf6a;">&gt;</span>false<span style="color:#e8bf6a;">&lt;/item&gt;<br /></span><span style="color:#e8bf6a;">        &lt;item </span><span style="color:#bababa;">name</span><span style="color:#6a8759;">="android:windowContentOverlay"</span><span style="color:#e8bf6a;">&gt;</span>@null<span style="color:#e8bf6a;">&lt;/item&gt;<br /></span><span style="color:#e8bf6a;">        &lt;item </span><span style="color:#bababa;">name</span><span style="color:#6a8759;">="android:windowBackground"</span><span style="color:#e8bf6a;">&gt;</span>@drawable/splash_background<span style="color:#e8bf6a;">&lt;/item&gt;<br /></span><span style="color:#e8bf6a;">    &lt;/style&gt;<br /></span><span style="color:#e8bf6a;">&lt;/resources&gt;</span><span style="color:#e8bf6a;"></span></pre><p><br /></p><p>java/com.zeronara.webview/MainActivity.java</p><pre style="background-color:#2b2b2b;color:#a9b7c6;font-family:'JetBrains Mono', monospace;font-size:9.8pt;"><span style="color:#cc7832;">package </span>com.zeronara.webview<span style="color:#cc7832;">;<br /></span><span style="color:#cc7832;"><br /></span><span style="color:#cc7832;">import </span>androidx.appcompat.app.AppCompatActivity<span style="color:#cc7832;">;<br /></span><span style="color:#cc7832;"><br /></span><span style="color:#cc7832;">import </span>android.os.Bundle<span style="color:#cc7832;">;<br /></span><span style="color:#cc7832;">import </span>android.view.Window<span style="color:#cc7832;">;<br /></span><span style="color:#cc7832;">import </span>android.webkit.WebSettings<span style="color:#cc7832;">;<br /></span><span style="color:#cc7832;">import </span>android.webkit.WebView<span style="color:#cc7832;">;<br /></span><span style="color:#cc7832;">import </span>android.webkit.WebViewClient<span style="color:#cc7832;">;<br /></span><span style="color:#cc7832;"><br /></span><span style="color:#cc7832;">public class </span>MainActivity <span style="color:#cc7832;">extends </span>AppCompatActivity {<br />    <span style="color:#cc7832;">public </span>WebView <span style="color:#9876aa;">webView</span><span style="color:#cc7832;">;<br /></span><span style="color:#cc7832;"><br /></span><span style="color:#cc7832;">    </span><span style="color:#bbb529;">@Override<br /></span><span style="color:#bbb529;">    </span><span style="color:#cc7832;">protected void </span><span style="color:#ffc66d;">onCreate</span>(Bundle savedInstanceState) {<br />        <span style="color:#cc7832;">super</span>.onCreate(savedInstanceState)<span style="color:#cc7832;">;<br /></span><span style="color:#cc7832;">        </span>requestWindowFeature(Window.<span style="color:#9876aa;font-style:italic;">FEATURE_NO_TITLE</span>)<span style="color:#cc7832;">;<br /></span><span style="color:#cc7832;">        </span>setContentView(R.layout.<span style="color:#9876aa;font-style:italic;">activity_main</span>)<span style="color:#cc7832;">;<br /></span><span style="color:#cc7832;"><br /></span><span style="color:#cc7832;">        </span><span style="color:#9876aa;">webView </span>= (WebView)findViewById(R.id.<span style="color:#9876aa;font-style:italic;">webView</span>)<span style="color:#cc7832;">;<br /></span><span style="color:#cc7832;">        </span>WebSettings webSettings = <span style="color:#9876aa;">webView</span>.getSettings()<span style="color:#cc7832;">;<br /></span><span style="color:#cc7832;">        </span>webSettings.setJavaScriptEnabled(<span style="color:#cc7832;">true</span>)<span style="color:#cc7832;">;<br /></span><span style="color:#cc7832;"><br /></span><span style="color:#cc7832;">        </span><span style="color:#808080;">// </span><span style="color:#808080;font-family:'맑은 고딕';">앱에서 표시할</span><span style="color:#808080;"> url </span><span style="color:#808080;font-family:'맑은 고딕';">입력<br /></span><span style="color:#808080;font-family:'맑은 고딕';">        </span><span style="color:#9876aa;">webView</span>.loadUrl(<span style="color:#6a8759;">"https://zeronara.net"</span>)<span style="color:#cc7832;">;<br /></span><span style="color:#cc7832;">        </span><span style="color:#9876aa;">webView</span>.setWebViewClient(<span style="color:#cc7832;">new </span>WebViewClient())<span style="color:#cc7832;">;<br /></span><span style="color:#cc7832;">    </span>}<br /><br />    <span style="color:#808080;">//</span><span style="color:#808080;font-family:'맑은 고딕';">폰의 뒤로가기 버튼의 동작 입력<br /></span><span style="color:#808080;font-family:'맑은 고딕';">    </span><span style="color:#bbb529;">@Override<br /></span><span style="color:#bbb529;">    </span><span style="color:#cc7832;">public void </span><span style="color:#ffc66d;">onBackPressed</span>() {<br />        <span style="color:#cc7832;">if</span>(<span style="color:#9876aa;">webView</span>.canGoBack()) {<br />            <span style="color:#9876aa;">webView</span>.goBack()<span style="color:#cc7832;">;<br /></span><span style="color:#cc7832;">        </span>} <span style="color:#cc7832;">else </span>{<br />            <span style="color:#cc7832;">super</span>.onBackPressed()<span style="color:#cc7832;">;<br /></span><span style="color:#cc7832;">        </span>}<br />    }<br />}</pre><p><br /></p><p>res/values/strings.xml</p><pre style="background-color:#2b2b2b;color:#a9b7c6;font-family:'JetBrains Mono', monospace;font-size:9.8pt;"><span style="color:#e8bf6a;">&lt;resources&gt;<br /></span><span style="color:#e8bf6a;">    &lt;string </span><span style="color:#bababa;">name</span><span style="color:#6a8759;">="app_name"</span><span style="color:#e8bf6a;">&gt;zeronara</span><span style="color:#e8bf6a;">&lt;/string&gt;<br /></span><span style="color:#e8bf6a;">&lt;/resources&gt;</span></pre><p><br /></p><p>res/values/colors.xml</p><pre style="background-color:#2b2b2b;color:#a9b7c6;font-family:'JetBrains Mono', monospace;font-size:9.8pt;"><span style="color:#e8bf6a;">&lt;?</span><span style="color:#bababa;">xml version</span><span style="color:#6a8759;">="1.0" </span><span style="color:#bababa;">encoding</span><span style="color:#6a8759;">="utf-8"</span><span style="color:#e8bf6a;">?&gt;<br /></span><span style="color:#e8bf6a;">&lt;resources&gt;<br /></span><span style="color:#e8bf6a;">    &lt;color </span><span style="color:#bababa;">name</span><span style="color:#6a8759;">="purple_200"</span><span style="color:#e8bf6a;">&gt;</span>#FFBB86FC<span style="color:#e8bf6a;">&lt;/color&gt;<br /></span><span style="color:#e8bf6a;">    &lt;color </span><span style="color:#bababa;">name</span><span style="color:#6a8759;">="purple_500"</span><span style="color:#e8bf6a;">&gt;</span>#FF6200EE<span style="color:#e8bf6a;">&lt;/color&gt;<br /></span><span style="color:#e8bf6a;">    &lt;color </span><span style="color:#bababa;">name</span><span style="color:#6a8759;">="purple_700"</span><span style="color:#e8bf6a;">&gt;</span>#FF3700B3<span style="color:#e8bf6a;">&lt;/color&gt;<br /></span><span style="color:#e8bf6a;">    &lt;color </span><span style="color:#bababa;">name</span><span style="color:#6a8759;">="teal_200"</span><span style="color:#e8bf6a;">&gt;</span>#FF03DAC5<span style="color:#e8bf6a;">&lt;/color&gt;<br /></span><span style="color:#e8bf6a;">    &lt;color </span><span style="color:#bababa;">name</span><span style="color:#6a8759;">="teal_700"</span><span style="color:#e8bf6a;">&gt;</span>#FF018786<span style="color:#e8bf6a;">&lt;/color&gt;<br /></span><span style="color:#e8bf6a;">    &lt;color </span><span style="color:#bababa;">name</span><span style="color:#6a8759;">="black"</span><span style="color:#e8bf6a;">&gt;</span>#FF000000<span style="color:#e8bf6a;">&lt;/color&gt;<br /></span><span style="color:#e8bf6a;">    &lt;color </span><span style="color:#bababa;">name</span><span style="color:#6a8759;">="white"</span><span style="color:#e8bf6a;">&gt;</span>#FFFFFFFF<span style="color:#e8bf6a;">&lt;/color&gt;<br /></span><span style="color:#e8bf6a;">    &lt;color </span><span style="color:#bababa;">name</span><span style="color:#6a8759;">="colorPrimary"</span><span style="color:#e8bf6a;">&gt;</span>#008577<span style="color:#e8bf6a;">&lt;/color&gt;<br /></span><span style="color:#e8bf6a;">    &lt;color </span><span style="color:#bababa;">name</span><span style="color:#6a8759;">="colorPrimaryDark"</span><span style="color:#e8bf6a;">&gt;</span>#000000<span style="color:#e8bf6a;">&lt;/color&gt;<br /></span><span style="color:#e8bf6a;">    &lt;color </span><span style="color:#bababa;">name</span><span style="color:#6a8759;">="colorAccent"</span><span style="color:#e8bf6a;">&gt;</span>#D81B60<span style="color:#e8bf6a;">&lt;/color&gt;<br /></span><span style="color:#e8bf6a;">    &lt;color </span><span style="color:#bababa;">name</span><span style="color:#6a8759;">="colorSplashBackground"</span><span style="color:#e8bf6a;">&gt;</span>#FFFFFFFF<span style="color:#e8bf6a;">&lt;/color&gt;<br /></span><span style="color:#e8bf6a;">&lt;/resources&gt;</span></pre><p><br /></p><p>drawable/splash_background.xml</p><pre style="background-color:#2b2b2b;color:#a9b7c6;font-family:'JetBrains Mono', monospace;font-size:9.8pt;"><span style="color:#e8bf6a;">&lt;?</span><span style="color:#bababa;">xml version</span><span style="color:#6a8759;">="1.0" </span><span style="color:#bababa;">encoding</span><span style="color:#6a8759;">="utf-8"</span><span style="color:#e8bf6a;">?&gt;<br /></span><span style="color:#e8bf6a;">&lt;layer-list </span><span style="color:#bababa;">xmlns:</span><span style="color:#9876aa;">android</span><span style="color:#6a8759;">="http://schemas.android.com/apk/res/android"</span><span style="color:#e8bf6a;">&gt;<br /></span><span style="color:#e8bf6a;">    &lt;item </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:drawable</span><span style="color:#6a8759;">="@color/colorSplashBackground"</span><span style="color:#e8bf6a;">/&gt;<br /></span><span style="color:#e8bf6a;">    &lt;item&gt;<br /></span><span style="color:#e8bf6a;">        &lt;bitmap </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:src</span><span style="color:#6a8759;">="@drawable/splash" </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:gravity</span><span style="color:#6a8759;">="center" </span><span style="color:#e8bf6a;">/&gt;<br /></span><span style="color:#e8bf6a;">    &lt;/item&gt;<br /></span><span style="color:#e8bf6a;">&lt;/layer-list&gt;</span></pre><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p>]]></description>
<dc:creator>제로</dc:creator>
<dc:date>2021-12-10T03:24:22+09:00</dc:date>
</item>


<item>
<title>노트북 받데리 확인</title>
<link>https://zeronara.com/tipntech/1102</link>
<description><![CDATA[<p>CMD에서</p><p><strong>powercfg/batteryreport</strong></p>]]></description>
<dc:creator>제로</dc:creator>
<dc:date>2023-11-02T20:54:54+09:00</dc:date>
</item>


<item>
<title>윈도우 텍스트 파일 합치기</title>
<link>https://zeronara.com/tipntech/1101</link>
<description><![CDATA[<p>CMD</p><p> </p><ol><li>type *.txt &gt; merged.txt</li><li>copy *.txt 텍스트명.txt</li></ol><p> </p>]]></description>
<dc:creator>제로</dc:creator>
<dc:date>2023-07-10T23:53:44+09:00</dc:date>
</item>


<item>
<title>유튜브, 비메오 영상 가져오기 이미지 가져오기</title>
<link>https://zeronara.com/tipntech/1100</link>
<description><![CDATA[<p>&lt;?php<br />if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가;</p><p>//아이디로 이미지 src 가져오기<br />function get_youtube_image($video_url, $thumb_type="", $thumb_width="") {</p><p>   $video = array();<br />   $query = array();</p><p>   $video_url = trim(strip_tags($video_url));</p><p>   list($url, $opt) = explode("|", $video_url);</p><p>   $url = trim($url);</p><p>   if($url) {<br />       if(!preg_match('/(http|https)\:\/\//i', $url)) {<br />           $url = 'http:'.$url;<br />       }<br />   } else {<br />       return;<br />   }</p><p>   $video['video'] = str_replace(array(" ", " "), array("", ""), $url);<br />   $video['video_url'] = str_replace(array(" ", "&amp;", " "), array("", "&amp;", ""), $url);</p><p>   $info = @parse_url($video['video_url']);</p><p>   if($info['host'] == "youtu.be") { //유튜브<br />       $video['type'] = 'youtube';<br />       $video['vid'] = trim(str_replace("/","", trim($info['path'])));<br />       $video['vid'] = substr($video['vid'], 0, 11);<br />   } else if($info['host'] == "www.youtube.com" || $info['host'] == "m.youtube.com") { //유튜브<br />       $video['type'] = 'youtube';<br />       if(preg_match('/\/embed\//i', $video['video_url'])) {<br />           list($youtube_url, $youtube_opt) = explode("/embed/", $video['video_url']);<br />           $vids = explode("?", $youtube_opt);<br />           $video['vid'] = $vids[0];<br />       } else {<br />           $vids = explode("?v=", $video['video_url']);<br />           $video['vid'] = substr($vids[1], 0, 11);<br />       }<br />   } else if($info['host'] == "vimeo.com") { //vimeo<br />       $video['type'] = 'vimeo';<br />       $video['vid'] = trim(str_replace("/","", trim($info['path'])));<br />       $video['vid'] = substr($video['vid'], 0, 9);</p><p>       $vimeo_url = "http://vimeo.com/api/v2/video/".$video['vid'].".json";<br />       $vimeo_curl = curl_init (); <br />       curl_setopt ($vimeo_curl, CURLOPT_URL, $vimeo_url); <br />       curl_setopt ($vimeo_curl, CURLOPT_POST, 0); <br />       curl_setopt ($vimeo_curl, CURLOPT_RETURNTRANSFER, 1);<br />       $vimeo_response = curl_exec ($vimeo_curl); <br />       $vimeo_returns = json_decode($vimeo_response);<br />   }</p><p>   if($video['vid']) {<br />       switch($thumb_type){<br />           /*case '0' :<br />               $videoimg = '//img.youtube.com/vi/'.$video['vid'].'/0.jpg';<br />               break;*/<br />           case '1' :<br />               $videoimg = '//img.youtube.com/vi/'.$video['vid'].'/1.jpg';<br />               break;<br />           case '2' :<br />               $videoimg = '//img.youtube.com/vi/'.$video['vid'].'/2.jpg';<br />               break;<br />           case '3' :<br />               $videoimg = '//img.youtube.com/vi/'.$video['vid'].'/3.jpg';<br />               break;<br />           case 'hq' :<br />               $videoimg = '//img.youtube.com/vi/'.$video['vid'].'/hqdefault.jpg';<br />               break;<br />           case 'mq' :<br />               $videoimg = '//img.youtube.com/vi/'.$video['vid'].'/mqdefault.jpg';<br />               break;<br />           case 'sd' :<br />               $videoimg = '//img.youtube.com/vi/'.$video['vid'].'/sddefault.jpg';<br />               break;<br />           case 'maxres' :<br />               $videoimg = '//img.youtube.com/vi/'.$video['vid'].'/maxresdefault.jpg';<br />               break;<br />           case 'thumbnail_small' :<br />               $videoimg = $vimeo_returns[0]-&gt;thumbnail_small;<br />               break;<br />           case 'thumbnail_medium' :<br />               $videoimg = $vimeo_returns[0]-&gt;videoimg;<br />               break;<br />           case 'thumbnail_large' :<br />               $videoimg = $vimeo_returns[0]-&gt;videoimg;<br />               break;<br />           default :<br />               $videoimg = '//img.youtube.com/vi/'.$video['vid'].'/default.jpg';<br />       }</p><p>       if($thumb_type) {<br />           echo '&lt;a href="'.$video_url.'" target="_blank" class="lt_thumb"&gt;&lt;img src="'.$videoimg.'" alt="" class="lt_img" width="'.$thumb_width.'"&gt;&lt;/a&gt;';<br />       } else {<br />           if($video['type'] == "youtube") { //youtube<br />               echo '&lt;div class="video-wrap"&gt;&lt;iframe width="1280" height="720" src="https://www.youtube.com/embed/'.$video['vid'].'" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen&gt;&lt;/iframe&gt;&lt;/div&gt;';<br />           } else if($video['type'] == "vimeo") { //vimeo<br />               echo '&lt;div class="video-wrap"&gt;&lt;iframe width="1280" height="720" src="https://player.vimeo.com/video/'.$video['vid'].'" title="vimeo-player" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;/div&gt;';<br />           }<br />       }<br />   }<br />}</p><p>?&gt;</p><p> </p><p>.video-wrap {position:relative; padding-bottom:56.25%; padding-top:30px; height:0; overflow:hidden;}<br />.video-wrap iframe,<br />.video-wrap object,<br />.video-wrap embed {position:absolute; top:0; left:0; width:100%; height:100%;}</p><p> </p><p> </p><p> </p>]]></description>
<dc:creator>제로</dc:creator>
<dc:date>2023-04-06T22:59:42+09:00</dc:date>
</item>


<item>
<title>중국, 러시아 아이피 전부 막기</title>
<link>https://zeronara.com/tipntech/1099</link>
<description><![CDATA[<p>function get_block_ip($ip)<br />{<br />   global $config, $g5;</p><p>   //$ip = $_SERVER['REMOTE_ADDR'];<br />   $query = @unserialize(file_get_contents('http://ip-api.com/php/'.$ip));<br />$arr = array("CN","RU");<br />   for ($i=0; $i&lt;count($arr); $i++)<br />   {<br />       if($arr[$i] == $query['countryCode']) {</p><p>           $sql = " select count(*) as cnt from {$g5['config_table']} where (INSTR(cf_intercept_ip, '$ip')) ";<br />           $chk = sql_fetch($sql);</p><p>           if (!$chk['cnt']) {<br />               $cf_intercept_ip = $config['cf_intercept_ip']."\n".$ip;<br />               sql_query(" update {$g5['config_table']} set cf_intercept_ip = '$cf_intercept_ip' ");<br />           } else {<br />               goto_url(G5_URL."/404.html");<br />           }<br />       }<br />   }<br />}</p>]]></description>
<dc:creator>제로</dc:creator>
<dc:date>2023-02-21T02:57:51+09:00</dc:date>
</item>


<item>
<title>폴더내 파일명 추출</title>
<link>https://zeronara.com/tipntech/1098</link>
<description><![CDATA[<p>cmd /c dir *.jpg *.gif *.png /b &gt; list.txt</p><p> </p><p>cmd파일을 폴더에 넣고 실행</p>]]></description>
<dc:creator>제로</dc:creator>
<dc:date>2022-12-31T18:58:18+09:00</dc:date>
</item>


<item>
<title>mysql 디비 중복값 삭제</title>
<link>https://zeronara.com/tipntech/1087</link>
<description><![CDATA[<p>// 중복삭제<br />$sql = " DELETE a FROM {$g5['g5_shop_coupon_log_table']} a, {$g5['g5_shop_coupon_log_table']} b WHERE a.cl_id &lt; b.cl_id AND a.od_id = b.od_id ";<br />sql_query($sql);</p>]]></description>
<dc:creator>제로</dc:creator>
<dc:date>2022-12-24T06:00:57+09:00</dc:date>
</item>


<item>
<title>jQuery 버튼 텍스트 변경, 클릭시 글씨 변경</title>
<link>https://zeronara.com/tipntech/1086</link>
<description><![CDATA[<p>&lt;script&gt;<br />$(function() {<br /> $('#button1').click( function() {<br />   if( $(this).html() == '받기' ) {<br />     $(this).html('확인');<br />   }<br />   else {<br />     $(this).html('받기');<br />   }<br /> });<br />});<br />&lt;/script&gt; <br />&lt;button id="button1"&gt;받기&lt;/button&gt;</p><p> </p><p><br />&lt;script&gt;<br />$(function() {<br /> $('#button1').click( function() {<br />   if( $(this).val() == '접기' ) {<br />     $(this).val('펼치기');<br />   }<br />   else {<br />     $(this).val('접기');<br />   }<br /> });<br />});<br />&lt;/script&gt; <br />&lt;input type="button" value="접기" id="button1"&gt;</p><p> </p><p> </p><p>&lt;script&gt;<br />$(function() {<br /> $('.sub_open').click( function() {<br />   $('.sub_img').toggle();<br />   if( $(this).html() == '열기' ) {<br />     $(this).html('닫기');<br />   }<br />   else {<br />     $(this).html('열기');<br />   }<br /> });<br />});<br />&lt;/script&gt;</p><p>&lt;div class="sub_open"&gt;열기&lt;/div&gt;<br /> </p>]]></description>
<dc:creator>제로</dc:creator>
<dc:date>2022-12-04T22:38:26+09:00</dc:date>
</item>


<item>
<title>Amazon Linux 2 인스턴스 Too many connections</title>
<link>https://zeronara.com/tipntech/1085</link>
<description><![CDATA[<p>$ mysql -u root -p</p><p> </p><p><strong>상태확인</strong><br />$ show variables like "%max_connections%";</p><p>max_connections: 최대 접속수<br />기본값은 151 -&gt; 변경 값 2000</p><p><br /><strong>wait_timeout 변경</strong><br />$ show variables like "%wait_timeout%";</p><p>wait_timeout은 mysqld와 client가 연결을 맺은 후, 다음 쿼리까지 기다리는 최대 시간입니다.<br />wait_timeout안에 요청이 들어오면 다시 0으로 초기화됩니다.<br />too many connections 에러가 뜨지 않기 위해선 바꿔줘야합니다.<br />기본값 28800(8시간) -&gt;  변경 값 3600</p><p><br /><strong>interactive_timeout 변경</strong><br />$ show variables like "%interactive_timeout%";</p><p>interactive_timeout은 터미널 모드 (ex: mysql&gt;)에서의 다음 쿼리까지 기다리는 최대 시간입니다.<br />기본값 28800(8시간) -&gt;  변경 값 3600</p><p> </p><p> </p><p><strong>/opt/bitnami/mariadb/conf/my.cnf</strong></p><p>[mysqld]</p><p>추가</p><p>max_connections=2000<br />interactive_timeout=3600<br />wait_timeout=3600</p><p> </p><p><strong>상태 확인</strong></p><p>$ sudo /opt/bitnami/ctlscript.sh status</p><p> </p><p><strong>전체 재부팅</strong></p><p>$ sudo /opt/bitnami/ctlscript.sh restart</p><p> </p><p><strong>개별 재부팅</strong></p><p>$ sudo /opt/bitnami/ctlscript.sh restart apache<br />$ sudo /opt/bitnami/ctlscript.sh restart mariadb</p>]]></description>
<dc:creator>제로</dc:creator>
<dc:date>2022-10-17T23:19:54+09:00</dc:date>
</item>


<item>
<title>Amazon Linux 2 인스턴스의 표준 시간대 변경</title>
<link>https://zeronara.com/tipntech/1084</link>
<description><![CDATA[<p>1. 시스템의 현재 표준 시간대 설정을 확인합니다.</p><p>[ec2-user ~]$ timedatectl</p><p> </p><p>선택한 표준 시간대를 설정합니다.<br />[ec2-user ~]$ sudo timedatectl set-timezone Asia/Seoul</p><p> </p><p>(선택 사항) timedatectl 명령을 다시 실행하여 현재 표준 시간대가 새 표준 시간대로 업데이트되는지 확인합니다.</p><p>[ec2-user ~]$ timedatectl</p><p> </p><p> </p><p>2. AWS EC2의 시간 변경하기 (TimeZone 변경하기)</p><p>[ec2-user ~]$ sudo su - root</p><p>[ec2-user ~]$ rm /etc/localtime</p><p>[ec2-user ~]$ ln -s /usr/share/zoneinfo/Asia/Seoul /etc/localtime</p><p>[ec2-user ~]$ date</p><p>[ec2-user ~]$ sudo reboot</p>]]></description>
<dc:creator>제로</dc:creator>
<dc:date>2022-10-02T03:08:48+09:00</dc:date>
</item>


<item>
<title>엑셀로 상품등록시 옵션 같이 등록하기</title>
<link>https://zeronara.com/tipntech/1083</link>
<description><![CDATA[<p>엑셀로 상품등록시 옵션 같이 등록하기</p><p>사용조건</p><p>옵션별 추가금액(0) 재고수량(9999) 통보수량(100) 사용여부(1)는 고정합니다.</p><p> </p><p>일반적인 사이즈나 색상만을 사용할 경우 아래코드를 사용해 주세요.</p><p> </p><p>itemexcelupdate.php</p><p>//--------------------------------</p><p>$it_option_subject = addslashes((string)$rowData[0][$j++]);<br />$it_opt1 = addslashes((string)$rowData[0][$j++]);<br />$it_opt2 = addslashes((string)$rowData[0][$j++]);<br />$it_opt3 = addslashes((string)$rowData[0][$j++]);<br />$it_explan2         = strip_tags(trim($it_explan));</p><p> </p><p> </p><p><br />       $sql = " INSERT INTO {$g5['g5_shop_item_table']}<br />                    SET it_id = '$it_id',<br />                        ca_id = '$ca_id',<br />                        ca_id2 = '$ca_id2',<br />                        ca_id3 = '$ca_id3',<br />                        it_name = '$it_name',<br />                        it_maker = '$it_maker',<br />                        it_origin = '$it_origin',<br />                        it_brand = '$it_brand',<br />                        it_model = '$it_model',<br />                        it_type1 = '$it_type1',<br />                        it_type2 = '$it_type2',<br />                        it_type3 = '$it_type3',<br />                        it_type4 = '$it_type4',<br />                        it_type5 = '$it_type5',<br />                        it_basic = '$it_basic',<br />                        it_explan = '$it_explan',<br />                        it_explan2 = '$it_explan2',<br />                        it_mobile_explan = '$it_mobile_explan',<br />                        it_cust_price = '$it_cust_price',<br />                        it_price = '$it_price',<br />                        it_point = '$it_point',<br />                        it_point_type = '$it_point_type',<br />                        it_stock_qty = '$it_stock_qty',<br />                        it_noti_qty = '$it_noti_qty',<br />                        it_buy_min_qty = '$it_buy_min_qty',<br />                        it_buy_max_qty = '$it_buy_max_qty',<br />                        it_notax = '$it_notax',<br />                        it_use = '$it_use',<br />                        it_time = '".G5_TIME_YMDHIS."',<br />                        it_ip = '{$_SERVER['REMOTE_ADDR']}',<br />                        it_order = '$it_order',<br />                        it_tel_inq = '$it_tel_inq',<br />                        it_option_subject = '$it_option_subject',<br />                        it_img1 = '$it_img1',<br />                        it_img2 = '$it_img2',<br />                        it_img3 = '$it_img3',<br />                        it_img4 = '$it_img4',<br />                        it_img5 = '$it_img5',<br />                        it_img6 = '$it_img6',<br />                        it_img7 = '$it_img7',<br />                        it_img8 = '$it_img8',<br />                        it_img9 = '$it_img9',<br />                        it_img10 = '$it_img10' ";</p><p>       sql_query($sql);</p><p>       $succ_count++;</p><p><br />       //-------------------------------------------<br />       $po_run = false;</p><p>       $opt1_val = isset($it_opt1) ? preg_replace(G5_OPTION_ID_FILTER, '', trim(stripslashes($it_opt1))) : '';<br />       $opt2_val = isset($it_opt2) ? preg_replace(G5_OPTION_ID_FILTER, '', trim(stripslashes($it_opt2))) : '';<br />       $opt3_val = isset($it_opt3) ? preg_replace(G5_OPTION_ID_FILTER, '', trim(stripslashes($it_opt3))) : '';</p><p>       $po_run = true;</p><p>       $opt1_count = $opt2_count = $opt3_count = 0;</p><p>       if($opt1_val) {<br />           $opt1 = explode(',', $opt1_val);<br />           $opt1_count = count($opt1);<br />       }</p><p>       if($opt2_val) {<br />           $opt2 = explode(',', $opt2_val);<br />           $opt2_count = count($opt2);<br />       }</p><p>       if($opt3_val) {<br />           $opt3 = explode(',', $opt3_val);<br />           $opt3_count = count($opt3);<br />       }</p><p>       if($po_run) {<br />       // 옵션<br />       sql_query(" delete from {$g5['g5_shop_item_option_table']} where it_id = '$it_id' "); // 기존옵션삭제</p><p>           for($o=0; $o&lt;$opt1_count; $o++) {<br />               $p = 0;<br />               do {<br />                   $q = 0;<br />                   do {<br />                       $opt_1 = isset($opt1[$o]) ? strip_tags(trim($opt1[$o])) : '';<br />                       $opt_2 = isset($opt2[$p]) ? strip_tags(trim($opt2[$p])) : '';<br />                       $opt_3 = isset($opt3[$q]) ? strip_tags(trim($opt3[$q])) : '';</p><p>                       $opt_2_len = strlen($opt_2);<br />                       $opt_3_len = strlen($opt_3);</p><p>                       $opt_id = $opt_1;<br />                       if($opt_2_len)<br />                           $opt_id .= chr(30).$opt_2;<br />                       if($opt_3_len)<br />                           $opt_id .= chr(30).$opt_3;<br />                       $opt_price = 0;<br />                       $opt_stock_qty = 9999;<br />                       $opt_noti_qty = 100;<br />                       $opt_use = 1;</p><p>                       $option_count = (isset($opt_id) &amp;&amp; is_array($opt_id)) ? count($opt_id) : array();</p><p>                       // 선택옵션등록<br />                       $comma = '';<br />                       $sql = " INSERT INTO {$g5['g5_shop_item_option_table']}<br />                                       ( `io_id`, `io_type`, `it_id`, `io_price`, `io_stock_qty`, `io_noti_qty`, `io_use` )<br />                                   VALUES ";<br />                           $sql .= $comma . " ( '".sql_real_escape_string($opt_id)."', '0', '$it_id', '0', '9999', '100', '1' )";<br />                           $comma = ' , ';</p><p>                       sql_query($sql);</p><p>                       $q++;<br />                   } while($q &lt; $opt3_count);</p><p>                   $p++;<br />               } while($p &lt; $opt2_count);<br />           } // for<br />       }<br />       //-------------------------------------------</p><p> </p>]]></description>
<dc:creator>제로</dc:creator>
<dc:date>2022-08-04T20:09:47+09:00</dc:date>
</item>


<item>
<title>닉네임 변경시 게시글 작성자 동시 변경하기</title>
<link>https://zeronara.com/tipntech/1082</link>
<description><![CDATA[<p>닉네임 변경시 게시글 작성자 동시 변경하기</p><p> </p><p>member_form_update.php</p><p>//-------------------------------------------------------------------</p><p>$sql = " select bo_table from {$g5['board_table']} ";<br />$result = sql_query($sql);<br />for ($i=0; $row = sql_fetch_array($result); $i++) {<br />   $tmp_write_table = $g5['write_prefix'] . $row['bo_table'];<br />   sql_query(" update {$tmp_write_table} set wr_name = '{$mb_nick}' where mb_id = '{$mb_id}' ");<br />}</p>]]></description>
<dc:creator>제로</dc:creator>
<dc:date>2022-08-04T20:03:55+09:00</dc:date>
</item>


<item>
<title>서버이전시 이미지 주소변경</title>
<link>https://zeronara.com/tipntech/1081</link>
<description><![CDATA[<p><strong>서버이전시 이미지 주소변경</strong></p><hr /><hr /><hr /><hr /><hr /><hr /><hr /><hr /><hr /><hr /><hr /><hr /><hr /><hr /><hr /><p>//-----------------------------------------------</p><p>&lt;?php<br />$sub_menu = "600100";<br />include_once('./_common.php');</p><p>auth_check($auth[$sub_menu], 'r');</p><p>if ($is_admin != 'super')<br />   alert('최고관리자만 접근 가능합니다.');</p><p>$g5['title'] = '이미지 주소 변경';<br />include_once ('./admin.head.php');</p><p>$pg_anchor = '&lt;ul class="anchor"&gt;<br />   &lt;li&gt;&lt;a href="#img_rename"&gt;이미지 주소 변경&lt;/a&gt;&lt;/li&gt;<br />&lt;/ul&gt;';</p><p>$frm_submit = '&lt;div class="btn_confirm01 btn_confirm"&gt;<br />   &lt;input type="submit" value="확인" class="btn_submit" accesskey="s"&gt;<br />   &lt;a href="'.G5_URL.'/"&gt;메인으로&lt;/a&gt;<br />&lt;/div&gt;';<br />?&gt;</p><p>&lt;div class="local_desc01 local_desc"&gt;<br />   &lt;p&gt;<br />       이미지 주소 변경 시 게시판, 내용관리에 등록된 이미지의 주소가 현재 사이트 주소로 변경됩니다.<br /> &lt;br&gt;&lt;strong&gt;그누보드5 , 영카드5&lt;/strong&gt; 에서 사용 가능합니다.<br />   &lt;/p&gt;<br />&lt;/div&gt;</p><p>&lt;form name="fconfigform" id="fconfigform" method="post" onsubmit="return fconfigform_submit(this);" enctype="MULTIPART/FORM-DATA"&gt;<br />&lt;input type="hidden" name="token" value="" id="token"&gt;</p><p>&lt;section id="img_rename"&gt;<br />   &lt;div class="tbl_frm01 tbl_wrap"&gt;<br />      &lt;table&gt;<br />       &lt;caption&gt;이미지주소변경&lt;/caption&gt;<br />       &lt;colgroup&gt;<br />           &lt;col class="grid_4"&gt;<br />           &lt;col&gt;<br />           &lt;col class="grid_4"&gt;<br />           &lt;col&gt;<br />       &lt;/colgroup&gt;<br />       &lt;tbody&gt;<br />       &lt;tr&gt;<br />           &lt;th scope="row"&gt;&lt;label for="previous_site"&gt;이전 사이트 주소&lt;strong class="sound_only"&gt;필수&lt;/strong&gt;&lt;/label&gt;&lt;/th&gt;<br />           &lt;td&gt;<br />               &lt;?php echo help('이전 사이트의 이미지 주소를 정확하게 입력해주세요.') ?&gt;<br />               &lt;?php echo help('ex) http://test.co.kr') ?&gt;<br />               &lt;input type="text" name="previous_site" value="" id="previous_site" class="frm_input required" size="30" required&gt;<br />           &lt;/td&gt;<br />           &lt;th scope="row"&gt;&lt;label for="now_site"&gt;현재 사이트 주소&lt;strong class="sound_only"&gt;필수&lt;/strong&gt;&lt;/label&gt;&lt;/th&gt;<br />           &lt;td&gt;<br />               &lt;?php echo help('수정불가.') ?&gt;<br />               &lt;input type="text" name="now_site" value="&lt;?php echo G5_URL ?&gt;" id="now_site" class="frm_input" size="30" readonly&gt;<br />           &lt;/td&gt;<br />       &lt;/tr&gt;<br />       &lt;/tbody&gt;<br />       &lt;/table&gt;<br />   &lt;/div&gt;<br />&lt;/section&gt;<br />&lt;?php echo $frm_submit; ?&gt;</p><p>&lt;/form&gt;</p><p>&lt;script&gt;<br />function fconfigform_submit(f)<br />{<br />   f.action = "./img_rename_update.php";<br />   return true;<br />}<br />&lt;/script&gt;</p><p>&lt;?php<br />include_once ('./admin.tail.php');<br />?&gt;</p><p>//-----------------------------------------------</p><p> </p><p>//-----------------------------------------------</p><p>&lt;?php<br />$sub_menu = "600100";<br />include_once('./_common.php');</p><p>auth_check($auth[$sub_menu], 'r');</p><p>if ($is_admin != 'super')<br />   alert('최고관리자만 접근 가능합니다.');</p><p>$g5['title'] = '이미지 주소 변경';<br />include_once ('./admin.head.php');</p><p>// 구사이트도메인 http://www. 제외<br />$old = $_POST['previous_site'];</p><p>$old = trim($old); // 도메인주소 앞뒤 공백 제거<br />$old = rtrim($old, '/'); // 도메인주소 마지막에 / 문자 제거</p><p>// 새사이트도메인 http://www. 제외<br />$new= $_POST['now_site'];</p><p>$sql = sql_query("select * from {$g5['board_table']}");</p><p>while($data = sql_fetch_array($sql)){<br />//echo"$data[bo_table]&lt;br&gt;";<br />sql_query("update {$g5['write_prefix']}{$data[bo_table]} set wr_content=REPLACE(`wr_content`,'$old','$new')");<br />sql_query("update {$g5['board_table']} set bo_content_head=REPLACE(`bo_content_head`,'$old','$new')");<br />sql_query("update {$g5['board_table']} set bo_mobile_content_head=REPLACE(`bo_mobile_content_head`,'$old','$new')");<br />}</p><p>$sql = sql_query("select * from {$g5['content_table']}");<br />sql_query("update {$g5['content_table']} set co_content=REPLACE(`co_content`,'$old','$new')");<br />sql_query("update {$g5['content_table']} set co_mobile_content=REPLACE(`co_mobile_content`,'$old','$new')");</p><p>if($g5['g5_shop_item_table']){<br />$sql = sql_query("select * from {$g5['g5_shop_item_table']}");<br />sql_query("update {$g5['g5_shop_item_table']} set it_explan=REPLACE(`it_explan`,'$old','$new')");<br />sql_query("update {$g5['g5_shop_item_table']} set it_mobile_explan=REPLACE(`it_mobile_explan`,'$old','$new')");<br />}</p><p>alert('이미지 주소변경이 완료되었습니다.', './img_rename.php?'.$qstr);</p><p>?&gt;</p><p>//-----------------------------------------------</p><p> </p>]]></description>
<dc:creator>제로</dc:creator>
<dc:date>2022-08-03T23:30:45+09:00</dc:date>
</item>


<item>
<title>AWS 서버에 그누보드 설치하기 6 - 하드용량늘리기</title>
<link>https://zeronara.com/tipntech/1080</link>
<description><![CDATA[<p>하드용량 확인</p><p>$ df -h</p><p> </p><p>용량이 부족한 하드의 사용량을 늘려 줍니다.</p><img src="https://zeronara.net/data/editor/2207/d9c653c6b081114000551004eddc48827564edb26s97.png" alt="d9c653c6b081114000551004eddc48827564edb26s97.png" /><p> </p><h2>용량을 확인합니다.</h2><h2>$ sudo lsblk</h2><p> </p><p>늘릴 하드를 찾아서 명령어를 입력를 입력합니다.</p><p>sudo growpart /dev/(disk 이름)</p><p>$ sudo growpart /dev/nvme0n1</p><p> </p><p>파티션된 하드를 찾아서 용량을 늘려 쥡니다.</p><p>sudo resize2fs /dev/(part명)</p><p>$ sudo resize2fs /dev/nvme0n1p1</p>]]></description>
<dc:creator>제로</dc:creator>
<dc:date>2022-07-08T17:54:09+09:00</dc:date>
</item>


<item>
<title>DHTML 에디터 때문에 생기는 쓰레기 이미지를 한번에 정리 (sir - 야수님)</title>
<link>https://zeronara.com/tipntech/1079</link>
<description><![CDATA[<p>보통 스마트에디터 등의 DHTML 에디터를 많이 사용하지만,</p><p>한번 올린 이미지는 삭제되지 않고, 계속 쌓이기만 합니다.</p><p> </p><p>쓸데없이 서버의 디스크 공간만 차지 하고, 쓰이지도 않는 이미지 파일들을 한번에 정리하고자 만들었습니다.</p><p>무식하게 파일마다, 모든 DHTML 에디터를 사용한 Table이 있는지 다 뒤져서 판별하기 때문에 서버에 많은 부하를 줄 수 있습니다.</p><p>사용하실 분은 꼭 소스 확인 해 보시고, 이해를 하신 뒤에 쓰시기를 권장합니다.</p><p> </p><p><span style="color:#e74c3c;"><strong>업무가 바쁜 관계로 후다닥 만들어서 완성도에 문제가 있을 수 있으므로,</strong></span></p><p><span style="color:#e74c3c;"><strong>사용하실 분들은 꼭 /data/editor 폴더를 백업 해두고 쓰시기 바랍니다.</strong></span></p><p><span style="color:#e74c3c;"><strong>문제 생겨도 책임 못져요 (필요한 파일 다 날릴 수 있음) ㅠ.ㅠ</strong></span></p><p> </p><p>사족으로 전체 몇개의 파일중에 몇개를 삭제 했으며, 삭제한 용량이 얼마인지 표시되게 하였습니다.</p><p>사용해 보시고, 개선해야 할 사항 있으시면 알려주세요.</p><p> </p><p>설치할 폴더는 /adm 입니다.</p><p>영카트에도 쓸 수 있습니다.</p><p> </p><p><span style="color:#c0392b;">* 추신 : 게시판이 많거나, 게시물이 많거나, editor 로 올린 이미지가 많을 경우에 서버에 엄청난 부하가 생길수 있으니 주의하시기 바랍니다.</span></p>]]></description>
<dc:creator>제로</dc:creator>
<dc:date>2022-07-08T16:36:54+09:00</dc:date>
</item>


<item>
<title>Javascript로 화면 PDF로 저장 jspdf html2canvas</title>
<link>https://zeronara.com/tipntech/1078</link>
<description><![CDATA[<p>&lt;script type="text/javascript" src="&lt;?php echo G5_PLUGIN_URL?&gt;/pdf/jspdf.min.js"&gt;&lt;/script&gt;<br />&lt;script type="text/javascript" src="&lt;?php echo G5_PLUGIN_URL?&gt;/pdf/html2canvas.min.js"&gt;&lt;/script&gt;</p><p>&lt;script&gt;<br />$(document).ready(function() {<br />$('#savePdf').click(function() { // pdf저장 button id<br /> <br />    html2canvas($('#pdfDiv')[0]).then(function(canvas) { //저장 영역 div id<br />           <br />           // 캔버스를 이미지로 변환<br />           var imgData = canvas.toDataURL('image/png');<br />                <br />           var imgWidth = 190; // 이미지 가로 길이(mm) / A4 기준 210mm<br />           var pageHeight = imgWidth * 1.414;  // 출력 페이지 세로 길이 계산 A4 기준<br />           var imgHeight = canvas.height * imgWidth / canvas.width;<br />           var heightLeft = imgHeight;<br />           var margin = 10; // 출력 페이지 여백설정<br />           var doc = new jsPDF('p', 'mm');<br />           var position = 0;<br />              <br />           // 첫 페이지 출력<br />           doc.addImage(imgData, 'PNG', margin, position, imgWidth, imgHeight);<br />           heightLeft -= pageHeight;<br />                <br />           // 한 페이지 이상일 경우 루프 돌면서 출력<br />           while (heightLeft &gt;= 20) {<br />               position = heightLeft - imgHeight;<br />               doc.addPage();<br />               doc.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);<br />               heightLeft -= pageHeight;<br />           }<br />        <br />           // 파일 저장<br />           doc.save('file-name.pdf');    <br />    });<br />}); <br />});<br />&lt;/script&gt;</p>]]></description>
<dc:creator>제로</dc:creator>
<dc:date>2022-07-06T00:54:47+09:00</dc:date>
</item>


<item>
<title>클립보드 복사하기</title>
<link>https://zeronara.com/tipntech/1077</link>
<description><![CDATA[<p>&lt;span class="data-copy"&gt;복사하기&lt;/span&gt;<br />&lt;input type="hidden" id="data-area" class="data-area" value=""&gt;<br /> </p><p>&lt;script&gt;<br />$('.data-copy').click(function() { <br />   $('#data-area').attr('type', 'text');<br />   $('#data-area').select();<br />   var copy = document.execCommand('copy');<br />   $('#data-area').attr('type', 'hidden');<br />   if(copy) { <br />       alert('복사되었습니다');<br />   }<br />});<br />&lt;/script&gt;</p>]]></description>
<dc:creator>제로</dc:creator>
<dc:date>2022-06-09T05:40:35+09:00</dc:date>
</item>


<item>
<title>explode 배열의 마지막 값 가져오기 end 함수</title>
<link>https://zeronara.com/tipntech/1076</link>
<description><![CDATA[<p>$file_name = “https://zeronara.net/bbs/write/tipntech”</p><p> </p><p>$arr =  explode("/". $file_name);<br />$end = end($arr);<br />echo $end;</p>]]></description>
<dc:creator>제로</dc:creator>
<dc:date>2022-06-03T02:31:08+09:00</dc:date>
</item>


<item>
<title>sh 백업파일 만들기</title>
<link>https://zeronara.com/tipntech/1075</link>
<description><![CDATA[<p>#!/bin/sh</p><p> </p><p>#실행시각<br />NOW_DATE=`date`</p><p> </p><p>#백업날짜<br />#BACKUP_DATE=`date +"%Y%m%d-%H%M%S"`<br />BACKUP_DATE=`date +"%Y%m%d"`</p><p> </p><p>#웹루트<br />WWWROOT_DIR=/home/users/2/zeronara/web</p><p> </p><p>#백업파일을 저장할 경로<br />BACKUP_DIR=${WWWROOT_DIR}/backup</p><p> </p><p>#날짜폴더 생성<br />if [ ! -d ${BACKUP_DIR}/${BACKUP_DATE} ]; then<br />   mkdir ${BACKUP_DIR}/${BACKUP_DATE}<br />fi</p><p>MKDIR=${BACKUP_DIR}/${BACKUP_DATE}</p><p> </p><p>#MySQL백업<br />mysqldump -hlocalhost -u_test1 -ptest1pw _test1 &gt; ${MKDIR}/${BACKUP_DATE}_test1.sql<br />mysqldump -hlocalhost -u_test2 -ptest2pw _test2 &gt; ${MKDIR}/${BACKUP_DATE}_test2.sql</p><p> </p><p>#웹소스백업<br />HOME_DIR=`/bin/ls -t ${WWWROOT_DIR} 2&gt;/dev/null`<br />for DIR in $HOME_DIR ; do<br />   tar zcvf ${MKDIR}/${BACKUP_DATE}_${DIR}.gz ${WWWROOT_DIR}/${DIR} --exclude=${BACKUP_DIR}/*</p><p>   rm -rf ${MKDIR}/${BACKUP_DATE}_backup.gz<br />   rm -rf ${MKDIR}/${BACKUP_DATE}_404.html.gz<br />   rm -rf ${MKDIR}/${BACKUP_DATE}_index.html.gz<br />   rm -rf ${MKDIR}/${BACKUP_DATE}_db_backup.sh.gz</p><p>done</p><p> </p><p>#소유주 및 권한변경(타 계정의 접근 차단용)<br />#chown -R root.root ${BACKUP_DIR}<br />#chmod -R 700 ${BACKUP_DIR}</p><p> </p><p># 오래된 백업데이터 삭제(14일 이상 된 것)<br />find ${BACKUP_DIR} -mindepth 1 -maxdepth 1 -mtime +14 -type d -exec rm -rf {} \;</p><p> </p><p>#메일 발송 (수신메일추가는 공백으로 구분하여 마지막에 열거)<br />echo "백업시각: ${BACKUP_DATE}\n백업경로: ${BACKUP_DIR}\n\n위와 같이 DB와 웹파일이 백업되었습니다." | mail -a "From:서버관리자 &lt;test@gmail.com&gt;" -s "자동서버백업안내" test@gmail.com</p><p> </p><p>exit 0</p>]]></description>
<dc:creator>제로</dc:creator>
<dc:date>2022-04-16T22:26:15+09:00</dc:date>
</item>


<item>
<title>json_encode()로 JSON 형식의 문자열로 변환</title>
<link>https://zeronara.com/tipntech/1074</link>
<description><![CDATA[<p>$data = array(<br />'test1'=&gt;'aaa',<br />'test2'=&gt; array(<br /> array(<br />  'test3'=&gt;'bbb'<br /> )<br />),<br />'test4'=&gt; array(<br /> array(<br />  'test5'=&gt;'ccc',<br />  'test6'=&gt;'ddd'<br /> )<br />)<br />);</p><p>$data_json = json_encode($data);</p><p> </p><p>**********************************</p><p> </p><p>{"test1":"aaa","test2":[{"test3":"bbb"}],"test4":[{"test5":"ccc","test6":"ddd"}]}</p><p> </p><p> </p><p>$array = array(<br />   "foo" =&gt; "bar",<br />   "bar" =&gt; "foo",<br />);<br /><br />// PHP 5.4 이전<br />$array = [<br />   "foo" =&gt; "bar",<br />   "bar" =&gt; "foo",<br />];</p>]]></description>
<dc:creator>제로</dc:creator>
<dc:date>2022-03-29T22:35:19+09:00</dc:date>
</item>


<item>
<title>로그파일 남기기</title>
<link>https://zeronara.com/tipntech/1073</link>
<description><![CDATA[<p>$requestData = file_get_contents('php://input');</p><p>function writelog($file, $log, $ln="")<br />{<br />   global $requestData;<br />   $fp = @fopen($file, "a+");<br />   ob_start();<br />   print_r($log);<br />   $msg = ob_get_contents();<br />   ob_end_clean();<br /><br />   $date = date("Y-m-d H:i:s");</p><p>   $logMsg = "\n\n==============================\n";<br />   $logMsg .= ($ln == "") ? ("[".$date."] ") : ("[".$date."] Ln".$ln.": ");</p><p>   $msg = $logMsg . $msg;<br />   $msg .= "\n";<br />   $msg .= $requestData;<br /><br />   @fwrite($fp, $msg);<br />   @fclose($fp);<br />}<br />$logFile = G5_PATH."/log/api_".G5_TIME_YMD.".log";</p><p> </p><p>echo json_encode($data);<br />writeLog($logFile, $mb_id.' - '.json_encode($data));</p>]]></description>
<dc:creator>제로</dc:creator>
<dc:date>2022-03-26T19:24:07+09:00</dc:date>
</item>


<item>
<title>Adblock 프로그램 감지하기</title>
<link>https://zeronara.com/tipntech/1072</link>
<description><![CDATA[<p>default.css</p><p>#h237 {position:fixed !important;position:absolute;top:0;top:expression((t=document.documentElement.scrollTop?document.documentElement.scrollTop:document.body.scrollTop)+"px");left:0;width:102%;height:102%;background-color:#fff;display:block;padding:10% 0}<br />#h237 *{text-align:center;margin:0 auto;display:block;text-decoration:none;color:#333}<br />#h237 strong {font-size:24px; font-weight:700;margin:10px;color:#e74c3c}<br />#h237 ~ *{display:none}</p><p> </p><p> </p><p>&lt;body&lt;?php echo isset($g5['body_script']) ? $g5['body_script'] : ''; ?&gt;&gt;<br />&lt;div id="h237"&gt;&lt;/div&gt;<br />&lt;script&gt;window.document.getElementById("h237").parentNode.removeChild(window.document.getElementById("h237"));(function(l,m){function n(a){a&amp;&amp;h237.nextFunction()}var h=l.document,p=["i","s","u"];n.prototype={rand:function(a){return Math.floor(Math.random()*a)},getElementBy:function(a,b){return a?h.getElementById(a):h.getElementsByTagName(b)},getStyle:function(a){var b=h.defaultView;return b&amp;&amp;b.getComputedStyle?b.getComputedStyle(a,null):a.currentStyle},deferExecution:function(a){setTimeout(a,250)},insert:function(a,b){var e=h.createElement("span"),d=h.body,c=d.childNodes.length,g=d.style,f=0,k=0;if("h237"==b){e.setAttribute("id",b);g.margin=g.padding=0;g.height="100%";for(c=this.rand(c);f&lt;c;f++)1==d.childNodes[f].nodeType&amp;&amp;(k=Math.max(k,parseFloat(this.getStyle(d.childNodes[f]).zIndex)||0));k&amp;&amp;(e.style.zIndex=k+1);c++}e.innerHTML=a;d.insertBefore(e,d.childNodes[c-1])},displayMessage:function(a){var b=this;a="abisuq".charAt(b.rand(5));b.insert("&lt;"+a+'&gt;&lt;img src="&lt;?php echo G5_THEME_URL?&gt;/img/adblock.png" alt="Stop-AdBlock" /&gt;&lt;strong&gt;Adblock detected!&lt;/strong&gt;&lt;br&gt;Please consider supporting us by disabling your ad blocker&lt;br&gt;Adblock 프로그램을 꺼주시면 더 많은 서비스를 제공하는데 도움이 됩니다.&lt;a href="JavaScript:window.location.reload()"&gt;[ Reload ]&lt;/a&gt;'+("&lt;/"+a+"&gt;"),"h237");h.addEventListener&amp;&amp;b.deferExecution(function(){b.getElementBy("h237").addEventListener("DOMNodeRemoved",function(){b.displayMessage()},!1)})},i:function(){for(var a="DivTopAd,ad-zone-1,ad_190x90,ads-sticky,iqadtile5,leftframeAD,tobsideAd,ad,ads,adsense".split(","),b=a.length,e="",d=this,c=0,g="abisuq".charAt(d.rand(5));c&lt;b;c++)d.getElementBy(a[c])||(e+="&lt;"+g+' id="'+a[c]+'"&gt;&lt;/'+g+"&gt;");d.insert(e);d.deferExecution(function(){for(c=0;c&lt;b;c++)if(null==d.getElementBy(a[c]).offsetParent||"none"==d.getStyle(d.getElementBy(a[c])).display)return d.displayMessage("#"+a[c]+"("+c+")");d.nextFunction()})},s:function(){var a={'pagead2.googlesyndic':'google_ad_client','js.adscale.de/getads':'adscale_slot_id','get.mirando.de/miran':'adPlaceId'},b=this,e=b.getElementBy(0,"script"),d=e.length-1,c,g,f,k;h.write=null;for(h.writeln=null;0&lt;=d;--d)if(c=e[d].src.substr(7,20),a[c]!==m){f=h.createElement("script");f.type="text/javascript";f.src=e[d].src;g=a[c];l[g]=m;f.onload=f.onreadystatechange=function(){k=this;l[g]!==m||k.readyState&amp;&amp;"loaded"!==k.readyState&amp;&amp;"complete"!==k.readyState||(l[g]=f.onload=f.onreadystatechange=null,e[0].parentNode.removeChild(f))};e[0].parentNode.insertBefore(f,e[0]);b.deferExecution(function(){if(l[g]===m)return b.displayMessage(f.src);b.nextFunction()});return}b.nextFunction()},u:function(){var a="ad&amp;adv_keywords=,-page-peel/,/adchain.,/adfootright.,/adsxml/ad,/adyard300.,/impopup/ad,/loadadsparam.,/meme_ad.,_adshare.".split(","),b=this,e=b.getElementBy(0,"img"),d,c;e[0]!==m&amp;&amp;e[0].src!==m&amp;&amp;(d=new Image,d.onload=function(){c=this;c.onload=null;c.onerror=function(){p=null;b.displayMessage(c.src)};c.src=e[0].src+"#"+a.join("")},d.src=e[0].src);b.deferExecution(function(){b.nextFunction()})},nextFunction:function(){var a=p[0];a!==m&amp;&amp;(p.shift(),this[a]())}};l.h237=h237=new n;h.addEventListener?l.addEventListener("load",n,!1):l.attachEvent("onload",n)})(window);&lt;/script&gt;</p><p> </p><p>이미지 제공</p><p>https://pixabay.com/</p>]]></description>
<dc:creator>제로</dc:creator>
<dc:date>2022-03-12T14:53:43+09:00</dc:date>
</item>


<item>
<title>php 현제 위치 파일명 확인</title>
<link>https://zeronara.com/tipntech/1071</link>
<description><![CDATA[<p>basename($_SERVER['PHP_SELF'])</p>]]></description>
<dc:creator>제로</dc:creator>
<dc:date>2022-03-10T18:47:50+09:00</dc:date>
</item>

</channel>
</rss>
