diff --git a/app/build.gradle b/app/build.gradle
index 45e3e0c..b105183 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -12,7 +12,7 @@ android {
targetSdk 33
versionCode 1
multiDexEnabled true
- versionName "1.0"
+ versionName "1.1-beta"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index a069ad4..09abb85 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -16,14 +16,16 @@
tools:targetApi="31">
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/java/br/com/nullexcept/webappmanager/app/BaseWebAppActivity.java b/app/src/main/java/br/com/nullexcept/webappmanager/app/BaseWebAppActivity.java
index d0cfa0b..a8cd40f 100644
--- a/app/src/main/java/br/com/nullexcept/webappmanager/app/BaseWebAppActivity.java
+++ b/app/src/main/java/br/com/nullexcept/webappmanager/app/BaseWebAppActivity.java
@@ -10,6 +10,7 @@
import android.os.Environment;
import android.os.Process;
import android.view.Window;
+import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -40,8 +41,17 @@ public class BaseWebAppActivity extends AppCompatActivity {
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- config = new Config(getClass().getName());
- config.load(getSharedPreferences("webapps",MODE_PRIVATE));
+ config = new Config(this, getClass().getName());
+ config.load();
+ if (!config.enable){
+ Toast.makeText(this, R.string.not_exists, Toast.LENGTH_LONG).show();
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ finishAndRemoveTask();
+ } else {
+ finish();
+ }
+ return;
+ }
setTitle(config.name);
@@ -52,37 +62,13 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
GeckoRuntimeSettings.Builder settings = new GeckoRuntimeSettings.Builder();
settings = settings.arguments(new String[]{
- "profile", getFilesDir().getAbsolutePath(),
- "--profile", getFilesDir().getAbsolutePath()
+ "--profile", config.getProfileDir().getAbsolutePath()
});
+ session.getSettings().setUserAgentOverride(config.user_agent);
+
runtime = GeckoRuntime.create(this, settings.build());
session.open(runtime);
- new Thread(()->{
- try {
- File dir = new File(getFilesDir().getParent(), "icon.png");
- dir.getParentFile().mkdirs();
- if (dir.exists()){
- loadIcon();
- return;
- }
- String url = config.url.substring(config.url.indexOf("://")+3);
- if (url.contains("/")){
- url = url.substring(0, url.indexOf("/"));
- }
- URLConnection connection = new URL((config.url.startsWith("https") ? "https" : "http")+"://"+url+"/favicon.ico").openConnection();
- connection.connect();
- InputStream down = connection.getInputStream();
- Bitmap bitmap = BitmapFactory.decodeStream(down);
- dir.delete();
- if (bitmap.getHeight() < 1 || bitmap.getWidth() < 1)return;
- FileOutputStream o = new FileOutputStream(dir);
- bitmap.compress(Bitmap.CompressFormat.PNG, 100, o);
- o.close();
- bitmap.recycle();
- loadIcon();
- }catch (Exception e){e.printStackTrace();}
- }).start();
view.setSession(session);
session.loadUri(config.url);
@@ -92,10 +78,11 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
setTaskDescription(new ActivityManager.TaskDescription(config.name, null, Color.WHITE));
}
setTitle(config.name);
+ checkIcon();
}
private void loadIcon() {
- File dir = new File(getFilesDir().getParent(), "icon.png");
+ File dir = new File(config.getSaveDir(), "icon.png");
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
setTaskDescription(new ActivityManager.TaskDescription(config.name, BitmapFactory.decodeFile(dir.getAbsolutePath()), Color.WHITE));
@@ -108,26 +95,13 @@ private void loadIcon() {
@Override
public void onBackPressed() {
session.goBack();
- if(System.currentTimeMillis() - oldTime < 350){
+ //Check double back click
+ if(System.currentTimeMillis() - oldTime < 500){
super.onBackPressed();
}
oldTime = System.currentTimeMillis();
}
- @Override
- public File getFilesDir() {
- File file = new File(super.getFilesDir(), "instances/"+getClass().getName()+"/files");
- file.mkdirs();
- return file;
- }
-
- @Override
- public ApplicationInfo getApplicationInfo() {
- ApplicationInfo info = super.getApplicationInfo();
- info.dataDir = getFilesDir().getAbsolutePath();
- return info;
- }
-
@Override
protected void onPause() {
super.onPause();
@@ -144,8 +118,27 @@ protected void onDestroy() {
@Override
public File getCacheDir() {
- File file = new File(getFilesDir().getParent(), "cache");
+ File file = new File(config.getSaveDir(), "cache");
file.mkdirs();
return file;
}
+
+ private void checkIcon(){
+ new Thread(()->{
+ try {
+ File dir = new File(config.getSaveDir(), "icon.png");
+ dir.getParentFile().mkdirs();
+ if (dir.exists()){
+ loadIcon();
+ return;
+ }
+
+ String url = config.url.substring(config.url.indexOf("://")+3);
+ if (url.contains("/")){
+ url = url.substring(0, url.indexOf("/"));
+ }
+ //@TODO Need add code to get Icon from GeckoSession
+ }catch (Exception e){e.printStackTrace();}
+ }).start();
+ }
}
diff --git a/app/src/main/java/br/com/nullexcept/webappmanager/app/MainActivity.java b/app/src/main/java/br/com/nullexcept/webappmanager/app/MainActivity.java
index b98bdbb..17c478f 100644
--- a/app/src/main/java/br/com/nullexcept/webappmanager/app/MainActivity.java
+++ b/app/src/main/java/br/com/nullexcept/webappmanager/app/MainActivity.java
@@ -32,6 +32,7 @@
import java.io.File;
import java.util.HashMap;
+import java.util.Objects;
import br.com.nullexcept.webappmanager.R;
import br.com.nullexcept.webappmanager.config.Config;
@@ -64,17 +65,22 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
if (savedInstanceState == null){
loadList();
findViewById(R.id.create).setOnClickListener((vw)->{
- String key = null;
- for (String ky:WEBAPPS.keySet()){
- if(!WEBAPPS.get(ky).enable){
- key = ky;
- break;
- }
- }
- showDialog(new Config(key));
+ showDialog(new Config(this, findLastFreeSlot()));
});
}
+ findLastFreeSlot();
+ }
+
+ public String findLastFreeSlot(){
+ String key = null;
+ for (String ky:WEBAPPS.keySet()){
+ if(!Objects.requireNonNull(WEBAPPS.get(ky)).enable){
+ key = ky;
+ break;
+ } else System.out.println(">> Slot ["+ky+"] is in use.");
+ }
+ return key;
}
private void showDialog(Config config){
@@ -142,10 +148,10 @@ private void createShortcut(Config config, Intent intent) {
private void checkAndCreateDatabase() {
for (Class clazz: LIST){
SharedPreferences prefs = getSharedPreferences("webapps", Context.MODE_PRIVATE);
- Config config = new Config(clazz.getName());
- config.load(prefs);
+ Config config = new Config(this, clazz.getName());
+ config.load();
WEBAPPS.put(clazz.getName(), config);
- config.save(prefs);
+ config.save();
}
}
diff --git a/app/src/main/java/br/com/nullexcept/webappmanager/config/Config.java b/app/src/main/java/br/com/nullexcept/webappmanager/config/Config.java
index 51b98c3..f7e0e5f 100644
--- a/app/src/main/java/br/com/nullexcept/webappmanager/config/Config.java
+++ b/app/src/main/java/br/com/nullexcept/webappmanager/config/Config.java
@@ -1,10 +1,21 @@
package br.com.nullexcept.webappmanager.config;
+import android.app.Activity;
+import android.app.Application;
+import android.content.Context;
import android.content.SharedPreferences;
+import android.content.pm.ApplicationInfo;
+import android.os.Environment;
import org.mozilla.geckoview.GeckoSession;
import org.mozilla.geckoview.GeckoView;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import br.com.nullexcept.webappmanager.util.FileUtils;
+
public class Config {
private final String base;
@@ -14,17 +25,48 @@ public class Config {
public boolean action_bar = false;
public boolean enable = false;
public boolean redirects = false;
+ public File data_directory;
+ public Context ctx;
- public Config(String base){
+ public Config(Activity ctx, String base){
this.base = base;
+ this.data_directory = ctx.getFilesDir();
+ this.ctx = ctx.getApplication();
+ System.out.println("Data directory: "+ ctx.getFilesDir());
+ }
+
+ public File getSaveDir(){
+ return mkdirs(new File(data_directory, "instances/"+base));
+ }
+
+ private File mkdirs(File file){
+ file.mkdirs();
+ return file;
}
+ public File getProfileDir(){
+ return mkdirs(new File(getSaveDir(), "profile"));
+ }
+
+ public void deleteAll(){
+ ArrayList baseDirectory = new ArrayList<>();
+ baseDirectory.addAll(Arrays.asList(ctx.getExternalFilesDirs(null)));
+ baseDirectory.add(ctx.getFilesDir());
+ baseDirectory.add(this.data_directory);
+ for (File file: baseDirectory){
+ FileUtils.delete(new File(file, "instances/"+base));
+ }
+ enable = false;
+ save();
+ }
public String getBase() {
return base;
}
- public void load(SharedPreferences prefs){
+ public void load(){
+ SharedPreferences prefs = ctx.getSharedPreferences("webapps",Context.MODE_PRIVATE);
+
enable = prefs.getBoolean(base, enable);
name = prefs.getString(base+"/name", name);
@@ -35,7 +77,8 @@ public void load(SharedPreferences prefs){
redirects = prefs.getBoolean(base+"/redirects", redirects);
}
- public void save(SharedPreferences prefs){
+ public void save(){
+ SharedPreferences prefs = ctx.getSharedPreferences("webapps",Context.MODE_PRIVATE);
prefs.edit()
.putString(base+"/name", name)
.putString(base+"/user_agent", user_agent)
diff --git a/app/src/main/java/br/com/nullexcept/webappmanager/dialog/EditWebAppDialog.java b/app/src/main/java/br/com/nullexcept/webappmanager/dialog/EditWebAppDialog.java
index 34531d9..af7e9e8 100644
--- a/app/src/main/java/br/com/nullexcept/webappmanager/dialog/EditWebAppDialog.java
+++ b/app/src/main/java/br/com/nullexcept/webappmanager/dialog/EditWebAppDialog.java
@@ -75,11 +75,11 @@ public EditWebAppDialog(Config config, MainActivity ctx){
if (config.enable){
layout.findViewById(R.id.delete).setVisibility(View.VISIBLE);
layout.findViewById(R.id.delete).setOnClickListener(v -> {
+ clearAllData();
dialog.hide();
config.enable = false;
- config.save(ctx.getSharedPreferences("webapps", MODE_PRIVATE));
+ config.save();
ctx.refreshList();
- clearAllData();
});
} else {
layout.findViewById(R.id.delete).setVisibility(View.INVISIBLE);
@@ -97,6 +97,7 @@ private void save() {
dialog.hide();
config.name = name.getText()+"";
config.url = url.getText()+"";
+ config.user_agent = user_agent.getText()+"";
config.action_bar = show_action.isChecked();
config.redirects = allow_redirects.isChecked();
if (!config.enable){
@@ -104,23 +105,14 @@ private void save() {
config.enable = true;
}
MainActivity.WEBAPPS.put(config.getBase(), config);
- config.save(ctx.getSharedPreferences("webapps", MODE_PRIVATE));
+ config.save();
ctx.refreshList();
}
private void clearAllData() {
- File data = new File(ctx.getFilesDir(), "instances/"+config.getBase());
- data.mkdirs();
- deleteRecursive(data);
- data.mkdirs();
+ config.deleteAll();
}
- void deleteRecursive(File fileOrDirectory) {
- if (fileOrDirectory.isDirectory())
- for (File child : fileOrDirectory.listFiles())
- deleteRecursive(child);
- fileOrDirectory.delete();
- }
private boolean touchUpdate(View vw, MotionEvent motion){
checkAndContinue();
diff --git a/app/src/main/java/br/com/nullexcept/webappmanager/util/FileUtils.java b/app/src/main/java/br/com/nullexcept/webappmanager/util/FileUtils.java
new file mode 100644
index 0000000..fc49139
--- /dev/null
+++ b/app/src/main/java/br/com/nullexcept/webappmanager/util/FileUtils.java
@@ -0,0 +1,17 @@
+package br.com.nullexcept.webappmanager.util;
+
+import java.io.File;
+import java.util.Objects;
+
+public class FileUtils {
+
+ //@TODO Delete recursive files.
+ public static void delete(File file){
+ if (file.isDirectory()){
+ for (File child: Objects.requireNonNull(file.listFiles())){
+ delete(child);
+ }
+ }
+ file.delete();
+ }
+}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 9010f7c..7afab8a 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,4 +1,5 @@
WebApp Manager
Shortcut created
+ This WebApp not exists.
\ No newline at end of file