Replace WebView with new subclass ContextMenuWebView to allow long clicks on urls and images for sharing links, copying them to clipboard, saving images to external memory and opening them in external browsers.

This commit is contained in:
Paul Schaub 2016-04-08 21:59:46 +02:00
parent 760fca5150
commit a310151b93
5 changed files with 208 additions and 6 deletions

View File

@ -69,6 +69,7 @@ import android.widget.ProgressBar;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;
import com.getbase.floatingactionbutton.FloatingActionsMenu;
import com.github.dfa.diaspora_android.App;
@ -77,6 +78,7 @@ import com.github.dfa.diaspora_android.data.AppSettings;
import com.github.dfa.diaspora_android.data.WebUserProfile;
import com.github.dfa.diaspora_android.listener.SoftKeyboardStateWatcher;
import com.github.dfa.diaspora_android.listener.WebUserProfileChangedListener;
import com.github.dfa.diaspora_android.ui.ContextMenuWebView;
import com.github.dfa.diaspora_android.util.Helpers;
import org.json.JSONException;
@ -96,6 +98,7 @@ public class MainActivity extends AppCompatActivity
static final int INPUT_FILE_REQUEST_CODE = 1;
private static final int REQUEST_CODE_ASK_PERMISSIONS = 123;
public static final int REQUEST_CODE_ASK_PERMISSIONS_SAVE_IMAGE = 124;
private static final String URL_MESSAGE = "URL_MESSAGE";
private App app;
@ -120,7 +123,7 @@ public class MainActivity extends AppCompatActivity
Toolbar toolbar;
@Bind(R.id.webView)
WebView webView;
ContextMenuWebView webView;
@Bind(R.id.fab_menubutton)
FloatingActionsMenu fab;
@ -147,6 +150,9 @@ public class MainActivity extends AppCompatActivity
appSettings = app.getSettings();
webUserProfile = new WebUserProfile(app, uiHandler, this);
this.registerForContextMenu(webView);
webView.setParentActivity(this);
// Setup toolbar
setSupportActionBar(toolbar);
toolbar.setOnClickListener(new View.OnClickListener() {
@ -599,7 +605,7 @@ public class MainActivity extends AppCompatActivity
if (hasWRITE_EXTERNAL_STORAGE != PackageManager.PERMISSION_GRANTED) {
if (!shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
new AlertDialog.Builder(MainActivity.this)
.setMessage(R.string.permissions)
.setMessage(R.string.permissions_screenshot)
.setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
@ -662,7 +668,7 @@ public class MainActivity extends AppCompatActivity
if (hasWRITE_EXTERNAL_STORAGE != PackageManager.PERMISSION_GRANTED) {
if (!shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
new AlertDialog.Builder(MainActivity.this)
.setMessage(R.string.permissions)
.setMessage(R.string.permissions_screenshot)
.setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
@ -1095,4 +1101,22 @@ public class MainActivity extends AppCompatActivity
return true;
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE_ASK_PERMISSIONS_SAVE_IMAGE:
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, R.string.permission_granted_try_again, Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(this, R.string.permission_denied, Toast.LENGTH_SHORT).show();
}
return;
default:
super.onRequestPermissionsResult(requestCode, permissions,
grantResults);
}
}
}

View File

@ -0,0 +1,153 @@
package com.github.dfa.diaspora_android.ui;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.DownloadManager;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Environment;
import android.util.AttributeSet;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.webkit.WebView;
import android.widget.Toast;
import com.github.dfa.diaspora_android.R;
import com.github.dfa.diaspora_android.activity.MainActivity;
import java.io.File;
/**
* Subclass of WebView which adds a context menu for long clicks on images or links to share, save
* or open with another browser
*/
public class ContextMenuWebView extends WebView {
public static final int ID_SAVE_IMAGE = 10;
public static final int ID_EXTERNAL_BROWSER = 11;
public static final int ID_COPY_LINK = 12;
public static final int ID_SHARE_LINK = 13;
private Context context;
private Activity parentActivity;
public ContextMenuWebView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.context = context;
}
public ContextMenuWebView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
}
@Override
protected void onCreateContextMenu(ContextMenu menu) {
super.onCreateContextMenu(menu);
HitTestResult result = getHitTestResult();
MenuItem.OnMenuItemClickListener handler = new MenuItem.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
HitTestResult result = getHitTestResult();
String url = result.getExtra();
switch(item.getItemId()) {
//Save image to external memory
case ID_SAVE_IMAGE: {
boolean writeToStoragePermitted = true;
if (android.os.Build.VERSION.SDK_INT >= 23) {
int hasWRITE_EXTERNAL_STORAGE = parentActivity.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (hasWRITE_EXTERNAL_STORAGE != PackageManager.PERMISSION_GRANTED) {
writeToStoragePermitted = false;
if (!parentActivity.shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
new AlertDialog.Builder(parentActivity)
.setMessage(R.string.permissions_images)
.setPositiveButton(context.getText(R.string.yes), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (android.os.Build.VERSION.SDK_INT >= 23)
parentActivity.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
MainActivity.REQUEST_CODE_ASK_PERMISSIONS_SAVE_IMAGE);
}
})
.setNegativeButton(context.getText(R.string.no), null)
.show();
}
parentActivity.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
MainActivity.REQUEST_CODE_ASK_PERMISSIONS_SAVE_IMAGE);
}
}
if(writeToStoragePermitted) {
if (url != null) {
Uri source = Uri.parse(url);
DownloadManager.Request request = new DownloadManager.Request(source);
File destinationFile = new File(Environment.getExternalStorageDirectory() + "/Pictures/Diaspora/"
+ source.getLastPathSegment());
request.setDestinationUri(Uri.fromFile(destinationFile));
((DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE)).enqueue(request);
Toast.makeText(context, context.getText(R.string.toast_saved_image_to_location) + " " +
destinationFile.getAbsolutePath(), Toast.LENGTH_LONG).show();
}
}
}
break;
case ID_EXTERNAL_BROWSER:
if(url != null) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
context.startActivity(intent);
}
break;
//Copy url to clipboard
case ID_COPY_LINK:
if(url != null) {
ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
clipboard.setPrimaryClip(ClipData.newPlainText("text", url));
Toast.makeText(context, R.string.toast_link_address_copied, Toast.LENGTH_SHORT).show();
}
break;
//Try to share link to other apps
case ID_SHARE_LINK:
if(url != null) {
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, url);
sendIntent.setType("text/plain");
context.startActivity(Intent.createChooser(sendIntent, getResources()
.getText(R.string.context_menu_share_link)));
}
break;
}
return true;
}
};
//Build context menu
if (result.getType() == HitTestResult.IMAGE_TYPE ||
result.getType() == HitTestResult.SRC_IMAGE_ANCHOR_TYPE) {
// Menu options for an image.
menu.setHeaderTitle(result.getExtra());
menu.add(0, ID_SAVE_IMAGE, 0, context.getString(R.string.context_menu_save_image)).setOnMenuItemClickListener(handler);
menu.add(0, ID_EXTERNAL_BROWSER, 0, context.getString(R.string.context_menu_open_external_browser)).setOnMenuItemClickListener(handler);
}
else if (result.getType() == HitTestResult.ANCHOR_TYPE ||
result.getType() == HitTestResult.SRC_ANCHOR_TYPE) {
// Menu options for a hyperlink.
menu.setHeaderTitle(result.getExtra());
menu.add(0, ID_COPY_LINK, 0, context.getString(R.string.context_menu_copy_link)).setOnMenuItemClickListener(handler);
menu.add(0, ID_SHARE_LINK, 0, context.getString(R.string.context_menu_share_link)).setOnMenuItemClickListener(handler);
}
}
public void setParentActivity(Activity activity) {
this.parentActivity = activity;
}
}

