Tuesday, June 19, 2012

GKproggy RSS News Reader - Now on Amazon App Store

Hi guys, application now available for the Kindle Fire. Check it out:

Amazon Link

Thanks!

Tuesday, June 5, 2012

RSS News Reader Application Now Available @ Google Play

Hey everyone, I have released a new application I worked on my free time on Google Play. The application is a simple RSS news reader. Check it out: Google Play Link

Thanks

Saturday, May 5, 2012

Android - Switch Tabs in TabHost within a Listview by Swipes using GestureDetector

Implementing a tabhost is a great way to add functionality to your app. Sadly, tabhost forces the user to click on the tabs to switch between screens. But thankfully we are programmers and can make our programs do what we want them to do. In this tutorial, Ill show you how to implement a GestureDetector to handle the left and right swipes from user to switch between tabs. Lets start with our XML layout of the main window:

main.xml

<?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:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical"
        android:padding="5dp" >

        <TabWidget
            android:id="@android:id/tabs"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />

        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="4"
            android:padding="5dp" >

            <com.daish.viewtest.TestListView
                android:id="@+id/custom_list"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content" />
        </FrameLayout>
    </LinearLayout>
</TabHost>

Next we have our main activity. I created a method called switchTabs(boolean direction) to tell tabhost which direction to switch tabs. I also implemented a listener on tabchanged. Once a tab is changed, the listener is fired and I then change the content on listview.

import android.app.TabActivity;
import android.os.Bundle;
import android.widget.TabHost;
import android.widget.TabHost.OnTabChangeListener;

public class ViewTestActivity extends TabActivity
{
 private TestListView testListView = null;
 private TabHost tabHost = null;
 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState)
 {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  tabHost = getTabHost(); // The activity TabHost
  TabHost.TabSpec spec; // Resusable TabSpec for each tab

  spec = tabHost.newTabSpec("Tab 1 Tag").setIndicator("Tab 1")
    .setContent(R.id.custom_list);
  tabHost.addTab(spec);

  testListView = (TestListView) findViewById(R.id.custom_list);
  
  spec = tabHost.newTabSpec("Tab 2 Tag").setIndicator("Tab 2")
    .setContent(R.id.custom_list);
  tabHost.addTab(spec);

  //Done to make list update itself on a tab change
  tabHost.setOnTabChangedListener(new TabChangeListener());
  tabHost.setCurrentTab(1);
 }
 
 public void switchTabs(boolean direction) 
 {
  if (direction) // true = move left
  {
   if (tabHost.getCurrentTab() == 0)
    tabHost.setCurrentTab(tabHost.getTabWidget().getTabCount() - 1);
   else
    tabHost.setCurrentTab(tabHost.getCurrentTab() - 1);
  }
  else
  // move right
  {
   if (tabHost.getCurrentTab() != (tabHost.getTabWidget().getTabCount() - 1))
    tabHost.setCurrentTab(tabHost.getCurrentTab() + 1);
   else
    tabHost.setCurrentTab(0);
  }
 }

 private class TabChangeListener implements OnTabChangeListener
 {

  @Override
  public void onTabChanged(String tabId)
  {
   testListView.init(tabHost.getCurrentTab());   
  }
  
 }
}

Next we have the heart of the content; the listview. The goal is to allow the user to swipe left and right and our program would switch tabs. Although, we have to make sure we did not remove the functionality of clicking on an item and scrolling up and down on list. On my first attempt, I made an @Override onTouchEvent(MotionEvent event) and I tried to handle the swipes. The problem my implementation had was if the user swiped, the item on the next tab would automatically click after user lifted their finger. As such, I had to find an alternative. This is where GestureDetector came in. This class gave me the ability to analyze the touch event. I kept the original @Override onTouchEvent(MotionEvent event), except I passed the event to the GestureDetector and let the class handle the left and right swipes. If the GestureDetector analysis of the touch event appeared to be anything other than left or right swipes, let ListView handle it (ex. scroll up and down as well as clicks). The result was the functionality I was looking for.

