diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 27b8f63..7510cc1 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -97,6 +97,7 @@
+
@@ -135,10 +136,13 @@
+
+
+
+
-
@@ -185,7 +189,11 @@
+
+ . */
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.database.sqlite.SQLiteDatabase;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+import android.widget.GridView;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.constraintlayout.widget.ConstraintLayout;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import app.fedilab.nitterizeme.R;
+import app.fedilab.nitterizeme.adapters.AppPickerAdapter;
+import app.fedilab.nitterizeme.entities.AppPicker;
+import app.fedilab.nitterizeme.helpers.Utils;
+import app.fedilab.nitterizeme.sqlite.DefaultAppDAO;
+import app.fedilab.nitterizeme.sqlite.Sqlite;
+
+import static app.fedilab.nitterizeme.helpers.Utils.KILL_ACTIVITY;
+import static app.fedilab.nitterizeme.helpers.Utils.URL_APP_PICKER;
+
+
+public class AppsPickerActivity extends Activity {
+
+
+ private String url;
+ private String appToUse;
+ private String appName;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_pickup_app);
+ if (getIntent() == null) {
+ finish();
+ }
+ Bundle b = getIntent().getExtras();
+ if (b == null) {
+ finish();
+ }
+ if (b != null) {
+ url = b.getString(URL_APP_PICKER, null);
+ }
+ if (url == null) {
+ finish();
+ }
+ //At this point we are sure that url is not null
+ Intent stopMainActivity = new Intent(KILL_ACTIVITY);
+ sendBroadcast(stopMainActivity);
+
+ Intent delegate = new Intent(Intent.ACTION_VIEW);
+ delegate.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ delegate.setData(Uri.parse(url));
+
+ List activities = getPackageManager().queryIntentActivities(delegate, PackageManager.MATCH_DEFAULT_ONLY);
+ SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
+ RelativeLayout blank = findViewById(R.id.blank);
+ blank.setOnClickListener(v -> finish());
+ String thisPackageName = getApplicationContext().getPackageName();
+ ArrayList packages = new ArrayList<>();
+ List appPickers = new ArrayList<>();
+ int i = 0;
+ for (ResolveInfo currentInfo : activities) {
+ String packageName = currentInfo.activityInfo.packageName;
+ if (!thisPackageName.equals(packageName) && !packages.contains(packageName)) {
+ AppPicker appPicker = new AppPicker();
+ appPicker.setIcon(currentInfo.activityInfo.loadIcon(getPackageManager()));
+ appPicker.setName(String.valueOf(currentInfo.loadLabel(getPackageManager())));
+ appPicker.setPackageName(packageName);
+ if (i == 0) {
+ appPicker.setSelected(true);
+ appToUse = packageName;
+ appName = String.valueOf(currentInfo.loadLabel(getPackageManager()));
+ }
+ appPickers.add(appPicker);
+ packages.add(packageName);
+ i++;
+ }
+
+ }
+ String defaultApp = new DefaultAppDAO(AppsPickerActivity.this, db).getDefault(packages);
+
+ TextView urlText = findViewById(R.id.url);
+ urlText.setText(url);
+
+ if (defaultApp != null) {
+ Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
+ intent.setPackage(defaultApp);
+ startActivity(intent);
+ finish();
+ } else {
+ ConstraintLayout app_container = findViewById(R.id.app_container);
+ app_container.setVisibility(View.VISIBLE);
+ GridView gridView = findViewById(R.id.app_list);
+ AppPickerAdapter appPickerAdapter = new AppPickerAdapter(appPickers);
+ gridView.setAdapter(appPickerAdapter);
+ gridView.setNumColumns(3);
+ gridView.setOnItemClickListener((parent, view1, position, id) -> {
+ for (AppPicker ap : appPickers) {
+ ap.setSelected(false);
+ }
+ appPickers.get(position).setSelected(true);
+ appToUse = appPickers.get(position).getPackageName();
+ appName = appPickers.get(position).getName();
+ appPickerAdapter.notifyDataSetChanged();
+ });
+
+
+ Button always = findViewById(R.id.always);
+ Button once = findViewById(R.id.once);
+
+ always.setOnClickListener(v -> {
+
+ boolean isPresent = new DefaultAppDAO(AppsPickerActivity.this, db).isPresent(appToUse);
+ long val = -1;
+ if (isPresent) {
+ ArrayList oldConcurrent = new DefaultAppDAO(AppsPickerActivity.this, db).getConcurrent(appToUse);
+ ArrayList newConcurrent = Utils.union(oldConcurrent, packages);
+ new DefaultAppDAO(AppsPickerActivity.this, db).update(appToUse, newConcurrent);
+ } else {
+ val = new DefaultAppDAO(AppsPickerActivity.this, db).insert(appToUse, packages);
+ }
+ if (val > 0) {
+ Toast.makeText(AppsPickerActivity.this, getString(R.string.default_app_indication, appName), Toast.LENGTH_LONG).show();
+ }
+ Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
+ intent.setPackage(appToUse);
+ startActivity(intent);
+ finish();
+ });
+
+ once.setOnClickListener(v -> {
+ Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
+ intent.setPackage(appToUse);
+ startActivity(intent);
+ finish();
+ });
+ }
+
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ }
+
+}
diff --git a/app/src/main/java/app/fedilab/nitterizeme/activities/DefaultAppActivity.java b/app/src/main/java/app/fedilab/nitterizeme/activities/DefaultAppActivity.java
new file mode 100644
index 0000000..c71d141
--- /dev/null
+++ b/app/src/main/java/app/fedilab/nitterizeme/activities/DefaultAppActivity.java
@@ -0,0 +1,90 @@
+package app.fedilab.nitterizeme.activities;
+/* Copyright 2020 Thomas Schneider
+ *
+ * This file is a part of UntrackMe
+ *
+ * This program is free software; you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * UntrackMe is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with UntrackMe; if not,
+ * see . */
+
+
+import android.database.sqlite.SQLiteDatabase;
+import android.os.Bundle;
+import android.view.MenuItem;
+
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import java.util.ArrayList;
+
+import app.fedilab.nitterizeme.R;
+import app.fedilab.nitterizeme.adapters.DefaultAppAdapter;
+import app.fedilab.nitterizeme.entities.DefaultApp;
+import app.fedilab.nitterizeme.helpers.Utils;
+import app.fedilab.nitterizeme.sqlite.DefaultAppDAO;
+import app.fedilab.nitterizeme.sqlite.Sqlite;
+
+
+public class DefaultAppActivity extends AppCompatActivity {
+
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_default_app);
+
+
+ setTitle(R.string.default_apps);
+ if (getSupportActionBar() != null) {
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+ getSupportActionBar().setDisplayShowHomeEnabled(true);
+ }
+
+ RecyclerView list_apps = findViewById(R.id.list_apps);
+ final LinearLayoutManager mLayoutManager;
+ mLayoutManager = new LinearLayoutManager(DefaultAppActivity.this);
+ list_apps.setLayoutManager(mLayoutManager);
+ list_apps.setNestedScrollingEnabled(false);
+
+ ArrayList appInfos = getAppInfo();
+ DefaultAppAdapter defaultAppAdapter = new DefaultAppAdapter(appInfos);
+ list_apps.setAdapter(defaultAppAdapter);
+ }
+
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (item.getItemId() == android.R.id.home) {
+ finish();
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+
+ /**
+ * Get default app set inside the application for opening links
+ *
+ * @return ArrayList
+ */
+ private ArrayList getAppInfo() {
+ ArrayList appInfos = new ArrayList<>();
+ SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
+ ArrayList packageName = new DefaultAppDAO(DefaultAppActivity.this, db).getDefault();
+ for (String p : packageName) {
+ DefaultApp defaultApp = new DefaultApp();
+ defaultApp.setApplicationInfo(Utils.getPackageInfo(DefaultAppActivity.this, p).applicationInfo);
+ appInfos.add(defaultApp);
+ }
+ return appInfos;
+ }
+
+}
diff --git a/app/src/main/java/app/fedilab/nitterizeme/activities/MainActivity.java b/app/src/main/java/app/fedilab/nitterizeme/activities/MainActivity.java
index a8bb059..0b7ba79 100644
--- a/app/src/main/java/app/fedilab/nitterizeme/activities/MainActivity.java
+++ b/app/src/main/java/app/fedilab/nitterizeme/activities/MainActivity.java
@@ -19,6 +19,8 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
@@ -33,11 +35,13 @@ import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SwitchCompat;
import androidx.appcompat.widget.Toolbar;
+import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.Group;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.textfield.TextInputEditText;
+import java.util.List;
import java.util.Objects;
import app.fedilab.nitterizeme.R;
@@ -88,7 +92,6 @@ public class MainActivity extends AppCompatActivity {
Objects.requireNonNull(getSupportActionBar()).setDisplayShowHomeEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
-
SharedPreferences sharedpreferences = getSharedPreferences(APP_PREFS, Context.MODE_PRIVATE);
TextView current_instance_nitter = findViewById(R.id.current_instance_nitter);
@@ -138,7 +141,6 @@ public class MainActivity extends AppCompatActivity {
enable_invidious.setChecked(invidious_enabled);
enable_bibliogram.setChecked(bibliogram_enabled);
enable_osm.setChecked(osm_enabled);
-
ImageButton save_instance_nitter = findViewById(R.id.button_save_instance_nitter);
ImageButton save_instance_invidious = findViewById(R.id.button_save_instance_invidious);
ImageButton save_instance_bibliogram = findViewById(R.id.button_save_instance_bibliogram);
@@ -462,6 +464,10 @@ public class MainActivity extends AppCompatActivity {
Intent intent = new Intent(MainActivity.this, AboutActivity.class);
startActivity(intent);
return true;
+ } else if (id == R.id.action_settings) {
+ Intent intent = new Intent(MainActivity.this, DefaultAppActivity.class);
+ startActivity(intent);
+ return true;
} else if (id == android.R.id.home) {
finish();
}
@@ -504,5 +510,14 @@ public class MainActivity extends AppCompatActivity {
bibliogram_instance.setText(bibliogramHost);
current_instance_bibliogram.setText(bibliogramHost);
}
+
+ List resolveInfos = getPackageManager().queryIntentActivities(new Intent(Intent.ACTION_VIEW, Uri.parse("https://fedilab.app")), PackageManager.MATCH_DEFAULT_ONLY);
+ String thisPackageName = getApplicationContext().getPackageName();
+ ConstraintLayout display_indications = findViewById(R.id.display_indications);
+ if (resolveInfos.size() == 1 && resolveInfos.get(0).activityInfo.packageName.compareTo(thisPackageName) == 0) {
+ display_indications.setVisibility(View.VISIBLE);
+ } else {
+ display_indications.setVisibility(View.GONE);
+ }
}
}
diff --git a/app/src/main/java/app/fedilab/nitterizeme/activities/TransformActivity.java b/app/src/main/java/app/fedilab/nitterizeme/activities/TransformActivity.java
index ded182c..336856b 100644
--- a/app/src/main/java/app/fedilab/nitterizeme/activities/TransformActivity.java
+++ b/app/src/main/java/app/fedilab/nitterizeme/activities/TransformActivity.java
@@ -15,18 +15,14 @@ package app.fedilab.nitterizeme.activities;
* see . */
import android.app.Activity;
-import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
-import android.os.Parcelable;
import android.util.Patterns;
import android.view.View;
import android.widget.Button;
@@ -35,7 +31,6 @@ import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.appcompat.app.AlertDialog;
-import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
@@ -43,7 +38,6 @@ import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -59,15 +53,16 @@ import static app.fedilab.nitterizeme.activities.CheckAppActivity.shortener_doma
import static app.fedilab.nitterizeme.activities.CheckAppActivity.twitter_domains;
import static app.fedilab.nitterizeme.activities.CheckAppActivity.youtube_domains;
import static app.fedilab.nitterizeme.activities.MainActivity.SET_BIBLIOGRAM_ENABLED;
-import static app.fedilab.nitterizeme.activities.MainActivity.SET_EMBEDDED_PLAYER;
import static app.fedilab.nitterizeme.activities.MainActivity.SET_INVIDIOUS_ENABLED;
import static app.fedilab.nitterizeme.activities.MainActivity.SET_NITTER_ENABLED;
import static app.fedilab.nitterizeme.helpers.Utils.KILL_ACTIVITY;
+import static app.fedilab.nitterizeme.helpers.Utils.URL_APP_PICKER;
import static app.fedilab.nitterizeme.helpers.Utils.ampExtract;
import static app.fedilab.nitterizeme.helpers.Utils.bibliogramAccountPattern;
import static app.fedilab.nitterizeme.helpers.Utils.bibliogramPostPattern;
import static app.fedilab.nitterizeme.helpers.Utils.maps;
import static app.fedilab.nitterizeme.helpers.Utils.nitterPattern;
+import static app.fedilab.nitterizeme.helpers.Utils.remove_tracking_param;
import static app.fedilab.nitterizeme.helpers.Utils.transformUrl;
import static app.fedilab.nitterizeme.helpers.Utils.youtubePattern;
@@ -116,9 +111,7 @@ public class TransformActivity extends Activity {
Intent delegate = new Intent(Intent.ACTION_VIEW);
delegate.setData(Uri.parse(notShortnedURLDialog.get(notShortnedURLDialog.size() - 1)));
delegate.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- if (delegate.resolveActivity(getPackageManager()) != null) {
- startActivity(delegate);
- }
+ forwardToBrowser(delegate);
}
dialog.dismiss();
finish();
@@ -171,10 +164,7 @@ public class TransformActivity extends Activity {
if (transformedURL != null) {
delegate.setData(Uri.parse(transformUrl(TransformActivity.this, url)));
delegate.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- if (delegate.resolveActivity(getPackageManager()) != null) {
- startActivity(delegate);
- finish();
- }
+ forwardToBrowser(delegate);
} else {
forwardToBrowser(intent);
}
@@ -190,10 +180,7 @@ public class TransformActivity extends Activity {
if (transformedURL != null) {
delegate.setData(Uri.parse(transformUrl(TransformActivity.this, url)));
delegate.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- if (delegate.resolveActivity(getPackageManager()) != null) {
- startActivity(delegate);
- finish();
- }
+ forwardToBrowser(delegate);
} else {
forwardToBrowser(intent);
}
@@ -210,10 +197,7 @@ public class TransformActivity extends Activity {
if (transformedURL != null) {
delegate.setData(Uri.parse(transformUrl(TransformActivity.this, url)));
delegate.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- if (delegate.resolveActivity(getPackageManager()) != null) {
- startActivity(delegate);
- finish();
- }
+ forwardToBrowser(delegate);
} else {
forwardToBrowser(intent);
}
@@ -232,10 +216,7 @@ public class TransformActivity extends Activity {
if (transformedURL != null) {
delegate.setData(Uri.parse(transformedURL));
delegate.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- if (delegate.resolveActivity(getPackageManager()) != null) {
- startActivity(delegate);
- finish();
- }
+ forwardToBrowser(delegate);
} else {
forwardToBrowser(intent);
}
@@ -249,10 +230,7 @@ public class TransformActivity extends Activity {
if (transformedURL != null) {
delegate.setData(Uri.parse(transformUrl(TransformActivity.this, url)));
delegate.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- if (delegate.resolveActivity(getPackageManager()) != null) {
- startActivity(delegate);
- finish();
- }
+ forwardToBrowser(delegate);
} else {
forwardToBrowser(intent);
}
@@ -304,6 +282,10 @@ public class TransformActivity extends Activity {
} else {
forwardToBrowser(intent);
}
+ } else {
+ String newUrl = remove_tracking_param(url);
+ intent.setData(Uri.parse(newUrl));
+ forwardToBrowser(intent);
}
}
@@ -327,64 +309,12 @@ public class TransformActivity extends Activity {
* @param i original intent
*/
private void forwardToBrowser(Intent i) {
- Intent intent = new Intent();
- intent.setAction(Intent.ACTION_VIEW);
- String type = i.getType();
- if (type == null) {
- type = "text/html";
- }
- intent.setDataAndType(i.getData(), type);
- List activities = getPackageManager().queryIntentActivities(intent, 0);
- ArrayList targetIntents = new ArrayList<>();
- String thisPackageName = getApplicationContext().getPackageName();
- ArrayList packages = new ArrayList<>();
- for (ResolveInfo currentInfo : activities) {
- String packageName = currentInfo.activityInfo.packageName;
- if (!thisPackageName.equals(packageName) && !packages.contains(packageName)) {
- Intent targetIntent = new Intent(Intent.ACTION_VIEW);
- targetIntent.setDataAndType(intent.getData(), intent.getType());
- targetIntent.setPackage(intent.getPackage());
- targetIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- targetIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- targetIntent.setComponent(new ComponentName(packageName, currentInfo.activityInfo.name));
- targetIntents.add(targetIntent);
- packages.add(packageName);
- }
- }
- //NewPipe has to be manually added
- if (isNewPipeInstalled() && Arrays.asList(invidious_instances).contains(Objects.requireNonNull(i.getData()).getHost()) && !packages.contains("org.schabi.newpipe")) {
- Intent targetIntent = new Intent(Intent.ACTION_VIEW);
- targetIntent.setDataAndType(intent.getData(), intent.getType());
- targetIntent.setPackage(intent.getPackage());
- targetIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- targetIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- targetIntent.setComponent(new ComponentName("org.schabi.newpipe", "org.schabi.newpipe.RouterActivity"));
- targetIntents.add(0, targetIntent);
- }
- SharedPreferences sharedpreferences = getSharedPreferences(MainActivity.APP_PREFS, Context.MODE_PRIVATE);
- boolean embedded_player = sharedpreferences.getBoolean(SET_EMBEDDED_PLAYER, false);
-
- if (Arrays.asList(invidious_instances).contains(Objects.requireNonNull(i.getData()).getHost()) && embedded_player) {
- if (!i.getData().toString().contains("videoplayback") && !i.getData().toString().contains("/channel/")) {
- Intent intentPlayer = new Intent(TransformActivity.this, WebviewPlayerActivity.class);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- intentPlayer.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
- }
- intentPlayer.putExtra("url", i.getData().toString());
- startActivity(intentPlayer);
- } else {
- Intent intentStreamingUrl = new Intent(Utils.RECEIVE_STREAMING_URL);
- Bundle b = new Bundle();
- b.putString("streaming_url", i.getData().toString());
- intentStreamingUrl.putExtras(b);
- LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intentStreamingUrl);
- }
- } else if (targetIntents.size() > 0) {
- Intent chooserIntent = Intent.createChooser(targetIntents.get(0), getString(R.string.open_with));
- chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetIntents.toArray(new Parcelable[]{}));
- startActivity(chooserIntent);
- }
+ Intent app_picker = new Intent(TransformActivity.this, AppsPickerActivity.class);
+ Bundle b = new Bundle();
+ b.putString(URL_APP_PICKER, i.getDataString());
+ app_picker.putExtras(b);
+ startActivity(app_picker);
finish();
}
@@ -429,6 +359,13 @@ public class TransformActivity extends Activity {
startActivity(sendIntent);
return;
}
+ Uri url_r = Uri.parse(url);
+ String scheme = url_r.getScheme();
+ if (scheme == null) {
+ scheme = "https://";
+ } else {
+ scheme += "://";
+ }
if (Arrays.asList(twitter_domains).contains(host)) {
boolean nitter_enabled = sharedpreferences.getBoolean(SET_NITTER_ENABLED, true);
@@ -438,9 +375,9 @@ public class TransformActivity extends Activity {
assert host != null;
if (host.compareTo("pbs.twimg.com") == 0 || host.compareTo("pic.twitter.com") == 0) {
try {
- newUrl = "https://" + nitterHost + "/pic/" + URLEncoder.encode(url, "utf-8");
+ newUrl = scheme + nitterHost + "/pic/" + URLEncoder.encode(url, "utf-8");
} catch (UnsupportedEncodingException e) {
- newUrl = "https://" + nitterHost + "/pic/" + url;
+ newUrl = scheme + nitterHost + "/pic/" + url;
}
} else if (url.contains("/search?")) {
newUrl = url.replace(host, nitterHost);
@@ -448,7 +385,7 @@ public class TransformActivity extends Activity {
Matcher matcher = nitterPattern.matcher(url);
while (matcher.find()) {
final String nitter_directory = matcher.group(2);
- newUrl = "https://" + nitterHost + nitter_directory;
+ newUrl = scheme + nitterHost + nitter_directory;
}
}
}
@@ -459,16 +396,16 @@ public class TransformActivity extends Activity {
while (matcher.find()) {
final String bibliogram_directory = matcher.group(2);
String bibliogramHost = sharedpreferences.getString(MainActivity.SET_BIBLIOGRAM_HOST, MainActivity.DEFAULT_BIBLIOGRAM_HOST).toLowerCase();
- newUrl = "https://" + bibliogramHost + bibliogram_directory;
+ newUrl = scheme + bibliogramHost + bibliogram_directory;
}
matcher = bibliogramAccountPattern.matcher(url);
while (matcher.find()) {
final String bibliogram_directory = matcher.group(2);
String bibliogramHost = sharedpreferences.getString(MainActivity.SET_BIBLIOGRAM_HOST, MainActivity.DEFAULT_BIBLIOGRAM_HOST).toLowerCase();
if (bibliogram_directory != null && bibliogram_directory.compareTo("privacy") != 0) {
- newUrl = "https://" + bibliogramHost + "/u" + bibliogram_directory;
+ newUrl = scheme + bibliogramHost + "/u" + bibliogram_directory;
} else {
- newUrl = "https://" + bibliogramHost + bibliogram_directory;
+ newUrl = scheme + bibliogramHost + bibliogram_directory;
}
}
}
@@ -489,14 +426,14 @@ public class TransformActivity extends Activity {
zoom = data[2];
}
String osmHost = sharedpreferences.getString(MainActivity.SET_OSM_HOST, MainActivity.DEFAULT_OSM_HOST).toLowerCase();
- newUrl = "https://" + osmHost + "/#map=" + zoom + "/" + data[0] + "/" + data[1];
+ newUrl = scheme + osmHost + "/#map=" + zoom + "/" + data[0] + "/" + data[1];
}
}
}
} else if (url.contains("/amp/s/")) {
Matcher matcher = ampExtract.matcher(url);
while (matcher.find()) {
- newUrl = "https://" + matcher.group(1);
+ newUrl = scheme + matcher.group(1);
}
} else if (Arrays.asList(youtube_domains).contains(host)) { //Youtube URL
boolean invidious_enabled = sharedpreferences.getBoolean(SET_INVIDIOUS_ENABLED, true);
@@ -506,15 +443,16 @@ public class TransformActivity extends Activity {
final String youtubeId = matcher.group(3);
String invidiousHost = sharedpreferences.getString(MainActivity.SET_INVIDIOUS_HOST, MainActivity.DEFAULT_INVIDIOUS_HOST).toLowerCase();
if (Objects.requireNonNull(matcher.group(2)).compareTo("youtu.be") == 0) {
- newUrl = "https://" + invidiousHost + "/watch?v=" + youtubeId + "&local=true";
+ newUrl = scheme + invidiousHost + "/watch?v=" + youtubeId + "&local=true";
} else {
- newUrl = "https://" + invidiousHost + "/" + youtubeId + "&local=true";
+ newUrl = scheme + invidiousHost + "/" + youtubeId + "&local=true";
}
}
}
} else if (Arrays.asList(shortener_domains).contains(host)) {
String finalUrl = url;
String finalExtraText = extraText;
+ String finalScheme = scheme;
Thread thread = new Thread() {
@Override
public void run() {
@@ -539,7 +477,7 @@ public class TransformActivity extends Activity {
while (matcher.find()) {
final String nitter_directory = matcher.group(2);
String nitterHost = sharedpreferences.getString(MainActivity.SET_NITTER_HOST, MainActivity.DEFAULT_NITTER_HOST).toLowerCase();
- newUrlFinal = "https://" + nitterHost + nitter_directory;
+ newUrlFinal = finalScheme + nitterHost + nitter_directory;
}
String newExtraText = finalExtraText.replaceAll(Pattern.quote(finalUrl), Matcher.quoteReplacement(newUrlFinal));
Intent sendIntent = new Intent();
@@ -554,9 +492,9 @@ public class TransformActivity extends Activity {
final String youtubeId = matcher.group(3);
String invidiousHost = sharedpreferences.getString(MainActivity.SET_INVIDIOUS_HOST, MainActivity.DEFAULT_INVIDIOUS_HOST).toLowerCase();
if (Objects.requireNonNull(matcher.group(2)).compareTo("youtu.be") == 0) {
- newUrlFinal = "https://" + invidiousHost + "/watch?v=" + youtubeId + "&local=true";
+ newUrlFinal = finalScheme + invidiousHost + "/watch?v=" + youtubeId + "&local=true";
} else {
- newUrlFinal = "https://" + invidiousHost + "/" + youtubeId + "&local=true";
+ newUrlFinal = finalScheme + invidiousHost + "/" + youtubeId + "&local=true";
}
}
String newExtraText = finalExtraText.replaceAll(Pattern.quote(finalUrl), Matcher.quoteReplacement(newUrlFinal));
@@ -581,7 +519,7 @@ public class TransformActivity extends Activity {
zoom = data[2];
}
String osmHost = sharedpreferences.getString(MainActivity.SET_OSM_HOST, MainActivity.DEFAULT_OSM_HOST).toLowerCase();
- newUrlFinal = "https://" + osmHost + "/#map=" + zoom + "/" + data[0] + "/" + data[1];
+ newUrlFinal = finalScheme + osmHost + "/#map=" + zoom + "/" + data[0] + "/" + data[1];
}
}
String newExtraText = finalExtraText.replaceAll(Pattern.quote(finalUrl), Matcher.quoteReplacement(newUrlFinal));
@@ -602,6 +540,8 @@ public class TransformActivity extends Activity {
};
thread.start();
return;
+ } else {
+ newUrl = remove_tracking_param(url);
}
if (newUrl != null) {
extraText = extraText.replaceAll(Pattern.quote(url), Matcher.quoteReplacement(newUrl));
@@ -613,17 +553,5 @@ public class TransformActivity extends Activity {
startActivity(sendIntent);
}
- /**
- * Check if NewPipe is installed
- *
- * @return boolean
- */
- private boolean isNewPipeInstalled() {
- try {
- getPackageManager().getPackageInfo("org.schabi.newpipe", 0);
- return true;
- } catch (PackageManager.NameNotFoundException e) {
- return false;
- }
- }
+
}
diff --git a/app/src/main/java/app/fedilab/nitterizeme/adapters/AppPickerAdapter.java b/app/src/main/java/app/fedilab/nitterizeme/adapters/AppPickerAdapter.java
new file mode 100644
index 0000000..441f694
--- /dev/null
+++ b/app/src/main/java/app/fedilab/nitterizeme/adapters/AppPickerAdapter.java
@@ -0,0 +1,100 @@
+package app.fedilab.nitterizeme.adapters;
+/* Copyright 2020 Thomas Schneider
+ *
+ * This file is a part of UntrackMe
+ *
+ * This program is free software; you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * UntrackMe is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with UntrackMe; if not,
+ * see . */
+
+import android.content.res.Resources;
+import android.os.Build;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.constraintlayout.widget.ConstraintLayout;
+
+import java.util.List;
+
+import app.fedilab.nitterizeme.R;
+import app.fedilab.nitterizeme.entities.AppPicker;
+
+public class AppPickerAdapter extends BaseAdapter {
+
+ private List appPickers;
+
+ public AppPickerAdapter(List appPickers) {
+ this.appPickers = appPickers;
+ }
+
+
+ @Override
+ public int getCount() {
+ return appPickers.size();
+ }
+
+ @Override
+ public AppPicker getItem(int position) {
+ return appPickers.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+
+ final ViewHolder holder;
+ AppPicker appPicker = appPickers.get(position);
+ if (convertView == null) {
+ LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
+ convertView = layoutInflater.inflate(R.layout.drawer_app_picker, parent, false);
+ holder = new ViewHolder();
+ holder.app_icon = convertView.findViewById(R.id.app_icon);
+ holder.app_name = convertView.findViewById(R.id.app_name);
+ holder.app_container = convertView.findViewById(R.id.app_container);
+ convertView.setTag(holder);
+ } else {
+ holder = (ViewHolder) convertView.getTag();
+ }
+
+ try {
+ holder.app_icon.setImageDrawable(appPicker.getIcon());
+ } catch (Resources.NotFoundException e) {
+ holder.app_icon.setImageResource(R.drawable.ic_android);
+ }
+ holder.app_name.setText(appPicker.getName());
+
+
+ if (appPicker.isSelected()) {
+ holder.app_container.setBackgroundResource(R.drawable.rounded_selector);
+ } else {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+ holder.app_container.setBackground(null);
+ }
+ }
+
+ return convertView;
+
+ }
+
+ private static class ViewHolder {
+ ImageView app_icon;
+ TextView app_name;
+ ConstraintLayout app_container;
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/app/fedilab/nitterizeme/adapters/DefaultAppAdapter.java b/app/src/main/java/app/fedilab/nitterizeme/adapters/DefaultAppAdapter.java
new file mode 100644
index 0000000..2345ca3
--- /dev/null
+++ b/app/src/main/java/app/fedilab/nitterizeme/adapters/DefaultAppAdapter.java
@@ -0,0 +1,120 @@
+package app.fedilab.nitterizeme.adapters;
+/* Copyright 2020 Thomas Schneider
+ *
+ * This file is a part of UntrackMe
+ *
+ * This program is free software; you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * UntrackMe is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with UntrackMe; if not,
+ * see . */
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.database.sqlite.SQLiteDatabase;
+import android.graphics.drawable.Drawable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.AlertDialog;
+import androidx.constraintlayout.widget.ConstraintLayout;
+import androidx.recyclerview.widget.RecyclerView;
+
+import java.util.List;
+
+import app.fedilab.nitterizeme.R;
+import app.fedilab.nitterizeme.entities.DefaultApp;
+import app.fedilab.nitterizeme.sqlite.DefaultAppDAO;
+import app.fedilab.nitterizeme.sqlite.Sqlite;
+
+public class DefaultAppAdapter extends RecyclerView.Adapter {
+
+ private List defaultApps;
+
+ public DefaultAppAdapter(List packageNames) {
+ this.defaultApps = packageNames;
+ }
+
+
+ @NonNull
+ @Override
+ public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int position) {
+ Context context = parent.getContext();
+ LayoutInflater layoutInflater = LayoutInflater.from(context);
+ return new ViewHolder(layoutInflater.inflate(R.layout.drawer_default_app, parent, false));
+ }
+
+
+ @Override
+ public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
+ DefaultApp defaultApp = defaultApps.get(viewHolder.getAdapterPosition());
+ ViewHolder holder = (ViewHolder) viewHolder;
+ Context context = holder.itemView.getContext();
+ if (defaultApp.getApplicationInfo() != null) {
+ Drawable icon = defaultApp.getApplicationInfo().loadIcon(context.getPackageManager());
+ try {
+ holder.app_icon.setImageDrawable(icon);
+ } catch (Resources.NotFoundException e) {
+ holder.app_icon.setImageResource(R.drawable.ic_android);
+ }
+ String app_name = context.getPackageManager().getApplicationLabel(defaultApp.getApplicationInfo()).toString();
+ String app_package = defaultApp.getApplicationInfo().packageName;
+ holder.app_name.setText(app_name);
+ holder.app_package.setText(app_package);
+ holder.delete.setOnClickListener(v -> {
+ AlertDialog.Builder confirmDialog = new AlertDialog.Builder(context, R.style.AppThemeDialogDelete);
+ confirmDialog.setMessage(context.getString(R.string.delete_app_from_default, app_name));
+ confirmDialog.setIcon(R.mipmap.ic_launcher);
+ confirmDialog.setPositiveButton(R.string.delete, (dialog, id) -> {
+ SQLiteDatabase db = Sqlite.getInstance(context.getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
+ new DefaultAppDAO(context, db).removeApp(app_package);
+ defaultApps.remove(defaultApp);
+ notifyItemRemoved(i);
+ dialog.dismiss();
+ });
+ confirmDialog.setNegativeButton(R.string.cancel, (dialog, id) -> dialog.dismiss());
+ AlertDialog alertDialog = confirmDialog.create();
+ alertDialog.show();
+
+ });
+ } else {
+ holder.app_icon.setImageResource(R.drawable.ic_android);
+ }
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public int getItemCount() {
+ return defaultApps.size();
+ }
+
+
+ static class ViewHolder extends RecyclerView.ViewHolder {
+ ImageView app_icon, delete;
+ TextView app_name, app_package;
+ ConstraintLayout main_container;
+
+ ViewHolder(@NonNull View itemView) {
+ super(itemView);
+ app_icon = itemView.findViewById(R.id.app_icon);
+ delete = itemView.findViewById(R.id.delete);
+ app_name = itemView.findViewById(R.id.app_name);
+ app_package = itemView.findViewById(R.id.app_package);
+ main_container = itemView.findViewById(R.id.main_container);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/app/fedilab/nitterizeme/entities/AppPicker.java b/app/src/main/java/app/fedilab/nitterizeme/entities/AppPicker.java
new file mode 100644
index 0000000..27dabb9
--- /dev/null
+++ b/app/src/main/java/app/fedilab/nitterizeme/entities/AppPicker.java
@@ -0,0 +1,57 @@
+package app.fedilab.nitterizeme.entities;
+
+import android.graphics.drawable.Drawable;
+
+/* Copyright 2020 Thomas Schneider
+ *
+ * This file is a part of UntrackMe
+ *
+ * This program is free software; you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * UntrackMe is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with UntrackMe; if not,
+ * see . */
+public class AppPicker {
+
+ private Drawable icon;
+ private String name;
+ private String packageName;
+ private boolean selected = false;
+
+ public Drawable getIcon() {
+ return icon;
+ }
+
+ public void setIcon(Drawable icon) {
+ this.icon = icon;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getPackageName() {
+ return packageName;
+ }
+
+ public void setPackageName(String packageName) {
+ this.packageName = packageName;
+ }
+
+ public boolean isSelected() {
+ return selected;
+ }
+
+ public void setSelected(boolean selected) {
+ this.selected = selected;
+ }
+}
diff --git a/app/src/main/java/app/fedilab/nitterizeme/entities/DefaultApp.java b/app/src/main/java/app/fedilab/nitterizeme/entities/DefaultApp.java
new file mode 100644
index 0000000..49bded1
--- /dev/null
+++ b/app/src/main/java/app/fedilab/nitterizeme/entities/DefaultApp.java
@@ -0,0 +1,29 @@
+package app.fedilab.nitterizeme.entities;
+/* Copyright 2020 Thomas Schneider
+ *
+ * This file is a part of UntrackMe
+ *
+ * This program is free software; you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * UntrackMe is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with UntrackMe; if not,
+ * see . */
+
+
+public class DefaultApp {
+
+ private android.content.pm.ApplicationInfo ApplicationInfo;
+
+ public android.content.pm.ApplicationInfo getApplicationInfo() {
+ return ApplicationInfo;
+ }
+
+ public void setApplicationInfo(android.content.pm.ApplicationInfo applicationInfo) {
+ ApplicationInfo = applicationInfo;
+ }
+}
diff --git a/app/src/main/java/app/fedilab/nitterizeme/helpers/Utils.java b/app/src/main/java/app/fedilab/nitterizeme/helpers/Utils.java
index 69ff979..313fccc 100644
--- a/app/src/main/java/app/fedilab/nitterizeme/helpers/Utils.java
+++ b/app/src/main/java/app/fedilab/nitterizeme/helpers/Utils.java
@@ -18,11 +18,14 @@ package app.fedilab.nitterizeme.helpers;
import android.app.DownloadManager;
import android.content.Context;
import android.content.SharedPreferences;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Environment;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
+import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URL;
@@ -31,10 +34,12 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
+import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
+import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -54,6 +59,7 @@ import static app.fedilab.nitterizeme.activities.MainActivity.SET_NITTER_ENABLED
public class Utils {
public static final String KILL_ACTIVITY = "kill_activity";
+ public static final String URL_APP_PICKER = "url_app_picker";
public static final Pattern youtubePattern = Pattern.compile("(www\\.|m\\.)?(youtube\\.com|youtu\\.be|youtube-nocookie\\.com)/(((?!([\"'<])).)*)");
public static final Pattern nitterPattern = Pattern.compile("(mobile\\.|www\\.)?twitter.com([\\w-/]+)");
public static final Pattern bibliogramPostPattern = Pattern.compile("(m\\.|www\\.)?instagram.com(/p/[\\w-/]+)");
@@ -107,27 +113,44 @@ public class Utils {
try {
comingURl = urls.get(urls.size() - 1);
- if (comingURl.startsWith("http://")) {
- comingURl = comingURl.replace("http://", "https://");
- }
url = new URL(comingURl);
- HttpsURLConnection httpsURLConnection = (HttpsURLConnection) url.openConnection();
- httpsURLConnection.setRequestProperty("http.keepAlive", "false");
- httpsURLConnection.setInstanceFollowRedirects(false);
- httpsURLConnection.setRequestMethod("HEAD");
- if (httpsURLConnection.getResponseCode() == 301) {
- Map> map = httpsURLConnection.getHeaderFields();
- for (Map.Entry> entry : map.entrySet()) {
- if (entry.toString().toLowerCase().startsWith("location")) {
- Matcher matcher = urlPattern.matcher(entry.toString());
- if (matcher.find()) {
- newURL = remove_tracking_param(matcher.group(1));
- urls.add(transformUrl(context, newURL));
+ if (comingURl.startsWith("https")) {
+ HttpsURLConnection httpsURLConnection = (HttpsURLConnection) url.openConnection();
+ httpsURLConnection.setRequestProperty("http.keepAlive", "false");
+ httpsURLConnection.setInstanceFollowRedirects(false);
+ httpsURLConnection.setRequestMethod("HEAD");
+ if (httpsURLConnection.getResponseCode() == 301) {
+ Map> map = httpsURLConnection.getHeaderFields();
+ for (Map.Entry> entry : map.entrySet()) {
+ if (entry.toString().toLowerCase().startsWith("location")) {
+ Matcher matcher = urlPattern.matcher(entry.toString());
+ if (matcher.find()) {
+ newURL = remove_tracking_param(matcher.group(1));
+ urls.add(transformUrl(context, newURL));
+ }
}
}
}
+ httpsURLConnection.getInputStream().close();
+ } else {
+ HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
+ httpURLConnection.setRequestProperty("http.keepAlive", "false");
+ httpURLConnection.setInstanceFollowRedirects(false);
+ httpURLConnection.setRequestMethod("HEAD");
+ if (httpURLConnection.getResponseCode() == 301) {
+ Map> map = httpURLConnection.getHeaderFields();
+ for (Map.Entry> entry : map.entrySet()) {
+ if (entry.toString().toLowerCase().startsWith("location")) {
+ Matcher matcher = urlPattern.matcher(entry.toString());
+ if (matcher.find()) {
+ newURL = remove_tracking_param(matcher.group(1));
+ urls.add(transformUrl(context, newURL));
+ }
+ }
+ }
+ }
+ httpURLConnection.getInputStream().close();
}
- httpsURLConnection.getInputStream().close();
if (newURL != null && newURL.compareTo(comingURl) != 0) {
URL redirectURL = new URL(newURL);
String host = redirectURL.getHost();
@@ -161,6 +184,14 @@ public class Utils {
} catch (MalformedURLException e) {
e.printStackTrace();
}
+ Uri url_r = Uri.parse(url);
+ String scheme = url_r.getScheme();
+ if (scheme == null) {
+ scheme = "https://";
+ } else {
+ scheme += "://";
+ }
+
if (Arrays.asList(twitter_domains).contains(host)) {
boolean nitter_enabled = sharedpreferences.getBoolean(SET_NITTER_ENABLED, true);
if (nitter_enabled) {
@@ -168,9 +199,9 @@ public class Utils {
assert host != null;
if (host.compareTo("pbs.twimg.com") == 0 || host.compareTo("pic.twitter.com") == 0) {
try {
- newUrl = "https://" + nitterHost + "/pic/" + URLEncoder.encode(url, "utf-8");
+ newUrl = scheme + nitterHost + "/pic/" + URLEncoder.encode(url, "utf-8");
} catch (UnsupportedEncodingException e) {
- newUrl = "https://" + nitterHost + "/pic/" + url;
+ newUrl = scheme + nitterHost + "/pic/" + url;
}
} else if (url.contains("/search?")) {
newUrl = url.replace(host, nitterHost);
@@ -178,7 +209,7 @@ public class Utils {
Matcher matcher = nitterPattern.matcher(url);
while (matcher.find()) {
final String nitter_directory = matcher.group(2);
- newUrl = "https://" + nitterHost + nitter_directory;
+ newUrl = scheme + nitterHost + nitter_directory;
}
}
return newUrl;
@@ -192,16 +223,16 @@ public class Utils {
while (matcher.find()) {
final String bibliogram_directory = matcher.group(2);
String bibliogramHost = sharedpreferences.getString(MainActivity.SET_BIBLIOGRAM_HOST, MainActivity.DEFAULT_BIBLIOGRAM_HOST).toLowerCase();
- newUrl = "https://" + bibliogramHost + bibliogram_directory;
+ newUrl = scheme + bibliogramHost + bibliogram_directory;
}
matcher = bibliogramAccountPattern.matcher(url);
while (matcher.find()) {
final String bibliogram_directory = matcher.group(2);
String bibliogramHost = sharedpreferences.getString(MainActivity.SET_BIBLIOGRAM_HOST, MainActivity.DEFAULT_BIBLIOGRAM_HOST).toLowerCase();
if (bibliogram_directory != null && bibliogram_directory.compareTo("privacy") != 0) {
- newUrl = "https://" + bibliogramHost + "/u" + bibliogram_directory;
+ newUrl = scheme + bibliogramHost + "/u" + bibliogram_directory;
} else {
- newUrl = "https://" + bibliogramHost + bibliogram_directory;
+ newUrl = scheme + bibliogramHost + bibliogram_directory;
}
}
return newUrl;
@@ -228,7 +259,7 @@ public class Utils {
String osmHost = sharedpreferences.getString(MainActivity.SET_OSM_HOST, MainActivity.DEFAULT_OSM_HOST).toLowerCase();
boolean geo_uri_enabled = sharedpreferences.getBoolean(MainActivity.SET_GEO_URIS, false);
if (!geo_uri_enabled) {
- newUrl = "https://" + osmHost + "/#map=" + zoom + "/" + data[0] + "/" + data[1];
+ newUrl = scheme + osmHost + "/#map=" + zoom + "/" + data[0] + "/" + data[1];
} else {
newUrl = "geo:0,0?q=" + data[0] + "," + data[1] + ",z=" + zoom;
}
@@ -253,9 +284,9 @@ public class Utils {
final String youtubeId = matcher.group(3);
String invidiousHost = sharedpreferences.getString(MainActivity.SET_INVIDIOUS_HOST, MainActivity.DEFAULT_INVIDIOUS_HOST).toLowerCase();
if (Objects.requireNonNull(matcher.group(2)).compareTo("youtu.be") == 0) {
- newUrl = "https://" + invidiousHost + "/watch?v=" + youtubeId + "&local=true";
+ newUrl = scheme + invidiousHost + "/watch?v=" + youtubeId + "&local=true";
} else {
- newUrl = "https://" + invidiousHost + "/" + youtubeId + "&local=true";
+ newUrl = scheme + invidiousHost + "/" + youtubeId + "&local=true";
}
}
return newUrl;
@@ -291,7 +322,7 @@ public class Utils {
* @param url String URL
* @return cleaned URL String
*/
- private static String remove_tracking_param(String url) {
+ public static String remove_tracking_param(String url) {
if (url != null) {
for (String utm : UTM_PARAMS) {
url = url.replaceAll("&" + utm + "=[0-9a-zA-Z._-]*", "");
@@ -336,4 +367,93 @@ public class Utils {
e.printStackTrace();
}
}
+
+
+ /**
+ * Check if an app is installed
+ *
+ * @return boolean
+ */
+ @SuppressWarnings("unused")
+ public static boolean isAppInstalled(Context context, String packageName) {
+ try {
+ context.getPackageManager().getPackageInfo(packageName, 0);
+ return true;
+ } catch (PackageManager.NameNotFoundException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Get PackageInfo for an app
+ *
+ * @return PackageInfo
+ */
+ @SuppressWarnings("unused")
+ public static PackageInfo getPackageInfo(Context context, String packageName) {
+ PackageInfo packageInfo = null;
+ try {
+ packageInfo = context.getPackageManager().getPackageInfo(packageName, 0);
+ } catch (Exception ignored) {
+ }
+ return packageInfo;
+ }
+
+
+ /**
+ * Convert an ArrayList to a string using coma
+ *
+ * @param arrayList ArrayList
+ * @return String
+ */
+ public static String arrayToString(ArrayList arrayList) {
+ if (arrayList == null || arrayList.size() == 0) {
+ return null;
+ }
+ StringBuilder result = new StringBuilder();
+ for (String item : arrayList) {
+ result.append(item).append(",");
+ }
+ return result.substring(0, result.length() - 1);
+ }
+
+ /**
+ * Convert an ArrayList to a string using coma
+ *
+ * @param arrayList ArrayList
+ * @return String
+ */
+ public static String arrayToStringQuery(ArrayList arrayList) {
+ if (arrayList == null || arrayList.size() == 0) {
+ return null;
+ }
+ StringBuilder result = new StringBuilder();
+ for (String item : arrayList) {
+ result.append("'").append(item).append("'").append(",");
+ }
+ return result.substring(0, result.length() - 1);
+ }
+
+ /**
+ * Convert String items to Array
+ *
+ * @param items String
+ * @return ArrayList
+ */
+ public static ArrayList stringToArray(String items) {
+ if (items == null) {
+ return null;
+ }
+ String[] result = items.split(",");
+ return new ArrayList<>(Arrays.asList(result));
+ }
+
+
+ public static ArrayList union(ArrayList list1, ArrayList list2) {
+ Set set = new HashSet<>();
+ set.addAll(list1);
+ set.addAll(list2);
+ return new ArrayList<>(set);
+ }
+
}
diff --git a/app/src/main/java/app/fedilab/nitterizeme/sqlite/DefaultAppDAO.java b/app/src/main/java/app/fedilab/nitterizeme/sqlite/DefaultAppDAO.java
new file mode 100644
index 0000000..7121bef
--- /dev/null
+++ b/app/src/main/java/app/fedilab/nitterizeme/sqlite/DefaultAppDAO.java
@@ -0,0 +1,154 @@
+package app.fedilab.nitterizeme.sqlite;
+/* Copyright 2020 Thomas Schneider
+ *
+ * This file is a part of UntrackMe
+ *
+ * This program is free software; you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * UntrackMe is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with UntrackMe; if not,
+ * see . */
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+
+import java.util.ArrayList;
+
+import app.fedilab.nitterizeme.helpers.Utils;
+
+public class DefaultAppDAO {
+
+ public Context context;
+ private SQLiteDatabase db;
+
+
+ public DefaultAppDAO(Context context, SQLiteDatabase db) {
+ this.context = context;
+ this.db = db;
+ }
+
+ public long insert(String packageName, ArrayList concurrentPackages) {
+ ContentValues values = new ContentValues();
+ values.put(Sqlite.COL_DEFAULT_PACKAGE, packageName.trim());
+ concurrentPackages.remove(packageName);
+ values.put(Sqlite.COL_CONCURRENT_PACKAGES, Utils.arrayToString(concurrentPackages));
+ try {
+ return db.insert(Sqlite.TABLE_DEFAULT_APPS, null, values);
+ } catch (Exception ignored) {
+ return -1;
+ }
+ }
+
+ public void update(String packageName, ArrayList concurrentPackages) {
+ ContentValues values = new ContentValues();
+ values.put(Sqlite.COL_CONCURRENT_PACKAGES, Utils.arrayToString(concurrentPackages));
+ try {
+ db.update(Sqlite.TABLE_DEFAULT_APPS, values, Sqlite.COL_DEFAULT_PACKAGE + " = ? ", new String[]{packageName});
+ } catch (Exception ignored) {
+ }
+ }
+
+ public int removeApp(String packageName) {
+ return db.delete(Sqlite.TABLE_DEFAULT_APPS, Sqlite.COL_DEFAULT_PACKAGE + " = \"" + packageName + "\"", null);
+ }
+
+ public int removeAll() {
+ return db.delete(Sqlite.TABLE_DEFAULT_APPS, null, null);
+ }
+
+ public ArrayList getConcurrent(String packageName) {
+ try {
+ Cursor c = db.query(Sqlite.TABLE_DEFAULT_APPS, null, Sqlite.COL_DEFAULT_PACKAGE + " = '" + packageName + "'", null, null, null, null, null);
+ return cursorGetConcurrent(c);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public ArrayList getDefault() {
+ try {
+ Cursor c = db.query(Sqlite.TABLE_DEFAULT_APPS, null, null, null, null, null, null, null);
+ return cursorGetDefaults(c);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public String getDefault(ArrayList packageNames) {
+ try {
+ Cursor c = db.query(Sqlite.TABLE_DEFAULT_APPS, null, Sqlite.COL_DEFAULT_PACKAGE + " IN ( " + Utils.arrayToStringQuery(packageNames) + ")", null, null, null, null, null);
+ return getBestMatchIfExists(c, packageNames);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public boolean isPresent(String packageName) {
+ Cursor mCount = db.rawQuery("select count(*) from " + Sqlite.TABLE_DEFAULT_APPS
+ + " where " + Sqlite.COL_DEFAULT_PACKAGE + " = '" + packageName + "'", null);
+ mCount.moveToFirst();
+ int count = mCount.getInt(0);
+ mCount.close();
+ return count > 0;
+ }
+
+ private ArrayList cursorGetConcurrent(Cursor c) {
+ if (c.getCount() == 0) {
+ c.close();
+ return null;
+ }
+ ArrayList items = null;
+ if (c.moveToFirst()) {
+ String concurrentStr = c.getString(c.getColumnIndex(Sqlite.COL_CONCURRENT_PACKAGES));
+ items = Utils.stringToArray(concurrentStr);
+ }
+ c.close();
+ return items;
+ }
+
+
+ private ArrayList cursorGetDefaults(Cursor c) {
+ if (c.getCount() == 0) {
+ c.close();
+ return null;
+ }
+ ArrayList items = new ArrayList<>();
+ while (c.moveToNext()) {
+ String packageName = c.getString(c.getColumnIndex(Sqlite.COL_DEFAULT_PACKAGE));
+ items.add(packageName);
+ }
+ c.close();
+ return items;
+ }
+
+
+ private String getBestMatchIfExists(Cursor c, ArrayList allPackages) {
+ if (c.getCount() == 0) {
+ c.close();
+ return null;
+ }
+ ArrayList concurrent = new ArrayList<>();
+ while (c.moveToNext()) {
+ String packageName = c.getString(c.getColumnIndex(Sqlite.COL_CONCURRENT_PACKAGES));
+ concurrent.addAll(Utils.stringToArray(packageName));
+ }
+ for (String conc : concurrent) {
+ allPackages.remove(conc);
+ }
+ c.close();
+ //Items will only returns concurrent for default apps.
+ //The winner will be the one not in concurrent
+ if (allPackages.size() == 1) {
+ return allPackages.get(0);
+ } else return null;
+ }
+
+}
diff --git a/app/src/main/java/app/fedilab/nitterizeme/sqlite/Sqlite.java b/app/src/main/java/app/fedilab/nitterizeme/sqlite/Sqlite.java
new file mode 100644
index 0000000..4cccaa1
--- /dev/null
+++ b/app/src/main/java/app/fedilab/nitterizeme/sqlite/Sqlite.java
@@ -0,0 +1,67 @@
+package app.fedilab.nitterizeme.sqlite;
+/* Copyright 2020 Thomas Schneider
+ *
+ * This file is a part of UntrackMe
+ *
+ * This program is free software; you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * UntrackMe is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with UntrackMe; if not,
+ * see . */
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+
+public class Sqlite extends SQLiteOpenHelper {
+
+ public static final int DB_VERSION = 1;
+ public static final String DB_NAME = "untrackme_db";
+ static final String TABLE_DEFAULT_APPS = "DEFAULT_APPS";
+ static final String COL_DEFAULT_PACKAGE = "DEFAULT_PACKAGE";
+ static final String COL_CONCURRENT_PACKAGES = "CONCURRENT_PACKAGES";
+ private static final String COL_ID = "ID";
+ private static final String CREATE_TABLE_DEFAULT_APPS = "CREATE TABLE " + TABLE_DEFAULT_APPS + " ("
+ + COL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ + COL_DEFAULT_PACKAGE + " TEXT NOT NULL UNIQUE, " + COL_CONCURRENT_PACKAGES + " TEXT)";
+ private static SQLiteDatabase db;
+ private static Sqlite sInstance;
+
+
+ private Sqlite(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
+ super(context, name, factory, version);
+ }
+
+ public static synchronized Sqlite getInstance(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
+ if (sInstance == null) {
+ sInstance = new Sqlite(context, name, factory, version);
+ }
+ return sInstance;
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ db.execSQL(CREATE_TABLE_DEFAULT_APPS);
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+
+ }
+
+ public SQLiteDatabase open() {
+ db = getWritableDatabase();
+ return db;
+ }
+
+ public void close() {
+ if (db != null && db.isOpen()) {
+ db.close();
+ }
+ }
+}
diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
deleted file mode 100644
index 1f6bb29..0000000
--- a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/drawable/ic_app_logo.xml b/app/src/main/res/drawable/ic_app_logo.xml
new file mode 100644
index 0000000..04ee601
--- /dev/null
+++ b/app/src/main/res/drawable/ic_app_logo.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_delete.xml b/app/src/main/res/drawable/ic_delete.xml
new file mode 100644
index 0000000..3760de2
--- /dev/null
+++ b/app/src/main/res/drawable/ic_delete.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/drawable/img1.jpg b/app/src/main/res/drawable/img1.jpg
new file mode 100755
index 0000000..080f825
Binary files /dev/null and b/app/src/main/res/drawable/img1.jpg differ
diff --git a/app/src/main/res/drawable/img2.jpg b/app/src/main/res/drawable/img2.jpg
new file mode 100755
index 0000000..6867afa
Binary files /dev/null and b/app/src/main/res/drawable/img2.jpg differ
diff --git a/app/src/main/res/drawable/img3.jpg b/app/src/main/res/drawable/img3.jpg
new file mode 100755
index 0000000..a3d3bf7
Binary files /dev/null and b/app/src/main/res/drawable/img3.jpg differ
diff --git a/app/src/main/res/drawable/rounded_error.xml b/app/src/main/res/drawable/rounded_error.xml
new file mode 100644
index 0000000..4b4c173
--- /dev/null
+++ b/app/src/main/res/drawable/rounded_error.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/rounded_selector.xml b/app/src/main/res/drawable/rounded_selector.xml
new file mode 100644
index 0000000..4527ef3
--- /dev/null
+++ b/app/src/main/res/drawable/rounded_selector.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_default_app.xml b/app/src/main/res/layout/activity_default_app.xml
new file mode 100644
index 0000000..a10f482
--- /dev/null
+++ b/app/src/main/res/layout/activity_default_app.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_pickup_app.xml b/app/src/main/res/layout/activity_pickup_app.xml
new file mode 100644
index 0000000..5e91a63
--- /dev/null
+++ b/app/src/main/res/layout/activity_pickup_app.xml
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/content_main.xml b/app/src/main/res/layout/content_main.xml
index 6b92d6c..65e800e 100644
--- a/app/src/main/res/layout/content_main.xml
+++ b/app/src/main/res/layout/content_main.xml
@@ -638,7 +638,7 @@
style="@style/containerCard"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintBottom_toTopOf="@+id/display_indications"
app:layout_constraintTop_toBottomOf="@id/osm_container">