項目解決方案:解壓app — 寫入檔案 — 壓縮app — jarsigner重新簽名app — 安裝app

來源:互聯網
上載者:User

標籤:android簽名apk   apk簽名   apk解壓   apk壓縮   

       記得上次在南昌中興的一個項目中遇到過一個這樣的需求:一個app可以給多個渠道商去運營,渠道商推廣出去可以獲得相應的推廣金額。那麼這種情況下就必須要使得這個app能夠唯一的標誌一個渠道商。那個時候我們在這個項目中的解決方案是:讓使用者在app中手動填入渠道商的工號,我現在想想這種方式也是醉了,真不知道那個時候專案經理是怎麼想的,竟然會給出這樣的方案。

這次的項目中又遇到了這個問題:需求是這個app能夠給多個渠道商去推廣,渠道商可以獲得推廣金額。這次我提出的解決方案是:先把打包後的app解壓,然後在assets目錄中寫入渠道商的唯一標識id,然後壓縮app,壓縮完畢重新簽名app,之後就大工告成。使用者在第一次進入app的時候,會把assets中的id讀出來,提交到伺服器,就完美的解決了這個使用者是此渠道商的推廣所獲得的使用者。

首先第一步:把app解壓,刪除META-INF檔案夾中的CERT.RSA和CERT.SF兩個檔案

第二步:讀取解壓後的assets目錄中的id.txt檔案,寫入渠道商的id

<span style="white-space:pre"></span>File file = new File("d:/app/assets/id.txt");OutputStream outputStream = new FileOutputStream(file);outputStream.write(user.getId().toString().getBytes());outputStream.flush();outputStream.close();
第三步:壓縮寫入渠道商id後的所有app檔案

<span style="white-space:pre"></span>ZipCompressor zc = new  ZipCompressor("d:/play.apk");  zc.compressExe("d:/app/");
具體的壓縮代碼如下:

package com.xyc.signSystem.utils;import java.io.BufferedInputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.util.zip.CRC32;import java.util.zip.CheckedOutputStream;import org.apache.tools.zip.ZipEntry;import org.apache.tools.zip.ZipOutputStream;/** * @ClassName: ZipCompressor * @author :andywuchuanlong   QQ:312037487 * @Description: 壓縮檔的通用工具類-採用org.apache.tools.zip.ZipOutputStream實現,較複雜。 * */public class ZipCompressor {static final int BUFFER = 8192;private File zipFile;/** * 壓縮檔建構函式 *  * @param pathName *            壓縮的檔案存放目錄 */public ZipCompressor(String pathName) {zipFile = new File(pathName);}/** * 執行壓縮操作 *  * @param srcPathName *            被壓縮的檔案/檔案夾 */public void compressExe(String srcPathName) {File file = new File(srcPathName);if (!file.exists()) {throw new RuntimeException(srcPathName + "不存在!");}try {FileOutputStream fileOutputStream = new FileOutputStream(zipFile);CheckedOutputStream cos = new CheckedOutputStream(fileOutputStream,new CRC32());ZipOutputStream out = new ZipOutputStream(cos);String basedir = "";compressByType(file, out, basedir);out.close();} catch (Exception e) {e.printStackTrace();throw new RuntimeException(e);}}/** * 判斷是目錄還是檔案,根據類型(檔案/檔案夾)執行不同的壓縮方法 *  * @param file * @param out * @param basedir */private void compressByType(File file, ZipOutputStream out, String basedir) {if (basedir.equals("play/")) {basedir = "";}/* 判斷是目錄還是檔案 */if (file.isDirectory()) {this.compressDirectory(file, out, basedir);} else {this.compressFile(file, out, basedir);}}boolean isFirst = true;/** * 壓縮一個目錄 *  * @param dir * @param out * @param basedir */private void compressDirectory(File dir, ZipOutputStream out, String basedir) {if (!dir.exists()) {return;}if (basedir.equals("play/")) {basedir = "";}File[] files = dir.listFiles();for (int i = 0; i < files.length; i++) {/* 遞迴 */compressByType(files[i], out, basedir + dir.getName() + "/");}}/** * 壓縮一個檔案 *  * @param file * @param out * @param basedir */private void compressFile(File file, ZipOutputStream out, String basedir) {if (!file.exists()) {isFirst = false;return;}if (basedir.equals("play/")) {basedir = "";}try {BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));ZipEntry entry = new ZipEntry(basedir + file.getName());out.putNextEntry(entry);int count;byte data[] = new byte[BUFFER];while ((count = bis.read(data, 0, BUFFER)) != -1) {out.write(data, 0, count);}bis.close();} catch (Exception e) {throw new RuntimeException(e);}}}

第四步:壓縮完畢之後,此時的包是沒有簽名過的,所以還需要簽名,簽名可以使用jarsigner工具,首先我們要尋找到java的安裝目錄

<span style="white-space:pre"></span>public  String getJavaPath() {String javaPath = (String) System.getenv("Path");String paths[]= javaPath.split(";");String myPath = null;for(String path:paths){if (path.contains("Java")&&!path.contains("jre")&&path.contains("bin") ){myPath = path;break;}}return myPath+"\\";}

簽名:

<span style="white-space:pre"></span>String javaPath = getJavaPath();Runtime rt = Runtime.getRuntime();String cmd = javaPath+ "jarsigner -verbose"+ " -keystore "+ keystorePath+ " -storepass player"// 密碼+ " -signedjar "+signedApkPath // 簽名後的apk存放位置+ " -digestalg SHA1  -sigalg  MD5withRSA "+ unsignedApkPath//未簽名的apk+ " player";// 別名Process child = rt.exec(cmd);

OK,簽名成功。










項目解決方案:解壓app — 寫入檔案 — 壓縮app — jarsigner重新簽名app — 安裝app

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.