當初為了達到自動安裝APK,而不會跳出任何訊息,且又不能使用非法的API或Java Reflection。
研究超久,試了網路上好多人的做法,一直無法成功,直到以下的方法才有效達到我想要的效果。
由於是很久以前試出來的,我也忘記出處在哪了,為了預防哪天我寫的的測試程式不小心被我清掉。因此在這裡備份一下程式碼。
private void autoInstall(Context context) { String apkfile = context.getFilesDir() + "/MyTest.apk"; String ACTION_INSTALL_COMPLETE = "cm.android.intent.action.INSTALL_COMPLETE"; try { PackageInstaller pi = context.getPackageManager().getPackageInstaller(); //給定模式,創建新的參數,創建新安裝會話,返回唯一 Id int sessionId= pi.createSession(new PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL)); //打開現有會話,主動執行工作 PackageInstaller.Session session = pi.openSession(sessionId); long sizeBytes = 0; final File file = new File(apkfile); if (file.isFile()) { sizeBytes = file.length(); } InputStream in = null; OutputStream out = null; in = new FileInputStream(apkfile); //打開一個流,將一個APK文件寫入會話 //指定有效長度系統將預先分配底層磁盤空間以優化磁盤上的放置 out = session.openWrite("app_store_session", 0, sizeBytes); int total = 0; byte[] buffer = new byte[65536]; int len; while ((len= in.read(buffer)) != -1) { total += len; out.write(buffer, 0, len); } //根據需要調用,用來確保字節已保留到磁盤 session.fsync(out); in.close(); out.close(); Log.d(TAG,"InstallApkViaPackageInstaller - Success: streamed apk " + total + " bytes"); PendingIntent broadCastTest = PendingIntent.getBroadcast( context, sessionId, new Intent(ACTION_INSTALL_COMPLETE), PendingIntent.FLAG_UPDATE_CURRENT); //提交之前必須關閉所有流 session.commit(broadCastTest.getIntentSender()); session.close(); } catch (Exception ex) { ex.printStackTrace(); } }
由於apk須放置在你執行的APP下,因此要在執行的app建立assets,複製到/data/data/< package name >/files/…
做法如下;
private void copyAssets(Context context) { Log.d(TAG, "Do copyAssets"); AssetManager assetManager = context.getAssets(); String[] files = null; try { files = assetManager.list(""); } catch (IOException e) { Log.e(TAG, "Failed to get asset file list.", e); } if (files != null) for (String filename : files) { InputStream in = null; OutputStream out = null; try { Log.d(TAG, "Copy " + filename + "......"); in = assetManager.open(filename); //File outFile = new File(context.getExternalFilesDir(null), filename); //File outFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/", filename); File outFile = new File(context.getFilesDir(), filename); Log.d(TAG, "outFile:" + outFile); out = new FileOutputStream(outFile); copyFile(in, out); } catch(IOException e) { Log.e(TAG, "Failed to copy asset file: " + filename, e); } finally { if (in != null) { try { in.close(); } catch (IOException e) { // NOOP } } if (out != null) { try { out.close(); } catch (IOException e) { // NOOP } } } } Log.d(TAG, "Finished copyAssets"); } private void copyFile(InputStream in, OutputStream out) throws IOException { byte[] buffer = new byte[1024]; int read; while((read = in.read(buffer)) != -1){ out.write(buffer, 0, read); } }
Place your comment