Windows11でAndroidアプリを動かしたい
はじめに
アプリストアに載ってるアプリすくなすぎる!!!!!
Windows11でアプリストアが動くという話は聞いていたけど、どうやら手動で入れればWindows Subsystem for Android(WSA)で様々なアプリを動かせるという噂が聞けたので実践してみた備忘録。
非推奨な動作環境を作成するので自己責任で行ってください!
1: Microsoft StoreからAmazonアプリストアを入手する
WSAのインストールが済んでいる or Amazonアプリストアのインストールが済んでいる場合は次に進んでください!
Microsoft Storeで検索をかけてAmazonアプリストアを入手。 このダウンロードと同時にWSAがダウンロードされる。(こっちがメイン)
表示されない場合はWindowsの更新を行う。もしかしたら Insider Programに参加してベータビルドにしないといけないかも? アプリストアの起動が確認できたら、PCを再起動。(WSAにアプリをインストールするときに接続できない可能性があるので)
2: WSAで開発者モードを有効にする
スタート
→すべてのアプリ
にある Android™用 Windowsサブシステム設定
をクリック。
開いたら、開発者
タブにある開発者モード
をオンに。
3: ADBのインストール
ADBインストール済みの方は次に進んでください! WSAにアプリを入れるために、ADBをインストールします。
リンク先のところから SDK Platform-Tools for Windows をダウンロード
を押してダウンロード。入れたものを展開。
3-2: 環境変数を設定する
色々なところで必要になる環境変数設定
Win11はスタートメニューの検索バーに「環境変数を編集」と入れてEnterを押すだけで設定メニューが開けて便利。
あとの説明はよくあるのでほかのサイト様にお任せで…
https://tech.la-fra.com/2018/07/29/post-204/
PowerShellを開き、adb
と入れてEnterを押したら
>adb Android Debug Bridge version 1.0.41 Version 33.0.3-8952118 ... (使い方が色々出てくる)
と出てくればOK。
4: apk, xapk(obb付きapk)をダウンロード
入れたいアプリのデータを持ってきます。
小さいアプリとかならapkだけでいいので手持ちの端末から持ってくるとかもできるけど、ゲームなど容量が大きいアプリになるとobbファイルも一緒にダウンロードする必要が出てきたのでちょっと困った。
自分は手持ちの端末からobbを持ってくる方法がわからなかったので↓のサイトからxapkをダウンロードしました。
以前トロイの木馬がつけられていた例もあるとのことで、ここからのダウンロードは必ず自己責任でお願いします
4-2: xapkの解凍
↑のサイトからダウンロードした場合、xapkという形式でダウンロードできるので、手動でインストールできる形に解凍していきます。
xapkを7zなどの解凍ソフトで解凍すると、このようなファイルが得られるので
の2つを見つけておく。
5: WSAにアプリをインストール
用意するものの再確認
- PowerShell (コマンドプロンプトでもOK)
- WSA
- apkファイル
- (必要に応じて)obbファイル
5-2: apkのインストール
> adb connect 127.0.0.1:58526
(多分IPアドレスは毎回固定)
で、WSAに接続し、
※ cannot connect to ~
と出る場合、PCを再起動して再チャレンジ。
※ その他接続できない場合は、WSAの開発者モードが有効になっているかを確認。
> adb -e install {apkファイルのパス}
で、apkがWSAにインストールできる。
{apkファイルのパス}
は、apkファイルを右クリックしたときに出てくる、パスのコピー
をクリックしたあとに貼り付けを行えばOKです。
※ `と出る場合、[こちら](https://qiita.com/zakuroishikuro/items/95c097992d0ff92d95e2#transport-id%E3%81%A7%E6%8C%87%E5%AE%9A-adb--t-1-shell) を参考にインストール先を指定してください。
※
no emulators found` と出る場合、Amazonアプリストアを開いて、WSAを起動してください。
apkのみの場合はこれでインストールは終了。
5-3: obbのインストール
> adb -e push {obbファイルのパス} /storage/emulated/0/Android/obb/{パッケージ名}/{obbファイル名}
というコマンドを実行。
{obbファイルのパス}
はapkファイルと同様、パスのコピーをしたものを貼り付ければOK。
{パッケージ名}
はapkファイルの.apk
より前の部分を入れる。
{obbファイル名}
は main.{ビルド番号}.{パッケージ名}.obb
となっているものをそのままコピペ。
例: apkファイル: C:\folder1\com.hoge.game.apk obbファイル: C:\folder2\main.100.com.hoge.game.obb の場合、
adb -e push C:\folder2\main.100.com.hoge.game.obb /storage/emulated/0/Android/obb/com.hoge.game/main.100.com.hoge.game.obb
となる。
Successの文字が出ればインストールは完了。 permission denied
が出た場合、もう1度やると成功する可能性が… :thinking_face:
6: 起動確認
スタートメニューにダウンロードしたアプリが増えてるはずなので、入れたものをタップ。そのまま起動すれば成功!
参考
Amazonアプリストアの一般公開を知ったニュース
https://forest.watch.impress.co.jp/docs/news/1434767.html
WSAについて
https://learn.microsoft.com/ja-jp/windows/android/wsa/
InsiderProgram参加方法
https://support.microsoft.com/ja-jp/windows/windows-insider-program-%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%99%E3%82%8B-ef20bb3d-40f4-20cc-ba3c-a72c844b563c
adbの入れ方
https://tech.la-fra.com/2018/07/29/post-204/
apkの入れ方
https://smartasw.com/archives/13868
obbの入れ方
https://doroid.org/how-to-install-xapk-android/
https://qiita.com/KuromameKota/items/3cda4800360be74cafb0
adb トラブルシューティング
https://ja.stackoverflow.com/questions/3023/operation-not-permitted
https://qiita.com/zakuroishikuro/items/95c097992d0ff92d95e2
https://learn.microsoft.com/en-us/answers/questions/788883/cannot-connect-to-12700158526-port-shown-under-the.html
ルーティングインスタンスを作りたかった
概要
GCP外部IPを割り当ててるとコストが発生してしまうので、なるべく低コストでインスタンスを動かしたいんよ
何もできなかったから、何やったかのメモだけ残してまた更新予定
現状
discord botを運用していて、コマンドで他のインスタンスをたち上げ、たち下げている。
各インスタンスは外部IPを持っており、そのインスタンスには割り振られたIPを用いてアクセスする。
概算でかかっている費用は各インスタンスの稼働コスト + インスタンスに割り当てられたIPコストがかかっている。
理想
この構成を外部IP一つで実現したい。 つまり、ルーターインスタンスを立ち上げ、特定のポートにアクセスすることで
port12345 - インスタンスA port23456 - インスタンスB …
ということを目指したい。
何が嬉しくなるか?
微々たるものだけど、割当IPがなくなるので、IP代のコスト削減になる。 そして、1つの外部IPで制御ができるということは、いちいち、立ち上がったインスタンスのIPを調べて…という作業がなくなる。
実現までのメモ
まず、ネットワークの知識が無知なので、こんなことができるのかな…というところから調べ、いくつかの手段にたどり着いた。
DNAT, SNAT
正式名称は(Destination | Source) Network Address Translationといい、IPアドレスを変換する技術らしい。 DNATは「送信先アドレス」を、SNATは「送信元アドレス」をそれぞれ変換する。
https://www.infraexpert.com/study/ip10.html 詳しい説明は参考にしたサイト様におまかせ。
この技術を使えば、課題である、ルーターを作ることができそう。
cloud NAT, cloud router
それぞれ、GCPのサービス。
ちゃんと理解していないが、これを使えばまさにやりたいことをやってくれそうな印象。しかし、またGCPのコスト上がるし、正直すべて無知だったので一旦断念
iptables
iptablesは、ご存知パケットのフィルタリングツール。特定ポートにやってくるパケットや特定の送信元以外のアクセスを許可などを構築してくれます。
ここからが自分は知らなくて、iptablesはNATに対応しているとのこと。 正しく設定を書けば、iptablesでルーティングができるらしい。 詳しい知人いわく、「プライベートIPアドレスを持つ端末と直接疎通できないようになってセキュリティ的に向上するからっていう流れでファイアウォールに入っている(と思っている)」 なるほど確かに。。。
まずパケットがインスタンスに通っているかを確認したいけど、その確認方法で詰まってしまった pingは通ってるけどポートが空いていることが確認できない…
chrome extentionを作った話
身内の趣味のサポートをプログラムで行えないかと考えたところ、chrome extentionを使えばできるやん!と思い立ったが、2時間くらい動かせなかったのでその時の備忘録。
内容は全く触れず、躓いたところとその対処法だけ書くので今回は短め。
Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist.
これ。
このエラーに2時間位悩まされた。
やったこととしては、
- 他の友人が書いていたextentionのソースをコピって来て、
- 動作することを確認
- 適当にhello, worldレベルのコードを追加して
- 拡張機能のページからリフレッシュ
- 何故か動かない
の5ステップ。明らかに動作に影響を与えない部分を変更しているのに、なぜかこのエラーが出て動かなくなってしまう。
解決法
動作させるページをリフレッシュしましょう!!!!
これだけでした。。。
更新ボタンを押しただけでは拡張機能の更新歯科行われず、使っているページヘの連携部分(イベントリスナーとか)はそのページをリフレッシュしないと動かないので注意。
また出た
いざ、目的のサイトに移動して動作確認…!と思ったら、また同じエラーが出た。
どうやら、manifest.jsonで許可していないページで使おうとしても同じエラーを吐くようだ。
コードのコピペで動かそうって考えてると簡単なエラーにも多大な時間がかかってしまうので、用法用量を守って適度にコピペしよう!
GoでREST APIサーバーを作ったときの備忘録
概要
Golangなんもわからない状態からREST APIを提供できるようになったので、その時の備忘録
TL; DR
github.com/julienschmidt/httprouter
を使えば簡単に作成できる
net/http
とは違い、ハンドラにわたす引数が1つ多いのでそこだけ注意
encoding/json
を組み合わせてJSONレスポンスまで作れたよ
完成物
本来は複数ファイルに分かれているけど、わかりやすさのためにまとめた
package main import ( "encoding/json" "fmt" "log" "net/http" "github.com/julienschmidt/httprouter" ) // ------------------ レスポンス作成/レンダー部分 ---------------------- type StatusCode int // レスポンス形式 resultの中に返したいものが含まれる // interface{} はどんな型でも受け付けるくん type Response struct { Status StatusCode `json:"status"` Result interface{} `json:"result"` } // 結果にステータスコードをつけ、JSON化する // []byteはjson.Marshalの返り値 func CreateJSON (data interface{}, status StatusCode) []byte { response := Response{status, data} res, err := json.Marshal(response) if err != nil { log.Panic(err) } return res } // 200のときはステータスコードを省略できる func RenderJSONOK(w *http.ResponseWriter, data interface{}) { RenderJSON(w, data, http.StatusOK) } // レスポンスの原型を受け取り、JSON形式で返す func RenderJSON(w *http.ResponseWriter, data interface{}, status StatusCode) { res := CreateJSON(data, status) (*w).Header().Set("Content-Type", "application/json") (*w.)WriteHeader(status) (*w).Write(res) } // --------------------------------------------------------------------- // ------------------------ APIメソッド部分 ---------------------------- func GetMessageList(w http.ResponseWriter, req *http.Request, _ httprouter.Params) { RenderJSONOK(&w, "Call GetMessageList!") // -> { "status": 200, "result": "Call GetMessageList!" } } func PostMessage(w http.ResponseWriter, req *http.Request, _ httprouter.Params) { RenderJSON(&w, "coming soon", http.StatusNotFound) // -> { "status": 404, "result": "comming soon" } } func GetMessageById(w http.ResponseWriter, req *http.Request, _ httprouter.Params) { RenderJSON(&w, "coming soon", http.StatusNotFound) // -> { "status": 404, "result": "comming soon" } } // ------------------------------------------------------------------- // -------------------- ルーティング登録部分 -------------------------- // ルーティング登録を切り出して見やすくしたつもり func Registration(router *httprouter.Router) { router.GET("/message", GetMessageList) router.POST("/message", PostMessage) router.GET("/message/:id", GetMessageById) } func main() { router := httprouter.New() Registration(router) err := http.ListenAndServe(":8080", router) if err != nil { log.Panic(err) } else { fmt.Println("something wrong") } }
解説
httprouterを使う
net/http
だけでも、メソッドごとに分割して作れなくも無いっぽいが
func Test(w http.ResponseWriter, r *http.Request) { // メソッドチェック switch (r.Method) { case: http.MethodGet: // GET処理 case: http.MethodPost // POST処理 } } func Registration() { http.HandleFunc("/", Test) // GET, POST, PUT }
このように記述することになる。 個人的には、Registrationの中で一発でメソッドを管理できないなど可読性が悪く感じるのでなし。
そこで、調べていたところ、12kスターが付いている github.com/julienschmidt/httprouter
を見つけた。
これを使うと、完成コードのように、
func TestGet(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { // GET処理 } func TestPost(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { // POST処理 } func Registration(router *httprouter.Router) { router.GET("/", TestGet) router.POST("/", TestPost) }
と、メソッドごとに処理を分けて記述することができる。
しかし、httprouterの基本機能として、Paramsが渡ってくる場所が別にあるため、これを受け取れるようにする必要がある。
ここまでで、自由にREST APIを作れるようになった。 ここからは、APIのレスポンスでおなじみのJSONを返すように少してを加える。
encoding/jsonを使う
encoding/json
は標準で搭載されている。
構造体に一手間加えると、JSONを返せるようになる便利パッケージ。
使い方は以下の通り
// `json:""` を忘れると、Hoge, Fugaなど1文字目が大文字になる(属性名そのままになる)ので注意 type Response struct { Hoge int `json:"hoge"` Fuga string `json:"fuga"` } func CreateJSON () []byte { response := Response{123, "abc"} json, err := json.Marshal(response) if err != nil { panic(err) } return json // {"hoge": 123, "fuga": "abc"} }
これで手軽にJSON形式を生成できるので、これをhttpレスポンスにのせて上げればもう完成。 それで、あちこち関数化などをして出来上がったのが上のコード。
まとめ
便利パッケージがある! 名前わかりにくすぎる! リファレンスちゃんと読まないと型が特定できないからドキュメントなどはちゃんと見よう!
参考にしたところ
へたへたQMA
アニメ・ゲーム
週間少年ジャンプに連載された、河下水希の漫画は?
河下水希の漫画作品。アニメ化もしていて単行本は全19巻と長め。 2002-2005年連載だったが、特別編が2017年に連載された。
どろどろした金融の世界を描いた青木雄二の漫画は?
青木雄二の漫画作品。TVドラマ化がされていたり、作者の没後に続編が2シリーズ連載されていたりした。(現在も心ナニワ金融道Rが連載中っぽい)
孤島で奮闘する外科医を主人公とする山田貴敏(やまだ たかとし)の漫画は?
主人公五島健助が離島の診療所に赴任し、島の患者を助けるお話
乗り込んで操縦するタイプの巨大ロボは?
マジンガーZは主人公兜甲児が乗って操縦、ガンダムは色々な人が乗って操縦する。 鉄人28号は小型操縦機(リモコン)を用いて操縦する
ALI PROJECTが歌った落第騎士の英雄譚のED曲は?
→波羅蜜蓮華
去年結成35周年とのこと、おめでとうございます 「ダークなロック・官能ゴシック・妖しいロリータ・極上バラード・きらびやかでキュートなポップスから大和ロック・現代音楽」うーんわからん
女性主人公アニメは?
→七つの海のティコ / ロミオの青い空, あらいぐまラスカル
ティコはシャチ。主人公はナナミ ラスカルはアライグマ。主人公はスターリング・ノース ロミオはロミオ
バッタに乗って旅をしている小さなガンマンは?
→アリンコキッド
芸能
林真理子の小説を原作とする2018年に放送された、NHK帯がドラマは?
→西郷どん
林真理子の小説「西郷どん!」を原作に、明治維新150周年として企画された2018年の大河ドラマ。主演は鈴木亮平さん。(わからん)
ベトナム戦争を描いた映画「プラトーン」の監督はオリヴァー・ストーンですが、「地獄の黙示録」は?
アメリカの映画監督。娘(ソフィア)も息子(ロマン)も映画監督やってる。 甥にニコラス・ケイジってめっちゃ映画界の覇権みたいな人っぽい
ナチュラリスト・畑正憲(はた まさのり)の愛称は?
→ムツゴロウさん
プロ雀士らしい… ナチュラリストは自然主義者のこと。 東大出身。すごい。
ハンパねぇのツッコミでおなじみ、藤田憲右と大村朋宏からなるお笑いグループは?
NSC3期生、同期は山田ルイ53世やAMEMIYAなど。
理系
「綿毛」が飛んでいくことで種を増やす、キク科の黄色い花は?
→たんぽぽ(o) よく見るのはセイヨウタンポポらしい。
コンピュータの画面上に現れるファイルの内容を絵で表した絵文字のことをなんという?
→アイコン
わかりにくい!!!
LPガスの主成分となっているC3H8
→プロパン
恒河沙は何川の砂という意味?
欠乏すると鳥目の原因となるビタミンは?
→ビタミンA
鳥目とは、夜になると視力が衰える病気。 他の症状と合わせてビタミンA欠乏症と呼ぶことも。(主に目の疲れが発生する)
文系
ペルシア戦争はいつから始まった?
→BC499~
芸術家の出身国は?
Arcaeaのポテンシャル管理シート作った
この記事は?
趣味でArcaeaやっている人がArcaea Wikiの情報を参考にポテンシャル管理シートを作ったから良ければ使ってみてねという紹介記事です。
余計な機能がほぼほぼないので、シンプルさを求めている人にはぴったりかもしれません。
また、スプレッドシートなのである程度自由にカスタマイズができると思います。お好みのスタイルにして使ってみてください!
ポテンシャル管理シートはこちら
https://docs.google.com/spreadsheets/d/1uK-NyVwGIJJ3TcW3jyMEjoal9sLhCnu5VOtOnaDVd28/copy#gid=0
↑のリンクをクリックすると、「コピーを作成」と出るので、そこをクリックすると自分のシートが作成されます。
黒枠内に曲名とスコアを入力すると現在のベスト枠を表示してくれます。
また、現在のポテンシャルを入力すると、リーセント枠の推定値を見ることができるので、今自分がポテンシャルを盛っているのかがひと目で分かります。
書き方がわからない場合は自分の記入例をサンプルシートに載せているので、そちらを参考にするか、コメントで質問してください。(自分の実力には触れないでいただけると…)
注意点
FTR, BYDのみの対応です。PST, PRSへ対応させるには譜面定数表を引っ張ってくる必要があります。 結構雑に作っているので、バグが至るところにあるかもしれません。大目にみて報告してくれるととても喜びます。
ここから下は原理の説明なので、興味がある人だけどうぞー
ご要望があれば教えていただけると追加するかも…?です!
原理は?
Arcaea Wiki様のポテンシャル研究所を参考に(というかコピペ)式と譜面定数を埋めました。
入力規則で曲名バリデーションしており、該当する曲を入れるとそれに対応した譜面定数を勝手に呼び出し、スコアから曲別ポテンシャルを計算する式を埋め込んでいます。
また、入力値を降順で並び替え、ベスト枠をひと目で確認できるように、ベスト枠と現在レートから逆算してリーセント枠を算出できるようにしてあります。
こいつまたSSHの鍵生成からGitHubに登録するまでの流れ忘れてるよ
はじめに
コマンドラインだけでマイクラのMODサーバーを立てるっていう記事を書いていたけどバックアップデータが飛んで立ち直れなくなったので備忘録書きます
ゴール
sshの鍵ペアを作れるようになる 公開鍵をGitHubに登録して、ユーザー名やパスワードを入れずにリポジトリ操作ができるようになる
手順
1. ssh-keygen
で鍵ペアを作る
$ ssh-keygen -t rsa -b 4096 -C "email@example.com" Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. The key fingerprint is: xxxxxxxxxxxxxxxxxxxxxxxxxxxxx The key's randomart image is: xxxxxxxxxxxxxxx
キーの保存場所と、使用する際にパスフレーズを要求するか否かを聞かれるので、適切なキーの場所(基本的にはデフォルトでいいはず)と適切なパスワード(なしでEnterでもOK)を入力する。
2. 公開鍵をGitHubに登録する
GitHubのSetting -> SSH and GPG keysにアクセスして、右上のNew SSH keyを押し、公開鍵を貼り付ければ終わり!