Sunday, December 29, 2013

Android Application - Develop,Build & Run Without Eclipse or any IDEs

We are generally using Eclipse IDE and ADT Plugin for developing Android applications. I too am doing the same in my mac. But few days back, something struck me, Android is an open-platform, and as such, we can create,build and test a java program without an IDE, simply using text editor,jdk and command line. On its core, programs for android are written in Java only. So why can't we try out doing the same for Android. Googled out, to surprise, its there in developer forum site itself. My bad, 2 years in android development, but in a hurry have never noticed it.

There are no hard steps to take off. Its very simple. We can create,run/debug as well get release version of apk using only command line and text editor along with Android SDK and Java JDK. No IDEs required !!

Before Getting Started
1. Download the Android SDK, Java JDK and Ant.

2. Add the android sdk, java jdk and Ant installation folder to the path variable. Please refer my blog on how to add path variables in mac.

3. Go to terminal and type the below,
        android list target
    to know the list of available android apis in the sdk. Download relevant apis using sdk manager. Note down the target id which you want to set as minsdk. To open sdk manager from command promt, type android

Creating a Project
1. Open terminal and type the below code,
   android create project --target 3 --name MyAppWithoutEclipse --path /Users/badrionapple/Documents/workshop/MyAppWithoutEclipse --activity MainActivity --package com.terminal.app
 Here --target     ->  Min SDK
          --name     ->  Project Name
          --path       ->  Physical location in the disk
          --activity  ->  Name of Main Activity
          --package ->  Package name for the app.
On successful completion, you will be able to find the full project structure being created in the location specified in path argument.

2. Edit manifest file, layouts, activity etc., as per your requirement.

Adding Libraries,Updating Projects
Please refer the link here.

Building and Running
Android projects are built using Ant tools. You will be able to find "Ant" folder in <android-sdk>/tools/.
1.Go to the root folder of your application and type the below in terminal,
    ant debug
  Compilation and build path errors will be listed, if any. On successful build, Now you have your apk signed in debug mode. You may, in addition face bufferoverflowexception, please refer here to solve it.
2. Opening emulator is easy. To know emulators i.e avds available, type android list avd in terminal. Managing AVDs from command line.
3. Type the below code, to start your avd, in terminal,
     emulator -avd <your-avd-name>
    [Note : You must have added both <android-sdk>/tools as well as <android-sdk>/platform-tools to path variable]
4. Verify whether avd is successfully started in terminal using below command,
     adb devices
5. Once your avd is listed, type the below to run your code,
     adb install bin/<your-Project-name.apk>

Distributing APKs
Please refer here.

Constraints that you may face while using command line,
  •  Unable to set breakpoint and debug your code.
  •  No Drag & Drop UI in xml for layouts, resources as well for manifest.
  •  Need to Set up everything manually for avds.
  •  Debugging is quite unfriendly(finding compile errors etc., and correcting it).
  •  No Ctrl+Shift+T or R to search classes,resources or search keywords in full workspace and other facilities that comes up with Eclipse or any IDE.


References
http://www.anddev.org/novice-tutorials-f8/developing-android-apps-without-eclipse-t13912.html
http://developer.android.com/tools/projects/projects-cmdline.html
http://developer.android.com/tools/building/building-cmdline.html
http://developer.android.com/tools/devices/managing-avds-cmdline.html



Tuesday, December 24, 2013

Handling ListView in Android

Android APIs provides many views i.e controls to present the information and interact with user. ListView is one among them. However for the sake of utilising the memory efficiently, Android system reuses the views in certain components.

ListView is a list of items to be displayed to the user from which he/she may choose an item. The item can either be a simple text or combination of image and text or still more complex layouts. When writing custom adapters to fit in data for such complex items in list, there would have been need to override the getView().

Issue
Now coming to the point, As said, android reuses the views. In case,there are more number of items in the list than that can be displayed to the user in the screen. In such cases, Listview is scrollable. Now when populating the data to such lists, you will get parameter in getView that identifies the position of the item that is inflated.

Say the screen can display 5 items. Populating data from either list or array using the position parameter will populate correctly for the first five items. From the next item onwards, getView() will be called only with the position parameter ranging from 0-4. Consequently, you will be able to see only the first five data in your data list getting repeated in the listview.


Solving the issue, 
Add these lines to the listview in xml,
       android:layout_height="0dp"
       android:layout_weight="1"

This solves the issue.

References :
http://lucasr.org/2012/04/05/performance-tips-for-androids-listview/
http://stackoverflow.com/questions/2618272/custom-listview-adapter-getview-method-being-called-multiple-times-and-in-no-co/2639159#2639159
http://stackoverflow.com/questions/10120119/how-does-the-getview-method-work-when-creating-your-own-custom-adapter

Friday, December 20, 2013

Kitkat in emulator

KitKat -  name of Chocolate Bar from Nestle?

Also the latest version of Android OS V4.4 from Google.

While everyone were expecting "Key Lime Pie" as the title for next release, It was a nice Strategy from Google to consider the name, its kind of win-win for both. Nestle gets popularity as well as Google. There was even a contest with KitKat chocolates wrapped up in special wrappers with Android Logo in it. There was promo-code and you could text it to a number and you had chance to win exciting gifts from Google like Playstore credits or Nexus devices.

The first mobile to come with kitkat is Nexus 5,

To know about the detailed set of features, please refer here.

Now lets get into the picture. I downloaded Kitkat apis for my android sdk and was trying to start an emulator running kitkat. Tried with all the alternatives changing the display settings, turning on/off use host gpu feature for emulator. Nothing worked, only black screen, not even android logo appeared. There were also buzzes in web, that for Mac, intel image is yet to be released and that default ARM image takes long time to load. I waited atleast 30 mins, even an hour, but in vain.

With advice from one of my colleague, since my mac was also having 4GB Ram, I increased the Ram size of the emulator to 2048MB, after which, all of a surprise android logo appeared and emulator got started.

PFB the settings which worked for me in my Mac,

























Buying an Android Device

There are many brands in android phone market. There are devices in all cost ranges. Which one to choose ? Read further.

To set things, I am not going to suggest any popular model phones, buy this, that etc., I am just going to give you hints and insight for buying a smartphone.

Deciding on the smartphone can depend on the following factors,
1. Need.
2. Budget.
3. Like for Brands.

NEED
 Question yourself, why do you need a smartphone.
   1. Are you a developer considering of testing your apps ?
   2. Are you a tech savvy person, buy the latest trend devices and test it ?
   3. Are you a gadget geek ?
   4. Are you going to use the phone for your work , need big screen for viewing maps,shares,GPS etc., need a phone or tablet ?
   5. All my friends / Everybody has, let me also have one.
   6. What are you going to do with your phone ? - just call/sms or more than that.. email, browsing, chat, social networking, hear songs, movies..

BUDGET
 If you are considering budget phones, go for local brands, but try to make the best brand as possible. Read the brands section. There are many shopping/comparison sites in the web which you can google out to find an idea on the price ranges and you can then go to a showroom and buy one.

BRANDS
Popular Brands : Samsung, LG, Sony, HTC
Popular but local : Micromax, Karbonn, Cellkon, Intex etc.,

Best things about each brand,

Samsung - Hardware, always latest trend in market
LG - Hardware
Sony - UI, richness of use
HTC - UI
Micromax - Affordable costs for Asian Market.

I personally own HTC Explorer A310e, I really love its UI, design, fonts, colors etc.,

My advice would be to avoid local brands as much possible.

Where can I buy from ?
  Nowadays there are many options through which one can buy a device. It can be done
   1. Via Shopping Sites(online)
   2. Via Showroom
   3. Via Manufaturer Sites(online)

