Thursday 27 November 2014

How to download files using web cache validation (ETag) - Android

If your app often download files, you want to efficiently keep track of the files you already have so you don't need to download them again.
The HTTP protocol helps us handle this task with much ease by making use of ETags

The class below is ready to use. Copy and paste the code into your Android project.
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.Writer;
import java.net.HttpURLConnection;
import java.net.URL;

public class FileDownloadHelper {
	private final int BUFFER_SIZE=1024*32;
	private final String IFNONEMATCH_HEADER_FIELD = "If-None-Match";
	private final String ETAG_HEADER_FIELD = "ETag";
	
	public void downloadToFile(String sourceUrl, String destFile) throws IOException{
		URL url = new URL(sourceUrl);
			
		downloadToFileHTTP(url, destFile);		
	}
		
	private void downloadToFileHTTP(URL url, String destFile) throws IOException{
		HttpURLConnection connection = (HttpURLConnection) url.openConnection();
		// accept compressed content
		connection.setRequestProperty("Accept-Encoding", "gzip, deflate");
		try{
			writeHTTPDataToFileStream(connection, destFile);
		}finally{
			connection.disconnect();
		}	
	}
	
	private void writeHTTPDataToFileStream(HttpURLConnection connection, String destFile) throws IOException{
		String etagFileName = buildEtagFileName(destFile);
		String etag = readTextFile(etagFileName);
		
		addETagHeader(connection, etag);
		
		int responseCode = connection.getResponseCode(); 		
		if(responseCode == HttpURLConnection.HTTP_OK){
			FileOutputStream destFileStream = new FileOutputStream(destFile);
			try{
				InputStream connectionStream = new BufferedInputStream(connection.getInputStream());
				try{
					int bytesRead;
					byte[] readBuffer = new byte[BUFFER_SIZE];
					while((bytesRead = connectionStream.read(readBuffer)) > 0){
						destFileStream.write(readBuffer, 0, bytesRead);
					}
				}finally{
					connectionStream.close();
				}
			}finally{
				destFileStream.close();
			}
			saveETagHeader(connection, destFile);
		}
		
	}
	
	private void saveETagHeader(HttpURLConnection connection, String destFile) throws IOException {
		String etag = connection.getHeaderField(ETAG_HEADER_FIELD);
		if(etag != null && etag.length()>2){
			String etagFile = buildEtagFileName(destFile);
			saveToTextFile(etagFile, etag);
		}
	}

	private void addETagHeader(HttpURLConnection connection, String etag){
		// greater than 2 because it must at least include the double quotes
		if(etag!=null && etag.length()>2){
			connection.addRequestProperty(IFNONEMATCH_HEADER_FIELD, etag);
		}
	}
	
	private String readTextFile(String fileName) throws IOException{
		File f = new File(fileName);
		if(f.exists() && f.length()>0){
			Reader reader = new BufferedReader(new FileReader(fileName));
			try {
				char[] buffer = new char[1024 * 8];
				StringBuilder resultBuilder = new StringBuilder();
				int br;
				while ((br = reader.read(buffer)) > 0) {
					resultBuilder.append(buffer, 0, br);
				}
				return resultBuilder.toString();
			} finally {
				reader.close();
			}
		}
		return "";
	}
	
	private void saveToTextFile(String fileName, String contents)	throws IOException {
		Writer writer = new BufferedWriter(new FileWriter(fileName));
		try {
			writer.write(contents);
		} finally {
			writer.close();
		}
	}
	
	private String buildEtagFileName(String fileName){
		return fileName + ".etag";
	}	
}


Note that a .etag file will be created in the same directory as the downloaded file and reused in future downloads.
Just call FileDownloadHelper.downloadToFile like this:

FileDownloadHelper client = new FileDownloadHelper(); // assuming you are in the activity context String fileName = getFilesDir().getAbsolutePath()+"/devhelpers.html"; // this will download an html page but you can pass any url to the method String webPageUrl = "http://devhelpers.blogspot.ca/"; client.downloadToFile(webPageUrl, fileName);

Sunday 16 November 2014

How to write to and read from text files in Java/Android

