×

Get the Blog Updates

Your information will not be shared with any 3rd parties under any circumstances.
Cancel
Image Image Image Image Image
Scroll to Top

To Top

Scroll to Top

To Top

Search Results for: label/android application Development

09

May
2014

No Comments

In Android

By Meera M.

How to monetize your Android application through In-App Billing?

On 09, May 2014 | No Comments | In Android | By Meera M.

In-App-Billing1What is In-app Billing ?

In-app products are the digital goods that you offer for sale from inside your Android application to your app users. You cannot use In-app Billing to sell personal services, physical goods, or anything that requires physical delivery.

Product types

The Version 3 API supports managed in-app products and subscriptions to give you flexibility in how you monetize your application. You can specify these types of products by using the Google Play Developer Console.

  • Managed in-app products:
    When a managed in-app item is purchased by an user, Google Play stores the purchase information for each item on a per-user basis.
  • Subscriptions :
    In In-app Billing, subscription plan offered you to sell content, services, or features to users from inside your app with recurring monthly or annual billing.

I will demonstrate a small example with In-app Billing,

To implement in app billing in your android project follow the below steps:

Step# 1: Installing the Google Play Billing Library
Before proceeding, verify you have installed the library by launching the Android SDK Manager by selecting the Eclipse Window -> Android SDK Manager option. Once loaded SDK Manager, scroll down to the Extras section and the Status column next to the Google Play Billing Library
Step# 2: Adding Billing Permission to the Manifest File
Add the following line in your AndroidManifest.xml file in order to make your app eligible to use in-App billing.

<uses-permission android:name=”com.android.vending.BILLING” />
Step# 3: Adding the Utility Classes to the Project
Find out the “TrivialDrive” sample project that was installed into the android SDK as part of the Google Play Billing library, includes a set of classes intended specifically for in-app billing implementation.

Locate the IInAppBillingService.aidl file in “TrivialDrive” sample project and add it to the package named “com.android.vending.billing”.

Then Select all nine Java files within “com.example.android.trivialdrivesample.util” package and copy and paste them into the <domainname>.inappbilling.util package of your InAppBilling project.

Step# 4: Designing the User Interface
Design your UI according to your need. This is a sample design developed to demonstrate the In-App Billing.

In-App-Billing-181x300

 

 

 

 

 

 

 

 

 

Step# 5: Obtaining the Public License Key for the App
Google Play billing must be identified by a unique public license key. The only way to get a public license key is to register an application within the Google Play.
Go to http://play.google.com/apps/publish Once you are logged in, In home page of the Google Play Developer Console, click the Add new application button, which specifying the default language and a title of InAppBilling. Once the above information has been entered, click the Upload APK button:
This APK file upload is not necessary at this point, so once the application has been registered, click on the Services & APIs option to display the Base64-encoded RSA public key for the application.

Step# 6: Creating a New In-app Product
Select the In-app Products menu item from the left hand panel of the developer console.To add a new product, click on Add new product button and, in the result panel, set the product type to Managed product and enter a Product ID (in this case com.andolasoft.testInApp). Click on Continue and in the second screen By entering a title, description and price for the item. Change on the menu at the top of the page to Activate.

Step# 7: Implementing “Purchase” Button click

public class MainActivity extends Activity {
 
    private static final String TAG = "<your domain>.inappbilling";
    IabHelper mHelper;
     
    private Button clickButton;
    private Button buyButton;
    private static final String TAG = "com.andolasoft.testInApp";
    IabHelper mHelper;
    static final String ITEM_SKU = "android.test.purchased";
.    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
 
        buyButton = (Button)findViewById(R.id.buyButton);
         
        String base64EncodedPublicKey =
                                       "<your license key here>";
         
            mHelper = new IabHelper(this, base64EncodedPublicKey);
         
            mHelper.startSetup(new
            IabHelper.OnIabSetupFinishedListener() {
                    public void onIabSetupFinished(IabResult result)
             {
                       if (!result.isSuccess()) {
                         Log.d(TAG, "In-app Billing setup failed: " +
                    result);
                       } else {             
                           Log.d(TAG, "In-app Billing is set up OK");
                              }
                      }
            });
    }
public void buyClick(View view) {
             mHelper.launchPurchaseFlow(this, ITEM_SKU, 10001,   
                    mPurchaseFinishedListener, "mypurchasetoken");
/*The developer payload token string. This can be any string value and is used to identify the purchase. For the purposes of this example, this is set to “mypurchasetoken”.*/
 
    }
@Override
protected void onActivityResult(int requestCode, int resultCode,
     Intent data)
{
      if (!mHelper.handleActivityResult(requestCode,
              resultCode, data)) {     
        super.onActivityResult(requestCode, resultCode, data);
      }
}
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener
    = new IabHelper.OnIabPurchaseFinishedListener() {
    public void onIabPurchaseFinished(IabResult result,
                    Purchase purchase)
    {
       if (result.isFailure()) {
          // Handle error
          return;
     }      
     else if (purchase.getSku().equals(ITEM_SKU)) {
         consumeItem();
        buyButton.setEnabled(false);
    }
           
   }
};
public void consumeItem() {
    mHelper.queryInventoryAsync(mReceivedInventoryListener);
}
     
IabHelper.QueryInventoryFinishedListener mReceivedInventoryListener
   = new IabHelper.QueryInventoryFinishedListener() {
       public void onQueryInventoryFinished(IabResult result,
          Inventory inventory) {
 
                       
          if (result.isFailure()) {
          // Handle failure
          } else {
                 mHelper.consumeAsync(inventory.getPurchase(ITEM_SKU),
            mConsumeFinishedListener);
          }
    }
};
IabHelper.OnConsumeFinishedListener mConsumeFinishedListener =
      new IabHelper.OnConsumeFinishedListener() {
       public void onConsumeFinished(Purchase purchase,
             IabResult result) {
 
     if (result.isSuccess()) {                
            //Here user paid for the app so write your logic to show the content to user
     } else {
             // handle error
     }
  }
};
 
@Override
public void onDestroy() {
    super.onDestroy();
    if (mHelper != null) mHelper.dispose();
    mHelper = null;
}
 
}

Step#8 : Upload the “APK”
Create the signed APK of your project and upload it in your added Application in Google Play Developer Console

Step# 9: Adding In-app Billing Test Accounts
Unfortunately, Google does not allow developers to make test purchases from their own Google accounts app billing, Other Google accounts used as testing accounts. . From ths ipoint on, in order to test in-app,  the users of these Google accounts must load your application onto their devices and make test purchases. To add a test user account, click Settings icon located on the left hand side of your Google Play Developer Console home screen and on the account details screen scroll down to the License Testing section. In the corresponding text box, give the Gmail accounts for the users who will be performing the in-app testing on your behalf before saving the changes.

Note: This email Id should be the primary account of an android device where this app is to be tested. Check with Google policy before publishing the app to the android market place.

Conclusion: I hope you find this post useful to sell your android in-app products and services, make transaction smoother and easier, and improve your revenue. If you are looking for any assistance regarding android application development or other android integration, then you can contact us.

See Also: How to monetize your iOS app through Apple In-App Purchase integration

Like this blog? I’d love to hear about your thoughts on this. Thanks for sharing your comments.

 

Tags | , ,

13

Feb
2013

No Comments

In Android

By Jay Dee

Android 4.2.2 brings minor updates for the Nexus users with improvements in Bluetooth audio issue

On 13, Feb 2013 | No Comments | In Android | By Jay Dee

androidimg

Android’s latest 4.2.2 update is already released and beginning to roll out for its Nexus devices. This update will late be availed to other Mobile devices too. Since its last update i.e. Android 4.2.1 during the late November, 4.2.2 appears to have minor fixes only.

Android 4.2.2 update has primarily resolved the issue of audio streaming over Bluetooth that used to skip during the operation. Reddit user WeeManFoo quoted “Bluetooth streaming works better (compared to 4.2.1) but it’s not perfect” and mentioned that for other notable fixes or features to 4.2.2, users might have to wait for an official changelog.

WeeManFoo also referred that his Galaxy Nexus still gets disconnected from Bluetooth speakers when switching from Wi-Fi to a 3G data connection. So, it appears that there is still some work to be done by the android developers.

Google has also modified the new ‘Quick Settings panel’ introduced in Android 4.2.2. The Wi-Fi and Bluetooth icons in the panel can now be turned OFF and ON by long-pressing the icons, instead of browsing to their respective settings panels.

Google has also introduced a notification sound for wireless charging and has changed the notification sound that indicates that the phone or tablet’s battery is running low.

None of these are major changes, but they sure bring the refinements that we expect from a minor update. Android 4.2.2 continues to roll out to Galaxy Nexus, Nexus 7, and Nexus 10 devices however Nexus 4 users will have to wait for now.

At Andolasoft we develop unique android mobile applications for individuals and from start-ups to established companies. We’ve an expertise team of android app developers who design the most innovative apps for all android devices.

Tags | ,

06

Feb
2013

No Comments

In Android

By Jay Dee

Android 4.2.2 is set for release this month!

On 06, Feb 2013 | No Comments | In Android | By Jay Dee

androidimg

Google is constantly working to roll out its Jelly Bean update in the form of Android 4.2.2 in the end of this month. It is likely to be a minor update that will fix the prevalent bugs and to enhance the performance speed of the Jelly Bean OS. It is also expected to patch the Bluetooth streaming issue in Nexus 7 devices.

Some reports suggested that, Google is already testing the 4.2.2 update on all Nexus devices like the Nexus 4, Nexus7 and Nexus 10. According to the website, Google claims to release it to the consumers by mid-February. These rumors have been there for quite some time since the last couple of months but reporters have already spotted some Google Nexus 4 devices in Malaysia and Brazil that were running Android 4.2.2.

Rumors have it, that Google will be releasing its next Android version 5.0 in-between April and June of this year. This update may also be called as ‘Key Lime Pie’. Google has announced that its next developer conference will take place during May 15 to May 17 of 2013, where they might introduce new android applications for version 5.0. Finally, as only 1.2 % of Android devices run 4.2 Jelly Bean versions, only a few users would be benefited from this update.

At Andolasoft we develop the most intriguing android applications for our customers. We have a pool of expertise android developers to provide innovative solutions for all versions of android operating software.

Tags | , ,

29

Nov
2011

No Comments

In Android

By Jay Dee

Various Resourceful Places to Find Amazing New Android Apps for Android Development

On 29, Nov 2011 | No Comments | In Android | By Jay Dee

androidNow-a- days iPhone apps stores are the king in the market. Android market is growing day by day. The online apps store has reached the 20,000 mark and it is doubled as compared to the last five months. End users and Android developers struggle to get appropriate applications to meet their needs. There are various websites which are providing wonderful android mobile apps. as listed below,

Android website: Here one can get the latest apps and games. It is the showcase for some of the featured and top ranked applications and games available. The site has various lists of featured and top apps with brief descriptions with screenshots each.

Androlib: This is an online marketing store of Android apps known to human being. Here one can search apps thorough categorized. You can also get frank user reviews, screenshots, and QR codes for download, and, video demonstrations of apps. The site also contains stats, forums and special sections for games and the top app of the day

Cyrket: Cyrket is the holy grail of Android-related sites. This is the advanced data analysis and extraction which helps users to find their needed apps to buy and to allow android developers to learn how their applications fit into the mobile application. QR codes, screenshots, descriptions and user comments for most apps are available here. User can search Apps or sort by popularity, rating, price and other factors.

AndroidZoom: AndroidZoom is an easy-to-use app directory. Here the app pages contain descriptions, screenshots, rating and QR codes, but user cannot give feedback, reviews or comments on a specific app. The site does, however, show similar or related apps from the same and other developers.

Android applications are more flexible smart phones operating system whose features have increased to satisfy the users and moving it in to a new level of opportunity. Many software development companies are spending their time in developing various applications in Android but Andolasoft inc. is one of the best Android application development company in the market.

We have developed many mobile applications as per the client and user requirements. We have a team of dedicated, skilled and creative Android application developers to develop apps like shopping list, to do list, multimedia gaming applications, Social networking application, business and web based apps for various customer requirements

 

Tags | ,

23

Jan
2012

No Comments

In Java

By Jay Dee

Various Components and Platforms For Mobile Application Development

On 23, Jan 2012 | No Comments | In Java | By Jay Dee

java1

In the era of latest technologies the mobile applications are becoming more n more popular being handy and easy-to-use with the help of latest gadgets.

People are not only taking full advantage of these gadgets but also getting profit in market through selling variety of mobile applications. These are safe, user-friendly and easily accessible regardless of geographical location. Prior to this technology the platforms like Symbian, Windows Mobile and Linux were used for mobile application development and the runtime environment like Mozilla Firefox, Opera Mini, RIM, virtual machines such as Java/J2ME, BREW, Flash were used to execute the applications. Now Android and Java are playing a vital role in creative mobile application development environment.

Android is a framework built specifically for mobile devices. It has a well-designed operating system through Linux by Google and Open Handset Alliance. Day-by-day it becomes the hottest, fast growing mobile platform in the world for mobile application development. Android is the exceptional platform that allows android developer to build unique, creative, sophisticate and multi tasking applications. In android smart phones the android applications can run simultaneously without affecting the performance.

Java is not only built for web pages or web application development but also it has huge contribution towards mobile application development. Using Java, html and css a java developer can build more powerful & faster mobile applications than the old generation applications written in C. Most smart phone mobile applications are built with J2ME components. J2ME mobile applications are more popular and widely used platform for wireless phones among the top manufacturing smart phone companies like BlackBerry, iPhone, Android.

Andolasoft is backed by a team having strong analytical skill & solid expertise in mobile application development in various platforms like Android and Java to satisfy your needs. You will get the right help & support from Andolasoft development team for any kind of mobile application development.

Tags | , , , ,

09

Jul
2010

No Comments

In Android
Ipad

By Jay Dee

The Future of iPhone/Android Applications Development

On 09, Jul 2010 | No Comments | In Android, Ipad | By Jay Dee

iphoneandandroid_image

Due to its advanced and hi-tech features like multi-touch screen and easy operating features, both iPhone and Android based mobile apps have instantly attracted the smart phone users. iPhone developers have built a vertical hierarchy of layers of menu instead of typical check boxes and switches.

At Andolasoft we use cut-through techniques to deliver transparent and trustworthy mobile apps. We have steadily made our ways through development of stand-alone applications such as palmtop and have steadily made progress in windows based smart phones and PDAs like iPhone as well as Android based mobile apps development. Our developers are also specialized in cross-platform development in mobile apps. Our developers have their expertise in developing mobile apps on various platforms including iPhone, Android, Blackberry among others.

Utilizing the iPhone/Android application development, our experts have recently developed an interesting application through which you can give update about any upcoming events of your company. You can post your blogs, let your company delegates know of any recent projects undertaken- there are so many things you can do with our application. With this applications integrated with iPhone, you can showcase your successfully completed projects and keep your clients updated. What’s more, you can integrate this application with Google maps to utilize it as a roadmap for getting the location update.

Tags | , ,

04

Feb
2013

No Comments

In CakePHP

By Jay Dee

CakePHP framework for faster development of next generation web application

On 04, Feb 2013 | No Comments | In CakePHP | By Jay Dee

cakePHP

There are numerous PHP frameworks available such as Zend, CodeIgniter, Akelos etc. CakePHP on the other hand is the most popular framework among them and reduces significant coding time and investment.  CakePHP is an open source web application development tool. It helps to build the web pages and applications faster and simpler.

Some features of CakePHP framework

  • Compatible with almost all PHP versions
  • Facilitates code scaffolding for faster development of prototypes
  • Doesn’t require any complex configuration
  • CakePHP is safe and secure:  It provides in-built tools for input validation, XSS prevention, SQL prevention for secure application development.
  • It provides built-in view helpers for AJAX, JavaScript, HTML etc.
  • CakePHP offers faster and flexible templating features as well as data validation features

These features make installation and use of CakePHP easy which in turn makes PHP more manageable. As it is an open source, it can be customized according to the needs of specific business requirements. It provides the CakePHP developers with MVC framework, Class inheritance, re-usability, Ajax support and many more to make the development process easier and effortless.  It assists the PHP developers at all levels and provide the ability to manage every part of project development.

Our CakePHP development team is highly experienced to deliver robust, logical, most reliable and effective solutions to our global clients. Our expertise in CakePHP development helps us for building cost effective apps that too matching customer budget with quick turn-around time.

Tags | ,

18

Jan
2012

No Comments

In Java

By Jay Dee

Advance Java and J2EE Helps Java Developer to Built Enterprise Java Application Development

On 18, Jan 2012 | No Comments | In Java | By Jay Dee

java1

Basically Java is an object oriented programming language. It was invented for the purpose of increasing the productivity of both developers and End Users. Java enterprise application development is not an easy task for a java developer being high risky. Before java, Professional developers were doing their jobs faster through COBOL, Pascal, C, or C++ in a complicated process and the end user can also build new creative mini applications using various. Now software marketer and enterprise application developers have rush to create creative new generation applications using java with less risk and more user friendly. The fourth-generation programming languages have gone to the back seat and the new generation developers giving more productivity to the market through advance java and J2EE.

Java came in the year 1990 with more portable option with C++ to develop embedded systems by Sun Microsystems. Sun Microsystems has offered java as a programming and development platform. It became an awesome choice for developer and software venders to develop high quality applications and software. Development of business and enterprise application development was bit complex at that time but after arrival of advanced java and J2ee it helped a lot. J2EE is the Java 2 Platform; Enterprise Edition helps in developing multitier enterprise applications. Before J2EE, the Java developers were also facing some problems during the application development because of the following reasons:

1. More use of modules in the projects. We are in the favor of modularity which helps java developers to work separately but when you have few line codes inserting many buckets the developer may face problem.

2. Developer can invent new programming language but Implementation can be done under the underlying platforms with traditional service provider.

3. The steady stream of new UI approaches reflects in the presentation layer due to Java’s lack of leadership.

4. The deficiencies of Java disclose in hibernate, spring, Struts, and other frameworks.

The advanced J2EE model provides modified and simplified approach to develop high quality java application development. The complexity of enterprise applications are managed through its components and application developers are free to stick on their logic. J2EE summarizes the layers of functionality in specific types of components. This helps in faster development in time, better quality, maintainability and portability of applications. It hides the complexity and create flexible user Interaction.

At Andolasoft the Java Developers are dedicated to provide quality Java and J2EE application developments that are robust and performance oriented. We follow Agile Methodology and this iterative process allows us to deliver enterprise applications quickly. Our team of skilled Java and J2EE Developers are highly experienced and ready to take on any technical challenges.

 

Tags | ,

13

May
2015

No Comments

In Android

By Omkar

Will ‘Fragment’ rule over ‘Activity’ the Android World in the Future?

On 13, May 2015 | No Comments | In Android | By Omkar

Banner_Androi1

Why to Use Fragment? What Is It All About!

A Fragment is an application’s user interface that can be placed in an activity which will enable more modular activity design for an application.You would be able to add multiple fragments in a single activity to create a multi-pane user interface and can reuse a fragment in many activities.

Fragment is a modular section/standard of an activity, which has its own life-cycle, model. It receives its own input events which you can add or remove while the activity is running (like a ‘sub activity’ that you can reuse in different activities).Fragments were added to the Android API in Honeycomb version which is API version 11.

Now, lets find out the benefits, steps to implememt fragment as explained in the infographics.

Android_Infographics_Fragment_0512_v6

Wrapping Up

Fragments are truly a masterpiece, secret Ingredient to Android App Designing.
We hope this article helps you to understand the concept of using fragment in Android Apps. We will be glad to receive any positive comments or view. Please Visit Andolasoft’s Android Service for more information and details. You can also write to us at info@andolasoft.com

To display the infographic in your site, use the below code

Tags | ,

04

Jul
2013

No Comments

In Android

By Meera M.

How to use ‘Contextual Action’ bar in ‘ListView’ page

On 04, Jul 2013 | No Comments | In Android | By Meera M.

Android_list_item

Introduction:

‘Android.View.ActionMode’ is an Android API that is used to set up contextual actionbar with the help of xml. When an app enables this action mode by selecting an item, a contextual action bar is displayed at the header of the page. Here, users are enabled to perform on the currently chosen item.

The contextual action bar disappears when the user selects other action icon (in this case ‘delete’ icon), or selects the ‘Done’ action on the left side of the action bar.

Note: The contextual action bar works independently and overtakes the action bar position.

Steps to create a contextual action bar with the delete action:

1. In the main activity, implement the ‘ActionMode.Callback’ interface and override all implemented methods as per application requirements:

  • public boolean onActionItemClicked(ActionMode mode, MenuItem item)
  • public boolean onCreateActionMode(ActionMode mode, Menu menu)
  • public void onDestroyActionMode(ActionMode arg0)
  • public boolean onPrepareActionMode(ActionMode arg0, Menu arg1)

2. For selecting list item, implement the ‘setOnItemLongClickListener’ method on ‘ListView ‘object and call ‘this.startActionMode()’ to start ‘actionmode’ by passing ‘ActionMode.Callback’ object.

Example of Main-Activity:

package com.example.contextualactionbardemo;

import java.util.ArrayList;

import android.os.Bundle;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.DialogInterface;
import android.util.Log;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.AdapterView.OnItemLongClickListener;

public class MainActivity extends ListActivity {
protected Object mActionMode;
private static int selectedItem = -1;
private ArrayList list;
private String listItem = "";
private ArrayAdapter adapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ListView listView = (ListView) findViewById(R.id.listview);
String[] values = new String[] { "Android List Item One",
"Android List Item Two",
"Android List Item Three",
"Android List Item Four",
"Android List Item Five",
"Android List Item Six",
"Android List Item Seven",
"Android List Item Eight"
};

list = new ArrayList();
for (int i = 0; i < values.length; ++i) {
list.add(values[i]);
}
adapter = new ArrayAdapter(this,
android.R.layout.simple_list_item_1, android.R.id.text1, list);
setListAdapter(adapter);

listView = getListView();
listView.setOnItemLongClickListener(new OnItemLongClickListener() {

public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
int pos, long id) {
Log.v("long clicked","pos"+" "+pos);
if (mActionMode != null) {
return false;
}
selectedItem = -1;
selectedItem = pos;
listItem = list.get(selectedItem);
mActionMode = MainActivity.this.startActionMode(mActionModeCallback);
arg1.setSelected(true);
return true;
}
});

}

private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.action_delete:
AlertDialog.Builder alertDialog = new AlertDialog.Builder(MainActivity.this);
// Setting Dialog Title
alertDialog.setTitle("Confirm Delete...");
// Setting Dialog Message
alertDialog.setMessage("Are you sure you want to delete?");
alertDialog.setPositiveButton("YES", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int which) {
adapter.remove(listItem);
adapter.notifyDataSetChanged();
}
});
// Setting Negative "NO" Button
alertDialog.setNegativeButton("NO", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
// Showing Alert Message
alertDialog.show();
mode.finish();
return true;
default:
return false;
}
}

@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.setTitle(listItem);
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.deletemenu, menu);
return true;
}

@Override
public void onDestroyActionMode(ActionMode arg0) {
// TODO Auto-generated method stub
mActionMode = null;
selectedItem = -1;
}

@Override
public boolean onPrepareActionMode(ActionMode arg0, Menu arg1) {
// TODO Auto-generated method stub
return false;
}
};
}

Example of /res/menu/deletemenu.xml:

Conclusion:

Contextual action mode is useful in following cases:

  • To show customize menu display with icon of edit, rename, delete
  • To display dynamic customize menu over the action bar

Have something to add to this topic? Share it in the comments.

Tags |

27

Jun
2013

No Comments

In Android

By Meera M.

How to show Captured Images dynamically in “GridView” Layout

On 27, Jun 2013 | No Comments | In Android | By Meera M.

gridview_sample-253x300