Buying online as well from showroom has its own advantages and disadvantages as well.

In online, you can have access to devices available worldwide and you may have some devices which is not currently available in market, but was once available, second hand mobiles etc., Offers may also be available. But you may need to put in a lot of effort to find out the genuinity of the seller and the brand he is marketing through online. You will not be able to touch the device.

In showroom, you can get a full touch and feel of the device. You can bargain. You will have many offers, like data plan, memory card etc., However brands may be restricted.

Tips
1. Keep branded phones as preferable.
2. Fix your budget and need.
3. Compare and choose one among the various models.
4. Talk to the users/friends who has the mobile that you have chosen and get their experience.
5. Make sure you get warranty and bill details while buying.

Most important thing to consider in a phone irrespective of brand/budget is Battery Life. Make sure it has sufficient battery life atleast for a day, because today's smartphones last one day in average. There are even apps available in market that retrieves the information of apps consuming more power which can be turned off safely.

Other most notable ones are screen resolution,memory card, camera quality,bluetooth,wi-fi. Apart from these, NFC,GPS etc., other stuffs are fancy items in the shelf.



Thursday, December 19, 2013

Code Snippet - Restricting Orientations

Recent week, I have been hard finding it to restrict orientation to portrait and reverse portrait only. Today, got a solution/workaround. Thought it would be useful to share it.

The concern is to restrict the screen orientation to portrait and reverse portrait. Landscape and reverse landscape should not be supported. Hope you know that setting the screen orientation for activity(screen) can be done in either manifest file or in activity.

There is an attribute called "sensorPortrait"which exactly solves our case, as given in Android Developers forum. The point is ofcourse, it's there.Works as expected in many devices. But it doesn't work in either Galaxy S3,S4 or Nexus. There is even a bug raised in google site. The challenge was to fix the orientation in these devices.

Was trying to address the issue with setting the configchanges  for orientation in manifest and trying to handle it in the onConfigurationChanged in activity. None of them worked out. Got insights from one of our old team-mate reg. (OrientationEventListener) and another app(The Ultimate Rotation Control) developer reg. (WindowOrientationListener).

Tried using the first one and referred the web and got a workaround.

PFB the workaround for my issue,
-------------------------------------------------------------------------------------------------------------
import android.os.Bundle;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.hardware.SensorManager;
import android.util.Log;
import android.view.Menu;
import android.view.OrientationEventListener;
import android.widget.Toast;

public class MainActivity extends Activity {
OrientationEventListener orientationListener;
    private static final int THRESHOLD = 10;

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toast.makeText(MainActivity.this, "On Create", Toast.LENGTH_SHORT).show();
        orientationListener = new OrientationEventListener(this, SensorManager.SENSOR_DELAY_NORMAL) {
            public void onOrientationChanged(int orientation) {
            if(isPortrait(orientation)){
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
            }else if(isReversePortrait(orientation)){
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
            }
            }
        };
        
    }

    @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 void onPause() {
// TODO Auto-generated method stub
orientationListener.disable();

super.onPause();
}


@Override
protected void onResume() {
// TODO Auto-generated method stub
orientationListener.enable();
super.onResume();
}


private boolean isReversePortrait(int orientation){
        return orientation >= (180 - THRESHOLD) && orientation <= (180 + THRESHOLD);
    }

private boolean isPortrait(int orientation){
   return (orientation >= (360 - THRESHOLD) && orientation <= 360) || (orientation >= 0 && orientation <= THRESHOLD);
}

public boolean canShow(int orientation){
   return isReversePortrait(orientation);
}

public boolean canDismiss(int orientation){
   return isPortrait(orientation);
}
    
    
}
-------------------------------------------------------------------------------------------------------------

The values, (180, 360) are for portrait and reverse portrait modes. For Landscape and reverse landscape, you can try up with 90 and 270, where THRESHOLD is nothing but the limit within which the device can be considered as rotated to that position.Example - (360+-THRESHOLD) is portrait.

