Background Task added, Dialogs Added, Latest ModdingAPI.dll added.
This commit is contained in:
parent
ac6a3b09a7
commit
d983e64f3f
Binary file not shown.
|
@ -19,13 +19,15 @@ public class ApkExtractor{
|
||||||
private static final String PACKAGE_NAME = "com.chucklefish.stardewvalley";
|
private static final String PACKAGE_NAME = "com.chucklefish.stardewvalley";
|
||||||
private static final String TAG = "ApkExtractor";
|
private static final String TAG = "ApkExtractor";
|
||||||
|
|
||||||
//Blank Constructor
|
private final Context context;
|
||||||
public ApkExtractor()
|
|
||||||
|
public ApkExtractor(Context appContext)
|
||||||
{
|
{
|
||||||
|
this.context = appContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Extracts the APK to a local directory where it can access the files
|
//Extracts the APK to a local directory where it can access the files
|
||||||
public void ExtractAPK(Context context) {
|
public boolean extractAPK(Context context) {
|
||||||
try {
|
try {
|
||||||
PackageManager packageManager = context.getPackageManager();
|
PackageManager packageManager = context.getPackageManager();
|
||||||
PackageInfo packageInfo = packageManager.getPackageInfo(PACKAGE_NAME, 0);
|
PackageInfo packageInfo = packageManager.getPackageInfo(PACKAGE_NAME, 0);
|
||||||
|
@ -48,7 +50,9 @@ public class ApkExtractor{
|
||||||
}
|
}
|
||||||
} catch (PackageManager.NameNotFoundException ex) {
|
} catch (PackageManager.NameNotFoundException ex) {
|
||||||
Log.e(TAG, ex.getLocalizedMessage());
|
Log.e(TAG, ex.getLocalizedMessage());
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void copy(File src, File dst) throws IOException {
|
private void copy(File src, File dst) throws IOException {
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
package com.MartyrPher.smapiandroidinstaller;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.os.Environment;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
public class BackgroundTask extends AsyncTask<Void, Integer, Boolean> {
|
||||||
|
|
||||||
|
private static final String TAG = "BackgroundTask";
|
||||||
|
private static final String DIR_APK_FILES = "/SMAPI Installer/ApkFiles/";
|
||||||
|
private Context contextActivity;
|
||||||
|
|
||||||
|
public BackgroundTask(Context context)
|
||||||
|
{
|
||||||
|
this.contextActivity = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPreExecute() {
|
||||||
|
super.onPreExecute();
|
||||||
|
DialogFrag.showDialog(contextActivity, R.string.modify_apk, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Boolean doInBackground(Void... voids) {
|
||||||
|
|
||||||
|
WriteApk writeApk = new WriteApk();
|
||||||
|
SignApk signApk = new SignApk();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File[] moddingAPI = {new File(Environment.getExternalStorageDirectory() + DIR_APK_FILES + "StardewModdingAPI.dll")};
|
||||||
|
publishProgress(1);
|
||||||
|
writeApk.addFilesToApk(new File(Environment.getExternalStorageDirectory() + "/SMAPI Installer/base.apk"), moddingAPI, "assemblies/", false, 0);
|
||||||
|
File[] resources = {new File(Environment.getExternalStorageDirectory() + DIR_APK_FILES + "AndroidManifest.xml"),
|
||||||
|
new File(Environment.getExternalStorageDirectory() + DIR_APK_FILES + "classes.dex")};
|
||||||
|
writeApk.addFilesToApk(new File(Environment.getExternalStorageDirectory() + "/SMAPI Installer/base.apk_patched0.apk"), resources, "", true, 1);
|
||||||
|
signApk.commitSignApk();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onProgressUpdate(Integer... values) {
|
||||||
|
super.onProgressUpdate(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(Boolean aBoolean) {
|
||||||
|
super.onPostExecute(aBoolean);
|
||||||
|
if (aBoolean)
|
||||||
|
{
|
||||||
|
DialogFrag.dismissDialog(contextActivity, R.string.finished);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Toast.makeText(contextActivity, "Something went wrong!", Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ package com.MartyrPher.smapiandroidinstaller;
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
|
@ -10,25 +11,47 @@ import android.support.v4.app.DialogFragment;
|
||||||
|
|
||||||
public class DialogFrag extends DialogFragment {
|
public class DialogFrag extends DialogFragment {
|
||||||
|
|
||||||
@NonNull
|
public static AlertDialog mAlertDialog;
|
||||||
@Override
|
|
||||||
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
|
||||||
builder.setMessage("This will Install SMAPI and require to Uninstall the current verison of Stardew Valley from the device. Continue?")
|
|
||||||
.setPositiveButton("Install", new DialogInterface.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
//Start AsyncTask
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
|
|
||||||
}
|
public DialogFrag()
|
||||||
});
|
{
|
||||||
return builder.create();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void showDialog(Context context, int message, int tag)
|
||||||
|
{
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||||
|
switch(tag)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
builder.setMessage(message);
|
||||||
|
builder.setCancelable(false);
|
||||||
|
mAlertDialog = builder.create();
|
||||||
|
mAlertDialog.show();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
builder.setMessage(message);
|
||||||
|
builder.setPositiveButton("Okay", null);
|
||||||
|
builder.show();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void dismissDialog(Context context, int message)
|
||||||
|
{
|
||||||
|
if(mAlertDialog.isShowing())
|
||||||
|
{
|
||||||
|
mAlertDialog.dismiss();
|
||||||
|
}
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||||
|
|
||||||
|
builder.setMessage(message);
|
||||||
|
builder.setPositiveButton("Awesome", new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
dialog.dismiss();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
builder.show();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
package com.MartyrPher.smapiandroidinstaller;
|
package com.MartyrPher.smapiandroidinstaller;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.content.res.AssetManager;
|
import android.content.res.AssetManager;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.v4.app.ActivityCompat;
|
||||||
|
import android.support.v4.content.ContextCompat;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
@ -24,51 +28,82 @@ public class MainActivity extends AppCompatActivity {
|
||||||
private static final String ASSET_STARDEW_FILES = "Stardew/";
|
private static final String ASSET_STARDEW_FILES = "Stardew/";
|
||||||
private static final String DIR_APK_FILES = "/SMAPI Installer/ApkFiles/";
|
private static final String DIR_APK_FILES = "/SMAPI Installer/ApkFiles/";
|
||||||
private static final String DIR_STARDEW_FILES = "/StardewValley/smapi-internal/";
|
private static final String DIR_STARDEW_FILES = "/StardewValley/smapi-internal/";
|
||||||
private static final String PATH_TO_SIGNED_APK = Environment.getExternalStorageDirectory() + "/SMAPI Installer/base_signed.apk";
|
|
||||||
private static final String TAG = "MainActivity";
|
private static final String TAG = "MainActivity";
|
||||||
|
|
||||||
private static final int UNINSTALL_REQUEST_CODE = 0;
|
private static final int UNINSTALL_REQUEST_CODE = 0;
|
||||||
private static final int INSTALL_REQUEST_CODE = 1;
|
private static final int MY_PERMISSION_REQUEST_STORAGE = 2;
|
||||||
|
|
||||||
|
private boolean hasPermissions = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(final Bundle savedInstanceState) {
|
protected void onCreate(final Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_main);
|
setContentView(R.layout.activity_main);
|
||||||
|
|
||||||
|
requestPermissions();
|
||||||
|
|
||||||
final Button start_button = findViewById(R.id.start_button);
|
final Button start_button = findViewById(R.id.start_button);
|
||||||
start_button.setOnClickListener(new View.OnClickListener() {
|
start_button.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
|
if (hasPermissions)
|
||||||
ApkExtractor apkExtractor = new ApkExtractor();
|
|
||||||
WriteApk writeApk = new WriteApk();
|
|
||||||
SignApk signApk = new SignApk();
|
|
||||||
|
|
||||||
apkExtractor.ExtractAPK(getApplicationContext());
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
copyAssets(ASSET_APK_FILES, DIR_APK_FILES);
|
boolean foundGame;
|
||||||
copyAssets(ASSET_STARDEW_FILES, DIR_STARDEW_FILES);
|
ApkExtractor apkExtractor = new ApkExtractor(MainActivity.this);
|
||||||
File[] moddingAPI = {new File(Environment.getExternalStorageDirectory() + DIR_APK_FILES + "StardewModdingAPI.dll")};
|
BackgroundTask backgroundTask = new BackgroundTask(MainActivity.this);
|
||||||
|
|
||||||
writeApk.AddFilesToApk(new File(Environment.getExternalStorageDirectory() + "/SMAPI Installer/base.apk"), moddingAPI, "assemblies/", false, 0);
|
foundGame = apkExtractor.extractAPK(getApplicationContext());
|
||||||
File[] resources = {new File(Environment.getExternalStorageDirectory() + DIR_APK_FILES + "AndroidManifest.xml"),
|
|
||||||
new File(Environment.getExternalStorageDirectory() + DIR_APK_FILES + "classes.dex")};
|
|
||||||
writeApk.AddFilesToApk(new File(Environment.getExternalStorageDirectory() + "/SMAPI Installer/base.apk_patched0.apk"), resources, "", true, 1);
|
|
||||||
signApk.CommitSignApk();
|
|
||||||
|
|
||||||
UninstallStardew();
|
if(foundGame)
|
||||||
Toast.makeText(getApplicationContext(), "Done :)", Toast.LENGTH_SHORT).show();
|
{
|
||||||
|
copyAssets(ASSET_APK_FILES, DIR_APK_FILES);
|
||||||
|
copyAssets(ASSET_STARDEW_FILES, DIR_STARDEW_FILES);
|
||||||
|
|
||||||
}catch (Exception ex)
|
backgroundTask.execute();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DialogFrag.showDialog(MainActivity.this, R.string.cant_find, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
|
requestPermissions();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UninstallStardew()
|
public void requestPermissions()
|
||||||
|
{
|
||||||
|
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||||
|
!= PackageManager.PERMISSION_GRANTED) {
|
||||||
|
ActivityCompat.requestPermissions(MainActivity.this,
|
||||||
|
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE},
|
||||||
|
MY_PERMISSION_REQUEST_STORAGE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hasPermissions = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||||
|
switch(requestCode)
|
||||||
|
{
|
||||||
|
case MY_PERMISSION_REQUEST_STORAGE:
|
||||||
|
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
|
||||||
|
{
|
||||||
|
hasPermissions = true;
|
||||||
|
Toast.makeText(this, "Permission Granted :)", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Prompts the user to Uninstall the current version of the game from the device
|
||||||
|
public void uninstallStardew()
|
||||||
{
|
{
|
||||||
String app_pkg_name = "com.chucklefish.stardewvalley";
|
String app_pkg_name = "com.chucklefish.stardewvalley";
|
||||||
|
|
||||||
|
@ -78,38 +113,7 @@ public class MainActivity extends AppCompatActivity {
|
||||||
startActivityForResult(intent, UNINSTALL_REQUEST_CODE);
|
startActivityForResult(intent, UNINSTALL_REQUEST_CODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
//Copies the needed files from the APK to a local directory so they can be used
|
||||||
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
|
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
|
||||||
switch(requestCode)
|
|
||||||
{
|
|
||||||
case UNINSTALL_REQUEST_CODE:
|
|
||||||
if (requestCode == RESULT_OK)
|
|
||||||
{
|
|
||||||
Log.d(TAG, "The User Accepted the Uninstall");
|
|
||||||
} else if (resultCode == RESULT_CANCELED)
|
|
||||||
{
|
|
||||||
Log.d(TAG, "The User Cancelled the Uninstall");
|
|
||||||
} else if (resultCode == RESULT_FIRST_USER)
|
|
||||||
{
|
|
||||||
Log.d(TAG, "Failed to Uninstall");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case INSTALL_REQUEST_CODE:
|
|
||||||
if (requestCode == RESULT_OK)
|
|
||||||
{
|
|
||||||
Log.d(TAG, "The User Accepted the Install");
|
|
||||||
} else if (resultCode == RESULT_CANCELED)
|
|
||||||
{
|
|
||||||
Log.d(TAG, "The User Cancelled the Install");
|
|
||||||
} else if (resultCode == RESULT_FIRST_USER)
|
|
||||||
{
|
|
||||||
Log.d(TAG, "Failed to Install");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void copyAssets(String asset, String dir) {
|
private void copyAssets(String asset, String dir) {
|
||||||
AssetManager assetManager = getAssets();
|
AssetManager assetManager = getAssets();
|
||||||
String[] files = null;
|
String[] files = null;
|
||||||
|
@ -152,6 +156,7 @@ public class MainActivity extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void copyFile(InputStream in, OutputStream out) throws IOException {
|
private void copyFile(InputStream in, OutputStream out) throws IOException {
|
||||||
byte[] buffer = new byte[1024];
|
byte[] buffer = new byte[1024];
|
||||||
int read;
|
int read;
|
||||||
|
|
|
@ -26,13 +26,12 @@ public class SignApk {
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CommitSignApk()
|
public void commitSignApk()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
String inputFile = APK_LOCATION;
|
String inputFile = APK_LOCATION;
|
||||||
String outputFile = Environment.getExternalStorageDirectory() + "/SMAPI Installer/base_signed.apk";
|
String outputFile = Environment.getExternalStorageDirectory() + "/SMAPI Installer/base_signed.apk";
|
||||||
|
|
||||||
//File keystoreFile = new File(KEYSTORE_LOCATION);
|
|
||||||
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();
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ public class WriteApk {
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddFilesToApk(File source, File[] files, String path, boolean compression, int count){
|
public void addFilesToApk(File source, File[] files, String path, boolean compression, int count){
|
||||||
try{
|
try{
|
||||||
byte[] buffer = new byte[4096];
|
byte[] buffer = new byte[4096];
|
||||||
ZipInputStream zin = new ZipInputStream(new FileInputStream(source));
|
ZipInputStream zin = new ZipInputStream(new FileInputStream(source));
|
||||||
|
@ -58,7 +58,7 @@ public class WriteApk {
|
||||||
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)){
|
||||||
out.putNextEntry(ze);
|
out.putNextEntry(ze);
|
||||||
for(int read = zin.read(buffer); read > -1; read = zin.read(buffer)){
|
for(int read = zin.read(buffer); read > -1; read = zin.read(buffer)){
|
||||||
out.write(buffer, 0, read);
|
out.write(buffer, 0, read);
|
||||||
|
@ -74,7 +74,7 @@ public class WriteApk {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 + files[i].getName()).equals(zeName)){
|
if((path + files[i].getName()).equals(zeName)){
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">SMAPI Android Installer</string>
|
<string name="app_name">SMAPI Android Installer</string>
|
||||||
|
<string name="cant_find">Could not find the Stardew Valley Apk. Is the game installed?</string>
|
||||||
|
<string name="modify_apk">Modifying the Apk…this might take some time fucker.</string>
|
||||||
|
<string name="finished">Finished!</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in New Issue