Save HTML5 Canvas Image to Gallery – Phonegap Android plugin

Update

Readers of this post have raised issues with the plugin. I have to personally check for the issues but while using the plugin if you find any issues, you might want to debug it in ADT. I will come up with a working plugin soon. Thanks.

Sometime back I worked on a Phonegap Android plugin that helps to save an HTML5 Canvas Image to the device’s gallery. Well, the title of this post may be misleading but note that when you save an image, you actually have to save it on the SD Card or the device’s memory. The Gallery is just an app that shows the collection of images from various locations on the SD Card. So, there’s nothing like saving an image directly to the Gallery.
I had this working with Phonegap 2.2.0 (the version that I used). Newer versions of Phonegap/Cordova are available and things might have changed a bit, specially in the way custom plugins are written. Hence, if you are using newer versions of Phonegap you should have a look at the official documentation before proceeding.
Alright, here is what I did. I tried to save an image using the FileWriter – Phonegap API, but as it turned out, it can save only text data on the device’s memory. So, only way to do it was write a Phonegap plugin, pass the Canvas details from JavaScript interface to the Java side and let the Java class save the Canvas image on the SD Card.
Note that I am not a Java developer, and there may be better ways of writing this plugin.

How to install the plugin?
You need to get hold of two files :
1) The Java class – SavePhotoPlugin.java
2) The JavaScript interface – SavePhotoPlugin.js

Read More »

Getting CSS3 Transformations Matrix values for Android/Firefox

Quick snippet of code that will return the CSS3 Transformations Matrix values for Firefox browsers. We make use of the window.getComputedStyle() method for retrieving the style values for our element which has been moved using CSS3 Transformations.

function getMatrix() {
var style = window.getComputedStyle(your_element, null);
var moz_transform = style.getPropertyValue("-moz-transform") || style.getPropertyValue("transform");
if(moz_transform){
var values = moz_transform.split('(')[1];
values = values.split(')')[0];
values = values.split(',');
var a = values[4];
return a;
}

An example to follow…

orientationchange does not work in Mobile Firefox for Androids… WTF !

Yes, orientation change does not work in mobile Firefox. Strange!, but it is. So, when you rotate your mobile device from portrait to landscape mode and back to portrait mode, the orientationchange event is not fired in Firefox browsers for Android devices.

Normally for mobile browsers we detect the orientation change happening by registering to the orientationchange event.

window.addEventListener('orientationchange', function() {
  alert('orientation: ' + orientation);
}, true);

where the orientation property of the global object gives the current orientation that the device has been tilted to. For eg. 0 for portrait and 90/-90 for landscape.

However, when you run this code in firefox browsers for Android, the event is not fired (I tested it on Firefox 20/Galaxy S3). And this happens to be a bug. I mean how can you miss such a common thing in a big big browser!!

But there is an alternative way to detect the orientation changes in firefox browsers and that is by using Media Query detection technique. Also to let you know, I used the window.resize event to detect the orientation but it did not give correct results. The Media Query method worked perfectly. Here it is,

var test = window.matchMedia("(orientation: portrait)");
test.addListener(function(m) {
  if(m.matches) {
    // Changed to portrait
    alert('portrait');
  }else {
    // Changed to landscape
    alert('landscape');
  }
});

Still the window.orientation property is undefined for firefox browsers. So, you can use that to detect if it actually supports orientation change event. Who knows later they might start supporting. This is how you can do that,

if(typeof window.orientation === 'undefined') {
  //use media query technique
} else {
  //use orientationchange event handler
}

Cooler modal popup example – how to open multiple popups, scrolling pop ups per page

Some time back I came up with a cooler modal pop up window using CSS3 and JavaScript specifically for mobile webkit browsers. The example that I presented had only a single button, a click on it would open a modal pop up window.

In this post I have a similar example but this time multiple pop ups can be opened from the same page. Opening multiple pop up’s from a single page was requested by some of my readers. And here it is. I will not go deep into explaining the bits and parts of how to create a pop up window. You can go through my previous post for that. But first let’s check a demo (meant only for web-kit based browsers):

Demo link (open in iOS or Android’s browser, you can also test this in Chrome or Safari in your computer) :  http://rialab.jbk404.site50.net/coolermultiplemodalpopup/

Open multiple pops from a single page

How to run this in Firefox, IE and other browsers?
For this you need to make changes in the CSS file. Add CSS3 prefixes for other browsers similarly as it is there for -webkit- . CSS3 junkies would already know what I am talking about.

CSS3 Transformations showing content outside overflow:hidden region in Firefox/Android

Some time back I was implementing a functionality for Firefox browsers on Android devices and I found a strange problem – For Firefox > 18 on Android devices if I move an element using CSS3 Transformations inside a parent container with overflow:hidden, then part of the element being moved is displayed outside the overflowed region. It seems like when you move the element it just discards the overflow:hidden property and everything is revealed rather. Normally the content outside overflow:hidden should be cut off from view.

I have a simple demo http://rialab.jbk404.site50.net/ffandroidissue/ – an image which is bigger than the container div is moved using CSS3 Transformations. The  div has a overflow:hidden set to it. There are two buttons. Click on them to see the various results. The first button causes the issue whereas the second button resolves it.

So this is what causes the issue – moving the image using CSS3 Transformations (for eg. transform:translateX(value);) inside a container with overflow:hidden

And this is what solves it – strange !!
Adding a background color and an opacity to the container element like this,

#container.noissue{
-moz-perspective: 1000px;
overflow: hidden;
background:#ccc;
width: 100px;
height: 50px;
display: block;
position:absolute;
top:50px;
right:50px;
  background:#ccc;
  opacity:0.99;
}

