Sunday, November 13, 2011

Android Training videos

These are the best Android training videos i have found so far:

http://marakana.com/techtv/android_bootcamp_screencast_series.html

These videos come from Marakana's 5-Day Android Bootcamp Training Course that Marko Gargenta taught in San Jose, CA earlier this year. 

Wednesday, November 9, 2011

Installing APk file into your emulator

You can use File explorer view in Eclipse to drag files there to install into Android.

If you dont want to do it with Eclipse, you can do it in command line. You need to use "adb.exe" to do that. First add "...android-sdk/platform-tools/ to your path from advanced computer settings, so you can call adb from command line.

Type "cmd" add search or run screen to launch command editor. If you have the path to adb, you can call that. Start the service: adb start-server

If you see some error, you may need to manually delete old running adb.exe from your task manager.

To install file after adb daemon running, you can type "adb install C:\yourfolder\yourfile.apk". If you previously installed this, it does not replace the old app. You need to delete that from emulator. You can use menu options to go to settings->apps>your app->uninstall.

Hope, this helps you to use android emulator

Friday, November 4, 2011

Rendering pdf in android app

I was expecting this to be easy, but it got some complications. Android does not have native rendering for pdf,so you have different options. I decided to load the pdf in async task and then open the available pdf application. One nice feature with the Android framework is "the intents". You can launch application from another application with those intents. They have very nice way of managing different instances of same app. You can read more about this here.

You need to set manifest file first to enable file permissions.

Here is my AndroidManifest.xml:

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

    <uses-sdk android:minSdkVersion="14" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:label="@string/app_name"
            android:name=".PdfprintdemoActivity" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />

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

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" >
    </uses-permission>
    <uses-permission android:name="android.permission.INTERNET" >
    </uses-permission>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" >
    </uses-permission>
    <uses-permission android:name="android.permission.READ_PHONE_STATE" >
    </uses-permission>
</manifest>


I put everything inside one activity to make this example simple. There are some important elements that need to be explained.

OnCreate method: It calls this method when creating the view. You should call the base method first then do your overrides.

/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        //call base
        super.onCreate(savedInstanceState);
        //set layout main.xml to be layout for this activity
        setContentView(R.layout.main);
        //create references to the controls
        startBtn = (Button) findViewById(R.id.startBtn);
        //attach listener in code or you can do that in layout file.
        startBtn.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                startDownload();
            }
        });         
    }




I used Async task to handle the download. It helps you to performasynchronous work on your user interface without halting the UI. You don't needto handle threads by yourself.

  • doInBackground() executes automatically on a worker thread if you call "execute" method from this class. 
  • onPreExecute(), onPostExecute(), onProgressUpdate() are all invoked on the UI thread. 
  • You can set the return value from the "doInBackround()" as input to onPostExecute()  
  • You can access publishProgress() from "doInBackround()" method to call "onProgressUpdate()" 


We are setting the dialog at onPreExecute():


@Override
        protected void onPreExecute() {
            super.onPreExecute();
            showDialog(DIALOG_DOWNLOAD_PROGRESS);
        }

        //do actual download
        @Override
        protected String doInBackground(String... aurl) {
            int count;
            String fullpath = "";
            try {
                URL url = new URL(aurl[0]);
                URLConnection conexion = url.openConnection();
                conexion.connect();
                int lenghtOfFile = conexion.getContentLength();
                Log.d("ANDRO_ASYNC", "Lenght of file: " + lenghtOfFile);
                //Get directory
                File root = Environment.getExternalStorageDirectory();
                InputStream input = new BufferedInputStream(url.openStream());
                OutputStream output =  new FileOutputStream(new File(root,
                        aurl[1]));
                byte data[] = new byte[1024];
                fullpath = root.getAbsolutePath()+"/"+aurl[1];
                Log.d("ANDRO_ASYNC","path:"+fullpath);
                long total = 0;
                while ((count = input.read(data)) != -1) {
                    total += count;
                    publishProgress("" + (int) ((total * 100) / lenghtOfFile));
                    output.write(data, 0, count);
                }
                output.flush();
                output.close();
                input.close();
                Log.d("ANDRO_ASYNC", "File closed1: " + lenghtOfFile);
            } catch (Exception e) {
                Log.d("error",e.getMessage());
            }
            return fullpath;
        }


