Thursday, August 19, 2010

Miscellaneous Tips

How to stretch a control?

Set Layout_weight to greater than 0

image

image

 

Issue with Check box in a list view

When I use anything other than textview in a listview, the context menu stop working. Now to have a check box in a list view, I have to use CheckedTextView. But the text in CheckedTextView appears on the left side of the checkbox. I don’t know how to change it, so I use a CheckedTextView with no text and a TextView.

 

Show checkbox in CheckedTextView

<CheckedTextView android:id="@+id/categoryCheckedTextView"
android:layout_width="wrap_content"
android:checkMark="?android:attr/listChoiceIndicatorMultiple"
android:layout_height="wrap_content"
android:clickable="true">
</CheckedTextView>


Display simple MessageBox in Android



AlertDialog alertDialog;
alertDialog = new AlertDialog.Builder(this).create();
alertDialog.setTitle("Packing List");
alertDialog.setMessage("Could not find the file.");
alertDialog.show();

 


Change emulator orientation


Use KEYPAD_7 or KEYPAD_9 on you desktop. You need to turn off your Num Lock.



Dynamically change the background color


To dynamically change the background color, use myView.setBackgroundResource(R.color.my_color) instead myView.setBackgroundColor(R.color.my_color)

 


How to align text in text view?

When trying to align the text to the right in text , set the “layout_gravity” to right doesn’t work. Need to set “gravity” to right.

Friday, August 13, 2010

Avoid Polluting SharePoint farm

A developer can easily pollute a SharePoint farm by exposing components to unintended audience as the following.

  1. In MOSS, you cannot target a feature to a specific site, site collection or web application. A deployed feature is visible to SharePoint administrators everywhere in the SharePoint Farm even though the feature should be used in a very specific context.
  2. Deploying a Dll to GAC makes the Dll fully trusted and accessible to the entire server. Any code running on the server may use the Dll.
  3. A user control deployed to the ControlTemplates directory can be used by any ASP.NET components deployed to the farm.
  4. An application page deployed to the Layouts directory is visible to end users from any SharePoint site in the Farm. Most importantly, you cannot manage the security permission on the Page easily. The page will observe the default security permission for all the pages in Layouts directory. Also, the code behind dll for an application page has to have full trust since everything in Layout has full trust. This violates the basic security principle.

Item 4 will do the most damage since end users will see the pollution right way and it is not easy to apply security to the page to fix it. Item 1 will only affect SharePoint administrators. Item 2 and 3 will affect developers and infrastructure team.

However, Item 4 is the least aware among developers since it is just so easy.

An alternative to create an application page is to deploy the page to a document library in the site needing the page. Because it is in a document library, you can apply different security policies to the page. So only the right people can access the page with the right permissions. Also, the code behind dll of it can be deployed to bin directory without full trust since it is not in Layouts directory. Obviously, this approach solves all the issues listed in Item 4.

Wednesday, August 11, 2010

ComponentOne 2.x upgrade issues

We  have been using ComponentOne 1.x for quite some time. We used C1PrintDocument to merge some RTF templates and generate PDF document. Recently we planed to upgrade our server to 64-bit machine. When we tested out the ComponentOne PDF generation code, we kept getting "Attempted to read or write protected memory. This is often an indication that other memory is corrupt" error. After upgrade to ComponentOne 2.x, that issue is gone. However, we ran into several other issues. When I re-compile the code after the upgrade, a lot of syntax do not work anymore. Some of them are easy to fix, but some of the deprecated functions are not that easy to replace since they no longer exist in the package. There are the changes I want to document here:

1. "Page [@@PageNo@@] of [@@PageCount@@]"

If you have used the code above, you have to add the following code now in order to use them:

c1PrintDocument1.TagOpenParen = "[@@";
c1PrintDocument1.TagCloseParen = "@@]";



2. Table border style



from:




RenderTable headerTable = new RenderTable(c1PrintDocument1);
headerTable.Style.Borders.AllEmpty = true;
headerTable.StyleTableCell.BorderTableHorz.Empty = true;
headerTable.StyleTableCell.BorderTableVert.Empty = true;



to:




RenderTable headerTable = new RenderTable(c1PrintDocument1);
headerTable.Style.Borders.All = LineDef.Empty;
headerTable.Style.GridLines.All = LineDef.Empty;



3. Page Header/Footer



from:




c1PrintDocument1.PageHeader.RenderObject = headerTable;



to:




c1PrintDocument1.PageLayouts.Default.PageHeader = headerTable;



4. Check remaining space



from:




RenderRichText obj = new RenderRichText(c1PrintDocument1);
obj = ...;
if (c1PrintDocument1.AvailableBlockFlowHeight < c1PrintDocument1.MeasureBlock(obj).Height)
c1PrintDocument1.NewPage();



to:




RenderRichText obj = new RenderRichText(c1PrintDocument1);
SizeD objSize = obj.CalcSize("2in", "auto");
if (c1PrintDocument1.AvailableBlockFlowHeight < objSize.Height)
c1PrintDocument1.NewPage();

Monday, August 9, 2010

Re-import Android project issue

After my laptop crashes, I have to re-install everything. After importing the existing projects, I got the following error “The method onClick(DialogInterface, int) of type new DialogInterface.OnClickListener(){} must override superclass method”

image

And this is what I found on google:

Eclipse is defaulting to Java 1.5 and you have classes implementing interface methods (which in Java 1.6 can be annotated with @Override, but in Java 1.5 can only be applied to methods overriding a superclass method).

Go to your project/ide preferences and set the java compiler level to 1.6 and also make sure you select JRE 1.6 to execute your program from eclipse.

image

How to debug on device?

For detail information, go to - http://developer.android.com/guide/developing/device.html. The following is a simplified version for my own reference.

1. Declare your application as "debuggable" in your Android Manifest.

In Eclipse, you can do this from the Application tab when viewing the Manifest (on the right side, set Debuggable to true). Otherwise, in the AndroidManifest.xml file, add android:debuggable="true" to the <application> element.

2. Turn on "USB Debugging" on your device.

On the device, go to the home screen, press MENU, select Applications > Development, then enable USB debugging.

3. Setup your system to detect your device.

If you're developing on Windows, you need to install a USB driver for adb. See the Windows USB Driver documentation.

image

ClassNotFound exception when unmarshalling

The following code is the serialization part of the Category class in PackingList project. Since the category has an arraylist of items, I have to put it in Bundle. To de-serialize it, I need to retrieve items from the Bundle. To do that, I was using Bundle d = in.readBundle(). However, I received “ClassNotFound exception when unmarshalling”. I have to pass in the ClassLoader so it knows it’s for the Item.

 

@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(category);
Bundle b = new Bundle();
b.putParcelableArrayList("items", items);
dest.writeBundle(b);

}

public static final Parcelable.Creator<Category> CREATOR =
new Parcelable.Creator<Category>() {
public Category createFromParcel(Parcel in) {
Category category = new Category();
category.category = in.readString();
Bundle b = in.readBundle(Item.class.getClassLoader());
category.items = b.getParcelableArrayList("items");

return category;
}

@Override
public Category[] newArray(int size) {
return new Category[size];
}
};

How to display progress dialog?

private ProgressDialog dialog;
public void onCreate(Bundle savedInstanceState) {
……

dialog = ProgressDialog.show(this, "",
"Loading Calendar and Tasks. Please wait...", true);

……
CalendarThread calendarThread = new CalendarThread();
calendarThread.start();

}

private class CalendarThread extends Thread {

@Override
public void run() {
//Long running process
……

handler.sendEmptyMessage(0);
}

private Handler handler = new Handler() {

@Override
public void handleMessage(Message msg) {
//Process after the long running process
……
dialog.dismiss();
}
};
}