Check out the demo in Firefox on an Android device. I am not sure if anybody has encountered this situation. But this definitely seems to be a bug in Firefox for Android’s. This is not seen for other browsers.

Authoring “Adobe Edge Inspect Starter”…

My book “Instant Adobe Edge Inspect Starter” on mobile web debugging and testing has been published and it is now available online. For more details and to purchase you can visit here.

My book on mobile web debugging and testing.

Mobile web testing is currently a really time consuming and cumbersome process as there are no direct debugging tools available with mobile web browsers. Since mobile devices vary so much it is important to ensure that your web page looks as intended across the multiple mobile devices that you are targeting for your audience. Edge Inspect is a perfect tool for web developers and designers who are developing for mobile devices, allowing them to simultaneously test on numerous devices in real time as they develop without learning anything new.

“Instant Adobe Edge Inspect Starter” is a practical, hands-on guide that provides you with a number of detailed steps, which will help you to get started on testing and previewing all your mobile web projects on multiple mobile devices. This book will also show you how to use all the other available features of Edge Inspect and make the entire testing process on mobile devices very simple, effortless, and faster.

This book starts with an introduction to Edge Inspect and will take you through a number of clear and detailed steps needed to set up a working installation, and get up and running with testing your web pages on mobile devices.

You will also learn why traditional ways of testing mobile web applications are not very helpful and how Adobe Edge Inspect overcomes it. You will have a look at connecting single and multiple mobile devices with your computer and how to browse in sync.You will learn about remotely inspecting and previewing mobile web pages on a targeted device and directly see the changes taking place on the device itself. The book discusses in detail about creating your very own simple mobile web application, running it from a local server and testing it across mobile devices. You will also take a look at how to use the Edge Inspect web inspector window and do some basic HTML, CSS, and JavaScript debugging. And then finally you will have a look at using your own local Weinre debug server with Edge Inspect and some other very important features. If you want to take advantage of Adobe Edge Inspect and make mobile web testing a lot easier, then this is the book is for you.

“Instant Adobe Edge Inspect Starter” will guide you in getting started with Edge Inspect and will make testing on mobile devices a lot simpler and faster. The book is packed with a lot of examples and diagrams that will help you to test all your mobile web projects without any hassle.

Who this book is for?
This book is for frontend web developers and designers who are developing and testing web applications targeted for mobile browsers. It’s assumed that you have a basic understanding of creating web applications using HTML, CSS, and JavaScript, as well as being familiar with running web pages from local HTTP servers. Readers are also expected to have a basic knowledge of debugging web applications using developer tools such as the Chrome web inspector. And of course you need some mobile devices for running the example in this book and testing it.

Reviews

Ben Forta (Adobe Systems Inc‘s Director of Developer Relations): http://forta.com/blog/index.cfm/2013/4/12/Instant-Adobe-Edge-Inspect-Starter

Creative and Codehttp://creativeandcode.com/review-adobe-edge-inspect-starter-ebook/


Handy eBook to have available – by Chris.M
Overall, the book does a great job of getting you up and running with Edge Inspect. The first couple of chapters focus on getting the application installed on your computer, and then getting it set up on your mobile devices. Though the installation is fairly straightforward, the instructions they provide are detailed with plenty of screenshots, so you should have no issues getting set up.
They also give an overview of the best features of Edge Inspect. I’ve been using Edge Inspect for a while now and even I learned a few new things. The application really does make mobile testing incredibly easy with remote inspection and console log.
The eBook wraps up with some great resources for using Edge Inspect. If you are thinking of working on Responsive Web Design, Adobe Edge Inspect is an invaluable tool. I think the eBook is super handy to have as a reference, and for 5 bucks, why not?