There are many ways to read and write files in Java and the size and type of data you're working with usually dictate the best method to do so.

For working with text files that are small enough, I find that the classes FileReader and FileWriter provide the most cost effective implementations.

The helper methods below are ready for use. They rely on the system's default Charset so be careful if you're passing around files across different systems and encodings. The code works on any Java platform including Android.

public static void saveToTextFile(String fileName, String contents) throws IOException{
 Writer writer = new BufferedWriter(new FileWriter(fileName));
 try{
  writer.write(contents);
 }finally{
  writer.close();
 }
}

public static String readTextFile(String fileName) throws IOException{
 Reader reader = new BufferedReader(new FileReader(fileName));
 try{
  char[] buffer = new char[1024*8];
  StringBuilder resultBuilder = new StringBuilder();
  int br;   
  while((br = reader.read(buffer))>0){
   resultBuilder.append(buffer, 0, br);
  }
  return resultBuilder.toString();
 }finally{
  reader.close();
 }
}


An usage example on Android would be
// 'this' here is the activity context
String fileName = this.getFilesDir().getAbsolutePath()+"/test.txt";
String contents = "Hello, World of Android";
try {
 saveToTextFile(fileName, contents);
 //do something...
 String contentsRead = readTextFile(fileName);
 Log.d("MYAPP", "I wrote '"+contents+"' and I read '"+contentsRead+"'");
} catch (IOException e) {   
 Log.e("MYAPP", e.getMessage(),e);
}

Friday 14 November 2014

PTaskScheduler - A Free and .Net pure parallel task scheduler

For Android, iOS, Windows Phone, Windows, MacOS, Linux and probably a whole set of other platforms that support .Net natively. Try it, it's free!

If you are new to UniParallel, please read the post Using PTaskScheduler - UniParallel Unity package first.


Version 0.6 of the UniParallel package adds a new type of task scheduler called  PSyncTaskScheduler  which has the same functionalities of the  PTaskScheduler  adding to it the ability to execute a routine in the main game Thread after a task is finished.
Only 3 of types of tasks are supported, named slightly different:

  • Use SyncImmediateTask if you want to schedule a task for immediate execution
  • Use SyncTimedTask if you want to schedule a task for delayed execution
  • Use SyncRepeatableTask to execute tasks a certain number of times on a interval

Infinite synchronized tasks are supported, obviously, since the purpose of the sync tasks is to execute another routine when finished.

And every starts with and instance of  PSyncTaskScheduler 

If you are looking for the Unity Version, get free at the Unity Asset Store


The .Net Library works on anything that can run .Net (including Mono and variations). Download the library free HERE



 [...]
 PSyncTaskScheduler scheduler = new PSyncTaskScheduler();
 // schedule your tasks
 [...]
 // check if there's any tasks finished and execute it's post completion routine
 scheduler.Update(); 

The line
scheduler.Update();
Is extremely important and must be included in your MonoBehaviour update loop. This call is responsible for executing and post-completion routine scheduled. That is, if there's any completed tasks. Calling PSyncTaskScheduler.Update() when there are no tasks completed or scheduled is completely safe and will cause no impact on your application performance whatsoever.
Let's see an example of a immediate task that will execute a heavy operation in the background and notify the game when completed
 
 [...]
 PSyncTaskScheduler scheduler = new PSyncTaskScheduler();
 SyncImmediateTask task = new SyncImmediateTask(MethodThatCanBlockMyGame, MethodToRunAfterBlockingMethodIsDone);
 scheduler.Enqueue(task);
 [...]

 // The MonoBehaviour update loop
 void Upate()
 {
    scheduler.Update()
 }
 object MethodThatCanBlockMyGame()
 {
    // this is running in the background and allowing your game to continue smoothly
    Boolean isDone = true;
    // Do a few very heavy operations
    ThisIsGoingToTakeALongTime();
    // isDone is the argument passed to MethodToRunAfterBlockingMethodIsDone
    return isDone;
 }
 
 void MethodToRunAfterBlockingMethodIsDone(object result)
 {
   // this is running inside the game's main thread and MUST BE very light-weight code
   Boolean booleanResult = (Boolean) result;  // result is coming from  MethodThatCanBlockMyGame
   if(result)
   {
     Debug.Log("Completed successfully");
   }
   else
   {
     Debug.Log("Ooops");
   }
 }

Note the signatures of the methods  MethodThatCanBlockMyGame  and  MethodToRunAfterBlockingMethodIsDone : they *must* work with only object types, the background method returning and object that will be passed as an argument to the method executed after the background routine is completed.
Let's take a look at the other 2 types of synchronized tasks. They are just as simple to use as immediate tasks. First, timed tasks
 
 [...]
 const int delay = 1000; // 1 second
 PSyncTaskScheduler scheduler = new PSyncTaskScheduler();
 SyncTimedTask timedTask = new SyncTimedTask(MethodToStartAfterDelay, MethodToExecuteAfterComplete, delay); 
 scheduler.Enqueue(timedTask);
 [...]

 // The MonoBehaviour update loop
 void Upate()
 {
    scheduler.Update()
 }
 object MethodToStartAfterDelay()
 {
    // this is running in the background, starting after the specified delay
    Integer calculationResult = DoSomeMath();
    return calculationResult;
 }
 
 void MethodToExecuteAfterComplete(object result)
 {   
   Debug.Log("The calculated number is "+result);   
 }

Then, SyncRepeatableTask tasks. This time of task is not only useful for executing heavy operations in background but also delayed repeatable operations that will result in something to be rendered, like a countdown timer
 
 [...]

 const int delay = 1000;// run every second ...
 const int executionCount = 10; // and 10 times
 
 int mInitialTimerValue = 10;

 PSyncTaskScheduler scheduler = new PSyncTaskScheduler();
 //count down 10 seconds
 SyncRepeatableTask repeatableTask = new SyncRepeatableTask(CountDown, OnEachCountDown, 
                delay, executionCount);
 scheduler.Enqueue(repeatableTask);

 // The MonoBehaviour update loop
 void Upate()
 {
    scheduler.Update()
 }
 
 object CountDown()
 {
    mInitialTimerValue--;
    return mInitialTimerValue;
 }
 
 void OnEachCountDown(object result)
 {   
   Debug.Log("The timer now is at "+result);   
   RenderTimer(mInitialTimerValue);
 }

Wednesday 12 November 2014

How to parse and read large (or small) XML files in .Net using C#

Frequently I hear people saying the XML is going to die soon and be full replaced by JSON. That may even happen one day but the truth is there's plenty of XML data around that needs to be processed.

The .Net framework offers many ways to parse and process XML files, some more convenient than others but I find that they can be problematic when parse extremely large amounts of data.

The example below demonstrates how you can quickly use the XmlTextReader class to read the contents of an XML file being modest on memory utilization

Assume you have an xml file like this:

<albums>
  <album releasedate="February 15, 1975">Fly by Night</album>
  <album releasedate="September 1, 1977">A Farewell to Kings</album>
  <album releasedate="June 12, 2012">Clockwork Angels</album>
</albums>


And want to extract all the album names in it. You can do it like this:

// this is just a outer method used to keep things clean.
// note the finally block closing the XML reader resources
// it will return a list of all album names in the XML file above, in their appearing order
private IList< String > GetAlbumNames(String albumXmlFileName)
{            
    // creates a xmlReader to parse the file in albumXmlFileName
    XmlTextReader xmlReader = new XmlTextReader(albumXmlFileName);
    try{
        return GetAlbumNames(xmlReader);
    }
    finally
    {
        xmlReader.Close();
    }                        
}

private IList< String > GetAlbumNames(XmlTextReader xmlReader)
{
    IList< String > albumNames = new List< String >();
            
    // keeps moving the "cursor" in the file till the end
    while (xmlReader.Read())
    {
        // regular nodes are typically a XML Element of type XmlNodeType.Element and the Name property
        // of the node
        if (xmlReader.NodeType == XmlNodeType.Element && xmlReader.Name == "album")
        {                  
            // at this exact point, the cursor is pointing to the Element node
            // we need to do another read to move the cursor to the content of the node we want to read  
            xmlReader.Read();
            string albumName = xmlReader.Value;
            albumNames.Add(albumName);
        }

    }
    return albumNames ;
}



If you want to read an attribute present in one of the nodes, e.g, "releaseDate" in your example XML above, you can just the method GetAttribute
Like this:
private IList< String > GetAlbumReleaseDates(XmlTextReader xmlReader)
{
    IList< String > albumReleaseDates = new List< String >();
            
    while (xmlReader.Read())
    {
        // the attribute releaseData belongs to the element album so we need to make sure
        // the cursor is in the right place
        if (xmlReader.NodeType == XmlNodeType.Element && xmlReader.Name == "album")
        {                  
            String releaseDate = xmlReader.GetAttribute("releaseDate");
            // always check for nulls, even if you're enforcing schema to have attributes. It is a good practice
            if(releaseDate != null)
            {
              albumReleaseDates.Add(releaseDate);
            }
        }
    }
    return albumReleaseDates ;
}


For more on XmlTextReader, see this. As I mentioned before, there plenty of other alternatives to parse XML in .Net and I shall write about them in my next posts.

Saturday 8 November 2014

How to encrypt strings using AES - Android/Java

Keeping your user's personal information safe is extremely important and sometimes you need to encrypt and store short strings (like user name and password) in the users's device or personal account.

The class Cypher provides various encryption algorithms and AES becoming very much a standard over 3DES.

The helper class FreeCryptoHelper is simple, ready to use and to be modified to your needs.

Pass your encryption key as an array of bytes to the constructor of the class. Read the comments in the code, keeping your key safe is extremely important. Also the length of the array must be observed or you will get an exception trying to create the key spec.

Call encryptString to encrypt a string and its counterpart decryptString to decrypt it.

Feel free to drop a comment if you have questions or suggestions.

Note that I'm using the Base64 class present in the android SDK. If you want to use pure java, checkout the Java class documentation
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import android.util.Base64;

public class FreeCryptoHelper {
  
 private SecretKeySpec mKeySpec;
 
 public FreeCryptoHelper(byte[] encryptionKey){
  // make sure encryptionKey is either 32, 64 or 128 bits long
  // and if you intend to hardcode it, have it well obfuscated within your code 
  mKeySpec = new SecretKeySpec(encryptionKey, "AES");
 }
 
 public String encryptString(String clearText) throws InvalidKeyException, NoSuchAlgorithmException, 
                NoSuchPaddingException, IllegalBlockSizeException, 
                BadPaddingException{
  Cipher cipher = Cipher.getInstance("AES");
  cipher.init(Cipher.ENCRYPT_MODE, mKeySpec);
  byte[] encData = cipher.doFinal(clearText.getBytes());
  
  return Base64.encodeToString(encData, Base64.DEFAULT);
 }

 public String decryptString(String encryptedText) throws InvalidKeyException, 
                NoSuchAlgorithmException, NoSuchPaddingException, 
                IllegalBlockSizeException, BadPaddingException{
  byte[] encData = Base64.decode(encryptedText, Base64.DEFAULT);
  Cipher cipher = Cipher.getInstance("AES");
  cipher.init(Cipher.DECRYPT_MODE, mKeySpec);
  byte[] decData = cipher.doFinal(encData);
  
  return new String(decData);
 }
}

Friday 7 November 2014

How to add an image to a button on Android - ImageButton

Creating a button that contains a glyph (image) and text, frequently referred as ImageButton, can be done entirely in the layout XML file using the attribute android:drawableTop.

For example, you can use Android stock images combined with your own text like this:

 <Button
  android:id="@+id/btnUp"        
  android:layout_width="200dp"
  android:layout_height="wrap_content"
  android:drawableTop="@android:drawable/arrow_up_float"
  android:text="Click here to go up"/>

  <Button
  android:id="@+id/btnDown"
  android:layout_width="200dp"
  android:layout_height="wrap_content"
  android:drawableTop="@android:drawable/arrow_down_float"
  android:text="Click here to go down"/>


You can also use your own resource image. In this case, I added the file ball.png to the drawable folder

<Button        
android:layout_width="200dp"        
android:layout_height="wrap_content"        
android:drawableTop="@drawable/ball"
android:text="Kick off!"/>



And here how they look like


Thursday 6 November 2014

Node.js - How to dump a Javascript object as JSON (Javascript object inspection)

When debugging your Node.js application, sometimes you will find yourself wanting to inspect an entire object. The Javascript module utils can be extremely helpful in this task.

Imagine you want to inspect the object "myobject" created below

var myobject= new Object();
myobject.property1 = "some object property";
myobject.intproperty = 42;
myobject.child = new Object();
myobject.child.property2 = "a property of the child object";
myobject.onDoSomething = function(arguments){
   console.log("Say hi!");
}


You can dump "myobject" as JSON like this:
var util = require("util");
console.log( util.inspect(myobject) ) ;


utils.inspect also allows controlling what will be dumped and how deep inside the object tree to go. This is done using the arguments showHidden and depth as show below
console.log( util.inspect(myobject, { showHidden: true, depth: 0 }) ) ;


You'll see that only the first level of the object contents is displayed. And you will also see that hidden attributes/objects/properties are dumped. To do a deep inspection of all levels, set depth to null
console.log( util.inspect(myobject, { showHidden: true, depth: null }) ) ;

Wednesday 5 November 2014

How to make a TextView (or any other view) clickable on Android

Oftentimes developers want to use clickable labels (TextViews) in their applications to give it a Webish look and hopefully make the UI a little more familiar to smartphone users.

Luckily the Android SDK allows any view to be clickable; all we need to do is assign an OnClickListener callback handler to the targeted view.

Assume you have this TextView in your layout file



All you need then is to use the method setOnClickListener() of the view to assign a callback object to it. These callbacks are objects that implement the interface View.OnClickListener, as show below in the all-purposed method setupEventsListeners()
private void setupEventsListeners(){
  View myTextView = findViewById(R.id.myTextView);
  myTextView.setOnClickListener(new View.OnClickListener() {   
    @Override
    public void onClick(View caller) {
      Toast
      .makeText(caller.getContext(), 
                     "You have clicked on a TextView", 
                     Toast.LENGTH_LONG)
      .show();    
    }
  });     
}

You need to assign an click handler to it as soon as possible, let's say, when the activity is created.
@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  // your other initialization code here   
  setupEventsListeners();
}


And then you are done!

Tuesday 4 November 2014

How to connect to an HTTPS web server using self-signed certificates (Android/Java)

Self-signed certificates are quite often used by devs and companies that don't want to pay for a real certificate until is time to go to production.
The Android (Java) HttpsURLConnection will refuse to connect to any web server using a self-signed certificate by default. To get around this, you need replace the default socket factory and make the host name verifier more lenient.
To replace the socket factory, you first need a trust manager. The class below is ready for use
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.X509TrustManager;

public class AllForgivingTrustManager implements X509TrustManager {

 @Override
 public void checkClientTrusted(X509Certificate[] arg0, String arg1)
   throws CertificateException {  
 }

 @Override
 public void checkServerTrusted(X509Certificate[] arg0, String arg1)
   throws CertificateException {  
 }

 @Override
 public X509Certificate[] getAcceptedIssuers() {  
  return new X509Certificate[0];
 }

}
Then you create a socket factory that uses our trust manager
private SSLSocketFactory createSocketFactory() throws KeyManagementException, NoSuchAlgorithmException{
 TrustManager[] trustMan = new TrustManager[] { new AllForgivingTrustManager() };
 SSLContext sslContext = SSLContext.getInstance("TLS");
 sslContext.init(new KeyManager[0], trustMan, new SecureRandom());
 return (SSLSocketFactory) sslContext.getSocketFactory();
}

The last part: create the HTTPS connection. Having a helper method for that can be quite handy. Note the setHostnameVerifier method being called below. Only do that if you want to ignore the host name in the certificate and keep in mind, ignoring the host name can be very dangerous!
private HttpsURLConnection getConnection(URL url) throws IOException{
 HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
 // set this only if you intend to POST data
        connection.setDoOutput(true);
 connection.setHostnameVerifier(new AllowAllHostnameVerifier());
 connection.setSSLSocketFactory(createSocketFactory());
 
 return connection;
}
And it's done! You can use all this to retrieve any web page or file. See my previous post How to download a file/web page using HTTP on Android/Java for more details.
public void downloadToFile(String sourceUrl, FileOutputStream destFile) throws IOException{
 URL url = new URL(sourceUrl);
 HttpsURLConnection connection = (HttpsURLConnection) getConnection(url);
 try{
  InputStream connectionStream = new BufferedInputStream(connection.getInputStream());
  try{
   int bytesRead;
   byte[] readBuffer = new byte[1024*32];
   while((bytesRead = connectionStream.read(readBuffer)) > 0){
    destFile.write(readBuffer, 0, bytesRead);
   }
  }finally{
   connectionStream.close();
  }
 }finally{
  connection.disconnect();
 }
}

Monday 3 November 2014

How to use the .Net ThreadPool

As many of you have requested, here are a few simple ways you can execute code in a thread using the .Net native ThreadPool.
It works on Windows, Unity (Mono, Android, iOS, Windows Phone)

The simplest case first: Executing a method disregarding the argument
private void SimpleThreadPoolTest()
{
  ThreadPool.QueueUserWorkItem(new WaitCallback(SimpleMethod));
}  

private void SimpleMethod(object ignoredArg)
{
  Console.WriteLine("Method called inside a thread");
}


As you may have noticed, the WaitCallback delegate takes one argument of type object, which we're ignoring right now.
But if you need to use, just pass any object as the second argument of QueueUserWorkItem, like:
private void ParameterizedThreadPoolTest()
{
  string arg = "This is a string parameter";
  ThreadPool.QueueUserWorkItem(new WaitCallback(SimpleMethod), arg);
}  

private void WaitCallback(object arg)
{
  Console.WriteLine("Executing inside a thread with argument "+arg);
}


You can also use lambda expressions instead of methods
private void LambdaThreadPoolTest()
{
  // unusedArgument is required, even though we're not using it, because WaitCallback takes 1 argument
  ThreadPool.QueueUserWorkItem(new WaitCallback(
        (unusedArgument)=>
        {
          // do something
          // then do something else
          Console.WriteLine("This is a lambda function running inside a thread");
        }
  ));
}  

Sunday 2 November 2014

How to programatically center text horizontally using TextView

Use the gravity attribute of the TextView. Like this:
The method setTextHorizontally below changes the text and the attributes of the TextView to center it horizontally. It assumes the text is in your string resource file
private void setTextHorizontally(int textResId){
  TextView textView = (TextView).findViewById(R.id.myTextView);
  textView.setText(textResId);
  textView.setGravity(Gravity.CENTER_HORIZONTAL);
}

Saturday 1 November 2014

How to download a file/web page using HTTP on Android/Java

If you're using HTTP and not HTTPS, the method below is ready to go!
I'll be writing how to do it in HTTPS shortly. Please come back later ;)
private void downloadToFile(String sourceUrl, FileOutputStream destFile) throws IOException{
	URL url = new URL(sourceUrl);
	HttpURLConnection connection = (HttpURLConnection) url.openConnection();
	try{
		InputStream connectionStream = new BufferedInputStream(connection.getInputStream());
		try{
			int bytesRead;
			byte[] readBuffer = new byte[1024*32];
			while((bytesRead = connectionStream.read(readBuffer)) > 0){
				destFile.write(readBuffer, 0, bytesRead);
			}
		}finally{
			connectionStream.close();
		}
	}finally{
		connection.disconnect();
	}
}

public void testDownloadWebPage() throws IOException{
	String fileName = "webpage.html";
	String webPageUrl = "http://devhelpers.blogspot.com/";
        // openFileOutput is available in the activity / context and will create a file in the app's data directory
	FileOutputStream fs = openFileOutput(fileName, Context.MODE_PRIVATE);
	try{
		client.downloadToFile(webPageUrl, fs);
	}finally{
		fs.close();
	}

}

How to parse and create JSON string Android/Java

Use the package org.json.JSONObject, present in the android SDK.

Example:
  JSONObject j = new JSONObject();
  // values can be strings, booleans, ints and/or objects
  j.put("stringFieldName", "fieldValue");
  j.put("intFieldName", 42);
  // put throws an exception if any of the arguments is invalid.
  // if you're not sure about if what you're trying to write to JSON is null or not, you can use putOpt
  String nonNullField = "nonNullFieldName";
  String nullField = "nullFieldName";
  String thisIsAnArgumentAndImNotSureIfItWillBeNull = null;
  j.putOpt(nonNullField, "this is a non nul value");
  // nullField will not be added to the JSON
  j.putOpt(nullField, thisIsAnArgumentAndImNotSureIfItWillBeNull);

  String jsonString = j.toString();
  // jsonString is
  // {"nonNullFieldName":"this is a non nul value","intFieldName":42,"stringFieldName":"fieldValue"}
  // use JSONObject.toString(2) to return an indented JSON string with 2 spaces
  /*
   {
     "nonNullFieldName": "this is a non null value",
     "intFieldName": 42,
     "stringFieldName": "fieldValue"
   }
  */
 

You can created JSON trees by putting a JSONObject into another JSONObject
Parsing a JSON string is just as easy
  String jsonString = ...;//something like // {"nonNullFieldName":"this is a non null value","intFieldName":42,"stringFieldName":"fieldValue"}
  JSONObject j = new JSONObject(jsonString);
  // use the get methods to return the parsed values
  int intValue = j.getInt(...);
  String strValue = j.getString(...);


It's a little different if you're using pure java though
  JsonObject jb = Json.createObjectBuilder();
  jb.add("firstName", "Donald duck");
  jb.add("address", "Jupiter")
  jb.add("number", 42);
  
  // and here you have it!
  String jsonText = jb.toString();
  
More here

Friday 31 October 2014

How to open an URL in a new window in Javascript

If you want to open a web page on another window using javascript, just use the method open of the object window.
Very useful to keep users on your web site
Example
Just add the line
  window.open("http://devhelpers.blogspot.ca");
Inside a <script> tag

Wednesday 29 October 2014

How to dynamically change the text of an android widget

This works for any android widget that support text labels, like TextViews and buttons


  // this code is assumed to run inside an activity class or view
  // in short, this must have the findViewById method
  // also, you need the text to be in your string resource file (usually strings.xml)

  TextView theLabelOnTheScreen = (TextView)this.findViewById(R.id.myLabel);
  theLabelOnTheScreen.setText(R.string.the_id_of_the_string_to_be_used);

How to make a TextView underlined

The best and easiest way to do that is use tags in your strings.xml (or whatever you call your strings resource file)

Example
<?xml version="1.0" encoding="utf-8"?>
  </resources>
    <string name="textview_string_id"><u>This is underlined text</u></string>
  <resources>


Other tags that also work
<i></i> (italic)
<b></b> (bold)

How to download files asynchronously using only HTTP

all you need is these 2 simple methods in your class.
private void downloadFile(string fileUrl)
{ 
  HttpWebRequest request;
 
  request = WebRequest.Create(fileUrl) as HttpWebRequest;
  // this reduces connection time considerably but it's not supported in windows phone 8
  request.Proxy = null; 
 
  if(request != null)
  {
    request.BeginGetResponse(downloadFile, request); 
  }
}
 
private void downloadFile(IAsyncResult responseResult)
{   
  HttpWebRequest request = responseResult.AsyncState as HttpWebRequest ;
  if(request != null)
  {
    // the using here is VERY important if you don't want leaks
    using (WebResponse response = request.EndGetResponse(responseResult))
    {
      if(((HttpWebResponse)response).StatusCode == HttpStatusCode.OK)
      {
        // if you want to use a dynamic file location, just make the file name a member variable in your class
        using(FileStream fileStream = File.Open(@"c:\files\my_downloaded.file", FileMode.Create))
        {
          Stream source = response.GetResponseStream();
          int bytesRead;
          byte[] streamBuffer = new byte[1024*64];
          while ((bytesRead = source.Read(streamBuffer, 0, streamBuffer.Length)) > 0)
          {
            fileStream.Write(streamBuffer, 0, bytesRead);
          }
        }
      }
    }
  }
}