diff --git a/app/build.gradle b/app/build.gradle index ee7a10b..ef4b0f3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -43,7 +43,7 @@ dependencies { implementation fileTree(dir: "libs", include: ["*.jar"]) implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'com.google.android.material:material:1.2.1' - implementation 'androidx.constraintlayout:constraintlayout:2.0.1' + implementation 'androidx.constraintlayout:constraintlayout:2.0.2' implementation 'androidx.navigation:navigation-fragment:2.3.0' implementation 'androidx.navigation:navigation-ui:2.3.0' testImplementation 'junit:junit:4.13' @@ -54,5 +54,5 @@ dependencies { implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' implementation 'com.github.GrenderG:Toasty:1.4.2' - + implementation 'com.karumi:dexter:6.2.1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 45b7f48..0601f97 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -5,9 +5,10 @@ - + + diff --git a/app/src/main/java/app/fedilab/mobilizon/MainActivity.java b/app/src/main/java/app/fedilab/mobilizon/MainActivity.java index 3d95713..7517241 100644 --- a/app/src/main/java/app/fedilab/mobilizon/MainActivity.java +++ b/app/src/main/java/app/fedilab/mobilizon/MainActivity.java @@ -2,18 +2,13 @@ package app.fedilab.mobilizon; import android.Manifest; import android.annotation.SuppressLint; -import android.annotation.TargetApi; +import android.app.Activity; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; -import android.location.Location; -import android.location.LocationListener; -import android.location.LocationManager; import android.net.Uri; -import android.os.Build; import android.os.Bundle; import android.text.SpannableString; import android.text.style.UnderlineSpan; @@ -22,6 +17,7 @@ import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.webkit.ValueCallback; import android.webkit.WebView; import android.widget.EditText; import android.widget.FrameLayout; @@ -40,11 +36,15 @@ import androidx.core.view.GravityCompat; import androidx.drawerlayout.widget.DrawerLayout; import com.google.android.material.navigation.NavigationView; +import com.karumi.dexter.Dexter; +import com.karumi.dexter.MultiplePermissionsReport; +import com.karumi.dexter.PermissionToken; +import com.karumi.dexter.listener.PermissionRequest; +import com.karumi.dexter.listener.multi.MultiplePermissionsListener; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; -import java.util.ArrayList; import java.util.List; import app.fedilab.mobilizon.client.RetrofitMobilizonAPI; @@ -56,35 +56,12 @@ import es.dmoral.toasty.Toasty; public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { - //public static int PICK_INSTANCE = 5641; + public static final int INPUT_FILE_REQUEST_CODE = 123; public static boolean isAuthenticated = false; - final private int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124; - private final LocationListener mLocationListener = new LocationListener() { - @Override - public void onLocationChanged(@NonNull final Location location) { - SharedPreferences sharedpref = getSharedPreferences(Helper.APP_SHARED_PREF, MODE_PRIVATE); - SharedPreferences.Editor editor = sharedpref.edit(); - editor.putString(Helper.LAST_LOCATION, location.getLongitude() + "," + location.getLatitude() + "," + location.getAltitude()); - editor.apply(); - } - - @Override - public void onStatusChanged(String provider, int status, Bundle extras) { - - } - - @Override - public void onProviderEnabled(@NonNull String provider) { - } - - @Override - public void onProviderDisabled(@NonNull String provider) { - - } - }; private RelativeLayout progress; private WebView main_webview; private FrameLayout webview_container; + private ValueCallback mFilePathCallback; @Override protected void onCreate(Bundle savedInstanceState) { @@ -111,9 +88,6 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On final NavigationView navigationView = findViewById(R.id.nav_view); navigationView.setNavigationItemSelectedListener(this); - if (Build.VERSION.SDK_INT >= 23) { - permissionsAPI(); - } WebView.setWebContentsDebuggingEnabled(true); drawMenu(); @@ -128,8 +102,24 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On main_webview.setWebChromeClient(mobilizonWebChromeClient); main_webview.setWebViewClient(new MobilizonWebViewClient(MainActivity.this)); + showProgressDialog(); main_webview.loadUrl("https://" + instance); + Dexter.withContext(this) + .withPermissions( + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION + ) + .withListener(new MultiplePermissionsListener() { + @Override + public void onPermissionsChecked(MultiplePermissionsReport report) {/* ... */} + + @Override + public void onPermissionRationaleShouldBeShown(List permissions, PermissionToken token) {/* ... */} + }).check(); + + } @Override @@ -244,7 +234,6 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On } } - @Override public void onBackPressed() { if (main_webview.canGoBack()) { @@ -258,15 +247,15 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On public boolean onNavigationItemSelected(@NonNull MenuItem item) { int id = item.getItemId(); if (id == R.id.nav_explore) { - main_webview.loadUrl("https://" + Helper.getLiveInstance(MainActivity.this) + "/search"); + main_webview.loadUrl("javascript:document.querySelector('a[href=\"/search\"]').click();"); } else if (id == R.id.nav_my_event) { - main_webview.loadUrl("https://" + Helper.getLiveInstance(MainActivity.this) + "/events/me"); + main_webview.loadUrl("javascript:document.querySelector('a[href=\"/events/me\"]').click();"); } else if (id == R.id.nav_my_group) { - main_webview.loadUrl("https://" + Helper.getLiveInstance(MainActivity.this) + "/groups/me"); + main_webview.loadUrl("javascript:document.querySelector('a[href=\"/groups/me\"]').click();"); } else if (id == R.id.nav_create_event) { - main_webview.loadUrl("https://" + Helper.getLiveInstance(MainActivity.this) + "/events/create"); + main_webview.loadUrl("javascript:document.querySelector('a[href=\"/events/create\"]').click();"); } else if (id == R.id.nav_login) { - main_webview.loadUrl("https://" + Helper.getLiveInstance(MainActivity.this) + "/login"); + main_webview.loadUrl("javascript:document.querySelector('a[href=\"/login\"]').click();"); } else if (id == R.id.nav_logout) { Helper.clearCookies(); new java.util.Timer().schedule( @@ -283,9 +272,9 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On 1000 ); } else if (id == R.id.nav_profile) { - main_webview.loadUrl("https://" + Helper.getLiveInstance(MainActivity.this) + "/identity/update"); + main_webview.loadUrl("javascript:document.querySelector('a[href=\"/identity/update\"]').click();"); } else if (id == R.id.nav_register) { - main_webview.loadUrl("https://" + Helper.getLiveInstance(MainActivity.this) + "/register/user"); + main_webview.loadUrl("javascript:document.querySelector('a[href=\"/register/user\"]').click();"); } DrawerLayout drawer = findViewById(R.id.drawer_layout); @@ -310,7 +299,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On (dialog, which) -> new Thread(() -> { try { String newInstance = input.getText().toString().trim(); - WellKnownNodeinfo.NodeInfo instanceNodeInfo = new RetrofitMobilizonAPI(MainActivity.this, newInstance).getNodeInfo(); + WellKnownNodeinfo.NodeInfo instanceNodeInfo = new RetrofitMobilizonAPI(newInstance).getNodeInfo(); if (instanceNodeInfo.getSoftware() != null && instanceNodeInfo.getSoftware().getName().trim().toLowerCase().compareTo("mobilizon") == 0) { SharedPreferences.Editor editor = sharedpreferences.edit(); editor.putString(Helper.PREF_INSTANCE, newInstance); @@ -338,57 +327,31 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On alert.show(); } - @TargetApi(Build.VERSION_CODES.M) - private void permissionsAPI() { - List permissionsNeeded = new ArrayList<>(); + public ValueCallback getmFilePathCallback() { + return mFilePathCallback; + } - final List permissionsList = new ArrayList<>(); - if (!addPermission(permissionsList)) - permissionsNeeded.add(getString(R.string.show_location)); + public void setmFilePathCallback(ValueCallback mFilePathCallback) { + this.mFilePathCallback = mFilePathCallback; + } - if (permissionsList.size() > 0) { - if (permissionsNeeded.size() > 0) { - - // Need Rationale - StringBuilder message = new StringBuilder(getString(R.string.access_needed, permissionsNeeded.get(0))); - - for (int i = 1; i < permissionsNeeded.size(); i++) - message.append(", ").append(permissionsNeeded.get(i)); - - showMessageOKCancel(message.toString(), - (dialog, which) -> requestPermissions(permissionsList.toArray(new String[0]), - REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS)); - return; + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + if (requestCode != INPUT_FILE_REQUEST_CODE || mFilePathCallback == null) { + super.onActivityResult(requestCode, resultCode, data); + return; + } + Uri[] results = null; + if (resultCode == Activity.RESULT_OK) { + if (data != null) { + String dataString = data.getDataString(); + if (dataString != null) { + results = new Uri[]{Uri.parse(dataString)}; + } } - requestPermissions(permissionsList.toArray(new String[0]), - REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS); } - } - - private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) { - new AlertDialog.Builder(MainActivity.this) - .setMessage(message) - .setPositiveButton(getString(R.string.validate), okListener) - .setNegativeButton(getString(R.string.cancel), null) - .create() - .show(); - } - - @TargetApi(Build.VERSION_CODES.M) - private boolean addPermission(List permissionsList) { - - if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { - permissionsList.add(Manifest.permission.ACCESS_FINE_LOCATION); - // Check for Rationale Option - return shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION); - } else { - LocationManager mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE); - - assert mLocationManager != null; - mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, Helper.LOCATION_REFRESH_TIME, - Helper.LOCATION_REFRESH_DISTANCE, mLocationListener); - } - return true; + mFilePathCallback.onReceiveValue(results); + mFilePathCallback = null; } public void drawMenu() { diff --git a/app/src/main/java/app/fedilab/mobilizon/client/RetrofitMobilizonAPI.java b/app/src/main/java/app/fedilab/mobilizon/client/RetrofitMobilizonAPI.java index a8b912c..6ef34bb 100644 --- a/app/src/main/java/app/fedilab/mobilizon/client/RetrofitMobilizonAPI.java +++ b/app/src/main/java/app/fedilab/mobilizon/client/RetrofitMobilizonAPI.java @@ -14,13 +14,11 @@ package app.fedilab.mobilizon.client; * You should have received a copy of the GNU General Public License along with Mobilizon app; if not, * see . */ -import android.content.Context; import java.io.IOException; import java.net.URL; import app.fedilab.mobilizon.client.entities.WellKnownNodeinfo; -import app.fedilab.mobilizon.helper.Helper; import retrofit2.Call; import retrofit2.Response; import retrofit2.Retrofit; @@ -30,20 +28,9 @@ public class RetrofitMobilizonAPI { private String finalUrl; - private Context _context; - private String instance; - public RetrofitMobilizonAPI(Context context) { - _context = context; - instance = Helper.getLiveInstance(context); - finalUrl = "https://" + Helper.getLiveInstance(context) + "/api/v1/"; - } - - - public RetrofitMobilizonAPI(Context context, String instance) { - _context = context; - this.instance = instance; + public RetrofitMobilizonAPI(String instance) { finalUrl = "https://" + instance.toLowerCase() + "/"; } diff --git a/app/src/main/java/app/fedilab/mobilizon/helper/Helper.java b/app/src/main/java/app/fedilab/mobilizon/helper/Helper.java index 4cff3cb..eef17f7 100644 --- a/app/src/main/java/app/fedilab/mobilizon/helper/Helper.java +++ b/app/src/main/java/app/fedilab/mobilizon/helper/Helper.java @@ -29,13 +29,8 @@ import java.io.InputStream; * see . */ public class Helper { - public static final String TAG = "mobilizon_app"; public static final String APP_PREFS = "app_prefs"; public static final String PREF_INSTANCE = "instance"; - public static String APP_SHARED_PREF = "app_shared_prefs"; - public static String LAST_LOCATION = "last_location"; - public static int LOCATION_REFRESH_TIME = 60000; - public static int LOCATION_REFRESH_DISTANCE = 100; /** * Returns the preferred instance @@ -63,7 +58,6 @@ public class Helper { webView.getSettings().setSupportZoom(true); webView.getSettings().setDisplayZoomControls(false); webView.getSettings().setBuiltInZoomControls(true); - webView.getSettings().setAllowContentAccess(true); webView.getSettings().setLoadsImagesAutomatically(true); webView.getSettings().setSupportMultipleWindows(false); webView.getSettings().setGeolocationDatabasePath(context.getFilesDir().getPath()); @@ -71,6 +65,10 @@ public class Helper { webView.getSettings().setAppCachePath(context.getCacheDir().getPath()); webView.getSettings().setAppCacheEnabled(true); webView.getSettings().setDatabaseEnabled(true); + webView.getSettings().setAllowFileAccess(true); + webView.getSettings().setAllowContentAccess(true); + webView.getSettings().setAllowFileAccessFromFileURLs(true); + webView.getSettings().setAllowUniversalAccessFromFileURLs(true); webView.getSettings().setDomStorageEnabled(true); webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE); webView.getSettings().setMediaPlaybackRequiresUserGesture(true); @@ -78,7 +76,7 @@ public class Helper { cookieManager.setAcceptThirdPartyCookies(webView, true); webView.setBackgroundColor(Color.TRANSPARENT); webView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); - + webView.requestFocus(); } diff --git a/app/src/main/java/app/fedilab/mobilizon/webview/MobilizonWebChromeClient.java b/app/src/main/java/app/fedilab/mobilizon/webview/MobilizonWebChromeClient.java index bc7cae2..0266ae9 100644 --- a/app/src/main/java/app/fedilab/mobilizon/webview/MobilizonWebChromeClient.java +++ b/app/src/main/java/app/fedilab/mobilizon/webview/MobilizonWebChromeClient.java @@ -15,17 +15,23 @@ package app.fedilab.mobilizon.webview; * see . */ import android.app.Activity; +import android.content.Intent; import android.media.MediaPlayer; +import android.net.Uri; import android.view.SurfaceView; import android.view.View; import android.view.ViewGroup; import android.webkit.GeolocationPermissions; +import android.webkit.ValueCallback; import android.webkit.WebChromeClient; import android.webkit.WebView; import android.widget.FrameLayout; import androidx.appcompat.app.AppCompatActivity; +import app.fedilab.mobilizon.MainActivity; + +import static app.fedilab.mobilizon.MainActivity.INPUT_FILE_REQUEST_CODE; /** @@ -79,6 +85,24 @@ public class MobilizonWebChromeClient extends WebChromeClient implements MediaPl super.onProgressChanged(view, newProgress); } + + @Override + public boolean onShowFileChooser(WebView webView, ValueCallback filePathCallback, FileChooserParams fileChooserParams) { + + if (((MainActivity) activity).getmFilePathCallback() != null) { + ((MainActivity) activity).getmFilePathCallback().onReceiveValue(null); + } + ((MainActivity) activity).setmFilePathCallback(filePathCallback); + + Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT); + contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE); + contentSelectionIntent.setType("*/*"); + Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER); + chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent); + this.activity.startActivityForResult(chooserIntent, INPUT_FILE_REQUEST_CODE); + return true; + } + @Override public void onShowCustomView(View view, CustomViewCallback callback) { if (view instanceof FrameLayout) { diff --git a/app/src/main/java/app/fedilab/mobilizon/webview/MobilizonWebViewClient.java b/app/src/main/java/app/fedilab/mobilizon/webview/MobilizonWebViewClient.java index 6a4e93e..0e5b5a9 100644 --- a/app/src/main/java/app/fedilab/mobilizon/webview/MobilizonWebViewClient.java +++ b/app/src/main/java/app/fedilab/mobilizon/webview/MobilizonWebViewClient.java @@ -87,9 +87,6 @@ public class MobilizonWebViewClient extends WebViewClient { @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { super.onPageStarted(view, url, favicon); - if (activity instanceof MainActivity) { - ((MainActivity) activity).showProgressDialog(); - } } diff --git a/app/src/main/res/layout/content_main.xml b/app/src/main/res/layout/content_main.xml index 953f8dd..d5e1b3d 100644 --- a/app/src/main/res/layout/content_main.xml +++ b/app/src/main/res/layout/content_main.xml @@ -16,7 +16,6 @@ app:layout_constraintTop_toTopOf="parent">