worth having it as a reference – by Siddarth Kalyankar
“Instant Adobe Edge Inspect Starter” indeed is a starter for developers who wish to explore the possibilites of using Adobe Edge Inspector tool during their day to day development activity. It talks about Step-by-step, hands-on recipes to debug, test, and preview web applications on multiple mobile devices with Adobe Edge Inspect (Previously known as “Adobe Shadow” ).
This book assumes that the person who reads this is already into mobile web development and address some of his/her problems which are faced during the development cycle. This book is not intended to help you start doing mobile web development, but if you are web developer and willing to do mobile web development, this could come in handy for you as well.
The books briefs you about what is Adobe Edge Inspect, What are the reasons to use it and What you can do with with it. The main focus is on installation of the required components on your computer, the Edge inspect client on mobile device , how to pair mobile device with your computer and how to debug and preview. I found this information quiet useful as the entire installation process has been very well illustrated with screen shots focusing on Mac/ Windows operating systems, and Android/IOS for mobile device. The author has also provided with the code which can be used by first time developers to get started on their mobile web development venture.
If you are looking at speeding up your mobile web development, Adobe Edge Inspect is the tool and this book is worth having it as a reference.

More reviews from – Amazon

Replicating the iPhone Swipe Gesture – Vertical swiping

For those who wanted a vertical swiping feature to the the swipe gesture gallery that I created earlier, this post has a new demo and minimal explanation about a vertical swipe gesture gallery. Now you can swipe the images up or down.
I will not go through the basics once again as I have explained them in details in my previous posts. You can refer them once again in these two tutorials – post 1, post 2. Check out the demo below. Open the link in a webkit browser in either your mobile device or your computer.

Demo link: http://rialab.jbk404.site50.net/swipegesture/vertical/

Below is a screenshot of the gallery in action. You can see that the images are being moved vertically.

Screenshot of vertical swiping through images
Screenshot of vertical swiping through images

Read More »

Adding Calendar Events – Phonegap Android plugin

Alright, I worked on this sometime back and I will share this with you. I was looking to programmatically  add events to the native Android calendar from a Phonegap android app. There is not an official plugin that is available as of now. So I wrote a custom workaround for this. Again, I am not a Java developer and there might be better ways of writing the plugin code. But just wanted to share the code, and any feedback would just be appreciated.

Alright, let’s get started. So, there are two files that I developed. One is the CalendarEventPlugin.java file which has the plugin’s JAVA code. The other one is the CalendarEventPlugin.js file which is the javascript interface of the plugin. At this point, if you are not sure of what goes into writing a custom Phonegap plugin for Android, then you might want to have a look at this. I am using Phonegap 2.2.0 for my purpose. There has been newer version of Phoengap that is available now, 2.4.0 being the latest at the time of writing. So you can use the latest version as well, but do check the documentation once, there might be some changes.

Check the two files out. I have inline comments that will help you to understand. Rest, is very simple to grasp. Now let’s check how to use and implement this plugin into your Phonegap Android project.

1) Firstly you have to add these two files to your Phonegap Android project. Add the CalendarEventPlugin.js file inside assets/www/ folder and provide a reference to it in your index.html file, like this

<script type="text/javascript" charset="utf-8" src="CalendarEventPlugin.js"></script>

2) Then create a directory inside your project’s src folder that matches the package name of CalendarEventPlugin.java class. For our case make a directory – /org/apache/cordova/plugin inside src and then paste CalendarEventPlugin.java file inside it. If you change the package name, make sure to change the directory structure as well. The package name can be found at the top of CalendarEventPlugin.java file.

3) Next thing to do is to register the plugin in the config file – open res/xml/config.xml and then add the plugin details given below to the <plugins></plugins> section of the XML file. The name attribute is the Java class name and the value is the path of the class. This should match the package name.

<plugin name="CalendarEventPlugin" value="org.apache.cordova.plugin.CalendarEventPlugin"/>

4) And then call the plugin inside your javascript (your script.js file or so) code like this. (You can call this inside a button click handler or so),
   window.addcalendareventplugin(function(val){
        alert(val);   //once success message come and you have tested it, you can remove this alert.
    });

Once everything runs fine, you will see that when you click a button or so in your demo app and it calls the callback function in step 4, the native Calendar Add event is popped up with values already set in it (which you can change in the java file of the plugin). From there on its just the normal way of adding events to Calendar.
Hope this helps!!

Note

  • I have tried this on an Android 4.0 device (Galaxy S3) and it works. I have not really tried this on lower Android versions.

Saving Image to Android device’s Gallery – Phonegap Android

Update
Save HTML5 Canvas Image to Gallery – Phonegap Android plugin
I have a Phonegap Android plugin that helps to save HTML5 Canvas Image to the Gallery. See it here.

Now, back to the actual post,