I have attached the full class file for reference.

References
http://stackoverflow.com/questions/8248274/android-detect-orientation-changed

Tuesday, December 17, 2013

Code Snippet - SD Cards & Network check

In many occassions, we may find a need to check for online condition and download files to our sd card.

PFB the code to check for network availability,

public boolean isNetworkAvailable() {
    ConnectivityManager cm =
        (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo netInfo = cm.getActiveNetworkInfo();
    if (netInfo != null && netInfo.isConnectedOrConnecting()) {
        return true;
    }
    return false;

}

PFB the code for SD Card mount check,

private boolean isSDCardMounted() {
String sdCardStatus = android.os.Environment.getExternalStorageState();
return sdCardStatus.equals(android.os.Environment.MEDIA_MOUNTED);
}

PFB the code that returns available space in SD Card,

public int getFreeExtMemory()
{
    StatFs statFs = new StatFs(Environment.getExternalStorageDirectory().getAbsolutePath());
    int free  =  ((statFs.getAvailableBlocks() * statFs.getBlockSize()) / 1024);
    Log.i("AppInstallChecker", "Available Space : " + free + " KB, Required Space : "+APPSIZE_KB+" KB");
    return free;
}

Note : The methods getAvailableBlocks() & getBlockSize() from the above method/snippet is deprecated after api 18, so put a check if needed.

References :

Thursday, December 12, 2013

Code Snippet - Download and install apk file programmatically

Downloading a file can be done in many ways.

either using httpurlconnection or httpclient or download manager in android.

using httpurlconnection

String result = "";
try {
URL url = new URL(this.url);
HttpURLConnection urlConnection = (HttpURLConnection) url
.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.connect();

File sdcard = Environment.getExternalStorageDirectory();
File file = new File(sdcard, "filename.apk");

FileOutputStream fileOutput = new FileOutputStream(file);
InputStream inputStream = urlConnection.getInputStream();

byte[] buffer = new byte[1024];
int bufferLength = 0;

while ((bufferLength = inputStream.read(buffer)) > 0) {
fileOutput.write(buffer, 0, bufferLength);
}
fileOutput.close();
result = "done";

catch (MalformedURLException e) {
e.printStackTrace();
catch (IOException e) {
e.printStackTrace();
}
return result;


using download manager works from api 9,

Uri src_uri = Uri.parse("http://your.url.here/File.apk");
Uri dst_uri = Uri.parse("file:///mnt/sdcard/download/File.apk");

DownloadManager.Request req = new DownloadManager.Request(src_uri);
req.setDestinationUri(dst_uri);
DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
dm.enqueue(req);
There is another one line technique,
org.apache.commons.io.FileUtils.copyURLToFile(URL, File)

Below is an example,

class InstallTask extends AsyncTask<Void, Void, String> {
ProgressDialog mProgressDialog;

Context context;
String url;

public InstallTask(Context context, String url) {
this.context = context;

this.url = url;

}

protected void onPreExecute() {
mProgressDialog = ProgressDialog.show(context,
"Download", " Downloading in progress..");
}

private String downloadapk() {
String result = "";
try {
URL url = new URL(this.url);
HttpURLConnection urlConnection = (HttpURLConnection) url
.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.connect();

File sdcard = Environment.getExternalStorageDirectory();
File file = new File(sdcard, "filename.apk");

FileOutputStream fileOutput = new FileOutputStream(file);
InputStream inputStream = urlConnection.getInputStream();

byte[] buffer = new byte[1024];
int bufferLength = 0;

while ((bufferLength = inputStream.read(buffer)) > 0) {
fileOutput.write(buffer, 0, bufferLength);
}
fileOutput.close();
result = "done";

} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}

protected String doInBackground(Void... params) {
String result = downloadapk();
return result;
}

protected void onPostExecute(String result) {
if (result.equals("done")) {
mProgressDialog.dismiss();
installApk();
} else {
Toast.makeText(context, "Error while downloading",
Toast.LENGTH_LONG).show();

}
}

private void installApk() {
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri uri = Uri.fromFile(new File("/sdcard/filename.apk"));
intent.setDataAndType(uri, "application/vnd.android.package-archive");
context.startActivity(intent);
}

}


just paste the above code to use it as an asynctask.

Make sure to add write external storage and internet permission.

You can add this code before calling installApk(), if you may want to check for corrupted/incomplete apk files.

private boolean isApkCorrupted() {
        boolean corruptedApkFile = false;
        try {
             new JarFile(new File("/sdcard/filename.apk"));
        } catch (Exception ex) {
             corruptedApkFile = true;
        }
        return corruptedApkFile;
    } 


Courtesy
http://bpsinghrajput.blogspot.in/2012/07/how-to-download-and-install-apk-from.html
http://gafurbabu.wordpress.com/2012/02/29/download-file-in-android-by-using-asynctask-in-background-operations/
http://stackoverflow.com/questions/11121121/android-download-an-application-using-the-downloadmanager-class
http://stackoverflow.com/questions/8338786/is-there-a-way-to-be-notified-when-apk-fails-to-being-installed

Wednesday, December 11, 2013

Code Snippet - Installed/Running Applications List

Create an Android Project as mentioned here.

List of Installed Apps:
Add the below code to get all the installed apps,

PackageManager packageManager = getPackageManager();
List<ApplicationInfo> appList =                  packageManager.getInstalledApplications(PackageManager.GET_ACTIVITIES);
for(ApplicationInfo info : appList){
    Log.i("AppInstallChecker",info.loadLabel(packageManager).toString());
 }

List of Running Apps:
Use the below code to get the list of running apps,

ActivityManager actvityManager = (ActivityManager) 
                                                                 this.getSystemService( ACTIVITY_SERVICE );
List<RunningAppProcessInfo> procInfos = actvityManager.getRunningAppProcesses();
for(RunningAppProcessInfo info : procInfos){
        Log.i("Running",info.processName);
 }

Check for App installed or not :
protected boolean isAppInstalled(String packageName) {
        Intent mIntent = getPackageManager().getLaunchIntentForPackage(packageName);
        if (mIntent != null) {
            return true;
        }
        else {
            return false;
        }

    }


Courtesy : 
http://stackoverflow.com/questions/13566479/check-app-is-installed-on-device-android-code
http://www.dreamincode.net/forums/topic/138412-android-20-list-of-running-applications/

About Android & Me

Android - Mobile Operating System based on Linux powered by Google. Android phones are most sought out smartphone by many people all round the world like iPhones.

Android devices now come in variety of sizes - phones as well as tablets, currently adding to the trend - hand gears made by Samsung and Sony.

Google has released its latest android version Kitkat. All the versions are named after a dessert in alphabetical order. Any smartphone/mobile OS becomes hit with its ease of usage, affordability costs of phone and the app ecosystem. Android has a rich app ecosystem - Google Play owned by Google. Also other third party markets do exist. Owing to the affordable costs from several manufacturers, it has become very popular in Asian, middle east and European, with iOS/iPhones leading in US.

Architecture



Below are some useful links

Wiki
Official Site
Developer
Download & Setup

After download and setup, you can either start developing apps with guidance available online as well offline.

online - refer to developer link mentioned above.
offline - <android-sdk> / docs / guide / guide_toc.html

About me
I am a budding Android developer working in India.
email address : badrionlion@gmail.com
mobile : 94880 19019

I started learning Android by 2012 and am currently working as a developer in an IT company.
Some of my Apps in Google Play.
CallSMS Stats
Abhivadhaye

I will be registering my voices, learning, latest trends in Android and other smartphone market from my next post onwards.