Added comments and summaries to DialogFrag.java, SignApk.java and WriteApk.java
This commit is contained in:
parent
a2b9823bbf
commit
ab6c021c1c
|
@ -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())
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)){
|
||||||
|
|
Loading…
Reference in New Issue