There are numerous camera apps in the market which displays shopping items (i.e. image view). In these camera apps we need to arrange each photo items in a list view, basically a ‘GridView’. In such cases, ‘table layout’ would be easier to use; but it is difficult to arrange large number of items in side scroll view. As ‘table view’ is just a layout manager, it doesn’t allow direct interaction with each item to the users.

In order to tackle such development issues, it would be smart to implement ‘GridView’ Layout.

What is “GridView” Layout?

GridView (android.widget.GridView) is a layout that is implemented to show two-dimensional view with scrollable structure. With the help of ‘List’ adapter, we can add images dynamically to a ‘GridView’ layout by customizing the number of columns.

Example of Layout xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >

<RelativeLayout
android:id="@+id/RelativeGridLayout"
android:layout_width="wrap_content"
android:layout_height="fill_parent" >

<GridView
android:id="@+id/gridviewimg"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:gravity="center"
android:numColumns="2"
android:scrollbarStyle="outsideInset"
android:smoothScrollbar="true"
android:verticalSpacing="10dp"
android:paddingBottom="50dp"
android:paddingTop="10dp"
/>
</RelativeLayout>

<RelativeLayout
android:id="@+id/RelativeLayout01"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:layout_alignBottom="@+id/RelativeGridLayout"
>

<Button
android:id="@+id/capture_btn1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:text="Camera" />
</RelativeLayout>

</RelativeLayout>

Example of Main form Activity class

1.MainActivity.java

package com.example.gridviewimagesdemo;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener {

Button captureBtn = null;
final int CAMERA_CAPTURE = 1;
private Uri picUri;
private DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private GridView grid;
private  List<String> listOfImagesPath;

public static final String GridViewDemo_ImagePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/GridViewDemo/";

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

captureBtn = (Button)findViewById(R.id.capture_btn1);
captureBtn.setOnClickListener(this);
grid = ( GridView) findViewById(R.id.gridviewimg);

listOfImagesPath = null;
listOfImagesPath = RetriveCapturedImagePath();
if(listOfImagesPath!=null){
grid.setAdapter(new ImageListAdapter(this,listOfImagesPath));
}
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
if (arg0.getId() == R.id.capture_btn1) {

try {
//use standard intent to capture an image
Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//we will handle the returned data in onActivityResult
startActivityForResult(captureIntent, CAMERA_CAPTURE);
} catch(ActivityNotFoundException anfe){
//display an error message
String errorMessage = "Whoops - your device doesn't support capturing images!";
Toast toast = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT);
toast.show();
}
}

}

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
//user is returning from capturing an image using the camera
if(requestCode == CAMERA_CAPTURE){
Bundle extras = data.getExtras();
Bitmap thePic = extras.getParcelable("data");
String imgcurTime = dateFormat.format(new Date());
File imageDirectory = new File(GridViewDemo_ImagePath);
imageDirectory.mkdirs();
String _path = GridViewDemo_ImagePath + imgcurTime+".jpg";
try {
FileOutputStream out = new FileOutputStream(_path);
thePic.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.close();
} catch (FileNotFoundException e) {
e.getMessage();
} catch (IOException e) {
e.printStackTrace();
}
listOfImagesPath = null;
listOfImagesPath = RetriveCapturedImagePath();
if(listOfImagesPath!=null){
grid.setAdapter(new ImageListAdapter(this,listOfImagesPath));
}
}
}
}

private List<String> RetriveCapturedImagePath() {
List<String> tFileList = new ArrayList<String>();
File f = new File(GridViewDemo_ImagePath);
if (f.exists()) {
File[] files=f.listFiles();
Arrays.sort(files);

for(int i=0; i<files.length; i++){
File file = files[i];
if(file.isDirectory())
continue;
tFileList.add(file.getPath());
}
}
return tFileList;
}

public class ImageListAdapter extends BaseAdapter
{
private Context context;
private List<String> imgPic;
public ImageListAdapter(Context c, List<String> thePic)
{
context = c;
imgPic = thePic;
}
public int getCount() {
if(imgPic != null)
return imgPic.size();
else
return 0;
}

//---returns the ID of an item---
public Object getItem(int position) {
return position;
}

public long getItemId(int position) {
return position;
}

//---returns an ImageView view---
public View getView(int position, View convertView, ViewGroup parent)
{
ImageView imageView;
BitmapFactory.Options bfOptions=new BitmapFactory.Options();
bfOptions.inDither=false;                     //Disable Dithering mode
bfOptions.inPurgeable=true;                   //Tell to gc that whether it needs free memory, the Bitmap can be cleared
bfOptions.inInputShareable=true;              //Which kind of reference will be used to recover the Bitmap data after being clear, when it will be used in the future
bfOptions.inTempStorage=new byte[32 * 1024];
if (convertView == null) {
imageView = new ImageView(context);
imageView.setLayoutParams(new GridView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
imageView.setPadding(0, 0, 0, 0);
} else {
imageView = (ImageView) convertView;
}
FileInputStream fs = null;
Bitmap bm;
try {
fs = new FileInputStream(new File(imgPic.get(position).toString()));

if(fs!=null) {
bm=BitmapFactory.decodeFileDescriptor(fs.getFD(), null, bfOptions);
imageView.setImageBitmap(bm);
imageView.setId(position);
imageView.setLayoutParams(new GridView.LayoutParams(200, 160));
}
} catch (IOException e) {
e.printStackTrace();
} finally{
if(fs!=null) {
try {
fs.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return imageView;
}
}
}

Example of Manifest.xml file content:

Example of AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.gridviewimagesdemo"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.gridviewimagesdemo.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>

Conclusion:

So, a ‘Grid view’ implementation would result in following features and benefits:

  • In ‘GridView’ layout items would be listed in a static grid, defined in layout xml file.
  • ‘Gridview’ extends android.widget.Adapter, so it could be used where large amount of data is managed in a single page frame.
  • Enhanced data source binding capabilities (Direct interaction with SQLite Data Source)
  • Built-in support for sorting and paging mechanism
  • Additional Column types (ImageField)

Recommended Reading: Display Images in GridView on iPhone

I hope you find this useful. If you want to develop android or mobile application  for you or for your organization, then you can hire single or group of developers from the pool of skilled and accomplished android specialists. Drop me a line below with your thoughts, thanks.

Tags |

19

Apr
2013

No Comments

In Android

By Jay Dee

Example of Webview Layouts and How to use in Android

On 19, Apr 2013 | No Comments | In Android | By Jay Dee

clip_image002-176x300

What is WebView class?

The WebView class is a subclass of “android.view” class that facilitates to fetch external URL running in web server and display it in device’s screen. It is specifically useful for displaying dynamic contents from the web server application. However, it will show only the contents, not the features of a fully html based web browser functionality.

In the WebView app, we implemented following steps to display the web content on device and also enabling the app to upload file to the web page contents:

  1. Verify the availability of device’s network connection
  2. Add progress bar logic for on click event of hyper-link in web page
  3. Add ability to upload file from local file storage on device through webview.

The only Requirement is…

External website URL should have UI contents compatible with the android device’s screen resolution.

Example of xml for activity

android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>

android:id="@+id/webview1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>

Example of Main Activity class

1.MainClass.java
=======================
package com.webviewdemo;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.net.http.SslError;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.Window;
import android.webkit.SslErrorHandler;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;
import android.widget.Toast;
public class MainClass extends Activity {

WebView webview;
ProgressDialog  progressBar;
ProgressBar progressBar1;
MainClass _activity;
AlertDialog alertDialog;
boolean loadingFinished = true;
boolean redirect = false;
private ValueCallback mUploadMessage;
private final static int FILECHOOSER_RESULTCODE = 1;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
progressBar = null;
this.getWindow().requestFeature(Window.FEATURE_PROGRESS);
_activity = this;
setContentView(R.layout.main );
webview = (WebView) findViewById( R.id.webview1 );
WebSettings settings = webview.getSettings();
settings.setJavaScriptEnabled(true);
settings.setSupportZoom(true);
settings.setBuiltInZoomControls(true);
settings.setCacheMode(WebSettings.LOAD_NO_CACHE);
webview.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
webview.setWebChromeClient(new WebChromeClient()
{
//The undocumented magic method override
//Eclipse will swear at you if you try to put @Override here
public void openFileChooser(ValueCallback uploadMsg) {
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
MainClass.this.startActivityForResult(Intent.createChooser(i,"File Chooser"), FILECHOOSER_RESULTCODE);
}
});
if(checkInternetConnection(_activity)==true){
if(savedInstanceState==null)
webview.loadUrl("http://www.andolasoft.com/");
else
webview.loadUrl("http://www.andolasoft.com/");
alertDialog = new AlertDialog.Builder(this).create();
progressBar = ProgressDialog.show(MainClass.this, "Please wait...", "Loading...");
webview.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String urlNewString) {
if (!loadingFinished) {
redirect = true;
}
loadingFinished = false;
webview.loadUrl(urlNewString);
return true;
}
public void onReceivedSslError (WebView view, SslErrorHandler handler, SslError error) {
handler.proceed() ;
}
@Override
public void onPageFinished(WebView view, String url) {
if(!redirect){
loadingFinished = true;
}
if(loadingFinished && !redirect){
//HIDE LOADING IT HAS FINISHED
if (progressBar != null && progressBar.isShowing()) {
progressBar.hide();
}
} else{
redirect = false;
}
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
loadingFinished = false;
progressBar.show();
}});
}
else{
AlertDialog.Builder builder = new AlertDialog.Builder(_activity);
builder.setMessage("Please check your network connection.")
.setCancelable(false)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
}
});

