Tech Tips

How to change foreground & background colors in a webview.

At times we need to change the font or background color of the webview in Android to make it more readable or to conform to a design of your app. This post will show how simple it can be to almost always achieve the result. The latter is more simple as webview provides an API :

setBackgroundColor (int color)

What one must note is if the HTML contains a value for the background it will override the color we set. The same is true for the foreground color too.

For the foreground color we make use of CSS to set the color and add it to the content we want to display in a div element wrapping the html we need to display. Here is the sample code

private final String htmlbegin = "<div style=\"color:#FFFFFF ;  \">";
private final String htmlend = " </div>";
private final String htmlBody = "<p>Summary</p>"
	+ "<p>Strong text</strong> Somemore text"
	+ "and the final line</p>";
WebView body;

@Override
public void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.main);

	body = (WebView) findViewById(R.id.message_body);
	body.setBackgroundColor(0);

	// body.setDef
	body.loadDataWithBaseURL("", htmlbegin + htmlBody + htmlend,
		"text/html", "utf-8", "");
}

As I stated before any css inside the html will override our css settings.


Retrieving Current Network Status in Android

Here is a quick snippet of code which will help us in getting the current status of an Android device’s data connection.  We make use of the ConnectivityManager class to get current active network information. We try to catch a NullPointerException which is thrown by the isConnected method when there is no active data connection.

/**
 * Returns availability of a data connection
 * @param mContext
 *            Context of app
 * @return True is data connection is available , false otherwise
 */
public static boolean isDataConnectionOn(Context mContext) {
	ConnectivityManager connectionManager = (ConnectivityManager) mContext
			.getSystemService(Context.CONNECTIVITY_SERVICE);
	try {
		if (connectionManager.getActiveNetworkInfo().isConnected()) {
			Log.d("ConStatus", "Data Connection On");
			return true;
		} else {
			Log.d("ConStatus", "Data Connection off");
			return false;
		}
	} catch (NullPointerException e) {
		// No Active Connection
		Log.d("ConStatus", "No Active Connection");
		return false;
	}
}

Code for resumable download

Another piece of code for PHP developers, useful in open source development.

Following is the function for application that needs functionality of resumable download.

public static function dl_file_resumable($file, $is_resume=TRUE)
{
//First, see if the file exists
if (!is_file($file))
{
die(“404 File not found!“);
}

//Gather relevent info about file
$size = filesize($file);
$fileinfo = pathinfo($file);

//workaround for IE filename bug with multiple periods / multiple dots in filename
//that adds square brackets to filename – eg. setup.abc.exe becomes setup[1].abc.exe
$filename = (strstr($_SERVER['HTTP_USER_AGENT'], ‘MSIE’)) ?
preg_replace(‘/\./’, ‘%2e’, $fileinfo['basename'], substr_count($fileinfo['basename'], ‘.’) – 1) :
$fileinfo['basename'];

$file_extension = strtolower($path_info['extension']);

//This will set the Content-Type to the appropriate setting for the file
switch($file_extension)
{
case ‘zip’: $ctype=’application/zip’; break;
default: $ctype=’application/force-download’;
}

//check if http_range is sent by browser (or download manager)
if($is_resume && isset($_SERVER['HTTP_RANGE']))
{
list($size_unit, $range_orig) = explode(‘=’, $_SERVER['HTTP_RANGE'], 2);
if ($size_unit == ‘bytes’)
{
//multiple ranges could be specified at the same time, but for simplicity only serve the first range
//http://tools.ietf.org/id/draft-ietf-http-range-retrieval-00.txt
list($range_from, $extra_ranges) = explode(‘,’, $range_orig, 2);
}
else
{
$range_from = ”;
}
}
else
{
$range_from = ”;
}

//figure out download piece from range (if set)
list($seek_start, $seek_end) = explode(‘-’, $range_from, 2);

//set start and end based on range (if set), else set defaults
//also check for invalid ranges.
$seek_end = (empty($seek_end)) ? ($size – 1) : min(abs(intval($seek_end)),($size – 1));
$seek_start = (empty($seek_start) || $seek_end 0 || $seek_end < ($size – 1))
{
header(‘HTTP/1.1 206 Partial Content’);
}

header(‘Accept-Ranges: bytes’);
header(‘Content-Range: bytes ‘.$seek_start.’-’.$seek_end.’/’.$size);
}

//headers for IE Bugs (is this necessary?)
//header(“Cache-Control: cache, must-revalidate”);
//header(“Pragma: public”);

header(‘Content-Type: ‘ . $ctype);
header(‘Content-Disposition: attachment; filename=”‘ . $filename . ‘”‘);
header(‘Content-Length: ‘.($seek_end – $seek_start + 1));

//open the file
$fp = fopen($file, ‘rb’);
//seek to start of missing part
fseek($fp, $seek_start);

//start buffered download
while(!feof($fp))
{
//reset time limit for big files
set_time_limit(0);
print(fread($fp, 1024*8));
flush();
ob_flush();
}

fclose($fp);
}


To get data from POST body in PHP

This may look a very simple and small piece of code, but it took me ages to work on this one and get it in a proper format hence thought of sharing it with all. I used this line of code to get the data from POST body. I hope this will help you with your PHP Development.

file_get_contents(‘php://input’);


Introduction to HTML 5 (part 1 of 10)

HTML 5

HTML is always considered as one of the important aspects of web development. Here, we are discussing about HTML5.

HTML5 which is currently under development is the next major revision of the HTML standard. Like its immediate Predecessors HTML4.01 and XHTML 1.1 , HTML5 is a standard for structuring and presenting content on world wide web.

This new standard incorporates features like video playback , drag and drop , geolocation, data storage , visiting websites offline , forms and many more.

Here is a brief history of HTML5.

HTML5 which is currently under development is the next major revision of the HTML standard.

There was never any such thing as HTML 1

The first official specification was HTML 2.0, published by the IETF, the Internet Engineering Task Force.

Later on the role of the IETF was superceded by the W3C, the World Wide Web Consortium, where subsequent iterations of the HTML standard have been published.

In the latter half of nineties HTML 4.01 was published.

After HTML 4.01, the next revision to the language was called XHTML 1.0

The content of the XHTML 1.0 specification was identical to that of HTML 4.01. No new elements or attributes were added.

The only difference was in the syntax of the language.

Valid XHTML 1.0 document requires all tags and attributes to be in lowercase. All attributes must be quoted.All elements must have a closing tag.

These rules were similar to that of XML.So they were moving towards XML more.

Then the W3C published XHTML 1.1.

It seemed as if the W3C were losing touch with the day-to-day reality of publishing on the web as they were moving towards XML.

They began working on XHTML 2

XHTML 2 wasn’t going to be backwards compatible with existing web content or even previous versions of HTML

Representatives from Opera, Apple and Mozilla were unhappy with this direction.

They formed their own group: the Web Hypertext Application Technology Working Group, or WHATWG

They started working on HTML Standard and came out with new revision HTML5

The W3C uses a consensus-based approach: issues are raised, discussed, and voted on.

At the WHATWG, issues are also raised and discussed, but the final decision on what
goes into a specification rests with the editor. The editor is Ian Hickson.

While HTML5 was being developed at the WHATWG, the W3C continued working on XHTML 2

Later on W3C admitted that the attempt to move the web from HTML to XML just wasn’t working.

Rather than start from scratch, they wisely decided that the work of the WHATWG should be used as the basis for any future version of HTML.

Later on W3C announced that they will stop working on XHTML 2 and they will support WHATWG.

There are two groups working on HTML5. The WHATWG is creating an HTML5 specification using its process of “commit then review.” The W3C HTML Working Group is taking that specification and putting it through its process of “review then
commit.”

TechJini Solutions
TechJini Solutions is Bangalore, India based company working in the areas of software product engineering services and creating next generation software products that bring real business value. We take pride in our philosophy of taking on challenging problems and providing innovative and outstanding solutions. We are proud to develop applications on different mobile/tablet platforms including iPhone, iPad, BlackBerry and Android.

Next time, we will look at Forms in HTML 5. Feel free to email me for more details – avidnyat@techjini.com


Steps For Publishing Application On Android Market

    Make your application non debuggable
  • Remove the android:debuggable="true" attribute from the <application> element of the manifest.
  • Remove log files, backup files, and other unnecessary files from the application project.
  • Check for private or proprietary data and remove it as necessary.
    Deactivate any calls to Log methods in the source code.
  • Is in your possession
  • Represents the personal, corporate, or organizational entity to be identified with the application
  • Has a validity period that exceeds the expected lifespan of the application or application suite. A validity period of more than 25 years is recommended.
  • If you plan to publish your application(s) on Android Market, note that a validity period ending after 22 October 2033 is a requirement. You can not upload an application if it is signed with a key whose validity expires before that date.
  • Is not the debug key generated by the Android SDK tools.
    Steps for creating the private key

  • Set the following paths for the environmental varialbles JAVA_HOME: C:\Program Files\Java\jdk1.6.0_20 PATH: C:\Program Files\Java\jdk1.6.0_20\bin

    (this value changes depending on where we have stored the jdk)

  • Right click on the project and do the following Androidtools>export signed application>next>select create new keystore>next>next>finish.
  • Open command prompt and type the following.Set the path to where the keystore is stored C:\Documents and Settings\bindu\Desktop>keytool -list -alias [aliasname] -keystore [keystorename]
  • We now have obtained the fingerprint
  • Now open the following link and enter the obtained finger print http://code.google.com/android/maps-api-signup.html
  • Now we have the private key in your google account.
    Register for a Maps API Key,if your application is using Map View element
    If your application uses one or more Mapview elements, you will need to register your application with the Google Maps service and obtain a Maps API Key, before your MapView(s) will be able to retrieve data from Google Maps. To do so, you supply an MD5 fingerprint of your signer certificate to the Maps service.

    Obfuscating the codeWe can use tools like ant and progaurd to obfuscate the code. Detailed steps for this is given in blog. http://android-developers.blogspot.com/

    Licensing the application After we finish all the above steps refer the following link to publish the application in the android market. http://developer.android.com/guide/publishing/licensing.html



Creating a Customized PopOver for MapView

The android developers tutorial guides to create an app that shows a map the user can use to zoom and add overlay items that mark points of interest. Suppose the user wants to display the location of the overlay items that were added,as a callout bubble, a customized layout has to be created and added as a subview of the mapView.

Creating a layout:
Create a new xml file in Layout folder,say popOver.xml.

<FrameLayout xmlns:android=”http://schemas.android.com/apk/res/android”

android:id=”@+id/mapBubbleWrap”

android:layout_width=”wrap_content”

android:layout_height=”wrap_content” >

<LinearLayout android:orientation=”horizontal” android:layout_width=”wrap_content” android:layout_height=”wrap_content” android:id=”@+id/bubble_container”>

<FrameLayout android:layout_width=”wrap_content” android:layout_height=”wrap_content”>

<ImageView android:layout_width=”wrap_content” android:layout_height=”wrap_content”

android:id=”@+id/dialogimage” android:src=”@drawable/popup_leftpointer”/>

<ImageView android:layout_width=”wrap_content” android:layout_height=”wrap_content” android:paddingLeft=”10dip” android:paddingTop=”7dip”

android:id=”@+id/dialogimage1″/>

</FrameLayout>

<FrameLayout android:layout_width=”wrap_content” android:layout_height=”wrap_content” android:background=”@drawable/popup_middlebg”>

<TextView android:id=”@+id/mapBubble”

android:layout_width=”wrap_content”

android:layout_height=”wrap_content”

android:gravity=”center” android:paddingTop=”7dip”/>

</FrameLayout>

<ImageView android:layout_width=”wrap_content” android:layout_height=”wrap_content” android:id=”@+id/dialogimage2″

android:src=”@drawable/popup_right” />

</LinearLayout>

</FrameLayout>

The above xml code just contains the image of the popover that is to be displayed onTap of the overlay item. I have 3 images joined together to form a single popover image. One can use a single image and add a text displaying the location inside it. However, 2 images and a text is being displayed in popover so 3 images are being used.

Figure(A)

Figure(B)

Figure(C)

I have used the figure(B) to display the text(location), the left pointer points the top of the item marker.

Figure(D)

Figure(D) shows how the popover will look once we add the above view in the mapview.

Adding the customized view in the MapView

Then,in the MapOverLay class that extends ItemizedOverlay,in the overridden OnTap method, inflate the popOver.xml layout.i.e. protected boolean onTap(int index)

First, we have to get the location of the overlay item. This is done by the getProjection method of the MapView class.

Point point = map.getProjection().toPixels(item.getPoint(), null);

- getProjection() gets a projection for converting between screen-pixel coordinates and latitude/longitude coordinates.

- item is the overlay item (Overlay item = (Overlay) getItem(index);)

Now,we know where we have to place the customized view on the screen. But the point we have got will place the popover on the marker. We need to place it on top of the marker. To get the marker image’s height and width ,use getIntrinsicHeight and getIntrincsicWidth.
height=marker.getIntrinsicHeight();
width=marker.getIntrinsicWidth();

The customized view now has to be moved a few pixels above that corresponds to the marker height and displaced a few pixels in the x-direction that is half the marker’s width.

Set the LayoutParams of the layout that is being inflated.

LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT, point.x – width/2, point.y
- height, 0);
layout.setLayoutParams(params);

