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);
            }
        }