""

Category: Android

Source: http://osx.wdfiles.com/local--files/icon:iruler/iRuler.png

Source: http://osx.wdfiles.com/local–files/icon:iruler/iRuler.png


I was supposed to detect the event when scroller/page of a webview reaches bottom so that i can show one decent translate animation of another small view(like an ad banner). That view will be overlayed definitely and when web page scrolls above center of page then view will hide via translate animation. I came up with a simple solution to detect scroll position. I made an subclass of webview and override onScrollChanged method. Inside this method i am checking scrollY position with the height of content height.

@Override
	public void  onScrollChanged (int l, int t, int oldl, int oldt){
		int height = (int) Math.floor(this.getContentHeight() * this.getScale());
		if(this.getScrollY() >= height){
			Log.i("THE END", "reached");
		}
	}

I could get content height from getContentHeight but i need to keep zoom level of page in mind too so i have multiplied scale factor. Now whenever scrollY reaches height then page end has been reached. It is not so, because we haven’t checked for offset value. That offset value is height of the scroller according to theory if scrollY is the exact Y coordinates of scroller :P. I tried many ways to calculate the height but still i am missing something. I checked the reference documentation and found lots of helpful stuffs. I’l cover everything that i used where i failed and had success. First i used getBottom and getTop, according to doc it returns top and bottom position relative to parent, since parent on my case was “relative layout” with “match_parent”. I would calculate the heght of scroller:

int webViewHeight = this.getBottom() - this.getTop();

Now i have height of content and height of web view so i calculated the height of the scroller from this:

int scrollerHeight = (webViewHeight * webViewHeight) / height; //height is content height

I calculated detection of end reach with this condition:

if(this.getScrollY() + scrollHeight >= height){
	Log.i("THE END", "reached");
}

But it wasn’t any way near to perfection 😛 I logged the values and saw that calculation for view of webview was getting wrong output. Even getBottom was no way near accurate since it was returning way low value than expected with respect to my 7 inch nexus tablet density.

Next, i used getMeasuredHeight() and this one gave me accurate value. So i applied same above calculation with new height of web view and result still not very accurate. After all this i did small change to my formula and BINGO!!

public void  onScrollChanged (int l, int t, int oldl, int oldt){
	int height = (int) Math.floor(this.getContentHeight() * this.getScale());
	int webViewHeight = this.getMeasuredHeight();
	if(this.getScrollY() + webViewHeight >= height){
		Log.i("THE END", "reached");
	}
}

Yes above code worked absolutely accurate and am still analyzing the formula on above condition :P, i.e offset here is height of the webview but not height of scroll [sighs]. I would love to hear your opinion on this. You can optimize the above code though i just wanted to share the idea behind.

Why flush ?

Interesting stuff i came to know about which i was unaware of. This post is more of a discussion on the problem. I haven’t understood the solution and so would request you to have a say.

I have done json parsing numerous times. I can tell if json is valid or not by looking it. I was using google-gson for android application and its awesome. Application was supported by php web service. The solution that fixed the problem is related to php and i am not a php developer and don’t have that much inner understanding of it. It was regular json parsing routine. Application just crashed when gson was parsing the json response from php service.

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 2

From error I understood the reason but that was not it. I was very confident that something else was the problem because json response was perfect. I wrote quick objective-c routine(SBJSON) to parse same json response and it worked there. I even did validation on jsonlint.com
After doing bit of research I came across a working solution. In php before sending response I had to put this:

ob_clean();
echo header('Content-Type: application/json');

I checked the php manual to understand what those lines means, header function was quite obvious. According to manual, ob_clean:

This function discards the contents of the output buffer.

Now I have no idea why discarding the contents of output buffer was working. This was the case for android, I mean in iphone I didn’t need ob_clean. I am still looking for the explanation on this.

Another post on phonegap and my not so called “adventure”. This time something interesting happened. I am working on phonegap project targeting both iphone and android devices. Its mostly been REST based. So i was testing on various android and iphone devices, things went well except few things like static footer and header not working from android 2.x and below phones but i’l come to this issue on my next post. I hadn’t tested on android 4.0 and above, so yeah when i ran the app on icecream sandwich(Sony Xperia U and Samsung galaxy s2) mighty exception punched me on my face. Here is the long excpetion trace

10-26 10:19:45.998: E/AndroidRuntime(23917): FATAL EXCEPTION: main
10-26 10:19:45.998: E/AndroidRuntime(23917): android.os.NetworkOnMainThreadException
10-26

