ANTIGRAVITY LABEN
記事一覧/アプリ開発
アプリ開発/2026-07-17上級

Android 17 のローカルネットワーク権限 — LAN に触る箇所を機械で洗い出してから、エージェントに直させる

新しい API レベルではローカルネットワークへの明示的な許可が必要になります。grep では 11 経路のうち 2 つしか見つかりませんでした。経路の種類で拾う検出器と、エージェントに渡せる作業単位への畳み方を実測とともに。

Android 17権限設計3移行7エージェント63ローカルLLM20

プレミアム記事

設定画面のホストは何も変えていないのに、アプリから手元の Ollama につながらない。

そういう報告が来たとき、まず疑うのは自分の設定ミスです。IP を打ち直し、ポートを確認し、ブラウザからは普通に応答が返ってくることを見て、それでも繋がらない。ログには例外すら残っていない。ただ、レスポンスが空で返ってきているだけ。

新しい API レベルを対象にしたアプリは、ユーザーの明示的な許可なしにローカルネットワークへアクセスできなくなります。厄介なのは、この失敗が例外ではなく「何もなかったこと」として返ってくる形をとりやすい点です。探索は 0 件で成功し、ソケットはタイムアウトし、Cast の一覧は空のまま。どれも、それ単体では正常な結果と見分けがつきません。

個人開発でアプリを保守していると、この種の変更はいつも「動かなくなってから気づく」やり方で処理しがちです。私自身、Android 16 の edge-to-edge の強制でそれをやりました。今回は先に棚卸しをしておきたい、と思って手を動かした記録です。

何が変わるのか、そして何を先に決めるべきか

対象は、新しい API レベルをターゲットにしたアプリです。ローカルネットワーク(同一 LAN 上の他の端末)への通信に、明示的なユーザー許可が要るようになります。インターネット越しの通信は従来どおりで、影響を受けるのは「家庭内や社内のネットワークの中で完結する通信」だけです。

手元の環境では android.permission.LOCAL_NETWORK_ACCESS という名前で扱われています。ただし名称も挙動もプラットフォームの世代で動きうるところなので、最終的な確認は Android Developers のバージョン別リリースノート で取ってください。この記事で固定したいのは権限の名前ではなく、自分のアプリのどこが LAN に触っているかを、記憶ではなく機械で答えられる状態にすることです。

影響範囲の当たりをつけるために、まず「LAN に出る経路」を書き出しました。

経路コードに現れる形権限なしでどう見えるか
私的アドレス直打ち192.168.x.x / 172.16-31.x.x / 10.x.x.x接続タイムアウト
mDNS 名前解決ollama.local など名前が解決しない
NSD によるサービス探索NsdManager.discoverServices0 件で成功する
マルチキャスト受信createMulticastLockロックは取れるが何も届かない
Cast / MediaRouteraddCallback の能動スキャン端末一覧が空のまま
UDP ブロードキャスト255.255.255.255 宛の送信応答が来ない
設定値のホストbaseUrl を実行時に受け取るユーザーの入力次第で変わる
WebViewLAN の URL を loadUrl読み込み失敗

この表を作った時点で、気になったことがひとつありました。右の列の大半が「エラーではない」のです。0 件、空リスト、タイムアウト。どれも、ネットワークが遅いときや相手が起動していないときと同じ顔をしています。つまり、権限が下りていないことをアプリ側は知らないまま、ユーザーには「見つかりませんでした」とだけ表示し続けることになる。

grep が見つけたのは、11 経路のうち 2 つでした

棚卸しの最初の一手は、当然 grep '192.168' です。手元のアプリで実際に使っている LAN 通信の書き方を 11 種類ぶん、検証用のツリーに並べて試しました。ファイルは 11 個、経路は 11 種類、すべてに「ここが LAN に出る」という意図を持たせてあります。

$ grep -rn "192\.168" --include="*.kt" --include="*.xml" .
./app/src/main/res/xml/network_security_config.xml:3:  <domain includeSubdomains="true">192.168.0.0</domain>
./app/src/main/java/net/example/app/Defaults.kt:4:  const val OLLAMA_FALLBACK = "http://192.168.11.8:11434"

コメント行を除いて 2 件。11 経路のうち 2 つ、率にして 18% です。

範囲を広げても大きくは変わりませんでした。私的アドレスの全レンジを書いた正規表現でも 5 件どまり、45% です。

$ grep -rnE "(10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[01])\.|169\.254\.)[0-9]" \
    --include="*.kt" --include="*.xml" . | wc -l
5

残りの 6 経路には、そもそも IP が書かれていません。NsdManager で探索するコードにも、MediaRouter で Cast 端末を探すコードにも、設定画面で入れたホストを使う OkHttp のラッパにも、数字の並びは一つも出てきません。LAN に出るかどうかはコードの見た目ではなく、実行時にどこへ向かうかで決まる。grep はそこを見られない。

見つからないだけならまだ救いがあります。困るのは、grep で 2 件見つかったときに「2 箇所直せば終わり」という感触が残ることです。手元の感覚として、これはかなり危うい。数字が出てしまうと、それが全体だと思ってしまう。

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
grep '192.168' が見つけたのは 11 経路中 2 つ。mDNS・Cast・設定値ホストには IP が現れない
経路の種類で拾う検出器 lan_scan.py(確度3段階・権限未宣言なら exit 1)の全文と実測結果
「Android 17 対応して」を 11 個の確認可能なタスクに畳んで渡す lan_tasks.py
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Antigravity Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

アプリ開発2026-07-02
審査リジェクトの朝に慌てないために — App Store の指摘をエージェントで分類し、再提出までの手順を固定する
App Store 審査リジェクトの文面を Antigravity に渡して分類し、ガイドライン別プレイブックと Info.plist リントで再提出まで最短で戻す運用設計。実測の所要時間短縮も紹介します。
アプリ開発2026-06-20
複数環境でエージェント設定が静かにずれていく — 設定ドリフトの検知と是正
2台のMacと自動運用環境でエージェントの設定が少しずつ食い違い、片方だけ失敗する——その「設定ドリフト」を、ハッシュ照合と是正手順で見える化する設計を、個人開発の現場からまとめます。
アプリ開発2026-04-20
Gemma 4 で RAG パイプラインを構築する — ローカルLLMで自分だけの検索AIを作る
Gemma 4をベースにしたRAG(Retrieval-Augmented Generation)パイプラインを、ChromaDB+LangChainで構築する完全実装ガイド。ローカル実行からAPI活用まで、実際に動くコードで全工程を解説します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →