Category Archives: Devel

[Android] Titanium recognizes image with a black border as a 9-patch image

If you use a image with black border as a background image, this kind of error is occurred in Android.
(Related issue : TIMOB-4889)

06-07 16:56:04.507: E/TiApplication(2738): (KrollRuntimeThread) [438,440] APP PROXY: ti.modules.titanium.app.AppModule@413ba7f8
06-07 16:56:14.105: E/TiApplication(2738): (main) [1156,8379] Sending event: exception on thread: main msg:java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0; Titanium 2.0.2,2012/05/30 10:21,2ff31a3
06-07 16:56:14.105: E/TiApplication(2738): java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
06-07 16:56:14.105: E/TiApplication(2738): 	at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
06-07 16:56:14.105: E/TiApplication(2738): 	at java.util.ArrayList.get(ArrayList.java:304)
06-07 16:56:14.105: E/TiApplication(2738): 	at org.appcelerator.titanium.util.TiNinePatchHelper.createChunk(TiNinePatchHelper.java:189)
06-07 16:56:14.105: E/TiApplication(2738): 	at org.appcelerator.titanium.util.TiNinePatchHelper.process(TiNinePatchHelper.java:52)
06-07 16:56:14.105: E/TiApplication(2738): 	at org.appcelerator.titanium.util.TiFileHelper.loadDrawable(TiFileHelper.java:308)
06-07 16:56:14.105: E/TiApplication(2738): 	at org.appcelerator.titanium.util.TiUIHelper.buildBackgroundDrawable(TiUIHelper.java:493)
06-07 16:56:14.105: E/TiApplication(2738): 	at org.appcelerator.titanium.view.TiUIView.handleBackgroundImage(TiUIView.java:783)
06-07 16:56:14.105: E/TiApplication(2738): 	at org.appcelerator.titanium.view.TiUIView.processProperties(TiUIView.java:562)
06-07 16:56:14.105: E/TiApplication(2738): 	at ti.modules.titanium.ui.widget.TiView.processProperties(TiView.java:39)
..

This happens because Titanium recognizes the image as a 9-patch image.

When opening the local image resource, Titanium checks whether it is a 9-patch image in TiNinePatchHelper.java.

If the 1-pixel edge of the image contains only black and transparent color, it recognizes as a 9-patch image.

So if you want to avoid the error, the border of the image should contain at least one pixel with other color, such as black pixel with a little bit transparency.

Using HTML format in TextView

In Android, HTML formatting is possible by using Html.fromHtml() in TextView.

TextView tv = (TextView)findViewById(R.id.text);
tv.setText(Html.fromHtml("Text with <br><font color=\'#ff0000\'>Color</font> and <b>Bold</b>"));

To use a string from a resource, the string have to be formatted this way:

[strings.xml]

<string name="html_string">Text with &lt;br&gt;&lt;font color=\'#898f97\'&gt;Color&lt;/font&gt; and &lt;b&gt;Bold&lt;/b&gt;</string>

[TestActivity.java]

TextView tv = (TextView)findViewById(R.id.text);
tv.setText(Html.fromHtml(getResources().getString(R.string.html_string)));

DB error while creating CookieSyncManager

If the app has services, or other processes, then you can see this kind of error when using CookieSyncManager.

01-13 16:44:46.674: E/Database(4298): CREATE TABLE android_metadata failed
01-13 16:44:46.690: E/Database(4298): Failed to setLocale() when constructing, closing the database
01-13 16:44:46.690: E/Database(4298): android.database.sqlite.SQLiteException: database is locked
01-13 16:44:46.690: E/Database(4298): at android.database.sqlite.SQLiteDatabase.native_setLocale(Native Method)
01-13 16:44:46.690: E/Database(4298): at android.database.sqlite.SQLiteDatabase.setLocale(SQLiteDatabase.java:2113)
01-13 16:44:46.690: E/Database(4298): at android.database.sqlite.SQLiteDatabase.(SQLiteDatabase.java:1966)
01-13 16:44:46.690: E/Database(4298): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:887)
01-13 16:44:46.690: E/Database(4298): at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:965)
01-13 16:44:46.690: E/Database(4298): at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:958)
01-13 16:44:46.690: E/Database(4298): at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:576)
01-13 16:44:46.690: E/Database(4298): at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203)
01-13 16:44:46.690: E/Database(4298): at android.webkit.WebViewDatabase.getInstance(WebViewDatabase.java:214)
01-13 16:44:46.690: E/Database(4298): at android.webkit.WebSyncManager.(WebSyncManager.java:65)
01-13 16:44:46.690: E/Database(4298): at android.webkit.CookieSyncManager.(CookieSyncManager.java:69)
01-13 16:44:46.690: E/Database(4298): at android.webkit.CookieSyncManager.createInstance(CookieSyncManager.java:96)

This happens because the DB created inside the CookieSyncManager is accessible from only one process.
I couldn’t find the way to use the CookieSyncManager from more than one process.

Also, I tried to CookieSyncManager.createInstance() from one process and CookieSyncManager.getInstance() from another, but it didn’t work.

I should have to solve this problem by only using the CookieSyncManager from one process.
Also keep in mind that CookieManager requires CookieSyncManager to work.