Monday, October 22, 2012

Windows 8 Tips

Windows 8 has some advantages and disadvantages.  The advantages are it seems to run much faster than previous versions and the start up time is very quick!  Also, the new Windows 8 Interface offers a cool way to get full screen apps via the Microsoft Store.  One huge disadvantage is the start menu has been redesigned and may take some getting used to now.  Also, switching between the desktop and the Windows 8 interface can be a little annoying.

So, here are some tips to help you get used to the new OS.

Start Menu
Aim the mouse to the bottom left corner of the screen and then click on the Start Box that comes up.  Also, you can simply press the "Windows" button if your keyboard has one, or you can press Ctrl-Esc.

Shutdown/Restart
This was the hardest thing for me to get used to.  However, once you know the trick its easy.  Press Windows Button and C at the same time, then on the right you should see the "Settings" button.  Press that button, then Press Power and you get the option to Sleep, Restart, or Shutdown.  Another way to get to this option is to move the mouse down to the lower right corner of the screen.

Switch to Open "Windows 8" Apps
Move the mouse to the top left corner of the screen and you will see a list of "running" Windows 8 apps.  If you do not have any open, then nothing will appear.

Search
Move your mouse either to the top right or the bottom right and you will see an overlay appear.  Then you can click on the Search Icon ( magnifying glass ).  Another quick way is Windows Button + C and then click the search icon.

Quitting a Windows 8 App
Despite what you may think, pressing Escape will not let you exit a Windows 8 app.  You can press the Windows Button ( ctrl-esc ) which will let the app continue to run, but you will get back to the start menu, or you can press alt-f4.  Also, you can grab the top of the app using the mouse and pull it down to the bottom to close at as well.  This can be done with the mouse or using the touch screen.

Snapped View
In Windows 8 you can have two apps open side by side.  This is called snapped view.  To do this, open one app that you want to have "snapped", then click on the top of it and drag the app to either the left or right side.  Then you can select on the larger content area and get back to the start menu to open another app.  This is a really cool feature for some types of apps, but for others it is pretty useless.


Well, good luck using Windows 8.  Give it time, it took me a month to completely adjust to the new interface.


Thursday, October 18, 2012

Get Client IP Address in JBoss AS 7


Recently I was trying to figure out how to get the ip address of the calling client using JBoss AS 7.  I found a few examples that have basically the following code.

 import javax.servlet.http.*;

   @GET
   @Path("/")
   @Produces("text/xml")
public String login(@QueryParam("user") String user,
@QueryParam("password") String password,
@Context HttpServletRequest req) {
{
String ipAddress=req.getRemoteAddr();
        userLogin(user, password, ipAddress);
}

They key is to use the @Context annotation to get an HttpServletRequest.  Then you can just call getRemoteAddr().

Now, I tried this and I kept getting compilation errors.  I for some reason assumed that all of the jar's that JBoss used would be added to the classpath of eclipse when I installed the JBoss Tools.  Well, I guess they were not.  So, all I had to do was go to the project properties, then select Java Build Path, then select the Libraries tab and the jboss-servlet-api_3.0_spec-1.0.0.Final.jar to the project.
This jar is located at <JBOSS-INSTALL>\modules\javax\servlet\api\main, so for me on windows it was at C:\jboss-as-7.1.1.Final\modules\javax\servlet\api\main

That's it!

Sunday, August 26, 2012

Add Listener To Checkbox in Android


This next code sample is to show how to add a listener to a checkbox in Android.

It's pretty simple, first thing you will need to do is get the instance of the checkbox using findViewById or you can create the checkbox dynamically.  After tha, you add a OnCheckChanged listener, then test the boolean isChecked to see if it was checked or not.  That's it!

Some imports required...
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;


Here is the code....


CheckBox checkbox=(CheckBox) findViewById(R.id.checkBox);
checkbox.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
   {
       if ( isChecked )
       {    
           //add code to handle checkbox being checked
       }else
       {
           //add code to handle checkbox being unchecked
       }
    }
}

Monday, May 7, 2012

Android Widget YouTube Videos