import android.app.AlertDialog;
import android.content.Context;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.GestureDetector.OnGestureListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class TestListView extends ListView
{
 Context context;
 private ArrayAdapter<String> test;
 String[] testItems = {"Larry", "John", "Gary","Larry", "John", "Gary","Larry", "John", "Gary","Larry", "John", "Gary","Larry", "John", "Gary","Larry", "John", "Gary"};
 String[] anotherTestItems = {"Homer", "Leslie", "Gary","Beaver","Homer", "Leslie", "Gary","Beaver","Homer", "Leslie", "Gary","Beaver","Homer", "Leslie", "Gary","Beaver"};
 
 //If built programmatically
 public TestListView(Context context)
 {
  super(context);
  this.context = context;
 }
 //This example uses this method since being built from XML
 public TestListView(Context context, AttributeSet attrs)
 {
  super(context, attrs);
  this.context = context;
 }
 
 //Build from XML layout 
 public TestListView(Context context, AttributeSet attrs, int defStyle)
 {
  super(context, attrs, defStyle);
  this.context = context;
 }
 
 public void init(int i)
 {
  if(i == 0)
   test = new ArrayAdapter<String>(getContext(),R.layout.row, R.id.label , testItems);
  else
   test = new ArrayAdapter<String>(getContext(),R.layout.row, R.id.label , anotherTestItems);
  setAdapter(test);
  setOnItemClickListener(new ListSelection());
 }
 
 //GestureDetector used to for analyze touch even from user
 private GestureDetector gesture = new GestureDetector(new GestureListener());
 
 //Method is called when ListView detects an onTouchEvent
 @Override
 public boolean onTouchEvent(MotionEvent event)
 {//Sends event to GestureDetector to see if we can use event
  boolean result = gesture.onTouchEvent(event);
  //if result is true, then we need to handle event, not listview
  //false means listview can handle event to pass it on
  if(result)
   return result;
  return super.onTouchEvent(event);
 }
 
 private float startX= 0;
 private float endX = 0;
 //Class which will analyze touch event and determine what user did
 private class GestureListener implements OnGestureListener
 {

  @Override
  public boolean onDown(MotionEvent e)
  {
   return false;
  }

  @Override
  public void onShowPress(MotionEvent e)
  {
  }

  @Override
  public boolean onSingleTapUp(MotionEvent e)
  {
   return false;
  }

  @Override
  public boolean onScroll(MotionEvent e1, MotionEvent e2,
    float distanceX, float distanceY)
  {
   return false;
  }

  @Override
  public void onLongPress(MotionEvent e)
  {
  }

  @Override
  public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
    float velocityY)
  {
   float x = velocityX < 0 ? -1*velocityX : velocityX;
   float y = velocityY < 0 ? -1*velocityY : velocityY;
   if(x > y)
   {
    System.out.println("Moving" + " " + (startX - endX));
    startX = e1.getX();
    endX = e2.getX();

    if ((startX - endX) < -120)
    {
     ((ViewTestActivity) context).switchTabs(true);
    }
    else if ((startX - endX) > 120)
    {
     ((ViewTestActivity) context).switchTabs(false);
    }
    return true;
   }
   return false;
  }
  
 }
 
 private class ListSelection implements OnItemClickListener
 {

  @Override
  public void onItemClick(AdapterView<?> parent, View view, int position,
    long id)
  {
   AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
   builder.setMessage("You pressed item #" + (position+1));
   builder.setPositiveButton("OK", null);
   builder.show();
  }
  
 }
}

Hope this was helpful. Enjoy!

Thursday, May 3, 2012

Android - Creating a Tabhost with ListView and Button under ListView

I decided this was worthy of a post since I had a hard time figuring this out. Android has a cool TabActivity which allow us to add tabs to our application. Of course we have to declare an XML file for our main window which includes all the containers and widgets needed to create UI:

Main.xml

<?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:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical"
        android:padding="5dp" >

        <TabWidget
            android:id="@android:id/tabs"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />

        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="4"
            android:padding="5dp" >

            <com.daish.viewtest.TestListView
                android:id="@+id/custom_list"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content" />
        </FrameLayout>

        <FrameLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="0"
            android:padding="5dp" >

            <Button
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text="BUTTON UNDER LISTVIEW!" />
        </FrameLayout>
    </LinearLayout>

</TabHost>

