Skip to content

Recent Articles

30
Sep

Distribute Android App From Your Own Web Server

Listing your app on Google Play or another centralized app store may not make sense for your situation.  This was the case for me when I created an app for small web community, which would be meaningless for anyone else.  There’s nothing stopping you from simply uploading the .apk file to your web server and linking to it, though.  And that’s what I did.

One thing I discovered is that not all devices will recognize the file as an installable app based on the file extension alone.  You must ensure you send the proper mime type.  You can achieve this for Apache by associating the correct mime type with .apk files.  Adding this line to .htaccess will do the trick:

AddType application/vnd.android.package-archive apk

When a user clicks a link to the file, their device will download it.  There will be a “download complete” notification when completed.  Clicking this will grant the option to install the app.  It’s a process that is likely to be unfamiliar to your users, but it’s not too complicated.

One thing you lose is the automatic management of app updates that Google Play provides.  Your users will have to manually download the latest version of the app and install again, which thankfully is handled properly at that point by Android–that is to say, it’s treated as an upgrade to a newer version rather than a clean install.  Consider adding some type of notification to the app’s functionality that will alert users to perform an update if their app version is not the latest.

29
Sep

How To Make an Android Home Screen Widget Update Only When Visible

Depending on the nature of your home screen widget, you may want it to stay closely synched to real-time data. It would be nice if Android fired a system event that you could register for whenever your widget is visible on the screen. However, Android does not do this, and could not be counted upon to do so in any case because some users may be using a 3rd party alternative to the default home screen.

You’d like to update your widget early and often, at times when the user might be looking at it. But you want to prevent it from updating (and wasting resources) when the user is not engaged. There is a way to achieve this. This technique isn’t perfect, because it will cause your widget to update even when hidden behind another running app, but that much is unavoidable. (Note to Google: an isWidgetVisible() method would be great!)

I’m going to describe how I used a Service to update my web community widget only when the screen is on.  The java classes involved are:

  • MRPWidget (extends AppWidgetProvider)
  • WidgetUpdate (extends IntentService)
  • MRPAlarmReceiver (extends BroadcastReceiver)

I described the MRPWidget class here: creating an Android home screen widget.  Now I will describe how the Service is used to update the widget.

Read moreRead more

28
Sep

Android Home Screen Widget: Creating the AppWidgetProvider

Extending AppWidgetProvider is a simple way to encapsulate your app’s management of your home screen widget.  It provides several widget life cycle methods you can override to handle such events as a user adding or removing the widget from their home screen.  It also provides an onUpdate method that ties into the periodic updates the Android system will trigger for your widget.  For my purposes, I disabled this periodic updating because I wanted to control it myself via a Service.

Your AppWidgetProvider interacts with the widget via the RemoteViews class.  The widget is itself hosted in a separate process from the one in which your app runs, and RemoteViews provides methods to cross that gap, update the views and add click listeners.  Note that RemoteViews methods provide only a limited subset of view functionality, and this may restrict what you’d like to do with your widget.  For example, animations are not supported.

I’m going to describe how I created my web community widget.  The java classes involved are:

  • MRPWidget (extends AppWidgetProvider)
  • WidgetUpdate (extends IntentService)
  • MRPAlarmReceiver (extends BroadcastReceiver)

My widget class is named MRPWidget, and it extends AppWidgetProvider.  All visual updates to the widget are handled by this class, as well as starting the service that will perform the updates.  For example, when the widget is enabled it should start the service: Read moreRead more

27
Sep

Creating an Android Home Screen Widget

The home screen of a smartphone is precious real estate.  As users interact with their phone throughout the day, the icons and widgets on the home screen are constantly seen and ready to be interacted with at a moment’s notice.  Offering a widget for your app, service or web site is therefore a uniquely compelling way to to boost its visibility and “stickiness.”

One site that I’ve built is a small online community where people interact mainly via message boards and private messages.  I had already built a simple Android app that users could install to notify them whenever there is a new reply or message.  But to take this app to the next level, I needed to add a home screen widget.

This widget would stay updated with the most recent post made on the site as well as show the names of the users currently active.  In this way, the widget would effectively be a small window into what was going on at the site at any given moment.  Clicking the widget should take you directly to that latest post, logging you in automatically.  Finally, the widget should also visually alert you to any pending unread messages.  It should do all this while taking up as small a footprint as possible, as smartphone users are reluctant to give up too much of their screen to a single widget.