AlertDialog alert = builder.create();
alert.show();
}
}

public static boolean checkInternetConnection(Activity _activity) {
ConnectivityManager conMgr = (ConnectivityManager) _activity.getSystemService(Context.CONNECTIVITY_SERVICE);
if (conMgr.getActiveNetworkInfo() != null
&& conMgr.getActiveNetworkInfo().isAvailable()
&& conMgr.getActiveNetworkInfo().isConnected())
return true;
else
return false;
}
@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {
if (requestCode == FILECHOOSER_RESULTCODE) {
if (null == mUploadMessage)
return;
Uri result = intent == null || resultCode != RESULT_OK ? null
: intent.getData();
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;

}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK){
if(webview.canGoBack()){
webview.goBack();
return true;
}
}
return super.onKeyDown(keyCode, event);
}
}

Example of User’s permission mentioned in androidmanifest.xml


WebView is really helpful in creating quick Mobile UI without using complex Views/Layouts of Android. A HTML developer can easily build a web page with dynamic contents using CSS/HTML tags. Generally, we can run everything on WebView i.e., in android browser we can run jQuery, Flash enabled app while replicating the web based platform to mobile based smaller screen.

Benefits:

WebView are useful in following cases:

  • Since the web contents are dynamically updated at server side, the android app will display the updated contents just by fetching from site through WebView.
  • Web apps can be easily integrated to native application through WebView controls.

Tags |

01

Apr
2013

No Comments

In Android

By Jay Dee

Expected devices with Android 4.2 upgrades

On 01, Apr 2013 | No Comments | In Android | By Jay Dee

android_jelly_been_123

Google’s Android 4.2 was released last October, which introduced numerous new features and enhancement for Jelly Bean OS platform. It included lock screen widgets and photo Sphere as well as new quick settings panel and screensaver function. For tablets, the upgrade included phone like user-interfaces and multi-user support

It has been nearly a year since the release of Samsung Galaxy Tab and apparently Samsung is planning to release an update to Android 4.1.2 first and then the final OTA Update with Android 4.2.2 Jelly Bean OS for the tablet. This will be the last official update from Samsung and hence further the users will have to rely on the Android development community for custom ROMs based on Android 5.0. The news first surfaced at ‘SamMobile’ and it seems like Samsung has fixed issues with Android 4.2.2 and Exynos CPU. Samsung will probably abandon updates for its former flagship tablet after the release of Jelly Bean 4.2.2 firmware update. These update i.e. Android 4.2.1 and 4.2.2 is expected to be available till September 2013. It is also rumored that Samsung devices with dual-core CPU will also receive Jelly Bean 4.2.2 updates.

There were other Galaxy Tab devices that are tested on Jelly Bean ROMs and its official release is expected by April 2013. The Jelly Bean OS is now tested on Galaxy Tab 10.1 GT 7500, Galaxy Tab GT 7300, Galaxy Tab 7.7 P6800 and the Galaxy Tab Plus P6200. These updates are yet to happen until Samsung decides to officially announce the release dates of OTA updates for Jelly Bean 4.2.2.

For Google’s nexus devices the upgrades are often early and directly from Google. Even carrier connected devices like the Verizon Galaxy Nexus are finally catching up, which generally experienced delays in update because of carrier interference. Asus gave Android 4.2 update to its Transformer Pad TF300 at the beginning of March and has said to release updates for Transformer Pad Infinity, MeMO Pad Smart and MeMO Pad, later this year. Sony has confirmed that it would release Android 4.2 upgrades for Xperia Z and Xperia Tablet Z devices. Motorola has also promised it would upgrade their Android OS for Motorola’s International Razr D1 and D3, but haven’t provided any definite timeline for the process.

Mobile device manufacturers are now willing to focus their Android Application Development efforts on Android 4.1 upgrade before heading to 4.2, because 4.2 is relatively a minor step from 4.1. Some companies are even considering to skip directly to the next major Android release i.e. Android Key Lime Pie, which is expected to be announced at Google’s I/O conference in May .

Tags | ,

11

Apr
2013

No Comments

In Android

By Jay Dee

How to Use Fragment Layouts in Android

On 11, Apr 2013 | No Comments | In Android | By Jay Dee

android-293x300-123

Fragment is a concept of UI components-with a new idea for the ability to retain state across configuration changes. As a result, web-pages load comparatively faster because it retains their previous state. Without Fragments components, the normal activity class causes running activities to be stopped, reloaded and re-rendered using the new parameters. A fragment allows building a UI as a series of smaller, reusable graphical elements that can be arranged as needed, based on the device’s capabilities.

Fragment layout in Android is pretty distinct from other platforms. This design was first introduced for the platform in version 3.0 and onwards.

Here are the main concepts about Android fragment layout:

  • Android tabs are most often presented as text compared to icons, because it is difficult to come up with descriptive icons for all the possible navigation option. Text is much better.
  • Android tabs aren’t square buttons.  They mostly contain text
  • Visual style of Android tabs is flat. There should not be any glossy or reflection effects like in html web design.

A Fragment framework works much like an activity.
To implement it in the app we need an independent Java activity class along with a fragment xml layout:

  1. Create a layout XML and an Activity subclass for your activity
  2. Create a layout XML and a Fragment subclass for your fragment
  3. Map the two together in your Activity layout XML (or using FragmentTransaction mostly in Java code)

Example of layout xml for activity

<?xml version="1.0" encoding="utf-8"?>
<TabHost
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent">

<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">

<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0"/>

<FrameLayout
android:id="@+android:id/realtabcontent"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"/>

<TabWidget
android:id="@android:id/tabs"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="55dip"
android:layout_weight="0"/>

</LinearLayout>
</TabHost>

Example of Activity subclass

package com.myproj;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Stack;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TabHost;
import android.widget.TextView;

public class AppMainTabActivity extends FragmentActivity {
/* Your Tab host */
private TabHost mTabHost;

/* A HashMap of stacks, where we use tab identifier as keys..*/
private HashMap<String, Stack<Fragment>> mStacks;

/*Save current tabs identifier in this..*/
private String mCurrentTab;

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_layout);
/*
*  Navigation stacks for each tab gets created..
*  tab identifier is used as key to get respective stack for each tab
*/
mStacks = new HashMap<String, Stack<Fragment>>();
mStacks.put(AppConstants.TAB_A, new Stack<Fragment>());
mStacks.put(AppConstants.TAB_B, new Stack<Fragment>());
mStacks.put(AppConstants.TAB_C, new Stack<Fragment>());
mStacks.put(AppConstants.TAB_D, new Stack<Fragment>());
mTabHost = (TabHost)findViewById(android.R.id.tabhost);
mTabHost.setOnTabChangedListener(listener);
mTabHost.setup();
initializeTabs();
}