I found some really good videos on how to build an Android Widget.  If my written tutorial is not clear, then these videos can help provide a different point of view on how to create a widget.












Android Development Tools

A very good video from the 2011 Google I/O event on android development tools.



Monday, March 12, 2012

Creating An Android Widget

In this next post, I will discuss how I created a Widget for one of my apps that I am working on. This widget will launch an Activity when added to the home screen so the user can customize it. Also, the widget will have a button on it so that an action can be done right from the screen. The motivation for this is so a user can quickly do an action without needing to open the app up and navigate to the action desired.

First thing that will need to be done is to update the manifest file. The first thing to add is an activity named SelectExample. This will be called when the widget is added to the desktop. That is why the intent-filter android.appwidget.action.APPWIDGET_CONFIGURE is nested inside that activity definition.

Finally, a receiver needs to be added to know when the widget is updated. This is so the widget can be drawn correctly. The receiver is labelled WidgetExample below where the full manifest file is:



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

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

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

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
     
       
<activity android:name=".SelectExample">
 <intent-filter>
        <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
 </intent-filter>
</activity>
<receiver android:name=".WidgetExample" android:label="Example">
 <intent-filter>
        <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />                  </intent-filter>
 <meta-data android:name="android.appwidget.provider" android:resource="@xml/widget1_info" />
</receiver>
    </application>

</manifest>
In the receiver block, you may notice the resource @xml/widget1_info.  This is very important.  You need to created a file in the res/xml folder and name it widget1_info.  Below is what the contents of mine look like.
The width and height are set so that the widget will be 2 blocks wide and 1 block tall.  The updatePeriodMillis is the number of milleseconds that will pass before Android will call the receiver for a chance to update the widget, if the value is less than 30 minutes, it is ignored.  Also, notice the android:configure value, this needs to point to the class that will handle the configuration of the widget when it is added to the home-screen.  The layout is defined in the widget1 file referenced in this XML and will be shown below.

res/widget1_info
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="147dp"
    android:minHeight="72dp"
    android:updatePeriodMillis="1000"
    android:configure="com.wetselsoftware.example.widgetexampleproject.SelectExample"
    android:initialLayout="@layout/widget1">
</appwidget-provider>



layout/widget1





<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="horizontal"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:gravity="center"
  android:layout_margin="4dp"
  android:background="@drawable/background">
  <LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
      <TextView
          android:id="@+id/widgetName"
          android:layout_gravity="left"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="TextView" />

  <Button
      android:id="@+id/widgetbutton"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_gravity="left"
      android:text="Launch"
      />
</LinearLayout>
 
</LinearLayout>

 OK, so that is the XML files.  Now, lets look at the WidgetExample receiver.  This class will extend the AppWidgetProvider class.  Specifically, the onUpdate() function needs to be implemented for the purposes of this demo.  This will update the GUI of the widget on the Home screen.  Basically in onUpdate, we loop through each widgetId, and for that ID grab the Name of the widget and use RemoteViews class to update the GUI dynamically.  In the SelectPet Activity which I will show next, it asks for a name for this Widget and I saved it in the SharedPrefernces and retrieved it in this class.
public class WidgetExample extends AppWidgetProvider {
  public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
    final int N = appWidgetIds.length;
    Log.i("WidgetExample",  "Updating widgets " + Arrays.asList(appWidgetIds)); 
    for (int i = 0; i < N; i++) {
      int appWidgetId = appWidgetIds[i];
      Intent intent = new Intent(context, WidgetExampleProjectActivity.class);
      intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, (int)appWidgetIds[i]);
      Uri data = Uri.withAppendedPath(  Uri.parse("example" + "://widget/id/") ,String.valueOf(appWidgetId));
 intent.setData(data);
      PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

      RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget1);     
      String widgetName=PreferenceManager.getDefaultSharedPreferences(context).getString("widget"+(int)appWidgetIds[i],null);
      views.setTextViewText(R.id.widgetName,widgetName );
      views.setOnClickPendingIntent(R.id.widgetbutton, pendingIntent);
      appWidgetManager.updateAppWidget(appWidgetId, views);
    }
  }  
}
Finally, I will show the class SelectExample.  This class is called when the Widget is first added to the home screen.  Basically there is a simple GUI with a text field.  When the button is pressed, this class will save off the text in the TextField as the name to use for the widget.  Also, I go ahead and update the views in this class so the Widget is drawn correctly right away in case onUpdate is not called immediately.  It is important to set the result to RESULT_OK and return the widgetId in the result Intent.

package com.wetselsoftware.example.widgetexampleproject;


import android.app.Activity;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RemoteViews;

public class SelectExample extends Activity{

int mAppWidgetId=-1;
@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Intent intent = getIntent();
        Bundle extras = intent.getExtras();
        if (extras != null) {
            mAppWidgetId = extras.getInt(
                    AppWidgetManager.EXTRA_APPWIDGET_ID, 
                    AppWidgetManager.INVALID_APPWIDGET_ID);
        }
    }
@Override
public void onResume(){
super.onResume();
setUpGUI();
}
public void setUpGUI(){
setContentView(R.layout.selectexample);
Button select=(Button)findViewById(R.id.button1);
select.setOnClickListener(new SelectHandler());
}
                
        private class SelectHandler implements View.OnClickListener
        {
        public void onClick(View v)
        {
        EditText et=(EditText)findViewById(R.id.editText1);
        String textName=et.getText().toString();
       
        //now save off name in the prefences
        SharedPreferences settings = PreferenceManager
.getDefaultSharedPreferences(getBaseContext());
        SharedPreferences.Editor editor = settings.edit();
editor.putString("widget"+mAppWidgetId, textName);
editor.commit();
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(getBaseContext());
Intent intent = new Intent(getBaseContext(), WidgetExampleProjectActivity.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID , mAppWidgetId);
Uri data = Uri.withAppendedPath(  Uri.parse("example" + "://widget/id/") ,String.valueOf(mAppWidgetId));
     intent.setData(data);
   PendingIntent pendingIntent = PendingIntent.getActivity(getBaseContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
   
RemoteViews views = new RemoteViews(getBaseContext().getPackageName(), R.layout.widget1);
views.setOnClickPendingIntent(R.id.widgetbutton, pendingIntent);
views.setTextViewText(R.id.widgetName, textName);
appWidgetManager.updateAppWidget(mAppWidgetId, views);
Intent resultValue = new Intent();
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(RESULT_OK, resultValue);
finish();
        }
        }                
}

 So, all the pieces are here now.  You can download this example project here.

Tuesday, January 31, 2012

Programatically Adding Scrolling Multiple LinearLayouts In Android

 So, the other day I was working on a new App idea I have, and I was trying to learn how to add a dynamic number of LinearLayouts to an Activity that scrolled.  I couldn't find a really good example so after I finally pieced together how to do this, I decided I'd make a little tutorial.  This is my first blog EVER so here goes nothing.

First thing you will need to do, is create a ScrollView.  One thing you need to know about a ScrollView is that it can only have one main element.  So, you need to add a LinearLayout to the ScrollView, then all of your other LinearLayouts get added to that.  So, below is my code example on how to do this.  This will create 10 LinearLayouts with a button in each.  Also, at the end, I call setContentView(scrollView) instead of the default way an Activity is set up to use a layout Id.

public class DynamiclinearsActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ScrollView scrollView= new ScrollView(this);
        LinearLayout mainLayout = new LinearLayout(this);
        mainLayout.setOrientation(LinearLayout.VERTICAL);               
        for (int i=0; i<10; i++){
            LinearLayout ll = new LinearLayout(this);
            ll.setOrientation(LinearLayout.HORIZONTAL);
            ll.setTag(i);                           
            TextView tv=new TextView(this);
            tv.setText("Row " + i);           
            ll.addView(tv);
            Button b = new Button(this);
            b.setTag(i);
            b.setText("Button " + i);           
            ll.addView(b);                   
            mainLayout.addView(ll);
        }
        scrollView.addView(mainLayout);
        setContentView(scrollView);
    }
}

The output looks like this...