Bug 769438 - Support sharing images via long press r=snorp

This commit is contained in:
Arkady Blyakher 2012-07-10 14:25:15 -07:00
Родитель d3ff86c923
Коммит 3fc748b074
6 изменённых файлов: 132 добавлений и 3 удалений

Просмотреть файл

@ -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