/*We use this method to update progress bar*/
        protected void onProgressUpdate(String... progress) {
            Log.d("ANDRO_ASYNC", progress[0]);
            mProgressDialogWindow.setProgress(Integer.parseInt(progress[0]));
        }

        
        /* This method takes the return param from doinbackground call as input*/
        @Override
        protected void onPostExecute(String linkname) {
            mProgressDialogWindow.setMessage("Finished");
            dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
            Log.d("onPostExecute","Send:"+linkname);
            OpenFile(linkname);
        }
        
        /*We are firing intent to open this file with avaialble pdf viewer*/
        protected void OpenFile(String linkname)
        {
            File file = new File(linkname);

            if (file.exists()) {
                Log.d("OpenFile","Exists:"+linkname);
                Uri path = Uri.fromFile(file);
                Intent intent = new Intent(Intent.ACTION_VIEW);
                intent.setDataAndType(path, "application/pdf");
                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

                try {
                    startActivity(intent);
                } 
                catch (ActivityNotFoundException e) {
                    Toast.makeText(PdfprintdemoActivity.this, 
                        "No Application Available to View PDF", 
                        Toast.LENGTH_SHORT).show();
                }
            }else
            {
                Log.d("OpenFile","DOES NOT Exists:"+linkname);
            }
        }

Sunday, October 30, 2011

Gitignore settings for Android


# ignore built application files
*.apk*.ap_


# Java class files
*.class
# VM files
*.dex
# dont need generated files
bin/
gen/
# Local configuration files
local.properties
#You can copy those into gitignore.txt and then save as ".gitignore" in "all files format". 

Monday, October 24, 2011

Ruby on Rails 3.0

I have created a webpage in Ruby on Rails after going through all those server setup at slicehost.com and all those plugins. I kinda like the CMS editor, but don't like plugin hell!

I installed one file management plugin to upload css and js files,but it was so stupid to cut off after some characters. After checking their code, i realized that they were using "Get" method to send data. I learned hard way that you should not trust those weird plugins they got. They got so many different versions and it needs to be compatible. Besides all those, I really like the scaffolding, conventions in modelling, and different view engine options. It is definitely ahead of the current Asp.net MVC 3 or 4 with all those features. You may know that recent asp.net mvc features and code sharing with nuget packages are copy of RoR. You can do scaffolding with T4 templates and do the data modeling style coding with new Entity framework code first approach. They are still weak on the data migration  part, but it is coming very strong.

If you setup a server for your RoR project before, you may know all different options and little things to do. If you have limited memory on your slice, it takes some time to restart worker threads after inactivity period. They are not very efficient. I did bunch different things to make it work. Good thing is you can find everything about to start a server from scratch. You can check articles at Slicehost.com for different server options.

Anyway, What do you think about Ruby on Rails and Asp.Net MVC?

Android ADT 14 and Android Unknown Command 'crunch'

I just setup a sample project to check out android development, but got weird error related to 'crunch' command. How is that possible with fresh sdk tools and all included eclipse package setup. It was very discouraging, but i decide to figure out a way to at least run some demos and see "hello world" in different platform versions.

Solution: You need to install this ADT 14. Yes. you need to uninstall all those old Android SDK and try again:)
I checked all necesary items in the Eclipse window. After downloading all those libraries, you should setup the SDK directory for android.

At the end, you should see references to correct version of ADT. "Hello world" will work fine now. You can create new projects from sample Android apps. It really helps to learn overall design.