Android: handling web service authentication

Something you might find yourself doing in Android is web authentication. Most web sites issue a cookie to track session ID's and keep a user logged in. In order to maintain this authentication, you will need to keep cookies synced between activities and between http clients and webviews. The method I ended up doing, which seems to work well enough, was to create a class that extends Application, then define a single HttpClient to be used throughout the rest of the Application. That code looks like:

public class AppSettings extends Application {
	private static final DefaultHttpClient client = createClient();
	@Override
	public void onCreate(){
	}
	static DefaultHttpClient getClient(){
		return client;
	}
	private static DefaultHttpClient createClient(){
		BasicHttpParams params = new BasicHttpParams();
		SchemeRegistry schemeRegistry = new SchemeRegistry();
		schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
		final SSLSocketFactory sslSocketFactory = SSLSocketFactory.getSocketFactory();
		schemeRegistry.register(new Scheme("https", sslSocketFactory, 443));
		ClientConnectionManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);
		DefaultHttpClient httpclient = new DefaultHttpClient(cm, params);
		httpclient.getCookieStore().getCookies();
		return httpclient;
	}

This class also creates an HttpClient that is suitable for AsyncTasks and making multiple simultaneous http requests. Using ThreadSafeClientConnManager for the ClientConnectionManager let's you run http requests inside AsyncTasks without causing a force close when you press the back button and start a second, or third. It also creates a single default cookie store that can be accessed in all your activities. You would use this in your other activities by calling the getClient() method. For example

public class SomeActivity extends Activity {
	static DefaultHttpClient mClient = AppSettings.getClient();
	...
	try {
		
		HttpGet httpget = new HttpGet('URL');
		HttpResponse response;
		response = mClient.execute(httpget);
		...
	}
	...
}

If you find it necessary to use a webview and need it to access and use the same cookies as your client. You can sync the client's cookie store using CookieManager:

DefaultHttpClient mClient = AppSettings.getClient();


Cookie sessionInfo;
List cookies = mClient.getCookieStore().getCookies();
	
if (! cookies.isEmpty()){
	CookieSyncManager.createInstance(getApplicationContext());
	CookieManager cookieManager = CookieManager.getInstance();
		
	for(Cookie cookie : cookies){
		sessionInfo = cookie;
		String cookieString = sessionInfo.getName() + "=" + sessionInfo.getValue() + "; domain=" + sessionInfo.getDomain();
		cookieManager.setCookie("example.com", cookieString);
		CookieSyncManager.getInstance().sync();
	}
}

You will need to switch example.com with the correct domain.

CSS3: Image rotation with css transforms

This is a small bit of CSS3 and jQuery that rotates an image to follow mouse movement. Put the following below the image you wish to rotate

<script type="text/javascript">
    var img = $('.image');
    if(img.length > 0){
	var offset = img.offset();
	function mouse(evt){
		var center_x = (offset.left) + (img.width()/2);
		var center_y = (offset.top) + (img.height()/2);
		var mouse_x = evt.pageX; var mouse_y = evt.pageY;
		var radians = Math.atan2(mouse_x - center_x, mouse_y - center_y);
		var degree = (radians * (180 / Math.PI) * -1) + 90; 
		img.css('-moz-transform', 'rotate('+degree+'deg)');
		img.css('-webkit-transform', 'rotate('+degree+'deg)');
		img.css('-o-transform', 'rotate('+degree+'deg)');
		img.css('-ms-transform', 'rotate('+degree+'deg)');
	}
	$(document).mousemove(mouse);
    }
</script>

Then simply give your image the class name "image"


And for example:

How To: Contact Form in Rails

This post will detail how to write a contact form in Rails 3 and Rails 2.3.x (tested on 2.3.5, and 3.03). When I first wrote this on the old site, I spent forever looking for examples of a working contact form in Rails, and nothing I read anywhere worked for me. So, here is an actual working contact form tutorial

I will assume you already have a controller for whatever various pages you have. This method will work with an existing controller, or you can create a new contact form controller if you'd prefer. Either way, you need to define a method for sending mail inside a controller.

def send_mail
  Notifications.deliver_contact(params[:email])
  flash[:notice] = "Email was sent successfully."
  redirect_to contact_path
end

Change 'contact_path' to whatever page is appropriate. This method calls an ActionMailer model called Notifications which looks for a 'contact' definition. Create a mailer with:

rails g mailer Notifications
(Rails 2.3.x users should substitute the 'rails g' command with script/generate)

This creates the file 'app/mailers/notifications.rb' ('app/models/notifications.rb' on Rails 2.3.x). Open that file and define the 'contact' method:

def contact(email_params, sent_at = Time.now)
  subject "Electronic Mail: " << email_params[:subject]
  recipients "your_email@example.com"
  from email_params[:address]
  sent_on sent_at
  body :message => email_params[:body], :sender_name => email_params[:name]
end
(Change "your_email@example.com" to the address where you want the mail to be delivered)

Mailers work by rendering a view and sending it over the email protocol rather than the HTTP protocol, so to format how the message will look, you will need to use a 'contact' view. This file will be located in 'app/views/notifications/contact.erb'. Create this file with the following contents:

<%= @sender_name %> wrote:
<%= @message %>

That's a pretty simple view and can be expounded upon as you see fit.

Then is the actual form itself. For the sake of easy copy/paste on my part, I'm going to show the HAML formatted form.

- form_tag('/email', :id => 'contact_form') do
  = label :email, :name, "Name:"
  = text_field :email, :name
  .clear
  = label :email, :address, "Address:"
  = text_field :email, :address, :class => 'required email'
  .clear
  = label :email, :subject, "Subject:"
  = text_field :email, :subject
  .clear
  = label :email, :body, "Message:"
  = text_area :email, :body, :rows => 8, :cols => 50
  .clear
  = submit_tag "Send", :id => 'submit_email'
(Rails 2.3.x should replace the form_tag with "- form_tag :action => "send_mail" do" )

HAML is awesome. You should be using it, but if for some reason, you don't like being awesome, you can convert that by replacing "=" with "<%=" and "-" with "<%" then closing each line with "%>" (the .clear is HAML syntax for <div class='clear'></div> and can be ignored depending on your CSS)

You'll notice the class definition on the :email text_field. That is there for validations. I am using the jQuery Validation plug-in which works quite nicely for ensuring both the presence of, and format of, all the fields. A validates method could be applied but ActionMailer does not include this by default.

Lastly, in your routes.rb file, you need to tell Rails how to handle the send_mail action

match '/email' => 'sections#send_mail'
Where 'sections' is whichever controller is calling your contact page and where you defined 'send_mail' (Rails 2.3.x does not need this routing specification)

There is no spam protection in place, but there are numerous articles about adding recaptcha to Rails applications on the internet. Or you can easily include a simple "What is six times seven" type of an input, then check it within the send_mail definition before calling Notifications.deliver.