Wednesday, January 25, 2012

Android API quirks - getting an image from gallery

Here's the recommended intent to get an image from gallery

final Intent i = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, REQUEST_GALLERY);

And then, uri can be retrieved from Intent in onActivityResult:

final Uri imageUri = data.getData();
final String[] columns = { MediaColumns.DATA }
final Cursor cursor = activity.getContentResolver().query(imageUri, columns, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(MediaColumns.DATA);
String filePath = cursor.getString(columnIndex);

However, on never OS's, 3.x and 4.x, images may come from picassa with the following urls: "content://com.google.android.gallery3d.provider/picasa/item/", and then MediaColumns.DATA cannot be used to retrieve file path.

There is an unresolved issue in google issue tracker. I found a way to support picassa urls. Namely, just use the following columns when querying provider (second one is supported by picassa):

final String[] columns = { MediaColumns.DATA, MediaColumns.DISPLAY_NAME };

and then, put it all together to get the actual data (using openInputStream for picassa provider):

int columnIndex = cursor.getColumnIndex(MediaColumns.DATA);
if (columnIndex != -1) {
//regular processing for gallery files
String fileName = cursor.getString(columnIndex);
} else {
// this is not gallery provider
columnIndex = cursor.getColumnIndex(MediaColumns.DISPLAY_NAME);
if (columnIndex != -1) {
final InputStream is = getContentResolver().openInputStream(imageUri);
}
}

I think that API is a bit quirky here, so this is more of a workaround, not real solution. If anyone knows a better solution, please post.

Thursday, February 4, 2010

64-bit version of JDIC

We are moving to 64-bit windows 7, and we needed 64-bit version of JDICPlus. Long story short, couldn't find it anywhere and the project seems dead. So I had to compile it myself. Downloading a trial version of Microsoft Visual Studio 2008 took ages (it's 4 gigabytes, just to build a simple dll :)

Haven't touched C++ in ages, guess it's a nice exercise. Oh, and visual studio is still so lacking compared to eclipse. Or maybe it's just me.

Here are the binares, let me know if it works.

Thursday, May 14, 2009

Java 6 and XML digital signatures (JSR-105)

I had to use digital signatures recently to sign XML files. What can I say, java 6 certainly makes it easy. Signature is embedded in your XML and is XML istself. Kudos :)

It is described nicely here:
http://java.sun.com/javase/6/docs/technotes/guides/security/xmldsig/XMLDigitalSignature.html
And here:
http://java.sun.com/developer/technicalArticles/xml/dig_signature_api/

You can even include a public key as a part of a signature - but that basically decreases the protection level from authenticated message to "unchanged" message, i.e., undamaged during transfer because you will not be able to verify who created that public key. Seems not very useful to me.

Beware of one really painful caveat: you cannot format a "signature" part of message. Obviously, you cannot touch the signed content, but why you cannot touch the signature part of XML, that's beyond me. Was just adding whitespace to it to make it look nice. Spent quite some time debugging this (no source code).

This is is part of JCP, but source code is not available. It is available "under java research license", but how to get that license? And with the demise of Sun Microsystems, we may never see that source code again. Oh, well...

So if anyone knows how to get source code for JSR-105, please let me know.

Tuesday, March 24, 2009

Oracle JDBC driver rant (writing BLOB)

I haven't touched JDBC and J2EE in general for quite some years. How was I surprised when I saw that J2EE is still quirky... After all these years...

Anyways, simple problem: when using proper J2EE way to get a database connection from J2EE datasource, most datasource implementations (JBoss in my case) will return connection/resultset wrappers. Now, oracle JDBC driver fails to write to BLOB when being wrapped. And, the fact that I need to import and use oracle-specific classes to write to BLOB in the first place, is, well, just ridiculous...

Thanks god, spring comes to help here (with support for various app servers, including tomcat):

http://static.springframework.org/spring/docs/1.1.5/api/org/springframework/jdbc/support/nativejdbc/JBossNativeJdbcExtractor.html

Now, here's a code to write blobs without importing oracle.jdbc.* and oracle.sql.* classes and without manually unwraping connections:

NativeJdbcExtractor jdbcExtractor = new JBossNativeJdbcExtractor();
OracleLobHandler handler = new OracleLobHandler();
handler.setNativeJdbcExtractor(jdbcExtractor);
.......
PreparedStatement ps = connection.prepareStatement("update xxx set segment=? where id='" + id + "'");
handler.getLobCreator().setBlobAsBytes(ps, 1, bytes);
ps.execute();


Looks neat, right? The downside is that you will need 3 spring jars (almost a megabyte) to have this nice feature. And of course, you can inject a proper jdbc extractor from config file if you need to, this is spring, after all.

So, this is how you can use spring even if you don't use it :)

Friday, January 23, 2009

Monday, January 19, 2009