View File

@ -13,7 +13,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView
<com.github.dfa.diaspora_android.ui.ContextMenuWebView
android:id="@+id/webView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"

View File

@ -17,11 +17,18 @@
<string name="no">NEIN</string>
<string name="change_pod_warning">Das wird alle Cookies und Session-Daten löschen. Willst du wirklich den Pod wechseln?</string>
<string name="permissions">Du musst der App Zugriff auf den Gerätespeicher gewähren, damit das Bildschirmfoto
<string name="permissions_screenshot">Du musst der App Zugriff auf den Gerätespeicher gewähren, damit das Bildschirmfoto
gespeichert werden kann. Danach solltest du die Anwendung komplett schließen oder das Telefon neu starten.
Wenn du den Zugriff verweigerst und die Funktion später doch nutzen willst, kannst du die Berechtigung
nachträglich erteilen. Öffne dafür: Systemeinstellungen - Apps - Wetter. Im Bereich Berechtigungen kannst
dann die entsprechende Einstellung vornehmen.</string>
<string name="permissions_images">Du musst der App Zugriff auf den Gerätespeicher gewähren, damit das Bild
gespeichert werden kann. Danach solltest du die Anwendung komplett schließen oder das Telefon neu starten.
Wenn du den Zugriff verweigerst und die Funktion später doch nutzen willst, kannst du die Berechtigung
nachträglich erteilen. Öffne dafür: Systemeinstellungen - Apps - Wetter. Im Bereich Berechtigungen kannst
dann die entsprechende Einstellung vornehmen.</string>
<string name="permission_denied">Berechtigung verweigert.</string>
<string name="permission_granted_try_again">Berechtigung erteilt. Bitte versuche es erneut.</string>
// Drawer and App
@ -154,5 +161,11 @@ along with this program. If not, see http://www.gnu.org/licenses.&lt;br> &lt;br
<string name="shared_by_diaspora_android">*[geteilt durch #DiasporaForAndroid]*</string>
<string name="settings_images_switch_off">Bilder nicht laden</string>
<string name="settings_images_switch_on">Bilder laden</string>
<string name="context_menu_save_image">Bild speichern</string>
<string name="context_menu_copy_link">Linkadresse kopieren</string>
<string name="context_menu_share_link">Linkadresse teilen</string>
<string name="context_menu_open_external_browser">In externem Browser öffnen…</string>
<string name="toast_saved_image_to_location">Speichere Bild als</string>
<string name="toast_link_address_copied">Linkadresse kopiert …</string>
</resources>

View File

@ -8,10 +8,16 @@
<string name="reload">Reload</string>
<string name="new_notifications">Unread notification. Want to read it?</string>
<string name="new_conversations">Unread conversation. Open it?</string>
<string name="permissions">You must grant \"Access Storage Permission\" to save screenshots. After that you should
<string name="permissions_screenshot">You must grant \"Access Storage Permission\" to save screenshots. After that you should
completely close the app or restart the phone. If you don\'t permit the storage access but want to use the
screenshot function at a later time, you can grant the permission later. Please open then: systemsettings - apps -
weather. In the permissions section you can grant the \"write storage permission\".</string>
<string name="permissions_image">You must grant \"Access Storage Permission\" to save images. After that you should
completely close the app or restart the phone. If you don\'t permit the storage access but want to save images
at a later time, you can grant the permission later. Please open then: systemsettings - apps -
weather. In the permissions section you can grant the \"write storage permission\".</string>
<string name="permission_denied">Permission denied.</string>
<string name="permission_granted_try_again">Permission granted. Please try again.</string>
//Pod Activity
@ -198,4 +204,10 @@
<string name="exit_app">Exit app</string>
<string name="diaspora" translatable="false">Diaspora</string>
<string name="shared_by_diaspora_android">*[shared by #DiasporaForAndroid]*</string>
<string name="toast_link_address_copied">Link address copied …</string>
<string name="context_menu_share_link">Share link address</string>
<string name="context_menu_save_image">Save image</string>
<string name="context_menu_open_external_browser">Open in external browser …</string>
<string name="context_menu_copy_link">Copy link address to clipboard</string>
<string name="toast_saved_image_to_location">Saving image to</string>
</resources>