AndroidはコードによってAPKをインストールする方法を詳しく説明します。


APK開発では、Javaコードを通じてシステムのインストールプログラムを開いてAPKをインストールすることはそれほど難しくないです。一般的なAndroidシステムは開放されています。
  • しかし、Androidシステムのバージョンの反復に従って、権限に対するコントロールがますます厳しくなっています。これは、以前は簡単なコードで実現できる機能をもたらしています。今は複雑です。
  • は、コードオンシステムによってプログラムをインストールする機能に対する制限であり、その分岐はAndroid 7.0、すなわちAndroid Nにある。通常はAndroid N以上のシステムで一つのやり方を使いますが、以下はもう一つのやり方を使います。
  • 従来のコードによってAPKをインストールする方式
  • 
    File apk = new File(...);
    	Uri uri = Uri.fromFile(apk);
    	Intent intent = new Intent();
    	intent.setClassName("com.android.packageinstaller", "com.android.packageinstaller.PackageInstallerActivity");
    	intent.setData(uri);
    	intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    	startActivity(intent);
    この方法は簡単で乱暴で実用的です。インストールするAPKの位置を知っていて、アクセス権限を持っていればいいです。
    しかし、現在市場で主流のAndroidの携帯電話システムのバージョンはすでに7.0より高くなりました。この方法はほとんど使われていません。
    高いバージョンのシステム上のコードでAPKをインストールする方式
    
    File apk = new File(...);
    	Intent intent = new Intent(Intent.ACTION_VIEW);
    	intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    	intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    	Uri uri = FileProvider.getUriForFile(this, "com.apk.demo.fileprovider", apk);
    	intent.setDataAndType(uri, "application/vnd.android.package-archive");
    	startActivity(intent);
     権限の問題について言えば、Androidのバージョンが増加しつつある中、システムのセキュリティもますます高くなっています。多くの権限はリストファイルに登録するだけではなく、メモリカードの読み書き権限は危険権限に属しています。コードを使って動的に追加する必要があります。ここでRxPermiisionのフレームを使いました。9.0以上のバージョンのシステムに遭遇した場合、アクセス権を得る方法は異なるかもしれません。
    
    private void rxPermission() {
      RxPermissions rxPermissions = new RxPermissions(this);
      rxPermissions.request(Manifest.permission.WRITE_EXTERNAL_STORAGE).subscribe(new Consumer<Boolean>() {
       @Override
       public void accept(Boolean granted) throws Exception {
        if (granted) {
         //    
         //            
        } else {
         //      
        }
       }
      });
     }
    Androidのより多くのパーミッションは、クエリを得ることができます:https://www.jianshu.com/p/24f79a70025b
    上のコードは伝統的な方式と大差がないように見えますか?
    確かにそうですが、本当の違いはJavaコードに現れていません。
    高いバージョンのシステムでは、APKは他のAPKのプライベートデータに直接アクセスできなくなりました。
    APKのプライベートデータは何ですか?
    APKはインストール中にdataディレクトリの下で作成された専属ディレクトリはもちろんプライベートデータです。また、アプリケーションにパッケージされたFileオブジェクトであれば、このファイル自体が当該プログラムによって作成されたものであるかどうかにかかわらず、このファイルは全て当該プログラムの「プライベートデータ」に該当する。例えば、携帯をパソコンに接続して、adb push方式でsdcardディレクトリの下にAPKファイルを押したとします。そして、私達は自分でコードを作成しました。このsdcardのインストールパッケージをシステムのPackage Installerに伝えてインストールします。いずれも安全エラーを報告します。これはsdcardディレクトリの下にあるファイルは私達のコードにとって「プライベートデータ」です。直接にPackage Installerに暴露することはできません。
    ここでは、他のプログラムに「プライベートデータ」を公開するための高いバージョンのシステムの方法を見てみましょう。
    高いバージョンでは、Android 7.0以上、プライベートデータを開放(暴露)する唯一の方法は、ContentProviderによって実現される。
    具体的な手順は大体以下の通りです。
  • は、Android Manifest.xmlのContentProvider情報を構成する。
  • オープンするパス情報を設定する。
  • は、JavaコードにおいてFileProviderによってファイル情報をカプセル化する。
  • 1、Android Manifest.xml配置
    前に述べましたが、高バージョンのシステムでは、以前の直接開放をContentProviderを通じて間接的に開放するということです。したがって、私たちはAndroid Manifest.xmlにプロviderタグを追加したいです。例は以下の通りです。
    
    <provider
     android:name="androidx.core.content.FileProvider"
     android:authorities="com.your.app.fileprovider"
     android:exported="false" 
     android:grantUriPermissions="true">
     <meta-data
      android:name="android.support.FILE_PROVIDER_PATHS"
      android:resource="@xml/file_paths" />
    </provider>
  • android:name属性はFileProvider類のフルネームです。このクラスは2つの値を記入できます。一つはsupport(android.support.v.4.content.FileProvider)の下にあります。もう一つはandrodx.co.FileProvider)の下にあります。この二つは全部記入できます。本質的には区別がありません。でも、実際の状況によって、どれを使うかを決めます。つまり、あなたの工事が引くのがアンディックス支援カバンですか?それともsupport支援カバンですか?supportとandroidxの関係については、ここでは言及しない。
  • android:authorities属性は普通のContentProviderと同じファイルリソースにアクセスするためのuriヘッダです。値の内容は実際の必要に応じて記入すればいいです。
  • android:exportdという属性は、他のアプリがこのプロバイダー
  • にアクセスできるかどうかを表しています。
  • android:grantUriPermissionsこの属性は、コンテンツプロバイダのデータセットに対して
  • を許可するために使用されます。
  • コンテンツプロバイダのgrantUriPermissions属性がtrueに設定されている場合、権限はコンテンツ提供器の範囲内の任意のデータを与えられる。しかし、grantUriPermission属性がfalseに設定されている場合、権限はこの要素によって指定されたデータセットしか与えられません。一つのコンテンツプロバイダは、任意の複数の要素を含むことができる。各パスは一つのパスしか指定できません。
  • meta-dataタグの内容に注目したいのは、android:resource属性の内容です。この属性の値は自分で設定したxmlファイルに引率されます。このxmlファイルに記載されているのは設備中の経路情報です。どのディレクトリのファイルリソースを第三者に公開したいのかを簡単に理解してください。このxmlの配置については第2歩の記載を見てください。
  • 2、パスの配置
  • は、工程resディレクトリの下にxmlディレクトリを新規作成し、xmlディレクトリの下にxmlファイルを新規作成するのが一般的です。ファイルの名前は、第1ステップの@xml/属性値の設定と一致していなければなりません。
  • は、第1ステップのコード例に従って、file_uを新規に作成する必要がある。paths.xmlファイルです。ここで私のアプリはプログラムに保存されているfileファイルに加えられています。このファイルの内容は以下の通りです。
  • 
    <?xml version="1.0" encoding="utf-8"?>
    <paths>
     <files-path path="apk/" name="apk" />
    </paths>
    他の経路の構成は、https://editor.csdn.net/md?articleId=106670247を参照してください。
    簡単に言えば、開放したいパスの種類を選んで、このタイプの相対パスを記入すればいいです。
    例をあげて詳しく話します。
    
    <?xml version="1.0" encoding="utf-8"?>
    <paths>
     <files-path path="apk/" name="apk" />
    </paths>
    これは私達がプログラムメモリの中のfilesディレクトリを開放したいということを表しています。そしてfilesディレクトリの下のサブパスは/appkです。絶対パスは/data/con.xx.xxx/files/appkです。nameタグはContentProviderのロゴとして使われていますが、一般的には必要に応じて異なる値に設定すればいいです。ここにサブディレクトリがあります。
    3、Javaコードの配置
    Javaコードの配置は特別なものではなく、直接チャプタヘッダのコードで使えばいいです。キーコードは実は一行だけです。
    Uri uri=FileProvider.get UriForFile(context、authority、file)
    ここの三つのパラメータはそれぞれです。
  • context:ここでは一つの文脈を伝えなければならないという意味です。
  • authority:Android Manifest.xmlにコードを通して
  • を得ることができます。
  • file:必要なインストールファイル
  • です。
    
    String authority = new StringBuilder(packageName).append(".provider").toString();
    //   strFile     +  ;  :/data/file/apk/xxx.apk
    File f=new File(strFile);
    Uri uri = FileProvider.getUriForFile(context, authority, file);
    通常はAndroidの高低バージョンのシステムを兼ね備えていますので、下記のような「混合型」コードを使います。
    
    public void install(){
    	try{//         ,        
    		Intent intent = new Intent(Intent.ACTION_VIEW);
    		intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    		intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
    			//  SDK  >=24, :Build.VERSION.SDK_INT >= 24
    		 String packageName = context.getApplicationContext().getPackageName();
    		 String authority = new StringBuilder(packageName).append(".provider").toString();
    		 uri = FileProvider.getUriForFile(context, authority, file);
    		 intent.setDataAndType(uri, "application/vnd.android.package-archive"); 
    		 } else{
    		 uri = Uri.fromFile(file);
    		 intent.setDataAndType(uri, "application/vnd.android.package-archive");
    		}
    		context.startActivity(intent);
    	}catch (Exception e) {
       e.printStackTrace();
     }
    }
    締め括りをつける
    ここで、Androidについて、コードを通じてAPKをインストールする方法について詳しく説明した文章を紹介します。これに関連して、Androidコードのインストールアプリの内容は以前の文章を検索してください。または、下記の関連記事を引き続きご覧ください。これからもよろしくお願いします。