Skip to content

Commit

Permalink
Merge pull request #664 from PhenoApps/github-release-updates
Browse files Browse the repository at this point in the history
Alter update mechanism to avoid REQUEST_INSTALL_PACKAGES
  • Loading branch information
trife authored Jul 29, 2023
2 parents a166c64 + 46dd32c commit 241c24c
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 279 deletions.
1 change: 0 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO"/>
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO"/>
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />

<!-- Wifi permissions for Android Q up -->
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
Expand Down
156 changes: 143 additions & 13 deletions app/src/main/java/com/fieldbook/tracker/activities/AboutActivity.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package com.fieldbook.tracker.activities;


import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.preference.PreferenceManager;
import androidx.swiperefreshlayout.widget.CircularProgressDrawable;

import com.danielstone.materialaboutlibrary.ConvenienceBuilder;
import com.danielstone.materialaboutlibrary.MaterialAboutActivity;
Expand All @@ -19,21 +24,39 @@
import com.fieldbook.tracker.BuildConfig;
import com.fieldbook.tracker.R;
import com.fieldbook.tracker.preferences.GeneralKeys;
import com.fieldbook.tracker.utilities.VersionChecker;
import com.michaelflisar.changelog.ChangelogBuilder;
import com.michaelflisar.changelog.classes.ImportanceChangelogSorter;
import com.michaelflisar.changelog.internal.ChangelogDialogFragment;
import com.mikepenz.aboutlibraries.LibsBuilder;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import org.json.JSONException;
import org.json.JSONObject;

public class AboutActivity extends MaterialAboutActivity {
//todo move to fragments so aboutactivity can extend base activity

// Declaration of the "Updates" action item
private MaterialAboutActionItem updateCheckItem;
private CircularProgressDrawable circularProgressDrawable;
private static final String TAG = AboutActivity.class.getSimpleName();

@Override
protected void onCreate(Bundle savedInstanceState) {
ThemedActivity.Companion.applyTheme(this);
super.onCreate(savedInstanceState);
checkForUpdate();
circularProgressDrawable = new CircularProgressDrawable(this);
circularProgressDrawable.setStyle(CircularProgressDrawable.DEFAULT);
circularProgressDrawable.start();
}

private MaterialAboutActionItem.Builder updatesButtonBuilder;
@Override
@NonNull
public MaterialAboutList getMaterialAboutList(@NonNull Context c) {
Expand All @@ -49,16 +72,14 @@ public MaterialAboutList getMaterialAboutList(@NonNull Context c) {
getString(R.string.about_version_title),
false));

appCardBuilder.addItem(new MaterialAboutActionItem.Builder()
.text(getString(R.string.updates_title))
.icon(R.drawable.ic_about_get_update)
.setOnClickAction(new MaterialAboutItemOnClickAction() {
@Override
public void onClick() {
checkForUpdate();
}
})
.build());
// Save a reference to the "Updates" action item
updateCheckItem = new MaterialAboutActionItem.Builder()
.text(getString(R.string.check_updates_title))
.icon(circularProgressDrawable)
.setOnClickAction(null) // Set initially to null, will be updated later
.build();

appCardBuilder.addItem(updateCheckItem);

appCardBuilder.addItem(new MaterialAboutActionItem.Builder()
.text(getString(R.string.changelog_title))
Expand Down Expand Up @@ -201,8 +222,117 @@ private String getCurrentAppVersion() {

private void checkForUpdate() {
String currentVersion = getCurrentAppVersion();
VersionChecker versionChecker = new VersionChecker(AboutActivity.this, currentVersion, "PhenoApps", "Field-Book");
versionChecker.execute();
String owner = "PhenoApps";
String repo = "Field-Book";
String apiUrl = "https://api.github.com/repos/" + owner + "/" + repo + "/releases/latest";

// Make the API call to check for updates
new AsyncTask<Void, Void, String>() {
@Override
protected String doInBackground(Void... params) {
try {
URL url = new URL(apiUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");

int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
reader.close();
return response.toString();
} else {
Log.e(TAG, "HTTP request failed with response code: " + responseCode);
}
} catch (IOException e) {
Log.e(TAG, "Error occurred while checking for updates: " + e.getMessage());
}
return null;
}

@Override
protected void onPostExecute(String result) {
if (result != null) {
try {
JSONObject json = new JSONObject(result);
String latestVersion = json.getString("tag_name");
String downloadUrl = json.getJSONArray("assets").getJSONObject(0).getString("browser_download_url");

// Compare the versions to check if a newer version is available
boolean isNewVersionAvailable = isNewerVersion(currentVersion, latestVersion);

// Update the UI based on the version check result
showVersionStatus(isNewVersionAvailable, latestVersion, downloadUrl);
} catch (JSONException e) {
Log.e(TAG, "Error parsing JSON response: " + e.getMessage());
}
} else {
Log.e(TAG, "Failed to retrieve version information from GitHub");
}
}
}.execute();
}


private void showVersionStatus(boolean isNewVersionAvailable, @Nullable String latestVersion, @Nullable String downloadUrl) {
circularProgressDrawable.stop();
if (updateCheckItem == null) {
// The "Updates" action item was not added to the card, something went wrong
return;
}

if (isNewVersionAvailable) {
updateCheckItem.setText(getString(R.string.found_updates_title));
updateCheckItem.setSubText(latestVersion);
updateCheckItem.setIcon(getResources().getDrawable(R.drawable.ic_about_get_update));

// Set the onClickAction to open the browser with the release URL
updateCheckItem.setOnClickAction(new MaterialAboutItemOnClickAction() {
@Override
public void onClick() {
if (downloadUrl != null) {
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(downloadUrl));
startActivity(browserIntent);
}
}
});
} else {
updateCheckItem.setText(getString(R.string.no_updates_title));
updateCheckItem.setIcon(getResources().getDrawable(R.drawable.ic_about_up_to_date));
updateCheckItem.setOnClickAction(null);
}
refreshMaterialAboutList();
}

private boolean isNewerVersion(String currentVersion, String latestVersion) {
// Split the version strings into their components
String[] currentVersionComponents = currentVersion.split("\\.");
String[] latestVersionComponents = latestVersion.split("\\.");
Log.i(TAG, "Comparing currentVersion " + currentVersion + " to latestVersion " + latestVersion);
// Ignore the last component (build number) if it exists
int versionComponentsToCompare = Math.min(currentVersionComponents.length, latestVersionComponents.length);
if (versionComponentsToCompare > 3) {
versionComponentsToCompare--; // Ignore the last component
}

// Compare each component of the version
for (int i = 0; i < versionComponentsToCompare; i++) {
int currentComponent = Integer.parseInt(currentVersionComponents[i]);
int latestComponent = Integer.parseInt(latestVersionComponents[i]);

if (currentComponent < latestComponent) {
return true; // latestVersion is newer
} else if (currentComponent > latestComponent) {
return false; // currentVersion is newer
}
}

// All compared components are equal, consider them equal versions
return false;
}

private void showChangelog(Boolean managedShow, Boolean rateButton) {
Expand Down
Loading

0 comments on commit 241c24c

Please sign in to comment.