So there are a number of challenges, each of which must be resolved.  Which specific data must be displayed on the widget (we want as much as possible without forcing a larger footprint)?  How to retrieve that data from the web site?  How to keep the data fresh while minimizing battery and data usage?  How to take the user to the correct page when the widget is clicked?  How to make the widget visually appealing?  This last one is difficult, speaking as someone who is not a graphic designer, but I gave it a solid try. 🙂

So in the next few posts I’ll go into how I created an Android widget. But first please have a look at it:

Screen cap of Android Home Screen Widget

The footprint is 2×1 cells on the home screen.  The top half displays the latest post on the site, alongside the user’s icon, with the user’s name (“Example User”) followed by the message board it was posted to.  The bottom half lists the names of currently-active users. Had there been more than can fit on one line, the text here would scroll as a marquee.  Not shown is a hidden middle section that expands to notify of unread post replies and private messages.  All of this is displayed atop a semi-transparent 9-patch image that stretches to encompass the content.

More details on crafting this widget to follow.

21
Jun

Why are JSPs so slow? (Tomcat 7 vs. Apache)

It would be unreasonable to expect JSPs to be served at the same rate as static files. Even after being compiled, requests to JSPs must pass through layers of servlet container code, not to mention the latency of the JSP code itself. However, the difference between static files vs. JSP is much larger than I would have expected.

I ran a test on a 6KB HTML file using Apache Benchmark on my Dell Inspiron N7010 laptop, using 1,000 requests @ 10 concurrent requests.  I also created a JSP by pasting the same HTML into a file, adding only a few dynamic elements: outputting the of the host name, port, and app URI.  No calls to any beans, JDBC, or other potentially slow resources were made.  Default installations were used for both Apache and Tomcat 7.  The results were stark:

  • Apache static HTML file: 971.25 pages/second (blazin’)
  • Tomcat 7 JSP file: 92.5 pages/second

As you can see, the JSP is not merely slower.  It is a full order of magnitude slower.  Because the dynamic content is trivial in this test file, the performance of the servlet container fully accounts for this difference.

I thought I’d also test loading the JSP through Apache using mod_jk to see what kind of performance penalty this imparts.  Results:

  • Tomcat 7 JSP file via Apache mod_jk: 74.80 pages/second

So in this test case, there was a 19% performance penalty fronting Tomcat with Apache.  Of course speed is not the only consideration when evaluating using this type of setup, but it is something to weigh against other concerns.

There is also a debate about whether Tomcat or Apache is faster at serving static files.  This test is only one data point, but Apache easily wins here.  Tomcat serving the static 6KB file:

  • Tomcat 7 static HTML file: 203.5 pages/second

In this test, Apache was nearly five times faster at serving this file (though more than twice as fast compared to the JSP version).

And now, for people who like charts. =)

Chart shows Apache/HTML easily bests Tomcat/JSP

1
Jun

Configure Lucene IndexWriter and IndexSearcher in Spring applicationContext.xml

Problem: you want to define Lucene IndexWriter and IndexSearcher as beans inside your Spring application to be injected/autowired into other beans.

Solution: follow the following steps.

  • define the Lucene version as a constant
  • define a Lucene analyzer (StandardAnalyzer) as a bean
  • define a Lucene directory as a bean, using a factory-method for instantiation
  • define an IndexWriter, wiring in the Lucene directory and an IndexWriterConfig set to use your previously-defined analyzer
  • define an IndexSearcher, wiring in the Lucene directory
  • define also a query parser (StandardQueryParser), wiring in the analyzer bean

You can then wire/autowire these beans into your application beans, for example:
Read moreRead more

27
May

Simple pagination taglib for JSP

Pagination is a common requirement when writing JSPs. Long sets of data must be broken up across multiple pages. There is no standard way to implement pagination in JSP or JSTL, however. You must use a custom tag to generate the page numbers.

I’ve created a simple pagination taglib that generates the page links. You can customize it to your needs. Usage example below. Here, I’m using it to paginate search results from Lucene:

<c:url var="searchUri" value="/searchResults.html?s=${searchval}&page=##" />
<paginator:display maxLinks="10" currPage="${page}" totalPages="${totalPages}" uri="${searchUri}" />

The paginator:display tag produces this output:

shows links 1 through 10

Read moreRead more

15
May

Convert between Java enums and PostgreSQL enums

PostgreSQL allows you to create enum types using the following syntax:

CREATE TYPE animal_type AS ENUM('DOG', 'CAT', 'SQUIRREL');

You can now use ‘animal’ as a datatype in your tables, for example:

create table pet (                         
                  pet_id        integer         not null,
                  pet_type      animal_type     not null,
                  name          varchar(20)     not null
                  );

In Java, you’d have a corresponding enum type:

