Added comments and summaries to DialogFrag.java, SignApk.java and WriteApk.java

This commit is contained in:
Chris 2019-11-12 18:48:26 -05:00
parent a2b9823bbf
commit ab6c021c1c
3 changed files with 95 additions and 6 deletions

View File

@ -16,34 +16,63 @@ import android.widget.TextView;
import java.util.Random; import java.util.Random;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
/**
* The dialog that is shown in different situations
*/
public class DialogFrag extends DialogFragment { public class DialogFrag extends DialogFragment {
//The alert dialog
public static AlertDialog mAlertDialog; public static AlertDialog mAlertDialog;
//Progress bar that is used... to show progress.
private static ProgressBar mProgressBar; private static ProgressBar mProgressBar;
//Text view used to show the install message
private static TextView mTextView; private static TextView mTextView;
/**
* Empty Constructor
* Do I even need this?
*/
public DialogFrag() public DialogFrag()
{ {
} }
/**
* Shows the required dialog
* @param context = The activities context
* @param message = The message to show
* @param tag = Which dialog to show (Install or Can't find the app)
*/
public static void showDialog(Context context, int message, int tag) public static void showDialog(Context context, int message, int tag)
{ {
//Build the dialog
AlertDialog.Builder builder = new AlertDialog.Builder(context); AlertDialog.Builder builder = new AlertDialog.Builder(context);
//Two different cases to show two different dialogs
switch(tag) switch(tag)
{ {
case 0: case 0:
//Dialog for showing the install progress
//Create the layout inflater and inflate it
LayoutInflater mLayoutInflater = LayoutInflater.from(context); LayoutInflater mLayoutInflater = LayoutInflater.from(context);
View dialogView = mLayoutInflater.inflate(R.layout.progress_bar_dialog, null); View dialogView = mLayoutInflater.inflate(R.layout.progress_bar_dialog, null);
//Set the view, message and is cancelable
builder.setView(dialogView); builder.setView(dialogView);
builder.setMessage(message); builder.setMessage(message);
builder.setCancelable(false); builder.setCancelable(false);
//Create the dialog and show it
mAlertDialog = builder.create(); mAlertDialog = builder.create();
mAlertDialog.show(); mAlertDialog.show();
//Set the progress bar and install text
mProgressBar = dialogView.findViewById(R.id.progressBar); mProgressBar = dialogView.findViewById(R.id.progressBar);
mTextView = dialogView.findViewById(R.id.install_message); mTextView = dialogView.findViewById(R.id.install_message);
break; break;
case 1: case 1:
//Dialog for not finding the app on the device
builder.setMessage(message); builder.setMessage(message);
builder.setPositiveButton("Okay", null); builder.setPositiveButton("Okay", null);
builder.show(); builder.show();
@ -51,18 +80,31 @@ public class DialogFrag extends DialogFragment {
} }
} }
/**
* Updates the progress bar
* @param progress = The progress measured in an int
* @param message = The fun little message to show
*/
public static void updateProgressBar(int progress, int message) public static void updateProgressBar(int progress, int message)
{ {
mProgressBar.setProgress(progress); mProgressBar.setProgress(progress);
mTextView.setText(message); mTextView.setText(message);
} }
/**
* Dismisses the dialog
*/
public static void dismissDialog() public static void dismissDialog()
{ {
if (mAlertDialog.isShowing()) if (mAlertDialog.isShowing())
mAlertDialog.dismiss(); mAlertDialog.dismiss();
} }
/**
* This is never used. Not sure why it's still here
* @param context = The activities context
* @param message = The message to show
*/
public static void dismissDialogString(Context context, String message) public static void dismissDialogString(Context context, String message)
{ {
if(mAlertDialog.isShowing()) if(mAlertDialog.isShowing())

View File

@ -13,29 +13,44 @@ import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey; import java.security.PrivateKey;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
/**
* Allows the new APK to be signed using JAR signing
*/
public class SignApk { public class SignApk {
//TAG used for
private static final String TAG = "SignApk"; private static final String TAG = "SignApk";
//Path of the keystore
private static final String KEYSTORE_LOCATION = Environment.getExternalStorageDirectory() + "/SMAPI Installer/ApkFiles/debug.keystore"; private static final String KEYSTORE_LOCATION = Environment.getExternalStorageDirectory() + "/SMAPI Installer/ApkFiles/debug.keystore";
//The password for the keystore
private static final String KEYSTORE_PASSWORD = "android"; private static final String KEYSTORE_PASSWORD = "android";
//Empty Constructor
public SignApk() public SignApk()
{ {
} }
/**
* Attempt tp sign the APK using ZIP Signer
*/
public void commitSignApk() public void commitSignApk()
{ {
try { try {
//Input APK and Output APK
String inputFile = Environment.getExternalStorageDirectory() + "/SMAPI Installer/" + ApkExtractor.sourceApkFilename + "_patched.apk"; String inputFile = Environment.getExternalStorageDirectory() + "/SMAPI Installer/" + ApkExtractor.sourceApkFilename + "_patched.apk";
String outputFile = Environment.getExternalStorageDirectory() + "/SMAPI Installer/base_signed.apk"; String outputFile = Environment.getExternalStorageDirectory() + "/SMAPI Installer/base_signed.apk";
//Set the keystore and alias
KeyStore keyStore = KeyStoreFileManager.loadKeyStore(KEYSTORE_LOCATION,KEYSTORE_PASSWORD.toCharArray()); KeyStore keyStore = KeyStoreFileManager.loadKeyStore(KEYSTORE_LOCATION,KEYSTORE_PASSWORD.toCharArray());
String alias = keyStore.aliases().nextElement(); String alias = keyStore.aliases().nextElement();
//get the Cert from the keystore
X509Certificate publicKey = (X509Certificate) keyStore.getCertificate(alias); X509Certificate publicKey = (X509Certificate) keyStore.getCertificate(alias);
try try
{ {
//Grab the private key and then use ZipSigner to sign the apk
PrivateKey privateKey = (PrivateKey) keyStore.getKey(alias, KEYSTORE_PASSWORD.toCharArray()); PrivateKey privateKey = (PrivateKey) keyStore.getKey(alias, KEYSTORE_PASSWORD.toCharArray());
ZipSigner.signZip(publicKey, privateKey, "SHA1withRSA", inputFile, outputFile); ZipSigner.signZip(publicKey, privateKey, "SHA1withRSA", inputFile, outputFile);
} }

View File

@ -1,6 +1,5 @@
package com.MartyrPher.smapiandroidinstaller; package com.MartyrPher.smapiandroidinstaller;
import android.nfc.Tag;
import android.util.Log; import android.util.Log;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
@ -14,9 +13,12 @@ import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream; import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream; import java.util.zip.ZipOutputStream;
/**
* Writes files to the APK
*/
public class WriteApk { public class WriteApk {
//TAG used for debug purposes
private static final String TAG = "WriteApk"; private static final String TAG = "WriteApk";
//Blank Constructor //Blank Constructor
@ -24,19 +26,28 @@ public class WriteApk {
{ {
} }
/**
* Adds the files to the APK
* @param source = The file source
* @param files = The file array to add to the APK
* @param path = The paths where the files need to go in the APK
* @param compression = Whether the file needs to be compressed inside the APK
*/
public void addFilesToApk(File source, File[] files, String[] path, boolean[] compression){ public void addFilesToApk(File source, File[] files, String[] path, boolean[] compression){
try try
{ {
byte[] buffer = new byte[4096]; //Hmmmmmmmmm
byte[] buffer = new byte[2048];
//Create new Input and Output stream
ZipInputStream zin = new ZipInputStream(new FileInputStream(source)); ZipInputStream zin = new ZipInputStream(new FileInputStream(source));
ZipOutputStream out = new ZipOutputStream(new FileOutputStream( source + "_patched.apk")); ZipOutputStream out = new ZipOutputStream(new FileOutputStream( source + "_patched.apk"));
//Create new CRC32
CRC32 crc = new CRC32(); CRC32 crc = new CRC32();
for(int i = 0; i < files.length; i++) for(int i = 0; i < files.length; i++)
{ {
if (!compression[i]) if (!compression[i])
{ {
int bytesRead; int bytesRead;
@ -51,6 +62,7 @@ public class WriteApk {
InputStream in = new FileInputStream(files[i]); InputStream in = new FileInputStream(files[i]);
ZipEntry compress = new ZipEntry(path[i] + files[i].getName()); ZipEntry compress = new ZipEntry(path[i] + files[i].getName());
//If the file doesn't need to be compressed then STORE them
if (!compression[i]) if (!compression[i])
{ {
compress.setMethod(ZipEntry.STORED); compress.setMethod(ZipEntry.STORED);
@ -66,10 +78,13 @@ public class WriteApk {
out.closeEntry(); out.closeEntry();
in.close(); in.close();
} }
for(ZipEntry ze = zin.getNextEntry(); ze != null; ze = zin.getNextEntry()){ for(ZipEntry ze = zin.getNextEntry(); ze != null; ze = zin.getNextEntry()){
if(!apkEntryMatch(ze.getName(), files, path)){ if(!apkEntryMatch(ze.getName(), files, path)){
ZipEntry loc_ze = new ZipEntry(ze.getName()); ZipEntry loc_ze = new ZipEntry(ze.getName());
loc_ze.setMethod(ZipEntry.DEFLATED); loc_ze.setMethod(ZipEntry.DEFLATED);
//STORE these type of files {Assemblies, resources and typemap}
if (loc_ze.getName().contains("assemblies") || loc_ze.getName().contains("resources.arsc") || loc_ze.getName().contains("typemap")) if (loc_ze.getName().contains("assemblies") || loc_ze.getName().contains("resources.arsc") || loc_ze.getName().contains("typemap"))
{ {
loc_ze.setMethod(ZipEntry.STORED); loc_ze.setMethod(ZipEntry.STORED);
@ -77,15 +92,19 @@ public class WriteApk {
loc_ze.setCompressedSize(ze.getCompressedSize()); loc_ze.setCompressedSize(ze.getCompressedSize());
loc_ze.setCrc(ze.getCrc()); loc_ze.setCrc(ze.getCrc());
} }
out.putNextEntry(loc_ze); out.putNextEntry(loc_ze);
ZipFile zipFile = new ZipFile(source); ZipFile zipFile = new ZipFile(source);
InputStream stream = zipFile.getInputStream(ze); InputStream stream = zipFile.getInputStream(ze);
for(int read = stream.read(buffer); read > -1; read = stream.read(buffer)){ for(int read = stream.read(buffer); read > -1; read = stream.read(buffer)){
out.write(buffer, 0, read); out.write(buffer, 0, read);
} }
out.closeEntry(); out.closeEntry();
} }
} }
//Close everything and delete the source file
out.close(); out.close();
zin.close(); zin.close();
source.delete(); source.delete();
@ -95,6 +114,19 @@ public class WriteApk {
} }
} }
/***********************************************************************************
| Check if the current entry matches a file that needs to be placed in the APK
| zeName = The ZipEntry Name
| files = The files that are being checked
| path = The path that is being checked
***********************************************************************************/
/**
* Check if the current entry matches a file that needs to be placed in the APK
* @param zeName = The ZipEntry Name
* @param files = The files that are being checked
* @param path = The path that is being checked
* @return true is the entry matches the file in the APK
*/
private boolean apkEntryMatch(String zeName, File[] files, String[] path){ private boolean apkEntryMatch(String zeName, File[] files, String[] path){
for(int i = 0; i < files.length; i++){ for(int i = 0; i < files.length; i++){
if((path[i] + files[i].getName()).equals(zeName)){ if((path[i] + files[i].getName()).equals(zeName)){