The XML layout includes a tabwidget, listview, and a button. The trick here is android:layout_weight="" which indicates which widget will take up portions of the screen. I also added a button which took up another portion. When it comes down to FrameLayouts, you have to indicate the weight to determine how much of the screen it will take up or else some widgets will appear to float infront of another, which is the nature of a framelayout. The problem is Tabhost needs to have a Framelayout for its content of the tabs and this was a way I found to add button. Linear Layout and Relative layout did not work for me. If someone has a better way, please feel free to share.

Here is my Main Activity Class:

import android.app.TabActivity;
import android.os.Bundle;
import android.widget.TabHost;

public class ViewTestActivity extends TabActivity
{
 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState)
 {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  TabHost tabHost = getTabHost(); // The activity TabHost
  TabHost.TabSpec spec; // Resusable TabSpec for each tab

  //tab creation
  spec = tabHost.newTabSpec("Tab 1 Tag").setIndicator("Tab 1").setContent(R.id.custom_list);
  tabHost.addTab(spec);

  spec = tabHost.newTabSpec("Tab 2 Tag").setIndicator("Tab 2").setContent(R.id.custom_list);
  tabHost.addTab(spec);

  tabHost.setCurrentTab(1);

 }
}

Here is the Class which extends ListView:

import android.app.AlertDialog;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class TestListView extends ListView
{
 private ArrayAdapter<String> test;
 String[] testItems = {"Larry", "John", "Gary","Larry", "John", "Gary","Larry", "John", "Gary","Larry", "John", "Gary","Larry", "John", "Gary","Larry", "John", "Gary"};
 
 //If built programmatically
 public TestListView(Context context)
 {
  super(context);
  init();
 }
 //This example uses this method since being built from XML
 public TestListView(Context context, AttributeSet attrs)
 {
  super(context, attrs);
  init();
 }
 
 //Build from XML layout 
 public TestListView(Context context, AttributeSet attrs, int defStyle)
 {
  super(context, attrs, defStyle);
  init();
 }
 
 public void init()
 {
  test = new ArrayAdapter<String>(getContext(),R.layout.row, R.id.label , testItems);
  setAdapter(test);
  setOnItemClickListener(new ListSelection());
 }
 
 private class ListSelection implements OnItemClickListener
 {

  @Override
  public void onItemClick(AdapterView<?> parent, View view, int position,
    long id)
  {
   AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
   builder.setMessage("You pressed item #" + (position+1));
   builder.setPositiveButton("OK", null);
   builder.show();
  }
  
 }
}

Here is the result of code above. Enjoy!

Wednesday, January 11, 2012

Android - Extending ListView and Instantiate with XML and AlertDialogs for itemSelect

Was doing a bit of coding and decided to demonstrate a way to create your own class which extends ListView. I wanted to manage specific code in regards to this listview and didnt want the code to be all over the place. Anywho, here is the source of a quick ListView showing names.

When you click on the items an AlertDialog box appears indicating what you clicked on.


NOTE: the XML files below should go in res/layout folder of your project.


Main.xml Make sure to make change to package name!


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

 <com.daish.viewtest.TestListView
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"/>

</LinearLayout>

row.xml This layout defines how each row is going to look like. This has a picture and name


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/icon"
        android:layout_width="22dp"
        android:layout_height="22dp"
        android:layout_marginLeft="4dp"
        android:layout_marginRight="10dp"
        android:layout_marginTop="4dp"
        android:src="@drawable/ic_launcher" >
    </ImageView>

    <TextView
        android:id="@+id/label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20dp" >
    </TextView>

</LinearLayout>

MainActivity (beginning of program)


import android.app.Activity;
import android.os.Bundle;