private View createTabView(final int id,String s) {
View view = LayoutInflater.from(this).inflate(R.layout.tabs_icon, null);
ImageView imageView =   (ImageView) view.findViewById(R.id.icon);
imageView.setImageDrawable(getResources().getDrawable(id));
TextView textview= (TextView) view.findViewById(R.id.title);
textview.setText(s);
return view;
}

public void initializeTabs(){
/* Setup your tab icons and content views.. Nothing special in this..*/
TabHost.TabSpec spec    =   mTabHost.newTabSpec(AppConstants.TAB_A);
mTabHost.setCurrentTab(-3);
spec.setContent(new TabHost.TabContentFactory() {
public View createTabContent(String tag) {
return findViewById(R.id.realtabcontent);
}
});
spec.setIndicator(createTabView(R.drawable.cameratab, "Camera"));
mTabHost.addTab(spec);

spec = mTabHost.newTabSpec(AppConstants.TAB_B);
spec.setContent(new TabHost.TabContentFactory() {
public View createTabContent(String tag) {
return findViewById(R.id.realtabcontent);
}
});
spec.setIndicator(createTabView(R.drawable.presettab, "Presets"));
mTabHost.addTab(spec);

//Create a class AppConstants to declare your variables

spec = mTabHost.newTabSpec(AppConstants.TAB_C);
spec.setContent(new TabHost.TabContentFactory() {
public View createTabContent(String tag) {
return findViewById(R.id.realtabcontent);
}
});
spec.setIndicator(createTabView(R.drawable.manualtab, "Manual Entry"));

mTabHost.addTab(spec);

spec = mTabHost.newTabSpec(AppConstants.TAB_D);
spec.setContent(new TabHost.TabContentFactory() {
public View createTabContent(String tag) {
return findViewById(R.id.realtabcontent);
}
});
spec.setIndicator(createTabView(R.drawable.infotab, "Info"));
mTabHost.addTab(spec);
}

/*Comes here when user switch tab, or we do programmatically*/
TabHost.OnTabChangeListener listener    =   new
TabHost.OnTabChangeListener() {
public void onTabChanged(String tabId) {
/*Set current tab..*/
mCurrentTab                     =   tabId;

if(mStacks.get(tabId).size() == 0){
/*
*    First time this tab is selected. So add first fragment of that tab.
*    Dont need animation, so that argument is false.
*    We are adding a new fragment which is not present in stack. So add to stack is true.
*/
if(tabId.equals(AppConstants.TAB_A)){
pushFragments(tabId, new Camera(), false,true);
}else if(tabId.equals(AppConstants.TAB_B)){
pushFragments(tabId, new PresetsActivity(), false,true);
}else if(tabId.equals(AppConstants.TAB_C)){
pushFragments(tabId, new ManualActivity(), false,true);
}else if(tabId.equals(AppConstants.TAB_D)){
pushFragments(tabId, new InfoActivity(), false,true);
}
}else {
/*
*    We are switching tabs, and target tab is already has atleast one fragment.
*    No need of animation, no need of stack pushing. Just show the target fragment
*/
pushFragments(tabId, mStacks.get(tabId).lastElement(), false,false);
}
}
};

/* Might be useful if we want to switch tab programmatically, from
inside any of the fragment.*/
public void setCurrentTab(int val){
mTabHost.setCurrentTab(val);
}

/*
*      To add fragment to a tab.
*  tag             ->  Tab identifier
*  fragment        ->  Fragment to show, in tab identified by tag
*  shouldAnimate   ->  should animate transaction. false when we switch tabs, or adding first fragment to a tab
*                      true when when we are pushing more fragment into navigation stack.
*  shouldAdd       ->  Should add to fragment navigation stack (mStacks.get(tag)). false when we are switching tabs (except for the first time)
*                      true in all other cases.
*/
public void pushFragments(String tag, Fragment fragment,boolean shouldAnimate, boolean shouldAdd){
if(shouldAdd)
mStacks.get(tag).push(fragment);
FragmentManager   manager         =   getSupportFragmentManager();
FragmentTransaction ft            =   manager.beginTransaction();
if(shouldAnimate)
ft.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left);
ft.replace(R.id.realtabcontent, fragment);
ft.commit();
}

public void popFragments(){
/*
*    Select the second last fragment in current tab's stack..
*    which will be shown after the fragment transaction given below
*/
Fragment fragment             =   mStacks.get(mCurrentTab).elementAt(mStacks.get(mCurrentTab).size() - 2);

/*pop current fragment from stack.. */
mStacks.get(mCurrentTab).pop();

/* We have the target fragment in hand.. Just show it.. Show a standard navigation animation*/
FragmentManager   manager         =   getSupportFragmentManager();
FragmentTransaction ft            =   manager.beginTransaction();
ft.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right);
ft.replace(R.id.realtabcontent, fragment);
ft.commit();
}

@SuppressLint("NewApi")
@Override
public void onBackPressed() {
if(((BaseFragment)mStacks.get(mCurrentTab).lastElement()).onBackPressed() == false){
/*
* top fragment in current tab doesn't handles back press, we can do our thing, which is
*
* if current tab has only one fragment in stack, ie first fragment is showing for this tab.
*        finish the activity
* else
*        pop to previous fragment in stack for the same tab
*
*/
if(mStacks.get(mCurrentTab).size() == 1){
super.onBackPressed();  // or call finish..
}else{
popFragments();
}
}else{
//do nothing.. fragment already handled back button press.
}
}