Quick snippet of code that will help a Phonegap Android app to save an image to the Android device’s SD Card and make it available to the Gallery app to show. The title of this post may be misleading but note that when you save an image, you actually have to save it on the SD Card or the device’s memory. The Gallery is just an app that shows the collection of images from various locations on the SD Card. So, there’s nothing like saving an image directly to the Gallery.

Moreover I tried to save an image using the FileWriter – Phonegap API, but as it turned out, it can save only text data on the device’s memory. So, only way to do it was write a Phonegap plugin, pass the image data from JavaScript interface to the Java side and let the Java class save the image on the SD Card. Well I am not going to talk on the entire plugin, but I will share the Java code,

The methods below should be included inside your plugin’s Java class. The idea is simple, whatever be your image/ image data (eg. Base64 data), you take that image data and save it on the SD Card using the FileOutputStream. You get the file path by querying the external storage public directory which is the first line inside the savePhoto() method below. Now, after the image is saved you broadcast it through the System’s Media Scanner so that it becomes available to the Android Gallery app and to other apps. Hope this is clear, time for action now.

private String savePhoto(Bitmap bmp)
{
  //File imageFileFolder = new File(Environment.getExternalStorageDirectory(),"MyFolder"); //when you need to save the image inside your own folder in the SD Card
  File path = Environment.getExternalStoragePublicDirectory(
     Environment.DIRECTORY_PICTURES
  ); //this is the default location inside SD Card - Pictures folder
  //imageFileFolder.mkdir(); //when you create your own folder, you use this line.
  FileOutputStream out = null;
  Calendar c = Calendar.getInstance();
  String date = fromInt(c.get(Calendar.MONTH))
  + fromInt(c.get(Calendar.DAY_OF_MONTH))
  + fromInt(c.get(Calendar.YEAR))
  + fromInt(c.get(Calendar.HOUR_OF_DAY))
  + fromInt(c.get(Calendar.MINUTE))
  + fromInt(c.get(Calendar.SECOND));
  File imageFileName = new File(path, date.toString() + ".jpg"); //imageFileFolder
  try
  {
    out = new FileOutputStream(imageFileName);
    bmp.compress(Bitmap.CompressFormat.JPEG, 100, out);
    out.flush();
    out.close();
    scanPhoto(imageFileName.toString());
    out = null;
  } catch (Exception e)
  {
    e.printStackTrace();
  }
  return imageFileName.toString();
}
private String fromInt(int val)
{
  return String.valueOf(val);
}

/* invoke the system's media scanner to add your photo to the Media Provider's database,
* making it available in the Android Gallery application and to other apps. */
private void scanPhoto(String imageFileName)
{
  Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
  File f = new File(imageFileName);
  Uri contentUri = Uri.fromFile(f);
  mediaScanIntent.setData(contentUri);
  //this.cordova.getContext().sendBroadcast(mediaScanIntent); //this is deprecated
  this.cordova.getActivity().sendBroadcast(mediaScanIntent); 
}

Note that I am not a Java developer, and you may need to modify this code as per your needs. But it should work. First save your image (create a Phonegap Android app and test it) and after that you can see it being displayed in the gallery app. I did collect this code by browsing the net and made it work 100%. Otherwise it was difficult for me, since I did not find any concrete answer on this. Leave a suggestion if there is a better solution.

HTML5 Canvas – toDataURL() support for Android devices – working Phonegap 2.2.0 Plugin

Update
Save HTML5 Canvas Image to Gallery – Phonegap Android plugin
I have a Phonegap Android plugin that helps to save HTML5 Canvas Image to the Gallery. See it here.

Back to the actual post,

I have been working on a Phonegap based Android app which involves the HTML5 Canvas. So this is what I had been trying for some time – get a png/jpeg image of the Canvas (its a Canvas paint app, something like this and I want to get an image of the drawing..) and then upload the image to Facebook on a user’s album. Let me tell you, it has been a heck of a task and around 15-20 days of restlessness.

The problem stood tall when I discovered that for Android 2.3 (in general Android < 4.0) devices the native HTML5 Canvas- toDataURL() function does not work, which would otherwise give a base64 encoded string  as image data which then can be used as a source for a HTML <img /> tag. It was working for 4.0 devices as I tested it on a Samsung Galaxy S3 and a Samsung Tab. Hence I Goggled a bit and found out various people had this issue before. So it seemed that older Android web-kits (a Phonegap app runs on the Android webview which is actually the webkit browser inside a native wrapper) does not support that native method of converting a Canvas to an image through toDataURL() generated base64 encoded strings. Guess what I had todo? I had to go for a custom Phonegap plugin as there was no other way. This is how I thought of implementing it – pass the canvas object from javascript side to the Phonegap plugin’s Java class and somehow get the base64 encoded string of the Canvas and return it back to javascript as the callback parameter. This is what the native toDataURL() method actually does – convert the Canvas to a base64 encoded image data string.

Read More »