質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.83%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Q&A

解決済

パッケージファイルをダウンロードして自分自身をバージョンアップさせたい

Momotaro
Momotaro

総合スコア1

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

1回答

0グッド

0クリップ

418閲覧

投稿2023/03/05 04:03

編集2023/03/06 08:08

実現したいこと

①FTPサーバーからパッケージファイルをダウンロードする
②それを起動させて自アプリ自身をバージョンアップする

前提

Javaで業務用アプリを作っています。
対象環境は Android 10.0 (API 29) のみです。
現時点ではエミュレータでのみテストしています。
FTPサーバーからパッケージファイルをダウンロードして外部ストレージに保存するところまではできています。
(Device File Explorer で該当ファイルが作成されていることを確認済みです。)

発生している問題・エラーメッセージ

ダウンロードされたファイルの情報を Intent に渡して開きたいのですが、エラーも出ずインストーラも立ち上がらず、という状況です。

Android 6.0 (API 23) 向けに作成していた以前のバージョンでは、もう少し簡易的な方法でうまく動いていました。
現在 Android 10.0 (API 29) 向けに改修中です。

問題の箇所ではエラーメッセージは出ないのですが、アプリ起動時に下記のメッセージが出力されます。関係あるでしょうか。
Unknown bits set in runtime_flags: 0x8000

原因や対処法などご教授いただければと思っております。

該当のソースコード

●AndroidManifest.xml(一部抜粋)

XML

1<?xml version="1.0" encoding="utf-8"?> 2<manifest xmlns:android="http://schemas.android.com/apk/res/android" 3 package="my.application"> 4 5 <uses-permission android:name="android.permission.INTERNET" /> 6 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 7 8 <application 9 android:requestLegacyExternalStorage="true"> 10 11 <!--中略--> 12 13 <provider 14 android:name="androidx.core.content.FileProvider" 15 android:authorities="${applicationId}.fileprovider" 16 android:grantUriPermissions="true" 17 android:exported="false"> 18 <meta-data 19 android:name="android.support.FILE_PROVIDER_PATHS" 20 android:resource="@xml/provider_paths" /> 21 </provider> 22 </application> 23 24</manifest>

●xml/provider_paths.xml

XML

1<?xml version="1.0" encoding="utf-8"?> 2<paths> 3 <external-files-path 4 name="externalFilesRoot" 5 path="./" /> 6</paths>

●ActivityMain.java(一部抜粋)

Java

1 // FTPサーバーからパッケージファイルを外部ストレージにダウンロード 2 // ftpClient:接続済みのFTPClient 3 File localApkFile = new File(getExternalFilesDir(""), "my_application.apk"); 4 FileOutputStream fos = new FileOutputStream(localApkFile, false); 5 ftpClient.retrieveFile(serverApkFileName, fos); 6 7 // 中略 8 9 // パッケージファイルを開く 10 Intent intent = new Intent(Intent.ACTION_VIEW); 11 Uri uri = FileProvider.getUriForFile(getApplicationContext(), BuildConfig.APPLICATION_ID + ".fileprovider", localApkFile); 12 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 13 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 14 intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 15 intent.setDataAndType(uri, "application/vnd.android.package-archive"); 16 startActivity(intent);

試したこと

FTPサーバーからのダウンロード先(localApkFile.getPath())をログ出力したところ、下記のようになっていました。
/storage/emulated/0/Android/data/[パッケージ名]/files/my_application.apk
これは想定通りの動きで、実際に動かす度に上記と下記にパッケージファイルが作成されます。
/sdcard/Android/data/[パッケージ名]/files/my_application.apk

Intent に渡している Uri の内容をログ出力したところ、下記のようになっていました。
content://[パッケージ名].fileprovider/externalFilesRoot/my_application.apk

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

回答1

0

自己解決

ベストな形ではなさそうですが、やりたいことは一応できたので書いておきます。

●AndroidManifest.xml(一部抜粋)

XML

1<?xml version="1.0" encoding="utf-8"?> 2<manifest xmlns:android="http://schemas.android.com/apk/res/android" 3 package="my.application"> 4 5 <uses-permission android:name="android.permission.INTERNET" /> 6<!-- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />--> 7 <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" /> 8 9 <application 10 11 <!--中略--> 12 13 <provider 14 android:name="androidx.core.content.FileProvider" 15 android:authorities="${applicationId}.fileprovider" 16 android:grantUriPermissions="true" 17 android:exported="false"> 18 <meta-data 19 android:name="android.support.FILE_PROVIDER_PATHS" 20 android:resource="@xml/provider_paths" /> 21 </provider> 22 </application> 23 24</manifest>

「REQUEST_INSTALL_PACKAGES」のパーミッションを追加しました。
また「WRITE_EXTERNAL_STORAGE」は不要だったので削除しました。
application タグに記載していた「android:requestLegacyExternalStorage="true"」も削除しました。

●xml/provider_paths.xml

XML

1<?xml version="1.0" encoding="utf-8"?> 2<paths> 3 <external-cache-path 4 name="externalCacheRoot" 5 path="./" /> 6</paths>

APK ファイルの保存先をキャッシュ領域に変更しましたが、問題の改善とは関係ありません。
一時的に必要なファイルなのでキャッシュの方が適切かなと思い変更しました。

●ActivityMain.java(一部抜粋)

Java

1 // FTPサーバーからパッケージファイルを外部ストレージにダウンロード 2 // ftpClient:接続済みのFTPClient 3 File localApkFile = new File(getExternalCacheDir(), "my_application.apk"); 4 FileOutputStream fos = new FileOutputStream(localApkFile, false); 5 ftpClient.retrieveFile(serverApkFileName, fos); 6 7 // 中略 8 9 // パッケージファイルを開く 10 Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE); 11 Uri uri = FileProvider.getUriForFile(getApplicationContext(), BuildConfig.APPLICATION_ID + ".fileprovider", localApkFile); 12 intent.setDataAndType(uri, getContentResolver().getType(uri)); 13 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 14 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 15 startActivity(intent);

APKファイルの保存先を「getExternalCacheDir()」に変更しましたが、これも先述の通り問題の改善とは関係ありません。
Intent のアクションを「ACTION_INSTALL_PACKAGE」に変更しました。これが非推奨なのでベストではない理由のひとつです。
Intent にセットする type を「getContentResolver().getType(uri)」で取得するようにしましたが結果は変わっていません。
「FLAG_GRANT_WRITE_URI_PERMISSION」は不要だったので削除しました。

なおこれを実機でテストしたところ、更新しようとしたタイミングで Play プロテクトによる警告が表示され、それでもインストールすると今度は Play プロテクトに送信してスキャンを促すメッセージが表示されます。これもベストではない理由です。試しに送信してみたので、万が一有害と判断されたらまたそのときに検討することにします。

PackageInstaller を使うやり方もあるようなのですが私の力が及ばず、ひとまずこれで解決とさせていただきます。

投稿2023/03/09 09:49

Momotaro

総合スコア1

下記のような回答は推奨されていません。

  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.83%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。