/*
*   Imagine if you wanted to get an image selected using ImagePicker intent to the fragment. Ofcourse I could have created a public function
*  in that fragment, and called it from the activity. But couldn't resist myself.
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

mStacks.get(mCurrentTab).lastElement().onActivityResult(requestCode, resultCode, data);
}
}

Example of Fragment subclass

package com.myproj;

import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;

public class BaseFragment extends Fragment {
public AppMainTabActivity mActivity;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

mActivity    = (AppMainTabActivity) this.getActivity();
}

public boolean onBackPressed(){
return false;
}
public void onActivityResult(int requestCode, int resultCode, Intent data){

}
}

Fragment layout in Android is pretty distinct from other platforms. This design was first introduced for the platform in version 3.0 and onwards.

Here are the main concepts about Android fragment layout:

  1. Android tabs are most often presented as text compared to icons. Because, it is difficult to come up with descriptive icons for all the possible navigation option. Text is much better.
  2. Android tabs aren’t square buttons.  They mostly contain text
  3. Visual style of Android tabs is flat. There should not be any glossy or reflection effects like in html web design.

A fragment must always be embedded in an activity and the fragment’s lifecycle is directly affected by the parent activity’s lifecycle. When we add a fragment as a part of an activity layout, it lives in ViewGroup inside the activity’s view hierarchy and the fragment defines its own view layout. We can insert a fragment into the activity layout by declaring the fragment in the activity’s layout file, as a <fragment> element, or from the application code by adding it to an existing ViewGroup.
To animate the transition between fragments or to animate the process of showing or hiding a fragment the Fragment Manager API can be used and create a Fragment Transaction.
Within each Fragment Transaction we can specify in and out animations that will be used for show and hide respectively (or both when replace is used).

Benefits:

Fragments are useful in following cases:

  • If we split up views on some devices/orientations and show them in two activities and show all the content in one on other devices. That would be a use case if you go on a tablet or maybe even in landscape mode on a phone: e.g. you show the list of items and the details on one screen. On a phone or in portrait mode you just show one part.
  • Another use case is reusable views. So if we have some views that are visible on different activities and also perform some actions we could put this behavior into a fragment and then reuse it.
  • Animated effects can availed when dynamically adding and removing fragments from the screen
  • Integration with the action bar for tabs, as a replacement for TabHost
  • Integration with the action bar for “list”-based navigation (really a Spinner in the action bar, toggling between different fragments)
See Also: Webview Layouts usages in Android

If you have thoughts about or experiences with Android fragments, share them with us. We’d love to hear from you.

Tags | ,

08

Jan
2013

No Comments

In Android

By Jay Dee

Android’s Fragmentation – Still A Problem For Android Developers

On 08, Jan 2013 | No Comments | In Android | By Jay Dee

android1Google’s Android possess a major flaw in its OS development, that is fragmentation issue. For this reason one android OS version still remains isolated from other android OS version. It offers a wide range of hardware and software options for the developers, which in turn increases time of development and causes complication for application design. From a latest survey of devices in the last two weeks, Google found that only 10% of android owners are running the latest version of the OS, and almost half (47%) are still using “Gingerbread” i.e. the version 2.33.

Android Developers have been challenged by Android’s open nature from the beginning. In addition, the release of OS updates to all the available hardware is dependent on a wide range of sources. For such reasons, Android developers have now targeted their Android application development for devices that run the Gingerbread platform and later, which is now on over 80% of Android devices.

Mobile Developers have faced even the worse fragmentation issues during the early days of development. With numerous hardware variants, developing app for a group of devices was almost impossible. With Android the fragmentation issue is more troublesome because of the advanced features which only a fraction of devices support it. This situation continuously drives the developers to focus on hardware specific abilities of the smartphones.

At Andolasoft we develop the most intriguing android mobile applications for individuals and from start-ups to established companies. We have team of experienced android developers who are skilled to develop innovative apps for all versions of android devices. Some of our apps showcased in the Google marketplace at:

https://play.google.com/store

/apps/details?id=com.andolasoft.christmasdemo&

feature=more_from_developer

Tags | ,

06

May
2013

No Comments

In Android

By Jay Dee

How to Import csv configuration file to device’s SQLite db

On 06, May 2013 | No Comments | In Android | By Jay Dee

SQLite_csv_1323

Like web applications, some android apps need to be initialized with certain configuration value for testing and deploying the app with different environment:

  • We used different web services API to access data on server, so we need to use same android APK to access data in dev server as well as stager server.
  • We need to control the camera configuration integrated in android APK
  • Similarly, we need different configuration settings to set dynamically in APK without changing the source code at run-time.

Considering the above scenario, the best thing is to use CSV files, such as the properties files used in Java and .NET platform. In Android, we put CSV file in the device’s phone storage (in this example, the file path is “/storage/sdcard0/Android/data/com.example/”). We have to write codes to read the CSV file and then spilt the data programmatically using separator. Then it has to be inserted in to a SQLite table (in this example uses ‘appconfigtbl‘).
The sample program in this blog will perform the below mentioned steps to achieve the above mentioned initialization of configuration value inside android app:

  • Check if the CSV file exists in the device with proper file path location defined in the APK
  • Use the asynchronous task that runs in the background of the app and initialize the CSV content to the targeted table.
  • While the data is imported from the CSV file to database, the user will see the progress bar of data being uploaded. In case of larger data, the progress bar dialog will be shown with the value of %completed.
  • Since the data is stored in a config-table, the app can retrieve the record from this table and use it in appropriate section.

Benefits:

  • The APK will be re-initialized with basic configuration data at any time.
  • No need to re-write the APK and compile it again.
  • Easier to setup and run inside the device. We get the changed configuration data at run time.
  • APK can be set up to a different configuration data base when required and can be deployed with different config data (CSV file) at different location easily.

Example of CSV File contents (appconfig.csv)

Config ID,Config Name,Config Value
validate_url,http://50.56.70.140/
webservice_url,http://50.56.70.140:8080/HOSTAPP/resources/inspection
camera_resolution_hight,800
camera_resolution_width,600
camera_flashlight_mode,auto
long_password,abc123

Example of Layout xml

xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >

<TextView
android:id="@+id/showResult"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="" />

Example of  Main form Activity class

1. MainActivity.java

package com.example.csvdemo;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.Date;

import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.database.Cursor;
import android.util.Log;
import android.view.Menu;
import android.widget.TextView;

public class MainActivity extends Activity {

private boolean isCsvFileNeedToInitialize = true;
private static final int DIALOG_DOWNLOAD_PROGRESS = 0;
private DBHelper mDbHelper;
private ProgressDialog mProgressDialog;
private static int totalRowsUpdate = 0;

public static final String external_sd = Environment.getExternalStorageDirectory().getAbsolutePath();
public static final File sdCard = Environment.getExternalStorageDirectory();
public static final String sdcardBaseDir = sdCard.getAbsolutePath();
public static final String externalPath = "/Android/data/com.example/";
public static final String csvFileName = "appconfig.csv";

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

mDbHelper = new DBHelper(this);
mDbHelper.open();
totalRowsUpdate = 0;

// create empty directory if not exist
File appDir = new File(sdcardBaseDir + externalPath);
if(!appDir.exists())
appDir.mkdirs();

File externalResourceFile = new File(sdcardBaseDir + externalPath + csvFileName);
isCsvFileNeedToInitialize = externalResourceFile.exists();
TextView lableResult = (TextView) findViewById(R.id.showResult);

if(isCsvFileNeedToInitialize)
{
new InitializeCSVFileAsync().execute("");

lableResult.setText( totalRowsUpdate + " fetched from 'appconfig.csv' into database successfully.");

} else {
lableResult.setText("'appconfig.csv' not found!");
PopIt("Exit Application", "'appconfig.csv' not found!");
}
}

public static void setTotalRecord(int ctr) {
totalRowsUpdate = ctr;
}

private void PopIt( String title, String message ){
AlertDialog.Builder alertbox = new AlertDialog.Builder(this);
alertbox.setTitle(title);
alertbox.setMessage(message);
alertbox.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
finish();
}
});
alertbox.show();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}

@Override
protected Dialog onCreateDialog(int id) {
Resources res = getResources();
String reader = "";
int ctr = 0;
try {
File f = new File(sdcardBaseDir + externalPath + csvFileName);
BufferedReader in = new BufferedReader(new FileReader(f));
while ((reader = in.readLine()) != null) { ctr++; }
setTotalRecord(ctr);
}catch(Exception e) {    e.getMessage();  }

switch (id) {
case DIALOG_DOWNLOAD_PROGRESS:
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setProgressDrawable(res.getDrawable(R.drawable.initialize_progress_bar_states));
mProgressDialog.setMessage("Initializing...");
mProgressDialog.setMax(ctr);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
return mProgressDialog;
default:
return null;
}
}

// Display Initialize progress bar for uploading CSVFiles to database
class InitializeCSVFileAsync extends AsyncTask<String, String, String>
{
@Override
protected void onPreExecute() {
super.onPreExecute();
mDbHelper.deleteCongigTableOldRecord();
if(isCsvFileNeedToInitialize)
showDialog(DIALOG_DOWNLOAD_PROGRESS);
}
@Override
protected String doInBackground(String... aurl) {
try {
float total = 0F;
float fctr = 1F;
String reader = "";
int ctr = 0;
boolean skipheader = true;
File f = new File(sdcardBaseDir + externalPath + csvFileName);
BufferedReader in = new BufferedReader(new FileReader(f));

while ((reader = in.readLine()) != null) {
// skip header column name from csv
if(skipheader) {
skipheader = false;
continue;
}
String[] RowData = reader.split(",");
mDbHelper.insertDB(RowData);
total += fctr;
publishProgress(""+(int)total);
//publishProgress((int)(total*100/lenghtOfFile));
}
in.close();
} catch(Exception e) {
e.getMessage();
}
return null;
}
protected void onProgressUpdate(String... progress) {
//Log.d("ANDRO_ASYNC",progress[0]);
mProgressDialog.setProgress(Integer.parseInt(progress[0]));
}
@Override
protected void onPostExecute(String unused) {

File f = new File(sdcardBaseDir + externalPath + csvFileName);
boolean result = f.delete();
if(isCsvFileNeedToInitialize)
dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
mDbHelper.close();
//fillAllList();
}
protected void onDestroy() {
if (mDbHelper != null) {
mDbHelper.close();
}
}
}
}

Example of  Helper class for sqlite database interaction:
Example of AbstractDbAdapter java

package com.example.csvdemo;

import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public abstract class AbstractDbAdapter {

protected static final String TAG = "ExampleDbAdapter";
protected DatabaseHelper mDbHelper;
protected SQLiteDatabase mDb;

protected static final String CONFIG_TABLE_CREATE =
"create table appconfigtbl (_id integer primary key," + "config_name text not null," + "config_value text," + " createdAt text, " + " updatedAt text);";

protected static final String DATABASE_NAME = "example";
protected static final int DATABASE_VERSION = 2;

protected final Context mCtx;

protected static class DatabaseHelper extends SQLiteOpenHelper {

DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CONFIG_TABLE_CREATE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS CONFIG_TABLE_CREATE");
onCreate(db);
}
}

public AbstractDbAdapter(Context ctx) {
this.mCtx = ctx;
}

public AbstractDbAdapter open() throws SQLException {
mDbHelper = new DatabaseHelper(mCtx);
mDb = mDbHelper.getWritableDatabase();
return this;
}

public void close() {
if (mDbHelper != null) {
mDbHelper.close();
}
//mDbHelper.close();
}
}

Example of DBHelper java

package com.example.csvdemo;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Hashtable;
import java.util.Vector;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.util.Log;

public class DBHelper extends AbstractDbAdapter{

public static final String KEY_ROWID = "_id";
public static final String KEY_CONFIG_NAME = "config_name";
public static final String KEY_CONFIG_VALUE = "config_value";
public static final String KEY_POSTED_DATE = "createdAt";
public static final String KEY_EDITED_DATE = "updatedAt";
public int maxLevelOnCurrentMenu = 1;

public int getMaxLevelOnCurrentMenu() {
return maxLevelOnCurrentMenu;
}

public void setMaxLevelOnCurrentMenu(int maxLevelOnCurrentMenu) {
this.maxLevelOnCurrentMenu = maxLevelOnCurrentMenu;
}

public static final String DATABASE_TABLE = "appconfigtbl";

public DBHelper(Context ctx) {
super(ctx);
}

public long insertDB(String config_name,String config_value, String createdAt, String updatedAt) {
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_CONFIG_NAME, config_name);
initialValues.put(KEY_CONFIG_VALUE, config_value);
initialValues.put(KEY_POSTED_DATE,createdAt);
initialValues.put(KEY_EDITED_DATE,updatedAt);
return mDb.insert(DATABASE_TABLE, null, initialValues);
}

public long insertDB(String[] RowData)
{
long result = 0;
ContentValues values = new ContentValues();
values.put(KEY_CONFIG_NAME, RowData[0]);
values.put(KEY_CONFIG_VALUE, RowData[1]);
values.put(KEY_POSTED_DATE, "");
values.put(KEY_EDITED_DATE, "");
result = mDb.insert(DATABASE_TABLE, null, values);
return result;
}

public boolean deleteList(long rowId) {

return mDb.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
}

public boolean deleteCongigTableOldRecord() {

return mDb.delete(DATABASE_TABLE,  null, null) > 0;
}

}

Example of initialize_progress_bar_states.xml [Used to show progressbar UI %progress value]


<gradient
android:startColor="#98887b"
android:centerColor="#ddd7c9"
android:centerY="0.95"
android:endColor="#0d1522"
android:angle="270"
/>

<corners
android:bottomRightRadius="7dp" android:bottomLeftRadius="7dp"
android:topLeftRadius="7dp" android:topRightRadius="7dp"/>

<gradient
android:startColor="#74c43f"
android:centerColor="#4a9c14"
android:centerY="0.85"
android:endColor="#06101d"
android:angle="270"
/>
<corners
android:bottomRightRadius="7dp" android:bottomLeftRadius="7dp"
android:topLeftRadius="7dp" android:topRightRadius="7dp"/>

Tags | ,

21

Feb
2013

No Comments

In Android

By Jay Dee

SwiftKey has unveiled its version 4 keyboard app for Android devices

On 21, Feb 2013 | No Comments | In Android | By Jay Dee

androidimg

To be completely honest, most android users are not satisfied with the android’s default keyboard. It can be fiddly for some users, who write languages other than English on a daily basis. After all it doesn’t cater to everyone’s typing style either. However “SwiftKey” has always proved to be the best keyboard app alternative for the android platform. This time the developers at SwiftKey have launched its version 4 for the android devices

One of the best features of this keyboard is its ability to gradually learn the user’s typing preferences. It studies how a user writes over time and generates predictive texts for him, which is surprisingly accurate and better than any other applications. SwiftKey has also included its swipe like feature called the SwiftKey Flow which lets the user type sentences without lifting finger from the mobile screen. SwiftKey now supports over 60 international languages.

Here are some of the most notable features in version 4 release:

  • SwiftKey Flow is a gesture typing feature that facilitates the users to write sentences simply by gliding over the keys. It also adds auto-correction ability as-well-as predicts the possible next words while typing.
  • It can also be blend with tap inputs and switching mid-word.
  • If the predicted word is correct then it can be inserted by simply lifting the finger off.
  • Flow through space lets the user type a complete sentence in one motion without lifting the finger, to give spaces between the words.
  • It supports word prediction for over 60 languages like Javanese, Sundanese, and Vietnamese etc with both auto-correction and word prediction abilities.
  • Easier correction and auto adaptability to users typing style.

According to reports Android application development with SwiftKey’s SDK now supports iOS, JVM, Linux, Mac OS-X, Windows, and C++ etc. SwiftKey had released its Flow feature in the last October and its Beta version was tested with a community of million users.  Being awarded numerous times for its keyboard application, it surely is one of the best android keyboard apps, plus it comes with a reasonable price.

Tags | ,

28

Jan
2013

No Comments

In Android

By Jay Dee

Technology to run Android on Windows without emulation

On 28, Jan 2013 | No Comments | In Android | By Jay Dee

android31There are numerous operating systems available in the market such as windows, MacOSX, Linux etc. But there is no way to run Android OS natively on a computer. In order to carve this problem, advancements have been made to run Android on a windows system without a simulator. It will enable the Android operating system to run on ‘Windows’ kernel instead of its usual ‘Linux’ kernel. This system will detach the need of an emulation layer, therefore making the android OS performance ultra-fast.

Some of the first hand users said that this wasn’t the first application to run Android on windows but its ability to negate the use of emulation layer, is what makes it welcoming.

The system is currently believed to be working with Android 4.0 and could be installed on Windows 8, Windows 7 and Windows Vista. But in order to set-up the application, it would require a little android application development familiarity, more than the basic knowledge of using an android Smartphone. Once installed, it can be used like a native android OS on a computer. It will be enabled to run all kinds of android applications including the 3D games. This technology will bring new possibilities to run simulated environment on a different OS, without any hindrances.

At Andolasoft we develop the most intriguing android mobile applications for individuals and from start-ups to established companies. We’ve an expertise team of android application developers developing the most innovative apps for all android devices.

Tags | ,

09

Jan
2013

No Comments

In Android

By Jay Dee

Android to be used in Consumer Electronic Appliances too

On 09, Jan 2013 | No Comments | In Android | By Jay Dee

android31Google’s Android operating system is the most widely used Smartphone operating system in the world. Besides that it is considered as the most user-friendly OS by the android users and has released it to other mobile device manufacturers.

But now Google has decided to power consumer home appliances with its android based software. These android applications will be developed specific to the instrument that will be embedded to its hardware.

Embedding Android directly into devices will make it easier for electronic appliances to exchange information with the humans. For example, android powered television can show a pop-up message from kitchen, indicating that the dish is ready to be served. The user could remotely access the kitchen appliances to turn it OFF or ON, from the TV. Google’s step is to bring the future imagination into reality. This will save a lot of time for the users and may avoid possible dangers. Like, if the device detects a gas leak in the kitchen it can automatically turn the appliance off or intimate the user about the situation. Devices will also be able to detect intrusions in the house when the user is not present.

Making such intelligent, connected appliances will need experienced android developers in the forefront. This advancement will also need advanced android application development for creating custom apps for the instruments. At Andolasoft we develop the most intriguing android applications for our customers. We have a pool of expertise android developers to provide innovative solutions for all versions of android operating software.

Tags | ,