1. ホーム
  2. android

[解決済み] INSTALL_PACKAGES 権限でアプリをサイレントにインストールする。

2023-02-18 11:05:44

質問

apkをシステムにサイレントインストールしようとしています。 私のアプリは /system/app にあり、許可 "android.permission.INSTALL_PACKAGES" が正常に付与されています。

しかし、この権限を使用する方法をどこにも見つけることができません。私はファイルを /data/app にコピーしようとしましたが、成功しませんでした。また、私は次のコードを使用してみました。

    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setDataAndType(
            Uri.parse("file:///sdcard/app.apk"),
            "application/vnd.android.package-archive");
    startActivity(intent);

しかし、このコードでは標準のインストールダイアログが開きます。どうすれば root 権限なしでアプリを静かにインストールできますか? android.permission.INSTALL_PACKAGES ?

PS 初回起動時にフォルダから多くのapkをシステムにインストールするアプリを書いています(セットアップウィザードの代わり)。ファームウェアを軽くするために必要なんです。

もし、私がウィルスを書いていると思うなら。すべてのプログラムは、/data/app にインストールされます。Install_packages 権限は、/system/app にあるシステムレベルのプログラムか、システムキーで署名されたものにのみ与えられます。ですから、ウイルスはそこに到達することはできません。

というように http://www.mail-archive.com/[email protected]/msg06281.html アプリは、install_packages パーミッションがあればサイレント インストールできます。さらに、サイレントでないパッケージをインストールするために Install_packages 権限は必要ありません。さらに http://www.androidzoom.com/android_applications/tools/silent-installer_wgqi.html

どのように解決するのですか?

最初の方法は、Android のネイティブの パッケージ インストーラー . そのアプリを好きなように変更するか、必要な機能だけを抽出することをお勧めします。


具体的には パッケージインストーラアクティビティ とそのメソッド onClickListener :

 public void onClick(View v) {
    if(v == mOk) {
        // Start subactivity to actually install the application
        Intent newIntent = new Intent();
        ...
        newIntent.setClass(this, InstallAppProgress.class);
        ...
        startActivity(newIntent);
        finish();
    } else if(v == mCancel) {
        // Cancel and finish
        finish();
    }
}

すると、実際のインストーラが InstallAppProgress クラスにあります。そのクラスを調べると initView がインストーラのコア関数で、これが最後に行うのは PackageManager 's installPackage という関数があります。

public void initView() {
...
pm.installPackage(mPackageURI, observer, installFlags, installerPackageName);
}

次のステップでは パッケージマネージャ を調べることです。これは抽象クラスです。これは抽象クラスです。 installPackage(...) 関数があります。悪いことに、これは @hide でマークされています。これは、直接利用できないことを意味します(このメソッドを呼び出してコンパイルすることはできません)。

 /**
  * @hide
  * ....
  */
  public abstract void installPackage(Uri packageURI,
             IPackageInstallObserver observer, 
             int flags,String installerPackageName); 

しかし、このメソッドにリフレクションでアクセスすることができるようになります。

もしあなたが、どのように PackageManager 's installPackage 関数が実装されていることを確認してください。 パッケージマネージャサービス .

概要

パッケージマネージャーオブジェクトを Context 's getPackageManager() . そして installPackage 関数をリフレクションで呼び出します。