зеркало из https://github.com/mozilla/gecko-dev.git
Bug 769438 - Support sharing images via long press r=snorp
This commit is contained in:
Родитель
d3ff86c923
Коммит
3fc748b074
|
@ -1250,6 +1250,10 @@ abstract public class GeckoApp
|
|||
} else if (event.equals("Share:Text")) {
|
||||
String text = message.getString("text");
|
||||
GeckoAppShell.openUriExternal(text, "text/plain", "", "", Intent.ACTION_SEND, "");
|
||||
} else if (event.equals("Share:Image")) {
|
||||
String src = message.getString("url");
|
||||
String type = message.getString("mime");
|
||||
GeckoAppShell.shareImage(src, type);
|
||||
} else if (event.equals("Sanitize:ClearHistory")) {
|
||||
handleClearHistory();
|
||||
}
|
||||
|
@ -1936,6 +1940,7 @@ abstract public class GeckoApp
|
|||
GeckoAppShell.registerGeckoEventListener("WebApps:Uninstall", GeckoApp.mAppContext);
|
||||
GeckoAppShell.registerGeckoEventListener("DesktopMode:Changed", GeckoApp.mAppContext);
|
||||
GeckoAppShell.registerGeckoEventListener("Share:Text", GeckoApp.mAppContext);
|
||||
GeckoAppShell.registerGeckoEventListener("Share:Image", GeckoApp.mAppContext);
|
||||
GeckoAppShell.registerGeckoEventListener("Sanitize:ClearHistory", GeckoApp.mAppContext);
|
||||
|
||||
if (SmsManager.getInstance() != null) {
|
||||
|
@ -2281,8 +2286,11 @@ abstract public class GeckoApp
|
|||
GeckoAppShell.unregisterGeckoEventListener("WebApps:Uninstall", GeckoApp.mAppContext);
|
||||
GeckoAppShell.unregisterGeckoEventListener("DesktopMode:Changed", GeckoApp.mAppContext);
|
||||
GeckoAppShell.unregisterGeckoEventListener("Share:Text", GeckoApp.mAppContext);
|
||||
GeckoAppShell.unregisterGeckoEventListener("Share:Image", GeckoApp.mAppContext);
|
||||
GeckoAppShell.unregisterGeckoEventListener("Sanitize:ClearHistory", GeckoApp.mAppContext);
|
||||
|
||||
deleteTempFiles();
|
||||
|
||||
if (mFavicons != null)
|
||||
mFavicons.close();
|
||||
|
||||
|
@ -2300,6 +2308,25 @@ abstract public class GeckoApp
|
|||
((GeckoApplication) getApplication()).removeApplicationLifecycleCallbacks(this);
|
||||
}
|
||||
|
||||
// Get/Create a temporary direcory
|
||||
public static File getTempDirectory() {
|
||||
File sdcard = Environment.getExternalStorageDirectory();
|
||||
File dir = new File(sdcard.getAbsolutePath() + "/firefox");
|
||||
dir.mkdirs();
|
||||
return dir;
|
||||
}
|
||||
|
||||
// Delete any files in our temporary directory
|
||||
public static void deleteTempFiles() {
|
||||
File[] files = getTempDirectory().listFiles();
|
||||
if (files == null)
|
||||
return;
|
||||
|
||||
for (File file : files) {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onContentChanged() {
|
||||
super.onContentChanged();
|
||||
|
|
|
@ -20,6 +20,8 @@ import org.mozilla.gecko.gfx.RectUtils;
|
|||
import java.io.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.nio.*;
|
||||
import java.net.URL;
|
||||
import java.net.MalformedURLException;
|
||||
import java.text.*;
|
||||
import java.util.*;
|
||||
import java.util.zip.*;
|
||||
|
@ -1054,6 +1056,79 @@ public class GeckoAppShell
|
|||
return type + "/" + subType;
|
||||
}
|
||||
|
||||
static void safeStreamClose(Closeable stream) {
|
||||
try {
|
||||
if (stream != null)
|
||||
stream.close();
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
|
||||
static void shareImage(String aSrc, String aType) {
|
||||
|
||||
Intent intent = new Intent(Intent.ACTION_SEND);
|
||||
boolean isDataURI = aSrc.startsWith("data:");
|
||||
OutputStream os = null;
|
||||
|
||||
File dir = GeckoApp.getTempDirectory();
|
||||
GeckoApp.deleteTempFiles();
|
||||
|
||||
try {
|
||||
// Create a temporary file for the image
|
||||
File imageFile = File.createTempFile("image",
|
||||
"." + aType.replace("image/",""),
|
||||
dir);
|
||||
os = new FileOutputStream(imageFile);
|
||||
|
||||
if (isDataURI) {
|
||||
// We are dealing with a Data URI
|
||||
int dataStart = aSrc.indexOf(',');
|
||||
byte[] buf = Base64.decode(aSrc.substring(dataStart+1), Base64.DEFAULT);
|
||||
os.write(buf);
|
||||
} else {
|
||||
// We are dealing with a URL
|
||||
InputStream is = null;
|
||||
try {
|
||||
URL url = new URL(aSrc);
|
||||
is = url.openStream();
|
||||
byte[] buf = new byte[2048];
|
||||
int length;
|
||||
|
||||
while ((length = is.read(buf)) != -1) {
|
||||
os.write(buf, 0, length);
|
||||
}
|
||||
} finally {
|
||||
safeStreamClose(is);
|
||||
}
|
||||
}
|
||||
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(imageFile));
|
||||
|
||||
// If we were able to determine the image type, send that in the intent. Otherwise,
|
||||
// use a generic type.
|
||||
if (aType.startsWith("image/")) {
|
||||
intent.setType(aType);
|
||||
} else {
|
||||
intent.setType("image/*");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
if (!isDataURI) {
|
||||
// If we failed, at least send through the URL link
|
||||
intent.putExtra(Intent.EXTRA_TEXT, aSrc);
|
||||
intent.setType("text/plain");
|
||||
} else {
|
||||
// Don't fail silently, tell the user that we weren't able to share the image
|
||||
Toast toast = Toast.makeText(GeckoApp.mAppContext,
|
||||
GeckoApp.mAppContext.getResources().getString(R.string.share_image_failed),
|
||||
Toast.LENGTH_SHORT);
|
||||
toast.show();
|
||||
return;
|
||||
}
|
||||
} finally {
|
||||
safeStreamClose(os);
|
||||
}
|
||||
GeckoApp.mAppContext.startActivity(Intent.createChooser(intent,
|
||||
GeckoApp.mAppContext.getResources().getString(R.string.share_title)));
|
||||
}
|
||||
|
||||
static boolean openUriExternal(String aUriSpec, String aMimeType, String aPackageName,
|
||||
String aClassName, String aAction, String aTitle) {
|
||||
Intent intent = getIntentForActionString(aAction);
|
||||
|
|
|
@ -105,6 +105,7 @@
|
|||
|
||||
<!ENTITY share "Share">
|
||||
<!ENTITY share_title "Share via">
|
||||
<!ENTITY share_image_failed "Unable to share this image">
|
||||
<!ENTITY save_as_pdf "Save as PDF">
|
||||
<!ENTITY find_in_page "Find in Page">
|
||||
<!ENTITY desktop_mode "Request Desktop Site">
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
|
||||
<string name="share">&share;</string>
|
||||
<string name="share_title">&share_title;</string>
|
||||
<string name="share_image_failed">&share_image_failed;</string>
|
||||
<string name="save_as_pdf">&save_as_pdf;</string>
|
||||
<string name="find_in_page">&find_in_page;</string>
|
||||
<string name="desktop_mode">&desktop_mode;</string>
|
||||
|
|
|
@ -1138,6 +1138,27 @@ var NativeWindow = {
|
|||
aTarget.mozRequestFullScreen();
|
||||
});
|
||||
|
||||
this.add(Strings.browser.GetStringFromName("contextmenu.shareImage"),
|
||||
this.imageSaveableContext,
|
||||
function(aTarget) {
|
||||
let imageCache = Cc["@mozilla.org/image/cache;1"].getService(Ci.imgICache);
|
||||
let props = imageCache.findEntryProperties(aTarget.currentURI, aTarget.ownerDocument.characterSet);
|
||||
let src = aTarget.src;
|
||||
let type = "";
|
||||
try {
|
||||
type = String(props.get("type", Ci.nsISupportsCString));
|
||||
} catch(ex) {
|
||||
type = "";
|
||||
}
|
||||
sendMessageToJava({
|
||||
gecko: {
|
||||
type: "Share:Image",
|
||||
url: src,
|
||||
mime: type,
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
this.add(Strings.browser.GetStringFromName("contextmenu.saveImage"),
|
||||
this.imageSaveableContext,
|
||||
function(aTarget) {
|
||||
|
@ -1146,9 +1167,12 @@ var NativeWindow = {
|
|||
let contentDisposition = "";
|
||||
let type = "";
|
||||
try {
|
||||
String(props.get("content-disposition", Ci.nsISupportsCString));
|
||||
String(props.get("type", Ci.nsISupportsCString));
|
||||
} catch(ex) { }
|
||||
contentDisposition = String(props.get("content-disposition", Ci.nsISupportsCString));
|
||||
type = String(props.get("type", Ci.nsISupportsCString));
|
||||
} catch(ex) {
|
||||
contentDisposition = "";
|
||||
type = "";
|
||||
}
|
||||
ContentAreaUtils.internalSave(aTarget.currentURI.spec, null, null, contentDisposition, type, false, "SaveImageTitle", null, aTarget.ownerDocument.documentURIObject, true, null);
|
||||
});
|
||||
},
|
||||
|
|
|
@ -213,6 +213,7 @@ contextmenu.shareLink=Share Link
|
|||
contextmenu.bookmarkLink=Bookmark Link
|
||||
contextmenu.changeInputMethod=Select Input Method
|
||||
contextmenu.fullScreen=Full Screen
|
||||
contextmenu.shareImage=Share Image
|
||||
contextmenu.saveImage=Save Image
|
||||
contextmenu.addSearchEngine=Add Search Engine
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче