Wednesday, 6 October 2010

iPhone/iPad Top Apps on Web

iPhone iPad pictureOne thing I think the whole iPhone/iPad ecosystem lacks, is a really good web site for browsing apps. I don't know what anyone else thinks, but the iTunes store UI pretty much sucks.



Well to acknowledge a step in the right direction, it looks like Apple has added the top 100 paid and free apps to its web site. Nice! More of the same please Apple.



Top 100 Free Apps

Top 100 Paid Apps

Tuesday, 5 October 2010

Setting up a Mac 01: Initial Steps

OS X pictureThese steps are performed before doing any software installation or any real setup steps.



First, just turn on the machine. Choose your language, time zone and all that fun stuff. When prompted for select a user id, I recommend using something other than your first and last name for your account. It takes too long to type and its not all that secure.



Once everything boots up, select Software Update from the Apple menu. This should get the patching process started. Running this command one or two times should get you up to date. After this, you should be ready to start installing software.



One thing I ran into with the 17 MacBook Pro was the 1600 x 1200 screen resolution. Although this is great for screen real estate, the default font sizes were not so great for my 40 year old eyes. Very tiny. Amazingly, there is no way to change the default system font size in OS X 10.6 Snow Leopard. However, there is a work around. Check out TinkerTool. This is a simple app that allows you to change most of the system fonts for your account. However, it does not work on all of them.



One other tip. Because of the resolution issue, I'm zooming in and out of web pages a lot. This can be done on a Mac by pressing Command + and Command - to zoom in and out respectively.

Notes on updatePeriodMillis in Home App Widget

updatePeriodMillis in Widget Provider Information XML file define How often, in milliseconds, that this AppWidget wants to be updated. The AppWidget manager may place a limit on how often a AppWidget is updated.

If you tried and run the exercise in "A simple Home Screen App Widget with configure activity", it can be noted that:


- The updatePeriodMillis attribute defines how often the App Widget framework should request an update from the AppWidgetProvider by calling the onUpdate() method. The actual update is not guaranteed to occur exactly on time with this value. Refer "App Widget using Alarm Manager" to implement App Widget with higher rate.

- Updates requested with updatePeriodMillis will not be delivered more than once every 30 minutes.

- Only one updatePeriodMillis schedule will be managed for all instances of the App Widget. For example, if the update schedule is defined to be every two hours, and a second instance of the App Widget is added one hour after the first one, then they will both be updated on the period defined by the first one and the second update period will be ignored (they'll both be updated every two hours, not every hour).

Setting Up a New Machine Series

Internet IconI recently purchased a new MacBook Pro 17inch with a matte finish to use as my primary work machine. So over the next few days or weeks, I'm going to be posting on topics related to the setup of the machine.



Since OS X 10.6 comes with Bootcamp, not only can the setup of OS X be covered, but also the setup of Windows 7. So its like two for one. :)



Well I hope you enjoy it. More posts to come.

Monday, 4 October 2010

Ever want to Customize VIM?

Linux LogoHave you ever wanted to customize VIM but you have no idea where to begin? Check out: How I boosted my VIM



It will at least give you an idea of what you can do.

Sunday, 3 October 2010

TinyUmbrella New UI - Status Update

Sorry for the delays folks :) I've been trying to balance work, life, this, and our (Chronic-Dev Team) jailbreak. I've been trying to help out a bit with the team when possible so I've somewhat neglected my TinyUmbrella UI implementation. That said, @iOPK put together some awesome icons for me to use in TinyUmbrella for device detection/recent devices. Have a peek. I'm also going to be adding Socks / HTTP Proxy support for those few of you that have asked for it :)

A simple Home Screen App Widget with configure activity

In the former article "A simple Home Screen App Widget to get Date/Time", we have a very minimal widget: simple self-described as a widget with update duration, then update the widget with current time. In the exercise, no configure activity have been defined; such that the update() method of the provider activity will be call when add the widget in home screen, and when update period is reached.

In this exercise, a configure activity wil be implemented; the onCreate() method of the configure activity will be called when the widget is added on home screen. And also, the onUpdate() method of the HelloWidgetProvider cass (extends AppWidgetProvider) will be modified to handle each appWidgetIds separately.

configure activity
The simple Home Screen App Widget

Modify onUpdate() of HelloWidgetProvider.java, and implemented updateAppWidget() method which will be called by onUpdate() and the new added configure activity.

onUpdate() includes a loop that iterates through each entry in appWidgetIds, which is an array of IDs that identify each App Widget created by this provider. In this way, if the user creates more than one instance of the App Widget, then they are all updated simultaneously.
package com.exercise.HelloWidget;

