package moe.feng.nhentai.util;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Looper;
import android.support.annotation.NonNull;
import android.support.v4.content.FileProvider;
import android.util.Log;
import android.widget.Toast;
import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import org.json.JSONObject;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.net.HttpURLConnection;
import moe.feng.nhentai.R;
public class Updates {
private static final String LATEST_RELEASE = "https://api.github.com/repos/FengMoeTeam/NHentai-android/releases/latest";
private static final String LATEST_GRADLE_FILE = "https://raw.githubusercontent.com/FengMoeTeam/NHentai-android/master/app/build.gradle";
private static final String KEY_IGNORE_UPDATE = "ignoreUpdate";
private static int prog = 0;
public static void check(final Activity activity) {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
try {
String version = HttpTools.getStringFromUrl(LATEST_GRADLE_FILE).trim().replace(" ", "");
Log.d("Update", "doInBackground: " + getAPKversionCode(activity));
final int code = Integer.parseInt(version.substring(version.indexOf("versionCode") + 11, version.indexOf("versionName")).trim());
if (code > getAPKversionCode(activity) && !isIgnored(activity, code)) {// >= Test
final JSONObject object = new JSONObject(HttpTools.getStringFromUrl(LATEST_RELEASE));
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
try {
new MaterialDialog.Builder(activity)
.title(activity.getResources().getString(R.string.new_version_available) + " " + object.getString("tag_name"))
.content(object.getString("body"))
.positiveText(R.string.button_update)
.negativeText(R.string.close)
.neutralText(R.string.ignore)
.onPositive(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
Looper.prepare();
Settings.getInstance(activity).putInt(KEY_IGNORE_UPDATE, -1);
final File downloadedUpdate = new File(activity.getExternalCacheDir() + "/updates/", "app-update.apk");
if (!downloadedUpdate.getParentFile().exists())
downloadedUpdate.getParentFile().mkdirs();
if (downloadedUpdate.exists())
downloadedUpdate.delete();
try {
HttpURLConnection connection = HttpTools.openConnection(object.getJSONArray("assets").getJSONObject(0).getString("browser_download_url"));
connection.connect();
BufferedInputStream inputStream = new BufferedInputStream(connection.getInputStream());
FileOutputStream outputStream = new FileOutputStream(downloadedUpdate);
int lenghtOfFile = connection.getContentLength();
byte data[] = new byte[1024 * 4];
long total = 0;
int count;
final MaterialDialog progress = new MaterialDialog.Builder(activity)
.title(R.string.updating)
.progress(false, 100, false)
.build();
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
progress.show();
}
});
while ((count = inputStream.read(data)) != -1) {
total += count;
final int tprog = (int) ((total * 100) / lenghtOfFile);
if (tprog > prog) {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
progress.setProgress(tprog);
progress.show();
}
});
prog = tprog;
}
outputStream.write(data, 0, count);
outputStream.flush();
}
outputStream.close();
connection.disconnect();
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
progress.dismiss();
}
});
Intent promptInstall = new Intent(Intent.ACTION_VIEW);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Uri uri = FileProvider.getUriForFile(activity, "moe.feng.nhentai.ui.HomeActivity", downloadedUpdate);
activity.grantUriPermission("com.android.packageinstaller", uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
promptInstall.setDataAndType(uri,
"application/vnd.android.package-archive");
} else {
promptInstall.setDataAndType(Uri.fromFile(downloadedUpdate),
"application/vnd.android.package-archive");
}
activity.finish();
activity.startActivity(promptInstall);
} catch (Exception e) {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(activity, R.string.updated_apk_download_error, Toast.LENGTH_SHORT).show();
}
});
e.printStackTrace();
}
return null;
}
}.execute();
}
})
.onNeutral(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
Settings.getInstance(activity).putInt(KEY_IGNORE_UPDATE, code);
}
}).build().show();
} catch (Exception e) {
Toast.makeText(activity, R.string.updated_apk_download_error, Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
});
} else {
if (code == getAPKversionCode(activity)) {
Log.d("Update", "Is Updated");
}
if (isIgnored(activity, code)) {
Log.d("Update", "Ignored: " + code);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}.execute();
}
public static void check(final Activity activity, final UpdateInterface updateInterface) {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
try {
String version = HttpTools.getStringFromUrl(LATEST_GRADLE_FILE).trim().replace(" ", "");
Log.d("Update", "doInBackground: " + getAPKversionCode(activity));
final int code = Integer.parseInt(version.substring(version.indexOf("versionCode") + 11, version.indexOf("versionName")).trim());
if (code > getAPKversionCode(activity)) {// >= Test
updateInterface.onChecked(false);
final JSONObject object = new JSONObject(HttpTools.getStringFromUrl(LATEST_RELEASE));
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
try {
new MaterialDialog.Builder(activity)
.title(activity.getResources().getString(R.string.new_version_available) + " " + object.getString("tag_name"))
.content(object.getString("body"))
.positiveText(R.string.button_update)
.negativeText(R.string.close)
.onPositive(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
Looper.prepare();
Settings.getInstance(activity).putInt(KEY_IGNORE_UPDATE, -1);
final File downloadedUpdate = new File(activity.getExternalCacheDir() + "/updates/", "app-update.apk");
if (!downloadedUpdate.getParentFile().exists())
downloadedUpdate.getParentFile().mkdirs();
if (downloadedUpdate.exists())
downloadedUpdate.delete();
try {
HttpURLConnection connection = HttpTools.openConnection(object.getJSONArray("assets").getJSONObject(0).getString("browser_download_url"));
connection.connect();
BufferedInputStream inputStream = new BufferedInputStream(connection.getInputStream());
FileOutputStream outputStream = new FileOutputStream(downloadedUpdate);
int lenghtOfFile = connection.getContentLength();
byte data[] = new byte[1024 * 4];
long total = 0;
int count;
final MaterialDialog progress = new MaterialDialog.Builder(activity)
.title(R.string.updating)
.progress(false, 100, false)
.build();
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
progress.show();
}
});
while ((count = inputStream.read(data)) != -1) {
total += count;
final int tprog = (int) ((total * 100) / lenghtOfFile);
if (tprog > prog) {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
progress.setProgress(tprog);
progress.show();
}
});
prog = tprog;
}
outputStream.write(data, 0, count);
outputStream.flush();
}
outputStream.close();
connection.disconnect();
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
progress.dismiss();
}
});
Intent promptInstall = new Intent(Intent.ACTION_VIEW);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Uri uri = FileProvider.getUriForFile(activity, "moe.feng.nhentai.ui.HomeActivity", downloadedUpdate);
activity.grantUriPermission("com.android.packageinstaller", uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
promptInstall.setDataAndType(uri,
"application/vnd.android.package-archive");
} else {
promptInstall.setDataAndType(Uri.fromFile(downloadedUpdate),
"application/vnd.android.package-archive");
}
activity.finish();
activity.startActivity(promptInstall);
} catch (Exception e) {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(activity, R.string.updated_apk_download_error, Toast.LENGTH_SHORT).show();
}
});
e.printStackTrace();
}
return null;
}
}.execute();
}
}).build().show();
} catch (Exception e) {
Toast.makeText(activity, R.string.updated_apk_download_error, Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
});
} else {
updateInterface.onChecked(true);
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}.execute();
}
private static boolean isIgnored(Context context, int gitVersion) {
return Settings.getInstance(context).getInt(KEY_IGNORE_UPDATE, -1) == gitVersion;
}
private static int getAPKversionCode(Context context) throws PackageManager.NameNotFoundException {
return context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionCode;
}
public interface UpdateInterface {
void onChecked(boolean isUpdated);
}
}