[
https://issues.apache.org/jira/browse/CB-14?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13264905#comment-13264905
]
Christopher Bailey commented on CB-14:
--------------------------------------
It's not much code and I'm only interested in the situation where the app was
destroyed after firing up the camera/album app. I'm sure it's easy to extend
for other plugins.
Firstly I override CameraLauncher.java just to make public the private vars. I
call this CustomCameraPlugin
Then in my activity I add the following:
{noformat}
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
if (savedInstanceState == null || savedInstanceState.isEmpty())
{
super.setIntegerProperty("splashscreen", R.drawable.startup);
super.loadUrl("file:///android_asset/www/index.html", 2000);
}
else
{
String sCallback = savedInstanceState.getString("callback");
if (sCallback != null)
{
try
{
if
(sCallback.equals(CustomCameraPlugin.class.toString()))
{
CustomCameraPlugin c = new
CustomCameraPlugin();
c.callbackId =
savedInstanceState.getString("callbackId");
c.setContext(this);
c.setView(this.appView);
String uri =
savedInstanceState.getString("imageUri");
if (uri != null)
{
c.imageUri = Uri.fromFile(new
File(uri));
}
c.mediaType =
savedInstanceState.getInt("mediaType");
c.targetHeight =
savedInstanceState.getInt("targetHeight");
c.targetWidth =
savedInstanceState.getInt("targetWidth");
setActivityResultCallback(c);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
// add a hash to the url to indicate we need to add the custom
callback
super.loadUrl("file:///android_asset/www/index.html#new");
}
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState)
{
IPlugin callback = (IPlugin) this.activityResultCallback;
if (callback != null)
{
String className = callback.getClass().toString();
savedInstanceState.putString("callback", className);
if (className.equals(CustomCameraPlugin.class.toString()))
{
CustomCameraPlugin c = (CustomCameraPlugin) callback;);
savedInstanceState.putString("callbackId", "Camera");
if (c.imageUri != null)
savedInstanceState.putString("imageUri",
c.imageUri.getPath());
savedInstanceState.putInt("mediaType", c.mediaType);
savedInstanceState.putInt("targetHeight",
c.targetHeight);
savedInstanceState.putInt("targetWidth", c.targetWidth);
}
}
super.onSaveInstanceState(savedInstanceState);
}
{noformat}
Finally in the webview, I add the following to pick up the modified callback:
{noformat}
if (window.location.hash) {
log("Location hash exists ... setting callback");
if (typeof cordova !== "undefined") {
cordova.callbacks["Camera"] = {
success : savePicUri,
fail : unableToTakePhoto
};
} else {
log(" ... callback setting failed. Cordova undefined.");
}
}
{noformat}
> CameraLauncher Plugin enhancement for loading big image files to avoid
> OutOfMemory exceptions
> ---------------------------------------------------------------------------------------------
>
> Key: CB-14
> URL: https://issues.apache.org/jira/browse/CB-14
> Project: Apache Callback
> Issue Type: Improvement
> Components: Android
> Affects Versions: 1.1.0
> Environment: Android SDK: 2.x & above
> JDK: 1.6
> Eclipse: Helios
> Reporter: Bright Zheng
> Assignee: Joe Bowser
> Priority: Critical
> Labels: CameraLauncher, OutOfMemory, decodeStream
> Fix For: 1.6.0
>
>
> Currently the CameraLauncher plugin of Phonegap (or Apache Callback) is using
> Android default API for stream decoding.
> It will be very easy to get crash by throwing out the OutOfMemory exceptions
> while loading bigger image files.
> So I add a new method called safeDecodeStream for better stream decoding.
> {code:title=safeDecodeStream method|borderStyle=solid}
> /**
> * A safer decodeStream method
> * rather than the one of {@link BitmapFactory}
> * which will be easy to get OutOfMemory Exception
> * while loading a big image file.
> *
> * @param uri
> * @param width
> * @param height
> * @return
> * @throws FileNotFoundException
> */
> protected Bitmap safeDecodeStream(Uri uri, int width, int height)
> throws FileNotFoundException{
> int scale = 1;
> BitmapFactory.Options options = new BitmapFactory.Options();
> android.content.ContentResolver resolver =
> this.ctx.getContentResolver();
>
> if(width>0 || height>0){
> // Decode image size without loading all data into
> memory
> options.inJustDecodeBounds = true;
> BitmapFactory.decodeStream(
> new
> BufferedInputStream(resolver.openInputStream(uri), 16*1024),
> null,
> options);
>
> int w = options.outWidth;
> int h = options.outHeight;
> while (true) {
> if ((width>0 && w/2 < width)
> || (height>0 && h/2 < height)){
> break;
> }
> w /= 2;
> h /= 2;
> scale *= 2;
> }
> }
> // Decode with inSampleSize option
> options.inJustDecodeBounds = false;
> options.inSampleSize = scale;
> return BitmapFactory.decodeStream(
> new
> BufferedInputStream(resolver.openInputStream(uri), 16*1024),
> null,
> options);
> }
> {code}
> And then change all the codes which are invoking the Android decodeStream API
> directly to this method.
> e.g.
> {code:title=usage example|borderStyle=solid}
> //Updated by Bright for safer decodeStream
> //android.content.ContentResolver resolver = this.ctx.getContentResolver();
> //bitmap =
> android.graphics.BitmapFactory.decodeStream(resolver.openInputStream(uri));
> bitmap = safeDecodeStream(uri, this.targetWidth, this.targetHeight);
> {code}
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators:
https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira