Friday, December 9, 2011

Open webpage using Android app and mark URL as Bookmark

Few of fellow developer friends drop me a query about an app which open a browser with predefined URL & mark that URL as bookmark. The solution is as follows:-
To open a browser with in a app, you have to create a browser Intent.

        private void browseURL(String url) {
            Intent browseIntent = new Intent(Intent.ACTION_VIEW);
            browseIntent.setData(Uri.parse(url));
            startActivity(browseIntent);
        }

Now before saving this URL as a bookmark, you need to check whether it's already exist or not. So to read bookmarks we need to access Android's Browser content provider using ContentResolver object. You can then use the ContentResolver's methods to interact with whatever content providers you're interested in.

private boolean isBookmarked() {
            boolean isBookemarked = false;                
            String[] projection = new String[] {
                Browser.BookmarkColumns.TITLE,
                Browser.BookmarkColumns.URL
            };
         Cursor mCur = managedQuery(Browser.BOOKMARKS_URI, projection,            Browser.BookmarkColumns.URL + " like '" +   m_url + "' AND " + Browser.BookmarkColumns.BOOKMARK + " = 1", null, null);
            mCur.moveToFirst();
int titleIdx = mCur.getColumnIndex(Browser.BookmarkColumns.TITLE);
int urlIdx = mCur.getColumnIndex(Browser.BookmarkColumns.URL);
            String bTitle = "";
            String bUrl = "";
            while (mCur.isAfterLast() == false) {
                bTitle = mCur.getString(titleIdx);
                bUrl = mCur.getString(urlIdx);
                mCur.moveToNext();
            }
            mCur.close();
if(bTitle.equalsIgnoreCase(m_title) && bUrl.equalsIgnoreCase(m_url)) {
                isBookemarked = true;
            }
            return isBookemarked;                
        }

The above method will query the Browser.BookmarkColumns table which containing both bookmarks and history items. To read this table requires the READ_HISTORY_BOOKMARKS permission and writing to it requires the WRITE_HISTORY_BOOKMARKS permission. Now if url is not marked in bookmarks then you need to save the url in bookmark.

private void saveBookmark(String title, String url) {
            final ContentValues bookmarkValues = new ContentValues();
            bookmarkValues.put(Browser.BookmarkColumns.TITLE, title);
            bookmarkValues.put(Browser.BookmarkColumns.URL, url);
            bookmarkValues.put(Browser.BookmarkColumns.BOOKMARK, 1);
            final Uri newBookmark = getContentResolver().insert(Browser.BOOKMARKS_URI, bookmarkValues);                
        }

ContentValues class is used to store a set of values that the ContentResolver can process. To verify you can check the browser bookmarks for new entry.

Wednesday, July 20, 2011

MIDlet Signing

J2ME Security Architecture is driven from Java Sandbox Architecture. J2ME represents two level of securities:-
  • Low Level KVM Security
  • Application Level Security
Low Level KVM Security is divided into two steps:
  1. Pre-verification performs certain checks on the Java bytecodes using preverify tool, if first level of verification is passed, then preverifier add special stack map attributes into class files to facilitate runtime in-device verification. Note that preverified class files with the special attribute are approximately 5% larger than the original files.
  2. In-device verification is performed on real device by KVM. It refers to the additional information attached to the pre-verified files & verify whether the class file is structurally or conceptually correct according to J2ME specifications.
As you know small devices are memory constraints, so split verifier improves verification process by generating annotations at compile time and then using this information at runtime. The runtime verification is therefore faster & use less memory.

The Low Level KVM Security is very limited & used to verify that the given set of Java classes in a MIDlet are valid classes and nothing more. Actual security threats are come into picture at this level such as accessing device file system, network connectivity etc. For normal Java, we have different mechanism to over come Security threats, but these are memory consuming and not suitable for handheld devices. So Application Level Security is an optimized variant of Java Sandbox Security Model, which means:-
  • Java class files are pre-verified and should be valid Java classes.
  • Only a limited, predefined set of APIs are available to the developer.
  • Downloading and management of MIDlet is performed by Application Manager (part of KVM).
  • No User-defined class loaders.
  • No support for Reflection.
  • No Thread groups or daemon threads.
Till now, we discuss the security architecture of J2ME; Now we'll discuss about MIDlet Signing Process. Most of you J2ME developer knows that while we access any restricted or limited set of APIs (JSR 75, Network Access etc), MIDlet will prompt a security alert to get the user confirmation. To avoid these kind of security alerts MIDlet Signing comes into picture. You can sign your MIDlet using three approaches and listed as follows:-
  1. Vendor Specific Signing
  2. Operator Specific Signing
  3. Java Verified Signing
MIDlet Signing Process
First we’ll discuss about Java Verified Signing, It’s a third party MIDlet Signing which cost 200 USD per year for one publisher ID, under this publisher ID you can submit ‘n’ number of applications. For Java verified testing, you can choose lead device as well as sub devices too. If you choose lead device then your application will be also supported on sub devices, according to the Java Verified documentation. For each vendor(Nokia, Sony Ericsson, Samsung, etc) they have different set of lead devices. You can also choose sub devices for signing according to the application's requirements for specific API support on sub device. For third party signing, prompts will still appear but with additional options: “Always Allowed” or “Allow for this session”. According to user selection MIDlet will changes it’s behavior. The main point to be consider here is device should have UTI root certificate, if it’s not present in device then MIDlet installation will fail.

Operator Specific Signing - If MIDlet is accessing any of the operator specific services like GPRS etc, then user will receive a prompt. To avoid those prompt this signing is very useful & also operator can verify that the MIDlet is authorize to access it’s services. It is mostly used in US & Europe continent by some of the operators.

Vendor Specific Signing – It comes under manufacturer domain signing and this signing will help you to remove all prompts from the application. For this signing, you need to contact each of the vendor & after that they will test your app on predefined test scenarios for MIDlet signing.