import java.text.SimpleDateFormat;
import java.util.Date;

import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.widget.RemoteViews;
import android.widget.Toast;

public class HelloWidgetProvider extends AppWidgetProvider {

private static SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy hh:mm:ss a");
static String strWidgetText = "";

@Override
public void onDeleted(Context context, int[] appWidgetIds) {
// TODO Auto-generated method stub
//super.onDeleted(context, appWidgetIds);
Toast.makeText(context, "onDeleted()", Toast.LENGTH_LONG).show();
}

@Override
public void onDisabled(Context context) {
// TODO Auto-generated method stub
//super.onDisabled(context);
Toast.makeText(context, "onDisabled()", Toast.LENGTH_LONG).show();
}

@Override
public void onEnabled(Context context) {
// TODO Auto-generated method stub
//super.onEnabled(context);
Toast.makeText(context, "onEnabled()", Toast.LENGTH_LONG).show();
}

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
// TODO Auto-generated method stub
super.onUpdate(context, appWidgetManager, appWidgetIds);

final int N = appWidgetIds.length;
for (int i=0; i<N; i++) {
int appWidgetId = appWidgetIds[i];
updateAppWidget(context, appWidgetManager, appWidgetId);

Toast.makeText(context, "onUpdate(): " + String.valueOf(i) + " : " + String.valueOf(appWidgetId), Toast.LENGTH_LONG).show();
}

}

public static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId){
String currentTime = formatter.format(new Date());
strWidgetText = currentTime;

RemoteViews updateViews = new RemoteViews(context.getPackageName(), R.layout.hellowidget_layout);
updateViews.setTextViewText(R.id.widgettext, "[" + String.valueOf(appWidgetId) + "]" + strWidgetText);
appWidgetManager.updateAppWidget(appWidgetId, updateViews);

Toast.makeText(context, "updateAppWidget(): " + String.valueOf(appWidgetId) + "\n" + strWidgetText, Toast.LENGTH_LONG).show();

}

}


Implement /res/layout/config.xml which is the layout of the configure activity
<?xml version="1.0" encoding="utf-8"?>
<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:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<Button
android:id="@+id/okconfig"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="OK"
/>
</LinearLayout>


Implement the configure activity, HelloWidgetConfig extends Activity. Actually, it do nothing except prompt the user to click on the OK button.
package com.exercise.HelloWidget;

import android.app.Activity;
import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class HelloWidgetConfig extends Activity {

Button configOkButton;
int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);

setResult(RESULT_CANCELED);

setContentView(R.layout.config);

configOkButton = (Button)findViewById(R.id.okconfig);
configOkButton.setOnClickListener(configOkButtonOnClickListener);

Intent intent = getIntent();
Bundle extras = intent.getExtras();
if (extras != null) {
mAppWidgetId = extras.getInt(
AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
}

// If they gave us an intent without the widget id, just bail.
if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
finish();
}
}

private Button.OnClickListener configOkButtonOnClickListener
= new Button.OnClickListener(){

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub

final Context context = HelloWidgetConfig.this;

AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);

//RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.hellowidget_layout);
//appWidgetManager.updateAppWidget(mAppWidgetId, views);
HelloWidgetProvider.updateAppWidget(context, appWidgetManager, mAppWidgetId);

Toast.makeText(context, "HelloWidgetConfig.onClick(): " + String.valueOf(mAppWidgetId) , Toast.LENGTH_LONG).show();

Intent resultValue = new Intent();
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(RESULT_OK, resultValue);
finish();
}};

}


Modify hellowidgetproviderinfo.xml to include android:configure="com.exercise.HelloWidget.HelloWidgetConfig"
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="72dp"
android:minHeight="72dp"
android:updatePeriodMillis="1800000"
android:initialLayout="@layout/hellowidget_layout"
android:configure="com.exercise.HelloWidget.HelloWidgetConfig"
>
</appwidget-provider>


Modify AndroidManifest.xml to add HelloWidgetConfig as a activity with intent-filter of "android.appwidget.action.APPWIDGET_CONFIGURE".
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.exercise.HelloWidget"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<receiver android:name="HelloWidgetProvider" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/hellowidgetproviderinfo" />
</receiver>
<activity android:name=".HelloWidgetConfig"
android:label="Hello Widget Config">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="7" />

</manifest>


Download the files.

Related Article:
- Notes on updatePeriodMillis in Home App Widget
- App Widget using Alarm Manager

Reference: Android Developers - App Widgets