public class ViewTestActivity extends Activity 
{
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

TestListView Class extending ListView


package com.daish.viewtest;

import android.app.AlertDialog;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class TestListView extends ListView
{
 private ArrayAdapter<String> test;
 String[] testItems = {"Larry", "John", "Gary"};
 
 //If built programmatically
 public TestListView(Context context)
 {
  super(context);
  init();
 }
 //This example uses this method since being built from XML
 public TestListView(Context context, AttributeSet attrs)
 {
  super(context, attrs);
  init();
 }
 
 //Build from XML layout 
 public TestListView(Context context, AttributeSet attrs, int defStyle)
 {
  super(context, attrs, defStyle);
  init();
 }
 
 public void init()
 {
  test = new ArrayAdapter<String>(getContext(),R.layout.row, R.id.label , testItems);
  setAdapter(test);
  setOnItemClickListener(new ListSelection());
 }
 
 private class ListSelection implements OnItemClickListener
 {

  @Override
  public void onItemClick(AdapterView<?> parent, View view, int position,
    long id)
  {
   AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
   builder.setMessage("You pressed item #" + (position+1));
   builder.setPositiveButton("OK", null);
   builder.show();
  }
  
 }
}


The code above should give you this:

Friday, January 6, 2012

Recovering Cisco IP Phone 7940 / 7960

These Cisco IP phones are a pain to setup. I was given the task to setup 6 Cisco IP phones. Out of the batch 2 did not boot up to the point where we could access the settings. On the Cisco 7940 we received TFTP timeout o / A and just remained there. The other was a Cisco 7960 and gave an error Application Protocol Invalid. I was able to recover the phones by doing the following:

CAUTION: The instructions configure phone to work as SIP Phones not Skinny SCCP.

You will need the following:

  1. TFTpd32 http://tftpd32.jounin.net/
  2. Cisco IP Phone firmware (I used P0S3-8-12-00) http://radiotwenterand.nl/~graver/cisco/SIP-7960/P0S3-8-12-00.zip
  3. Cisco IP Phone configuration files http://www.minded.ca/default/wp-content/uploads/2009/12/Cisco-Config-Files.zip. If you do not know how to setup config files, check out the site http://www.minded.ca/2009-12-16/configure-cisco-ip-phones-with-asterisk/
  4. Switch
  5. Computer

Instructions:

  1. Download TFTpd32 at http://tftpd32.jounin.net/ and firmware and configuration files.
  2. Grab a computer and install TFTpd32. Unzip firmware and configuration files to a folder. To be safe, setup configuration files to have SIP[Phone MAC Address].cnf and SEP[Phone MAC Address].cnf.xml (Check website above if you don't know how to setup configs)
  3. Disconnect computer from network and plug into switch (Switch should only have computer and phone. Leave Cisco Phone powered off while you setup TFTpd32)
  4. Set the computer IP address to 192.168.1.1 MASK 255.255.255.0. Bring up TFTpd32 and go to settings.
    • Under Global Tab, only enable TFTP Server and DHCP Server.
    • Click on TFTP tab. Set Base Directory to the location of the folder where Cisco IP firmware and configuration files are. Set TFTP security to none.
    • Click on DHCP tab and set IP pool starting address to 192.168.1.2. Set pool to 5 or something like that. Default router put 192.168.1.1 mask 255.255.255.0 Additional option 66 in small box and ip 192.168.1.1 in the box next to it. Uncheck Ping Address before assignation and Persistant leases.
  5. Hit OK and Restart TFTpd32.



  6. While your TFTP is running, power on the Cisco IP phone. If all goes well, TFTpd32 will log the connection and show the files it requests.



  7. The phones will show upgrading firmware.



  8. Phones should now boot up completely once installation is complete.



Saturday, December 17, 2011

Automatically Shutdown Windows 7 / XP through Command Prompt

There have been many times where I wish a program would shutdown my computer once it has completed its processes. Unfortunately, some programs do not have this option. The following command which is executed in the command prompt will allow you shutdown windows with also the possibility to restart the OS.

If the following code is copied into your command prompt, it will shutdown the computer at 6:30pm
at 18:30 shutdown -s
To confirm task has been added, just type "at" in the command prompt, and you will see the scheduled tasks. If you would like to remove the job type:
at [id] /delete 
//[id] = replace with the ID number to delete
To restart windows, just add -r command. A prompt can also be given to give notification of upcoming shutdown by adding -c. The command can also be generated to work on certain days of the week. Ex:
at 18:30 /every:T,Th,F shutdown -s -r -c "Computer is going to restart!"
The code above says the computer will restart at 6:30pm every Tuesday through Friday and give the message indicating pc is restarting. Hope this helped! IMPORTANT: If this command is being issued through windows 7, please ensure you run command prompt as Administrator or else you will get "Access Denied".