public enum AnimalType {
    DOG,
    CAT,
    SQUIRREL;
 }

Converting between Java and PostgreSQL enums is straightforward. For example, to insert or update an enum field you could use the CAST syntax in your SQL PreparedStatement:

INSERT INTO pet (pet_id, pet_type, name) VALUES (?, CAST(? AS animal_type), ?);

--or

INSERT INTO pet (pet_id, pet_type, name) VALUES (?, ?::animal_type, ?);

Postgres will also let you insert/update an enum just by passing its value as a string.

Whether casting or not, the Java side is the same. You would set the fields like this:

stmt.setInt(1, 1);
stmt.setString(2, AnimalType.DOG.toString());
stmt.setString(3, 'Rex');

Retrieving the enum from a SELECT statement looks like this:

AnimalType.valueOf(stmt.getString("pet_type"));

Take into consideration that enums are case-sensitive, so any case mismatches between your Postgres enums and Java enums will have to be accounted for. Also note that the PostgreSQL enum type is non-standard SQL, and thus not portable.

Also, FYI, to view the set of values in a given Postgres enum type, you can use the following SQL query:

SELECT enumlabel FROM pg_enum 
    WHERE enumtypid = 'your_enum'::regtype ORDER BY oid;
14
May

Web scraping in Java with Jsoup, Part 2 (How-to)

Web scraping refers to programmatically downloading a page and traversing its DOM to extract the data you are interested in. I wrote a parser class in Java to perform the web scraping for my blog analyzer project. In Part 1 of this how-to I explained how I set up the calling mechanism for executing the parser against blog URLs. Here, I explain the parser class itself.

But before getting into the code, it is important to take note of the HTML structure of the document that will be parsed. The pages of The Dish are quite heavy–full of menus and javascript and other stuff, but the area of interest is the set of blog posts themselves. This example shows the HTML structure of each blog post on The Dish:
Read moreRead more

12
May

Disable URL session IDs (JSESSIONID) in Tomcat 7, Glassfish v3

URL-based session tracking is intended for web clients that do not support session cookies. Every browser worth mentioning supports these cookies, and almost nobody surfs with them disabled. Most web sites either state explicitly or assume that a user’s browser supports session cookies. URL rewriting schemes that add the session ID as a parameter on every URL thus provide very little benefit, if any at all. Session IDs showing up in URLs is just bad form, and may confuse search engine spiders. Thankfully the Servlet 3.0 standard gives you two ways to disable URL session rewriting. This works in Tomcat 7, Glassfish v3, and any other Servlet 3.0-compliant servlet container.

First, you can add this to your web.xml web-app config:

<session-config> 
    <tracking-mode>COOKIE</tracking-mode> 
</session-config> 

Or programmatically, you can use:

servletContext.setSessionTrackingModes(EnumSet.of(SessionTrackingMode.COOKIE));

I’ve used the web.xml method in Tomcat 7, and it works. No jsessionid in the URLs when using <c:url …> in my JSPs.

28
Apr

Web scraping in Java with Jsoup, Part 1

In order to obtain the data to feed into my blog analyzer, content must be parsed from the pages of the blog itself.  This is called “web scraping”.  Jsoup will be used to parse the pages, and because this is a Spring project, Spring scheduling will be used to invoke the parser.

The following classes were created:

  • BlogRequest – invokes the parser on a given blog URL, passes parsed content to service layer
  • BlogRequestQueue – queues up and executes blog requests
  • BlogParser – interface with parseURL method
  • DishBlogParser – implements BlogParser, used to parse the blog The Dish

Each of these (aside from the interface) is configured as a Spring-managed bean.  The code for BlogRequest:
Read moreRead more

28
Apr

A Blog Analyzer Project

In the coming days, I will be writing about a project I’m working on which will perform analysis on Andrew Sullivan’s The Dish blog, which is one of the most popular blogs on American politics.  The intent of the project, which will utilize such technologies as Spring 3, JSP/JSTL, JDBC, PostgreSQL, and jQuery/Ajax, is to web scrape the blog, extract key data elements, and reorganize and present this data in new and interesting ways.  Additionally, I will create a bookmarklet that will add value to the blog site itself.

Development tools used include Netbeans 7.0, Firefox with Firebug, and the always handy psql Postgres command line tool.

There are many interesting technical challenges involved, and I will write about them on this blog.  Additionally, there is the question of copyright law, which is an unavoidable concern when building off of content from a third party.  Copyright law was not meant to stifle innovation, though, provided certain criteria are met: the content originator must not be harmed in the marketplace, repurposed content must be transformed into a novel work, and small portions must be used.  I believe my project fits these criteria.