10:19:45.998: E/AndroidRuntime(23917):  at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1099)
10-26 10:19:45.998: E/AndroidRuntime

(23917):  at java.net.InetAddress.lookupHostByName(InetAddress.java:391)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at

java.net.InetAddress.getAllByNameImpl(InetAddress.java:242)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at java.net.InetAddress.getAllByName

(InetAddress.java:220)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at libcore.net.http.HttpConnection.(HttpConnection.java:71)
10-26 10:19:45.998:

E/AndroidRuntime(23917):  at libcore.net.http.HttpConnection.(HttpConnection.java:50)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at

libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:351)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at

libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:86)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at

libcore.net.http.HttpConnection.connect(HttpConnection.java:128)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at

libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:308)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at

libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:460)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at

libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:432)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at

libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:282)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at libcore.net.http.HttpEngine.sendRequest

(HttpEngine.java:232)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at libcore.net.http.HttpURLConnectionImpl.getResponse

(HttpURLConnectionImpl.java:273)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at libcore.net.http.HttpURLConnectionImpl.getInputStream

(HttpURLConnectionImpl.java:168)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at libcore.net.http.HttpsURLConnectionImpl.getInputStream

(HttpsURLConnectionImpl.java:270)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at com.facebook.android.Util.openUrl(Util.java:215)
10-26 10:19:45.998:
.
.

(FbDialog.java:146)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at android.webkit.CallbackProxy.uiOverrideUrlLoading(CallbackProxy.java:234)
10-26

10:19:45.998: E/AndroidRuntime(23917):  at android.webkit.CallbackProxy.handleMessage(CallbackProxy.java:349)
10-26 10:19:45.998: E/AndroidRuntime(23917):  

at android.os.Handler.dispatchMessage(Handler.java:99)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at android.os.Looper.loop(Looper.java:137)
10-26

10:19:45.998: E/AndroidRuntime(23917):  at android.app.ActivityThread.main(ActivityThread.java:4507)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at

java.lang.reflect.Method.invokeNative(Native Method)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at java.lang.reflect.Method.invoke(Method.java:511)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
10-26 10:19:45.998:

E/AndroidRuntime(23917):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at

dalvik.system.NativeStart.main(Native Method)

So exception thrown was NetworkOnMainThreadException, so first thing, i checked out the documentation for the details. So according to reference:

“The exception that is thrown when an application attempts to perform a networking operation on its main thread.

This is only thrown for applications targeting the Honeycomb SDK or higher. Applications targeting earlier SDK versions are allowed to do networking on their main event loop threads, but it’s heavily discouraged”.

So one thing became clear to me that phonegap-facebook plugin is performing networking operation for facebook on main thread rather than separate thread like asynctask. From API level 11, httpclient is not allowed to execute on main thread. So i found the way to remove this restriction by changing the thread policy. Here is the small snippet that goes on onCreate():

if (android.os.Build.VERSION.SDK_INT >= 11) {
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);
}

I am tweeting: Android

Someone might be looking for integrating twitter to their android application. I found few alternatives(more than enough) on the web. I’l be talking about few of them on my upcoming posts. All this libraries are unofficial, not provided by twitter itself as there isn’t any official twitter sdk available for android. In this post i’l be talking about one library that i recently used, its Twitter4J. I am again not writing any tutorial for using it. I am here to share some pitfall i fell into, which many people can face for first time. But don’t worry, there is THIS BLOG which has full detail on setting up Twitter4J with your project and get you started tweeting in no time(techically 30 minutes :P).

So i suppose now you have setup the project as detailed in that blog. Now if everything is working than Good Job, if its not working for you yet then go through the steps again and see if you are not missing something. But if you are having problem that i faced and which i will be talking about it here then “GOOD JOB” too 😛

I faced two problems which are very basic but critical.

“oauth.signpost.exception.OAuthNotAuthorizedException: Authorization failed (server replied with a 401). This can happen if the consumer key was not correct or the signatures did not match.”

This error gave me lotsa pain since it was very difficult to find the reason. I spent many hours figuring out what was happening. Error is very specific which states that consumer key might not be matching. But i cross checked keys and everything, everything was in place, so what could be the possible reason ? Then all of a sudden, somehow i just fixed the issue like hitting my hand everywhere or shooting the arrow in dark. I was so desperate. So thing that was causing this issue was, during resgistration of app on dev.twitter.com, Callback URL value wasn’t provided. Yeah i didn’t provide any callback url because it was optional, so i skipped it. So i provided a callback url, you can provide anything there. Now you’l find that above error doesn’t happens anymore and you can start tweeting from your app.

“error – Read-only application cannot POST”

Second issue i faced was this, and this one is very easy to figure out and fix it. It means that your registered twitter app is read only. So go to settings page of your application and make it “read and write”. Thats it.

I am showing you the screenshot of how settings will look like.

Adios.

RTL support on android

Hola everyone,
Long time no see 😀 I was making an app based on hebrew language. Its true that hebrew is not fully supported on all android phones. On some device it may work RTL and on some hebrew won’t be supported at all. Anyway here i am again to share something that i learned. On devices that supported hebrew(rendering) had a minor issue, lets say there is a number 52 on a hebrew sentence and when u try to display this sentence then 52 number is displayed reverse i.e 25. Now just imagine how messed up will whole sentence be because of this reverse number. Thus i found loophole in new android RTL support. So i had to do something about it as this was full hebrew language based app. I was using textview to display this hebrew sentence and this sentence was coming from xml web service. So i came up with my awesome solution. I chose to use webview to render/display hebrew sentence with html formatting. SO my code looked like this to prepare html:

public static String BuildHtml(String hebrewText)
{       
StringBuilder sb = new StringBuilder();
sb.append("");
sb.append("");
sb.append("");
sb.append("");
sb.append(hebrewText.trim());
sb.append("");
sb.append("");
	
return sb.toString();
}

Now i load my html on a webview by calling my method that returns my hebrew string encoded in html format.

webView.loadData(BuildHtml(myHebrewText), "text/html", "utf-8");

This code worked flawlessly. The number 56 was getting displayed as 56 in a hebrew sentence.
I hope this helps those who faced simillar problem.

Gracias.

Hola everyone,
Been very busy and christmas season on way. Anyway i am here again and have something to show and tell. There was a project i was working on, and i want to send some email message from my app. So i used an intent to open up options of my email clients installed on my device. So its not a big deal to use an intent and i used android.content.Intent.ACTION_SEND and i got the options. But i didn’t just got email clients but also other communication app like text message, dropbox, facebook, twitter etc. That i didn’t want it. I just wanted email clients to show up i.e like email, gmail, hotmail, email text only(or other email client u have installed). After doing research for long hours i came up with 2 solutions. First solution works but not perfect and second solution is just awesome, works perfectly. But first i’l show my code that i used before:

String[] recipients = new String[]{"sendme@me.com", ""};
Intent testIntent = new Intent(android.content.Intent.ACTION_SEND);
testIntent.setType("text/plain");
testIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "blah blah subject");
testIntent.putExtra(android.content.Intent.EXTRA_TEXT, "blah blah body message");
testIntent.putExtra(android.content.Intent.EXTRA_EMAIL, recipients);
startActivity(testIntent);

Well the above code doesn’t work if u need just email clients to show but this code shows all communication apps. So i decided to change setType of intent from (“text/plain”) to (“text/email”).

testIntent.setType("text/email");

Well it did filter some apps but still not perfect because it still showed some apps like andFTP, dropbox, google docs etc.
Now i had to do some serious research, i asked in forum but didn’t got much help and then i stumbled into one post that asked similar question on stackoverflow. So i found 2 solution, both works, one is not too perfect but works in most scenario, and second solution is awesomely perfect, well it worked for me so u have to test yourself to see if it works for u 😛

Solution 1:
just change setType to “message/rfc822”. Yes this works but with very minor flaw. It filtered out all communicatio app exept one, i.e andFTP yeah it didn’t filtered out andFTP and this ruined it. But it filtered out others and showed only email clients.

String[] recipients = new String[]{"sendme@me.com", ""};
Intent testIntent = new Intent(android.content.Intent.ACTION_SEND);
testIntent.setType("message/rfc822");
testIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "blah blah subject");
testIntent.putExtra(android.content.Intent.EXTRA_TEXT, "blah blah body message");
testIntent.putExtra(android.content.Intent.EXTRA_EMAIL, recipients);
startActivity(testIntent);

Now Solution 2, which worked perfectly for me. here you don’t use android.content.Intent.ACTION_SEND but Intent.ACTION_VIEW

Intent testIntent = new Intent(Intent.ACTION_VIEW);
Uri data = Uri.parse("mailto:?subject=" + "blah blah subject" + "&body=" + "blah blah body" + "&to=" + "sendme@me.com");
testIntent.setData(data);
startActivity(testIntent);

filtering non email client programs


Well above code just worked perfectly for me. It filtered out all other communication apps and showed just exclusive email client programs. I hope this works for you also.

Gracias.

Dude where is my javascript ?

Hola everyone,
a very hectic schedule going on this season. Working my ass off in my upcoming ambitious project. Anyway i am here and writing about just very basic problem that i faced. For a game project i wanted to show leaderboards, for this part i decided to use web view to show leaderboards page optimized for device. It has some javascript function that is doing its stuff of retrieving leaderboards details and all that. So i wrote a line to load the url pointing to my leaderboard page and guess what it didn’t rendered fully and i was again left scratching my head 😀 . Then after going through many testing i found that stuffs that were dependent on javascript were not getting rendered on my web view so i got the root of the problem i.e dude where is my javascript ? . Then i did a peroid(.) operator on my webview reference variable and found a method setJavaScriptEnabled(), so i did something like this:

webView.getSettings().setJavaScriptEnabled(true);

and yeah u guessed it right, it rendered fully after calling that method. So i guess by default javascript is disabled on webview. Phew.

Gracias.

Hide soft keyboard: Android

I just wanted to share two ways about hiding your soft keyboard. When i was making a screen for submitting score to leaderboards, when i touch edittext to enter my name soft keyboard appears and when i click submit button i wanted that soft keyboard to disappear so i found this one way to do that:

InputMethodManager inputManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(Test.this.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);

Now for second issue that i faced, i had a AutoCompleteTextView on my one application activity so whenever that activity takes screen a soft keyboard appears with focus on autocomplete obviously. This thing didn’t happened with EditText. But whenever i had autocompletetextview soft keyboard appears automatically. I didn’t wanted this. Instead i wanted soft keyboard to appear only when i touch AutoCompleteTextView. But i found a simple solution for this:

 

yeah just add android:windowSoftInputMode=”stateAlwaysHidden” attribute to activity tag, so whenever my activity takes screen keyboard will not show up until i touch any editable view. This has worked for me till now, so you can give it a try.

Gracias

Well i have been playing around a lot with android client connectivity with remote MySQL database. Lately i wanted a UI/View, something input textfield, i wanted to show completion suggestions automatically in a drop down menu while the user is typing, suggestions would be coming from MySQL database. Basically whenever i type, i am calling php sending the input and php will query database and return the values(in my case just names) that have “input” as substring (like if i type ‘pa’ then it would return names that have ‘pa’ as substring). I am sending results to android client via encoded json. In android side i am decoding json and filling my ArrayAdapter. Lets see the points that are being done:

1) PHP

I somehow looking at google i wrote this code. This php gets the input text from my android and it runs query at database for records whose company names has “input text” as a substring. You can see the query statement above. In the end it encodes the result in json.

2) Main.xml (my layout)
Here is the xml layout file for my ui.





3) Main Activity class
Here is the main class that extends Activity. Here is the code of calling php module and parsing json. I have explained this all in my previous post so you could go through it. i’l explain just AutoCompleteTextView part here.

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.widget.ArrayAdapter;
public class AutoComptest extends Activity {
    
	private CustomAutoCompleteView autoComplete;	 	
	 
	private ArrayAdapter autoCompleteAdapter;
	
	/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        autoCompleteAdapter = new ArrayAdapter(this, android.R.layout.simple_dropdown_item_1line); 
        autoCompleteAdapter.setNotifyOnChange(true); // This is so I don't have to manually sync whenever changed  
        autoComplete = (CustomAutoCompleteView)  findViewById(R.id.autoCompleteCountry);
        autoComplete.setHint("Country");
        autoComplete.setThreshold(3);
        autoComplete.setAdapter(autoCompleteAdapter);
        
        autoComplete.addTextChangedListener(textChecker);
        
    }
    
    final TextWatcher textChecker = new TextWatcher() {
        public void afterTextChanged(Editable s) {}
 
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
 
        public void onTextChanged(CharSequence s, int start, int before, int count)
        {
                   
                autoCompleteAdapter.clear();
                
                callPHP();
                               
        }     
    };
   
    private void callPHP(){
    	String result = "";   	
    	InputStream is=null;    	
    	try{
    			ArrayList nameValuePairs = new ArrayList();
    			nameValuePairs.add(new BasicNameValuePair("st",autoComplete.getText().toString()));
    	        HttpClient httpclient = new DefaultHttpClient();
    	        HttpPost httppost = new HttpPost("http://10.0.2.2/gaanza_android/android_database.php");
    	        httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
    	        HttpResponse response = httpclient.execute(httppost);
    	        HttpEntity entity = response.getEntity();
    	        is = entity.getContent();
    	}catch(Exception e){
    	        Log.e("log_tag", "Error in http connection "+e.toString());
    	}
    	
    	try{		 	
	        BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
	        StringBuilder sb = new StringBuilder();
	        String line = null;
	        while ((line = reader.readLine()) != null) {	        	   	                
	        	    sb.append(line + "\n");
	        }
	        is.close();
	 
	        result=sb.toString();	        
	}catch(Exception e){
	        Log.e("log_tag", "Error converting result "+e.toString());
	}
	

//parse json data
try{
JSONArray jArray = new JSONArray(result);
for(int i=0;icatch(JSONException e){ Log.e(“log_tag”, “Error parsing data “+e.toString()); } } }

Note: remember “http://10.0.2.2/” in my last post. I had to use 10.0.2.2 instead of localhost because emulator consider itself as localhost and my xammp local server is not in emulator localhost.

Ok so i want to detect an event when a text is typed/deleted from my autocompletetextview, basically i want a listener which detects a change in text of my view. So what should we do ? Well in my case i searched the android developer documentation 😀 , there i found something called TextWatcher. What i am doing is attach a TextWatcher object to editable like my AutoCompleteTextView so whenever any text changes in my editable the functions/methods of TextWatcher will be called and in these methods i had to write my logic codes which is what i want to achieve if text changes in autocompletetextview ?. There are three abstract methods in TextWatcher class so you have to override them, well anyway thats what we wanted. Methods are:

afterTextChanged(Editable s)
	beforeTextChanged(CharSequence c, int start, int count, int after)
	onTextChanged(CharSequence c, int start, int before, int count)

Best way to understand them is going through the document here. Anyway i had to write my logic code on beforeTextChanged() method so that it performs action whenever there is a change in text of autocompletetextview.

In above code sample i am calling PHP whenever i am typing something. So i am calling callPHP function at onTextChanged() method. So whenever i type something it will call PHP giving text to the function in PHP and PHP will query MySql database for results and PHP will send results to me in json. This is it. So i decode json and fill the results in ArrayAdapter after clearing it, whenever ArrayAdapter changes it notify the changes being made and AutoCompleteView will show the new drop down suggestions.

There was still one very minor problem and i solved it with my another very stupid solution 😛 So problem was that whenever the results from database gets filled in ArrayAdapter and AutoCompleteTextView shows drop down suggestions, it showed me filtered suggestions like suppose i type “can” and i get results(which has “can” as substring) from database, so for “can” ArrayAdapter contents get filtered and i get suggestion starting with text “can” which i didn’t wanted because i already has got filtered results from database and i wanted to show all results that i am receiving from database. So for this i had to write my custom AutoCompleteTextView. It isn’t hard at all, i just had to extend AutoCompleteTextView and override the methods.

4) CustomAutoCompleteView which extends AutoCompletetextView

public class CustomAutoCompleteView extends AutoCompleteTextView {
	
	public CustomAutoCompleteView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
	}

	public CustomAutoCompleteView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
	}

	public CustomAutoCompleteView(Context context, AttributeSet attrs,
			int defStyle) {
		super(context, attrs, defStyle);
		// TODO Auto-generated constructor stub
	}
	
	@Override
	protected void performFiltering(final CharSequence text, final int keyCode) {
		String filterText = "";
		super.performFiltering(filterText, keyCode);
	}
    /**
    * After a selection, capture the new value and append to the existing
    * text
    */
    @Override
    protected void replaceText(final CharSequence text) {
    	super.replaceText(text);
    }

}

How to remove the filter on an ArrayAdapter used in an AutoCompleteTextView? I had to override performFiltering() method. In this method i am telling AutoCompletetextView to not filter any suggestions, just show all suggestions. I searched on google for this topic but i didn’t find any good solution, maybe i didn’t searched it properly. Whatever, i just wrote a stupid trick to remove any filter, actually instead of technically removing filter i am adding a filter which does a job to show all suggestions :D. I defined a filter which filters all suggestion based on “” yeah a blank string :D. But this works like a charm. Just try it.

So now your are getting results suggestion from database dynamically to AutoCompleteTextView.

But But But But But ok enough, In above code way of fetching data from database to AutoCompletetextView just sucks. Never never ever call a http PHP call in UI Thread. I did a lot of testing with this code. When i was getting small number of results from Database(live database not local) it was working fine but when i was getting large number of results say more than 150 and it was taking a bit of time which caused my UI to be non-responsive and thus famous FORCE CLOSE occured. So never call it from UI thread because u don’t know how much time it will take to complete whole http connection. So always call it in separate thread that i will discuss in Part II of this subject. yes i’l be posting new better version of same problem.

Gracias

While working on submitting and retrieving global game high scores from a remote database like mysql i learned few things. During start experiment i decided to use PHP to connect to mysql database. What i was trying to do is that i wanted to call php, then php would make a database connection and make a sql query and retrieve the result, then php would encode that result into JSON format and i would decode this JSON at my android program and display the results. I haven’t done much PHP before(never actually setup PHP server before :D). So i came to know this xampp server, so i installed/setup the xampp server(its a php apache server and it comes with mysql also). I am not telling how to setup xampp and create a databse and tables as you can find it in their wiki.

I create a php file, which makes a database connection and makes a query and encodes a result. As i told before i am not familiar to PHP so i wrote this code looking here and there by googling it :D. Code looks like this:


Well code is not that hard to understand. You are making a mysql connection by providing credentials. Then you select a databse. Then you execute a query and result is assigned to $q. Next what i seen is that result is in ArrayCollection type (i saw it in xampp console) so i think we are converting it into Array while iterating through collection(I am not quite sure so if u know then please share). Then You are just encoding the result into JSON.

Now lets see how we will decode the JSON at our android program. Code looks like this:

void parseJSON()
    {
    	
    	String result = "";
    	String x = "";
    	InputStream is=null;
    	//http post
    	try{
    			ArrayList nameValuePairs = new ArrayList();
    	        HttpClient httpclient = new DefaultHttpClient();
    	        HttpPost httppost = new HttpPost("http://localhost/game_php_testing/android_database.php");
    	        httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
    	        HttpResponse response = httpclient.execute(httppost);
    	        HttpEntity entity = response.getEntity();
    	        is = entity.getContent();
    	}catch(Exception e){
    	        Log.e("log_tag", "Error in http connection "+e.toString());
    	}
    	//convert response to string
    	try{
    		 	
    	        BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
    	        StringBuilder sb = new StringBuilder();
    	        String line = null;
    	        while ((line = reader.readLine()) != null) {
    	                sb.append(line + "\n");
    	        }
    	        is.close();
    	 
    	        result=sb.toString();
    	        
    	}catch(Exception e){
    	        Log.e("log_tag", "Error converting result "+e.toString());
    	}
    	 

//parse json data
try{
JSONArray jArray = new JSONArray(result);
for(int i=0;i catch(JSONException e){ Log.e(“log_tag”, “Error parsing data “+e.toString()); } }

I faced two problems/exception while connecting to php. PHP was connecting to mysql perfectly as when i run in browser it printed results so there was some issues on my above code which i’l address here and this is common problems which will be faced by every newcomer to android like me :D. Before that i’l just explain my php file and localhost path setup. When i installed xampp, in xampp folder there must be folder called htDocs so i have to make a project folder here inside htDocs and inside this project folder will be my php. So my php path would look like this “/htDocs/game_php_testing/android_database.php” So when i will make a call to php via “http://localhost/game_php_testing/android_database.php”

Now i will address the two problems that i faced.
First,

java.net.socketexception -permission denied

yes whenever i was trying to call my php i was getting this exception. How did i solved it ??? Well i just provided a permission to internet access at AndroidManifest.xml file. You have to put this permission above tag


Now second Problem, this one is very important.

java.net.ConnectException -Connection Refused.

Well what i found is that when u call localhost android thinks that u r calling to android emulator itself not the localhost machine. So localhost/127.0.0.1 wouldn’t work. So i found the solution to that: instead of localhost use 10.0.2.2, code will be like this:

HttpPost httppost = new HttpPost("http://10.0.2.2/game_php_testing/android_database.php");

Well problem solved :D. Now i decode the json that i got from php. I am printing the result on LOG. Please see that when i am calling “json_data.getString(“Player_name”)“, Player_name is a column/attribute in my database table and its type is varchar so i used getString() on it.

I hope this post helped you as you may also faced similar problem at first time.

Gracias.