Now,add the view to the mapView.

mapView.addView(layout);

The x and y parameters being set in the LayoutParams depends on the kind of image being used as the popover. The image that I have used has a pointer that has to be displayed in the middle of the marker and it won’t be set in the middle of the marker if I use the above logic of setting the x and y parameters of the LayoutParams to half the width of the marker and the full height of the marker. If I do so,the left corner of the image will be displayed on the marker as shown. So use it according to the image being used.


Capturing the direct links for google analytics.

Capturing the direct links for google analytics.

There are many occasions where one wants to know how many clicks were attracted by a direct link . It could be a link to download some app or pdf or any other direct link. It is general assumption that we need to have a page with google analytics code for google to capture the visit to the page.

Often to achieve this, a page with google analytics code is created for all direct links and then that page redirects to the actual target. However, there is a simpler way to achieve this, using javascript.

If the page having the link already has google’s analytics code embedded, then all you have to do is to use onclick event on <a> tag to call pagetracker function, for example,

<a href=”http:\\www.yoursite.com\docs\help.pdf” onclick=”javascript: pageTracker._trackPageview(‘help_pdf’);” >Help</a>

In the snippet above, help_pdf will be your reference to search for when looking over reports in the google analytics admin page.

If you want to do more than just track the link, then you can have a javascript function in the page with your logic and a call to above function, for example,

function trackDirectLinks(linkName) {

	//your logic here

	//if analytics code is not embedded in the page, then paste it here.

	var pageTracker=_gat._getTracker("UA-xxxxx-x");
    	pageTracker._trackPageview(page);
}

And call this function in your links,

<a href=”http:\\www.yoursite.com\docs\help.pdf” onclick=”javascript: trackDirectLinks(‘help_pdf’);” >Help</a>

Check in the analytics if the link is getting captured. The results are almost realtime, for me, I had to wait for 15-20 mins before the results in the analytics got updated.

If you don’t see them, then one probable reason apart from hundred other syntax related errors could be that you are using the older version of google analytics code. Copy the latest version (its been around for quite a while now) of analytics code from analytics page and replace all your old code. The advantage of using newer code is you can place it anywhere in your page not necessarily at the bottom, as it uses asynchronous calls which does not block loading of your page content until the call is finished. All browsers support these calls.


quicktip: Working with strings.xml in Android and little bit about @

Very simple so straight to the point.

BAD:

In your xmls
- <Button android:id="@+id/buy_button" android:text="Buy Me" />

In your java code
- myButton.setText("Second Button");

GOOD:

Define your strings in strings.xml (You can name it anything) and place it in ‘res/values’ folder


<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="buy_button">Buy</string>
</resources>

and then


- <Button android:id="@+id/buy_button" android:text="@string/buy_button" />
- myButton.setText(this.getString(R.string.buy_button));

Syntax for using a ‘resource’ in a xml or code is :
package.R.resource_type.resource_name
and
@[package:]resource_type/resource_name

NOTE: package here does not mean ‘java package’ but package == application, so if you are accessing a resource which is defined in your own app you can skip it. Thats why we use @strings/name or directly R.strings.name. Similarly to use resources defined by android we will use @android:string/name or android.R.string.name

For converting R.string.id to String you can either use getString(int) or getString(int, Object…) for adding dynamic values.


quicktip: How to convert a view to an image (android)

This is a quick tip to convert or draw your view on a canvas so that you can either show it as preview or use it for any drag – drop kind of operation. Very simple and self explanatory so just posting the code


View viewToBeConverted;

Bitmap viewBitmap = Bitmap.createBitmap(viewToBeConverted.getWidth(), viewToBeConverted.getHeight(),Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(viewBitmap);

viewToBeConverted.draw(canvas);

Thats it, now you can use ‘viewBitmap’ as a normal image. You can change a few parameters to create different kinds of image, for eg when you drag your app icon on bring it on the trash can to drop it becomes red etc


  • TechJini Solutions

  • © Copyright 2009 TechJini Solutions Private Limited. All Rights Reserved
    iDream theme by Templates Next | Powered by WordPress