Thursday, December 22, 2011

Titanium Image Gallery

Creating an Image Gallery that scrolls side to side isn't terribly difficult with Titanium.

Here is how I did it:

// put this in a file, for instance "ImageGallery.js"
var ImageGallery = {};
(function() {

    ImageGallery.imageViewArray = [];
    ImageGallery.imageNameArray = [];
    ImageGallery.nextImageIndex;
    ImageGallery.Gallery = null;
   
   
    ImageGallery.createGallery = function(params) {
       
        if (params.Images) {
            ImageGallery.imageNameArray = params.Images;
        }
        ImageGallery.init(params);
       
        ImageGallery.Gallery.addEventListener('click', function(e){});
        for(var i = 0; i < ImageGallery.imageNameArray.length ; i++){
            ImageGallery.Gallery.views[i].image = ImageGallery.imageNameArray[i];
        }
        ImageGallery.nextImageIndex = 1;
       
        return ImageGallery.Gallery;
    };
   
    ImageGallery.init = function(params) {
        var imageParams = {
            width:Ti.Platform.displayCaps.platformWidth - 4,
            height:Ti.Platform.displayCaps.platformHeight/2,
            hires:true,
            left:2,
            right:2
        };
       
        for(var i = 0; i < ImageGallery.imageNameArray.length ; i++){
            ImageGallery.imageViewArray[i] = Titanium.UI.createImageView(imageParams);
        }
       
        var p = {
            width: 310,
            height: 450,
            top: 5,
            left: 5,
            borderWidth: 2,
            borderColor: '#000',
            showPagingControl: false,
            pagingControlColor: '#fff',
            currentpage:0
        };
        for (var prop in params) {
            p[prop] = params[prop];
        }
        p.views = ImageGallery.imageViewArray;
        p.backgroundColor = "#000";
        ImageGallery.Gallery = Titanium.UI.createScrollableView(p);
    };
   
})();


 Assuming that you include the file above in your view, you then can use it like so:

var gallery = ImageGallery.createGallery(
            {

                // here images is an array of image URLs
                Images:images,
                width:Ti.Platform.displayCaps.platformWidth,
                height:Ti.Platform.displayCaps.platformHeight/2,
                top:null,left:null
            }
        );


What do you think?

Thursday, November 03, 2011

PHP and writing to Apache logs

Printing to STDERR is quite easy, once you figure it out!

file_put_contents('php://stderr', print_r($your_string, TRUE));

Of course, you can also replace 'stderr' with 'stdout'.

You could also use error_log but it truncates long strings ...

Saturday, July 16, 2011

Android App Piracy

As you may know, I have a bunch of apps on the Android market. Recently, I have been fielding questions from users that have had problems with my app. Turns out their contacts were being deleted. Their contacts were receiving lewd photos and messages.

After some digging around, it became clear that they downloaded pirated versions of my apps. Aside from feeling glad that people too cheap to buy something that costs the same as a bag of chips and a soda got what was coming to them, I was inclined to post a message about piracy on my apps home page.

Basically, the gist of what I posted is this:

Would you openly give all of the data on your phone to a third party that you did not know or trust? By downloading applications from sources where the original author did not intend to publish them, you are doing just that.

Most paid applications on the market implement some form of weak licensing that Google endorses. Unfortunately, this licensing is very easy to beat. In order to beat it, pirates must add their own bits of source code to apps.

So ask yourself, what would stop them from injecting more code, to say, read all of your contacts and send them to a third party? Or, reading your banking details?

Some will read this post and assume that I am just trying to protect my interests. Well, of course I am. But understand, my claims are real:
The list could go on and on ... Basically, they all say the same thing; Download applications from sources that you trust (Android Market, App Store, etc) and not pirate web sites.

In the end, is the couple of bucks you save worth all of the headache of having your information stolen, your accounts hacked and your life turned upside down?

A little bit of brain goes a long way.

Thursday, January 06, 2011

ServletContextListener: reading init parameters

Previously, I showed you how to schedule an ongoing task with servlets.

Recently, I needed a way to set the location of a configurable properties file for my web application. This location was to be used by each Servlet/JSP in my web application. You could add an init-param to each servlet declaration, like it is explained here. But why do this if each servlet is going to have the same value?

The better choice is to declare this parameter once and have it read when the web application is loaded by the servlet engine.

To do this, you need to once again implement the interface for ServletContextListener,

public class MyServletContextListener
   implements javax.servlet.ServletContextListener
This interface requires you to provide an implemention for
  • public void contextDestroyed(ServletContextEvent sce), and
  • public void contextInitialized(ServletContextEvent sce)
Before we get to the implementation for our listener, let's add a context parameter to our web application. This is the 'global' variable our servlets and JSP pages are interested in!
If you open web.xml and add something like the following as a direct child element of the <web-app> element,

<context-param>   
   <param-name>some parameter</param-name>
   <param-value>some parameter value</param-value>
</context-param>

And while we have the web.xml open, we will declare our listener (right below our <context-param> declaration):

<listener>    
  <listener-class>
your.package.path.MyServletContextListener  </listener-class>  
</listener>

Having declared our listener and a context parameter, our contextInitialized() will look something like:

public void contextInitialized(ServletContextEvent sce) {
  ServletContext c = sce.getServletContext();
  if (c != null) {
    if (c.getInitParameter( "some paramter") != null) {      
      c.setAttribute(         
       "some parameter",
        c.getInitParameter( "some parameter")
      );    
    }  
  }
}
When the servlet container unloads our web application, we need to clean up after ourselves (not 100% that this is necessary, but it is still a good practice):

public void contextDestroyed(ServletContextEvent sce) {
  ServletContext c = sce.getServletContext();
  if (c.getAttribute("some parameter") != null) {
     c.removeAttribute( "some parameter");
  }
}

Now, these attributes are available for each of our individual servlets by calling getServletContext().getAttribute("some parameter").

Nothing to it!