embedded linux ,android

2010年11月18日 星期四

一流點子,還是一流團隊?


一流點子,還是一流團隊?

撰文者:郭奕伶

如果你是一個領導者,資源有限,你要選擇一流的點子,還是一流的團隊? 我曾經以為,好點子最重要,即便執行力打折,都瑕不掩瑜。畢竟,執行力的效率,怎麼打得過創新的破壞力?

然而,在加州爾灣(Irvine),我們深入製作《魔獸世界》的秘密基地——暴雪娛樂(Blizzard Entertainment)後,我發現,答案並非如此。

這裡,應該是全世界最看重創意、最自由的地方,但一進到工作現場,昏暗、沉默、密密麻麻的會議時間表??。

他們,是一支紀律嚴明的軍隊,十五年來只出過三個系列的遊戲,卻款款熱賣逾十年,光一款《魔獸世界》,過去四年就進帳一千二百億元,去年淨利率是蘋果電腦(Apple)的兩倍。
想像一下,在《魔獸世界》裡,有一千四百個地點、三萬個物件、七千六百個冒險任務,而且它要用十一種語言發行,還要讓萬人同時上線互動、將全球玩家分級??。這裡頭,有多少細節?

「紀律,」創辦人兼總裁默罕(Michael Morhaime)解答,一切都奠基在「專注的紀律」。
故事,並非一開始就如此完美,草創初期,他們曾經貪心、曾經自負,甚至必須賣掉公司以換取生存,但「從回顧的角度看,我們發現,那些我們說『不』的決定,讓我們能聚焦在重要的事,」默罕將此稱為「專注的酷」(Concentrated Coolness)。
然而,誘惑從來不會停止。

尤其當一個人成功了,富有了,上門的試煉自然多了起來,決策難度也變高,所幸,這個組織的靈魂是「不斷的自我批判」,因此,即便後退兩步,下次還是會拉回正軌,再進個五步以上。一退一進、來回修正間,這家公司成為全球的線上遊戲王國。
所以,一流的點子重要,還是一流的執行團隊重要?

曾經,暴雪的數個天王級製作人出走,但最後都浮沉於世,再無驚人之作。這證明了,偉大的任務要完成,「要拿到最後的一○%,要花上比前面九○%更多的力氣。」默罕這麼說,而最後這一○%,就要靠一流團隊的執行力。

如果一定要選擇,我完全相信,一流的團隊能把二流的點子,執行到一流;但二流的團隊卻可能把一流的點子完全搞砸!

[轉]忘記會做微軟 不然就等死


反省篇PC大廠採購主管告白



忘記會做微軟  不然就等死



3年前台灣就啟動石減法革命,推出小筆電,遇上蘋果卻完全被取代。同樣的創意,為何台灣人就只能走上失敗?

林俊劭、林宏達



當台灣電子五哥金年上半年的獲利總和,第一次輸給傳產五哥的這一刻,台灣的電子代工業,正站在一個轉型的十字路口。三年前,當華碩推出第一台以簡便、快速上網為訴求的小筆電EeePC時,在市場上引起轟動,曾經每五秒賣出一台,刺激惠普(HP)、戴爾(Dell)等國際大廠跟進,被《富比世》(Forbes)雜誌評選為二OO八年年度的風雲產品。

然而,不到兩年的時間,小筆電又殺成一片紅海。現在,iPad問世半年後,卻產生天翻地覆的變化。小筆電,成了iPad出現後的主要犧牲者,看到iPad的出現,過去做小筆電的台灣業者,又開始了一窩蜂的平板電腦風潮,然而,這次能成功複製iPad平板電腦嗎?

「如果你的出發點是把Netbook(小筆電)做小,變成平板電腦,對不起,死路一條,你要想的是把smart phone(智慧型手機)做大。」


這是一位市值上千億的科技代工大廠,採購主管的告白。



他,在科技業資歷超過十年,從國內某品牌廠的研發工程師做起,經歷過台灣科技產業起飛的年代,看盡PC產業的興衰起伏,也曾主導過小筆電的研發與製造,如今手握千億採購金額,對於台灣電子業的結構有深刻觀察。

以下是他在前線的第一手觀察:

兩年前我就對Netbook不看好,我說這個東西是「曇花一現」、「falling star」,一個品牌多賣一台Netbook(小筆電),他就少(賣)一台Netbook(筆電),這是顯而易見的道理,多賣多死,revenue(營收)只有原來的三分之二,利潤更只有原來的三分之一。



「賣小筆電是虛的,賣越多死越慘」



Netbook至少還有兩萬塊,Netbook只要八千塊,淪落到外勞買來打skype回家的工具,這樣的市場你還留戀什麼?賣越多死越慘啊!表面上看來,這幫助他們把市占率提升,但這是虛的,對獲利沒有幫助啊!


小筆電剛出的時候,大家講說是第一年十五咪(編按:million,百萬台),第二年三十咪,第三年四十咪,再來馬上五年內就破百咪。大家是這樣想的,但去年三十四個咪,今年還會繼續衰退啊!


平板電腦今年是蠶食,明年是鯨吞!

iPad是硬體簡單,但豐富了應用軟體。兩年前的小筆電,是華碩發動的失敗的減法革命,當時以為這是個成功的減法革命,但是他同時減掉了軟體跟硬體。

平板是蘋果成功的減法革命,硬體減的更誇張,筆電七四七的噴射引擎,蘋果的CPU A4減到只剩下機車的引擎。


IPad為什麼可以待機七天還有電?因為它瘋狂了硬體,沒有USB孔,沒有讀卡機,也沒有耳機,只有一個連結器,但在軟體上它豐富得很啊!硬體上只有摩托,但上網比飛機還快,人們會appreciate這個東西。



「搞低價結果,傷敵七分自損三分」



小筆電當初出來的時候被稱為上網機,結果iPad上網速度比它快三倍!第一個實現微軟與英特爾夢想的竟然是蘋果,真諷刺!


兩年前小筆電是潘朵拉,打開的下場是所有人的ASP(平均單價)全部往下降,雖然有量但沒有價,七傷拳,傷敵七分,自損三分,多賣一台把敵人幹掉一台,但你同時傷了自己,高價格的筆電賣不掉啊!


小筆電曾經定義為你的第二台NB,但現在淪落為外勞的電話機,iPad的減法不是只是為了減而減,而是減了為了加,加快上網速度,加快閱讀資訊的方便性,這是減法才有意義。

對於小筆電占比很高的公司,那就是等死啊!


IPad的市場是多出來的,我估計三年後會成長到一億台,不會因此侵蝕到傳統NB的市場,它硬生生在智慧型手機與NB中間卡出了一個位置,這個位置是小筆電想要的。


整個產業沒有一個完整配套的solution跟它打,但是以後會不會起來?會啊!為什麼兩年前我說
小筆電必死?因為它進入障礙低啊!


台灣人的宿命,就只能賺組裝的錢,這是宿命啦!


你在某方面的成功會造成你在另一方面的失敗,這是經營者與主事者的心態要改變,如果心態再不轉過來,沒有破釜沈舟,以宏達電為例,他以前做PDA代工做得很成功,但如果一直顧著眼前的成功,沒有想到要轉,那就沒有今年的宏達電啦!現在也是一樣,當他發現Android才有未來的時候,就把微軟的工程師全都轉到Android,叫他們忘記「以前會做微軟」,不這樣就會死翹翹啊!


富士康還在想著以前最賺錢的時代是摩托羅拉V3的時代,所以轉不過來啊。

一個成功的平板電腦,硬體要簡單,但簡單反而難。一個長期做汽車的公司,你覺得它能馬上做五千CC的引擎,但你要他做出一台五十CC的,要減掉兩個零耶!英特爾做的CPU都必死,雙A(華碩、宏碁)研發能力再強,能馬上做出十萬個軟體來嗎?



從硬體轉軟體,最大問題在人才



從硬體走到軟體,說起來容易,但實際上卻困難重重,最大的問題在於人才的嚴重不足。

「台灣的軟體過去二十年都被微軟給慣壞了,只要修修改改,懂開發的不多,」一位曾擔任過美商軟體大廠高階主管,現任國內某代工大廠的軟體總監,很感概的表示:「過去二十年我們再怎麼努力,也不過培養了六百五十個(軟體)工程師,現在去大陸,一個月就可以訓練出一百個,外面還有五百個排隊在等。」


「在學校培養出來的人,台灣就是硬體製造,離軟體開發、雲端運算『很遠很遠很遠』,」他指出,以前國際大廠如戴爾等客戶來,都是談硬體的價格,但現在,來就直接問你「軟體(部門)有多少人?」這顯示軟體研發能力已成功當前科技業最主要的競爭力。


「當公司要從製造硬體,轉換到軟體和服務,現有的營運系統(台灣代工產業),並不熟悉如何操作這種新營運模式。」台大國企系教授李吉仁說。


他解釋,「電子代工產業擅長玩的是,有限利潤下進行成本減法的遊戲,」客戶給的資源是固定的,能從哪裡再多省一點,不管是供應商的利潤還是材料的採購成本,只要少一點,公司的成本就能再下降一點,這個遊戲,常常是零和的結果。


「服務的邏輯卻不是這樣,」以蘋果的App Store為例,蘋果要建成一個有影響力的平台,先考慮的卻是如何讓別人賺到錢。「這個『共利』的平台策略,值得台灣廠商思考。」李吉仁說。

「創新分兩種,技術創新和商業創新,」李吉仁分析。台灣廠商許多生產的know-how是自己培養出來的,蘋果卻相反,除了作業系統跟介面軟體,大部分內容和軟體都是市場上買得到的。 

再不改變,台灣電子業會有什麼影響?


「硬體代工不會滅亡,只是利潤越來越薄。」李吉仁下了這個結論。



摘自商業周刊第1191

android thread




ThreadDemo .java
package wandroide.blogspot.com;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.ProgressBar;
import android.widget.TextView;

import java.util.concurrent.atomic.AtomicBoolean;

public class ThreadDemo extends Activity 
{
    ProgressBar bar1 = null;
    ProgressBar bar2 = null;
    TextView    tv   = null;

    Handler handler=new Handler(){
 @Override
 public void handleMessage(Message msg) 
 {
     bar1.incrementProgressBy(5);
 }
    };

    Handler handler2=new Handler(){
 @Override
 public void handleMessage(Message msg) 
 {
     bar2.incrementProgressBy(-5);
 }
    };
   
    AtomicBoolean isRunning=new AtomicBoolean(false);
    AtomicBoolean isRunning2=new AtomicBoolean(false);

    @Override
    public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  tv   = (TextView)findViewById(R.id.tv);
  bar1 = (ProgressBar)findViewById(R.id.progressbar1);
  bar2 = (ProgressBar)findViewById(R.id.progressbar2);
    }

    public void onStart() 
    {
 super.onStart();
 bar1.setProgress(0);
 bar2.setProgress(100);
     
 Thread background=new Thread(new Runnable() 
 {
      public void run() 
      {
          try {
              for (int i=0;i<20 && isRunning.get();i++) 
              {
                  Thread.sleep(1000);
                  handler.sendMessage(handler.obtainMessage());
              }
          }
          catch (Throwable t) {
               // just end the background thread
          }
       }
  });
      
  Thread background2=new Thread(new Runnable() 
  {
      public void run() 
      {
          try {
              for (int i=0;i<20 && isRunning2.get();i++) 
              {
                  Thread.sleep(1000);
                  handler2.sendMessage(handler2.obtainMessage());
              }
          }
          catch (Throwable t) {
              // just end the background thread
          }
      }
   });

   isRunning.set(true);
   background.start();
       
   isRunning2.set(true);
   background2.start();
    }

    public void onStop() {
  super.onStop();
  isRunning.set(false);
  isRunning2.set(false);
    }
}

2010年11月16日 星期二

BCB thread

解ATE bug
thread跑完就結束了,不需要delete


unit2.h
#ifndef Unit2H
#define Unit2H
//---------------------------------------------------------------------------
#include <Classes.hpp>
//---------------------------------------------------------------------------
class TGridThread1 : public TThread
{
protected:
        void __fastcall Execute();
public:
        __fastcall TGridThread1(bool CreateSuspended);
};
//---------------------------------------------------------------------------
#endif
unit2.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit2.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
//   Important: Methods and properties of objects in VCL can only be
//   used in a method called using Synchronize, for example:
//
//      Synchronize(UpdateCaption);
//
//   where UpdateCaption could look like:
//
//      void __fastcall TGridThread1::UpdateCaption()
//      {
//        Form1->Caption = "Updated in a thread";
//      }
//---------------------------------------------------------------------------

__fastcall TGridThread1::TGridThread1(bool CreateSuspended)
        : TThread(CreateSuspended)
{
}
void __fastcall TGridThread1::Execute()
{
        //---- Place thread code here ----
}
uint1.cpp
#include 
#pragma hdrstop

#include "Unit1.h"
#include "Unit2.h"
#include "Unit3.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "CGAUGES"
#pragma resource "*.dfm"
TForm1 *Form1;
TGridThread1 *GridThread1;

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
    // Create the thread objects
    GridThread1 = new TGridThread1(true);

    // Initial setup for threads and buttons
    GridThread1->Resume();
}

資料儲存與Content Provider

在使用手機時,user需要儲存一些資訊,如果這些資訊是比較固定的,此時若能儲存起來,就可免去每次輸入這些資訊的手續,在android有三種資料儲存方式:
Shared Preferences(xml形式)、檔案儲存與資料庫儲存。
Android 並沒有一個共同的儲存空間讓所有應用程式存取,因此若要讓其它的應用程式使用我的資料,就必須使用Content Provider,用來分享資料用的。


DataStorageDemo.java
package wandroide.blogspot.com;

import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class DataStorageDemo extends Activity implements OnClickListener
{
    private TextView mTextView         = null;
    private EditText mEditText         = null;         
    private Button   mSharedPrefButton = null;
    private Button   mFileButton       = null;
    private Button   mSqliteButton     = null;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
           
        mTextView         = (TextView)findViewById(R.id.ltextview);
    mEditText         = (EditText)findViewById(R.id.ledittext);          
 mSharedPrefButton = (Button)findViewById(R.id.lsharedprefbutton);
 mFileButton       = (Button)findViewById(R.id.lfilebutton);
 mSqliteButton     = (Button)findViewById(R.id.lsqlitebutton);
      
 mSharedPrefButton.setOnClickListener(this);
 mFileButton.setOnClickListener(this);
 mSqliteButton.setOnClickListener(this);
    }
    
    public void onClick(View v) 
    {
 if(v == mSharedPrefButton)
 {
     //write
     SharedPreferences pref = getSharedPreferences("PREF_DATA", MODE_WORLD_READABLE);
       SharedPreferences.Editor preEdt = pref.edit();
       preEdt.putString("PREF_EDITTEXT", mEditText.getText().toString());
       preEdt.commit();
       //read
       String pref_edittext = pref.getString("PREF_EDITTEXT", "hello shared preference");
            mTextView.setText(pref_edittext);
       mEditText.setText("");
 }
 else if(v == mFileButton)
 {
     
 }
 else if(v == mSqliteButton)
 {
          
 }    
    }
}
ContentProviderDemo.java
package wnadroide.blogspot.com;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;

public class ContentProviderDemo extends Activity implements OnClickListener
{    
    private TextView mTextView              = null;
    private Button   mGetPrefButton         = null;
    private Button   mContentProviderButton = null;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        mTextView      = (TextView)findViewById(R.id.ltextview);
        mGetPrefButton = (Button)findViewById(R.id.lgetprefbutton);
        mContentProviderButton = (Button)findViewById(R.id.lcontentproviderbutton);
       
        mGetPrefButton.setOnClickListener(this);
        mContentProviderButton.setOnClickListener(this);
    }
  
    public void onClick(View v) 
    {
 if(v == mGetPrefButton)
        {
     Context otherApp = null;
     try {
      otherApp = createPackageContext("wandroide.blogspot.com", 0);
     } catch (Exception e) {
      Log.d("wandroide", e.toString());
      finish();
     }
     SharedPreferences pref = otherApp.getSharedPreferences("PREF_DATA",MODE_WORLD_READABLE);
     String pref_edittext = pref.getString("PREF_EDITTEXT", "get不到");
     mTextView.setText(pref_edittext);
 }
 else if(v == mContentProviderButton)
 {
     Cursor c = getContentResolver().query(Uri.parse("content://wade.dbprovider"),
                null, null, null, null);
         
     if(c.getCount() != 0) 
     {
         c.moveToFirst();
      String name = c.getString(c.getColumnIndex("name"));
      if ( name == null ) return;
      mTextView.setText(name);
     }
     
   }
    }
}
DBProvider.java
package wnadroide.blogspot.com;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;

public class DBProvider extends ContentProvider {
    Context mCtx;
    SQLiteDatabase db;

    @Override
    public int delete(Uri arg0, String arg1, String[] arg2) {
 return -1;
    }

    @Override
    public String getType(Uri uri) {
 return null;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
 return null;
    }

    @Override
    public boolean onCreate() {
 mCtx = getContext();
 DoDB dbHelper;
 dbHelper = new DoDB(mCtx);
 db = dbHelper.getWritableDatabase();
 return true;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
   String[] selectionArgs, String sortOrder) {
 Cursor c = db.rawQuery("select * from nametable;", null);
 return c;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection,
   String[] selectionArgs) {
 return 0;
    }
}
DoDB.java
package wnadroide.blogspot.com;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DoDB extends SQLiteOpenHelper {
    private final static String DATABASE_NAME = "namedb";
    private final static int DATABASE_VERSION = 1;
    private final static String TABLE_NAME = "nametable";
    public final static String FIELD_NAME = "name";
  
    public DoDB(Context context)
    {
        super(context, DATABASE_NAME, null, DATABASE_VERSION); 
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
 String sql = "CREATE TABLE " + TABLE_NAME + " (" + FIELD_NAME + ")";
 db.execSQL(sql);
 ContentValues cv = new ContentValues();
 cv.put(FIELD_NAME, "aaaaa");
 db.insert(TABLE_NAME, null, cv);
    }

    @Override
    public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
    }
 
    public Cursor select()
    {
 return null;
    }
}
AndroidManifest.xml
<provider android:name=".DBProvider" 
          android:authorities="wade.dbprovider">
</provider>

2010年11月15日 星期一

NAS110_88f6281




uboot env
===NAS110 PCBA nfs_boot:
setenv ipaddr '192.168.1.99'
setenv serverip '192.168.1.100'
setenv setconsole 'console=ttyS0,115200'
setenv setip 'ip=dhcp'
setenv setip 'ip=192.168.1.98'
setenv setnfs 'root=/dev/nfs nfsroot=192.168.1.100:/home/NAS110/rootfilesystem/rootfs'
setenv loadkernel 'tftpboot 0x200000 uImage.20090930'
setenv bootcmd '$(loadkernel);setenv bootargs $(setconsole) $(setip) $(setnfs);bootm 0x200000;'
saveenv

===NAS110 PCBA nand boot(mtd boot)
setenv mtdids 'nand0=nand_mtd'
setenv mtdparts 'mtdparts=nand_mtd:0x100000@0(uboot)ro,0x100000@0x100000(system1),0x100000@0x200000(system2),0x300000@0x300000(kernel)ro,0x700000@0x600000(RootFS)ro'
setenv bootcmd 'nand read 0x2000000 0x300000 0x300000 ;setenv bootargs $(console) $(mtdparts) rootfstype=squashfs root=/dev/mtdblock5;bootm 0x2000000;'
setenv console 'console=ttyS0,115200'
setenv ipaddr '192.168.1.99'
setenv serverip '192.168.1.100'
setenv bootargs ''

===NAS110 PCBA nand boot(ramdisk boot)
setenv loadimage ''
setenv setbootargs 'setenv bootargs console=ttyS0,115200 root=/dev/ram0 rootfstype=squashfs initrd=0x2000000,0x700000 ramdisk_size=7168'
setenv bootcmd 'nand read 0x800000 0x300000 0x300000;nand read 0x2000000 0x600000 0x700000;$(setbootargs);bootm 0x800000;'
setenv console 'console=ttyS0,115200'
setenv ipaddr '192.168.1.99'
setenv serverip '192.168.1.100'

===build squashfs
mksquashfs ./rootfs rootfs20090917

===load image
nand erase 0x300000 0x300000
tftpboot 0x1000000 uImage.20090930
nand write 0x1000000 0x300000 0x300000

nand erase 0x600000 0x700000
tftpboot 0x1000000 rootfs20090917.sqfs
nand write 0x1000000 0x600000 0x700000

===write uboot:
bubt u-boot-db88f6281abp_400db_nand_20090819.bin
bubt u-boot-db88f6281abp_400db_nand@20090821.bin
bubt u-boot-db88f6281abp_400db_nand-3.4.19@20090824.bin
bubt u-boot-db88f6281abp_400db_nand_20090826.bin
bubt u-boot-db88f6281abp_400db_nand_3.4.18_20090826.bin
bubt u-boot-db88f6281abp_3.4.19_nand@20090902.bin
bubt u-boot-db88f6281abp_400db_nand.bin
bubt u-boot-Foxlink-1GB.bin
bubt u-boot-1114.bin
bubt u-boot-20090915.bin
bubt u-boot-20090916.bin
bubt u-boot-20090917_2.bin
==========================================================================
==========================================================================
=====proware nand boot
nand erase  0x300000 0x300000
tftpboot  0x1000000 uImage.20090930
nand write  0x1000000 0x300000 0x300000

nand erase  0x600000 0x3500000
tftpboot  0x1000000 rootfs.squashfs_0930
nand write  0x1000000 0x600000 0x3500000

nand erase 0x3b00000 0x6b00000
tftpboot 0x1000000 dom_0930.img
nand write 0x1000000 0x3b00000 0x6b00000

setenv loadimage ''

setenv setbootargs  ‘setenv bootargs console=ttyS0,115200 rootfstype=squashfs initrd=0x2000000,0x3500000 ramdisk_size=128000’

setenv bootcmd  ‘nand read 0x800000 0x300000 0x300000;nand read 0x200000 0x600000 0x3500000;$(setbootargs);bootm 0x800000;’
bubt
Marvell>> setenv ipaddr '192.168.1.99'
Marvell>> setenv serverip '192.168.1.100'
Marvell>> bubt u-boot-db88f6281abp_400db_nand-3.4.19@20090824.bin
Using egiga0 device
TFTP from server 192.168.1.100; our IP address is 192.168.1.99
Filename 'u-boot-db88f6281abp_400db_nand-3.4.19@20090824.bin'.
Load address: 0x2000000
Loading: #################################################################
         ############################
done
Bytes transferred = 474036 (73bb4 hex)

**Warning**
If U-Boot Endiannes is going to change (LE->BE or BE->LE), Then Env parameters should be overriden..
Override Env parameters? (y/n) n
Erase 0 - 655360 ... 
Copy to Nand Flash... Failed write verify, nand offset 0x00000000. Suggest to erase block and repeat write ope!
 If problem persists suggest marking block as bad (nand markbad ) and repeating the operation!
writing NAND page at offset 0x0 failed
Data did not fit into device, due to bad blocks
Error - NAND burn faild!
build kernel
1. cd /home/NAS110/Kernel/linux-2.6.22.18
2. . ./set_path.sh
3. make mrproper
4. make mv88f6281_defconfig
5. make uImage (uImage會放在arch/arm/boot/)
6. cp ./arch/arm/boot/uImage /home/NAS110/images

2010年11月14日 星期日

App Widget




AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="wandroide.blogspot.com"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <receiver android:name=".MyAppWidget" android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>
            <meta-data android:name="android.appwidget.provider"
                        android:resource="@xml/myappwidget_provider" />
    </receiver>
    </application>
    <uses-sdk android:minSdkVersion="7" />
</manifest> 
main.xml
<?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:id="@+id/widget_textview"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
    />
</LinearLayout>
strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello World!</string>
    <string name="app_name">MyAppWidget</string>
</resources>
myappwidget_provider.xml
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:minWidth="146dip"
  android:minHeight="72dip"
  android:updatePeriodMillis="10000"
  android:initialLayout="@layout/main">
</appwidget-provider>
MyAppWidget.java
package wandroide.blogspot.com;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;
import android.content.ComponentName;
import android.content.Context;
import android.appwidget.AppWidgetProvider;
import android.appwidget.AppWidgetManager;
import android.widget.RemoteViews;

public class MyAppWidget extends AppWidgetProvider 
{
//====顯示widget 
 @Override
 public void onUpdate(Context context, AppWidgetManager appWidgetManager,
                       int[] appWidgetIds) 
 {
     Timer timer = new Timer();
     timer.scheduleAtFixedRate(new MyTime(context, appWidgetManager), 1, 1000);
 }
 
 private class MyTime extends TimerTask 
 {
     RemoteViews remoteViews;
     AppWidgetManager appWidgetManager;
     ComponentName thisWidget;
     DateFormat format = SimpleDateFormat.getTimeInstance(SimpleDateFormat.MEDIUM,
                            Locale.getDefault());
     public MyTime(Context context, AppWidgetManager appWidgetManager) 
      {
         this.appWidgetManager = appWidgetManager;
         remoteViews = new RemoteViews(context.getPackageName(), R.layout.main);
         thisWidget = new ComponentName(context, MyAppWidget.class);
      }
     
     @Override
     public void run() 
      {
         remoteViews.setTextViewText(R.id.widget_textview,
                       "Time = " + format.format(new Date()));
         appWidgetManager.updateAppWidget(thisWidget, remoteViews);
      }
 }
}

Android Service , aidl 與 Broadcast Receiver

什麼是service
沒有UI的程式,在背景執行的Process
啟動service的方式
1. startService(),stopService()
啟動 onCreate() --> onStart()
結束 onDestory()
若沒有StopService()則會繼續執行下去
2. bindService(),unbindService()
啟動onCreate() --> onBind()
結束onUnBind() --> onDestory()
啟動已執行起來的service,當然也可以啟動未執行起來的service
兩種方式可以混用,但必須stopService()且unbindService()才真正結束service


























demo code

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.wandroid.servicedemo"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".ServiceDemo"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name=".xxxService" android:exported="true"></service>
        <service android:name=".xxxRemoteService" android:process=":remote"/>
        <receiver android:name="xxxBroadcastReceiver">
           <intent-filter>
                 <action android:name="com.wandroid.servicedemo.Play_MUSIC"/>
         </intent-filter> 
      </receiver>
    </application>
    <uses-sdk android:minSdkVersion="7" />
</manifest> 
res/layout/main.xml
<?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:id="@+id/text"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
    />
<Button
  android:id="@+id/startservice"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:text="startService"
 />
<Button
  android:id="@+id/stopservice"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:text="stopService"
 />
<Button
  android:id="@+id/bindservice"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:text="bindService"
 />
<Button
  android:id="@+id/unbindservice"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:text="unbindService"
 />
<TextView  
    android:id="@+id/remotetext"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/remotehello"
    /> 
<Button
  android:id="@+id/remotebindservice"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:text="remote bindService"
 /> 
<Button
  android:id="@+id/remoteunbindservice"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:text="remote unbindService"
 />  
<Button
  android:id="@+id/musicbroadcast"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:text="music broadcast"
 /> 
</LinearLayout>
res/raw/music.mp3 res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello World, ServiceDemo!</string>
    <string name="app_name">ServiceDemo</string>
    <string name="remotehello">Hello World,Remote ServiceDemo!</string>
</resources>
ServiceDemo.java
package com.wandroid.servicedemo;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class ServiceDemo extends Activity implements OnClickListener
{   
 private xxxService        mxxxService              = null;
 private IxxxRemoteService mxxxRemoteService        = null;
 private TextView          mTextView                = null;
 private TextView          mremoteTextView           = null;
 private Button            startServiceButton       = null;
 private Button            stopServiceButton         = null;
 private Button            bindServiceButton        = null;
 private Button            unbindServiceButton       = null;
 private Context           mContext                  = null;
 private Button            remotebindServiceButton   = null;
 private Button            remoteunbindServiceButton = null;
 private Button            musicbroadcastButton      = null;
 
 //ServiceConnection在bind時建立連線
 private ServiceConnection mServiceConnection = new ServiceConnection() 
 { 
  public void onServiceConnected(ComponentName name, IBinder service) 
  {
   if( name.getClassName().compareTo
                            ("com.wandroid.servicedemo.xxxService") == 0 )
   {
       //===local service
       mxxxService = ((xxxService.xxxBinder)service).getService();
       try {
     mTextView.setText("I am frome Service :"+                 
                                              Integer.toString(mxxxService.sum(5, 5)));
       } catch (RemoteException e) {
     e.printStackTrace();
       }
   }
   else
   {
       //===remote service
              mxxxRemoteService =  IxxxRemoteService.Stub.asInterface(service);
       try {
    mremoteTextView.setText("I am frome remote Service :"+
                                     Integer.toString(mxxxRemoteService.sumabc(5, 5, 5)));    
       } catch (RemoteException e) {
            e.printStackTrace();
       }
   }
  }
  
  public void onServiceDisconnected(ComponentName name) 
  {
   if(mxxxService != null)
   {
       mxxxService = null;
   }
   else
   {
       mxxxRemoteService = null;
   }
  }
 };
//activity=======   
 public void onCreate(Bundle savedInstanceState) 
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
     
            mContext              = ServiceDemo.this;
         mTextView             = (TextView)findViewById(R.id.text);
         mremoteTextView       = (TextView)findViewById(R.id.remotetext);
         startServiceButton    = (Button)findViewById(R.id.startservice);
         stopServiceButton     = (Button)findViewById(R.id.stopservice);
         bindServiceButton     = (Button)findViewById(R.id.bindservice);
         unbindServiceButton   = (Button)findViewById(R.id.unbindservice);
         remotebindServiceButton   = (Button)findViewById(R.id.remotebindservice);
         remoteunbindServiceButton = (Button)findViewById(R.id.remoteunbindservice);
         musicbroadcastButton      = (Button)findViewById(R.id.musicbroadcast);
          
         startServiceButton.setOnClickListener(this);
         stopServiceButton.setOnClickListener(this);
         bindServiceButton.setOnClickListener(this);
         unbindServiceButton.setOnClickListener(this);
         remotebindServiceButton.setOnClickListener(this);
         remoteunbindServiceButton.setOnClickListener(this);
         musicbroadcastButton.setOnClickListener(this);
        }
   
 public void onClick(View v) 
 {
  if(v == startServiceButton)
  {
   Intent i  = new Intent();
   i.setClass(ServiceDemo.this, xxxService.class);
   mContext.startService(i);
  }
  else if(v == stopServiceButton)
  {
   Intent i  = new Intent();
   i.setClass(ServiceDemo.this, xxxService.class);
   mContext.stopService(i);
  }
  else if(v == bindServiceButton)
  {
   Intent i  = new Intent();
   i.setClass(ServiceDemo.this, xxxService.class);
   mContext.bindService(i, mServiceConnection, BIND_AUTO_CREATE);
  }
  else if(v == unbindServiceButton)
  {
   if( mServiceConnection != null)
   {
       mContext.unbindService(mServiceConnection);
   }
  }
  else if(v == remotebindServiceButton)
  {
   Intent i  = new Intent();
   i.setClass(ServiceDemo.this, xxxRemoteService.class);
   mContext.bindService(i, mServiceConnection, BIND_AUTO_CREATE);
  }
  else if(v == remoteunbindServiceButton)
  {
   if( mServiceConnection != null)
   {
       mContext.unbindService(mServiceConnection);
       mremoteTextView.setText("");
   }
  }
  else if(v == musicbroadcastButton)
  {
    Intent i  = new Intent();
    i.setAction("com.wandroid.servicedemo.Play_MUSIC");
    sendBroadcast(i);
  }
 }  
}
xxxService.java
package com.wandroid.servicedemo;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

public class xxxService extends Service 
{
 private static final String TAG = "xxxService";
 
 //bindService()時,建立connection用
 public class xxxBinder extends Binder
 {
     xxxService getService()
     {
  Log.e(TAG, "===getService()===");
  return xxxService.this;
     }
 }

 private xxxBinder mxxxBinder = new xxxBinder();
 
 @Override
 public IBinder onBind(Intent intent) 
        {
  Log.e(TAG, "===onBind===");
  return mxxxBinder;
 }

 @Override
 public boolean onUnbind(Intent intent) 
        {
  Log.e(TAG, "===onUnbind===");
  return super.onUnbind(intent);
 }

//===由startService啟動只會用到以下三個 
 @Override
 public void onCreate() 
        {
  Log.e(TAG, "===onCreate===");
  super.onCreate();
 }
 
 //由bindService啟動,就沒有onStart()
 @Override
 public void onStart(Intent intent, int startId) 
        {
  Log.e(TAG, "===onStart===");
  super.onStart(intent, startId); 
 }
 
 @Override
 public void onDestroy() 
        {
  Log.e(TAG, "===onDestroy===");
  super.onDestroy();
 } 
//service function==== 
 public int sum(int a, int b) throws RemoteException 
 {
  Log.e(TAG, "===sum()===");
  return a+b;
        }
}
xxxRemoteService.java
package com.wandroid.servicedemo;

import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

public class xxxRemoteService extends Service 
{
 private static final String TAG = "xxxRemoteService";
 private MediaPlayer  mp         = null;
 
 private final IxxxRemoteService.Stub binder= new IxxxRemoteService.Stub()
 {    
            public int sumabc(int a, int b, int c) throws RemoteException 
     {
  Log.e(TAG, "===remote sumabc()===");
                mp = MediaPlayer.create(xxxRemoteService.this, R.raw.music);
                mp.start();
  return a+b+c;
            }
 };
 
 @Override
 public IBinder onBind(Intent arg0) 
 {
     Log.e(TAG, "===remote onBind()===");
            return this.binder; 
 }
 
 @Override
 public boolean onUnbind(Intent intent) 
        {
     Log.e(TAG, "===remote onUnbind()===");
     mp.stop();  
     return super.onUnbind(intent);
 }

//===由startService啟動只會用到以下三個 
 @Override
 public void onCreate() 
        {
     Log.e(TAG, "===remote onCreate()===");
     super.onCreate();
 }
 
 //由bindService啟動,就沒有onStart()
 @Override
 public void onStart(Intent intent, int startId) 
        {
  Log.e(TAG, "===remote onStart()===");
  super.onStart(intent, startId); 
 }
 
 @Override
 public void onDestroy() 
        {
  Log.e(TAG, "===remote onDestroy()===");
  mp.release();
  super.onDestroy();
 } 
}
IxxxRemoteService.aidl
package com.wandroid.servicedemo;

interface IxxxRemoteService 
{
   int sumabc(int a, int b,int c);
}
xxxBroadcastReceiver.java
package com.wandroid.servicedemo; 
  
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
  
public class xxxBroadcastReceiver extends BroadcastReceiver 
{ 
    private static final String TAG = "xxxBroadcastReceiver";
  
    private IxxxRemoteService mxxxRemoteService = null;
  
    private ServiceConnection mServiceConnection = new ServiceConnection() 
    { 
 public void onServiceConnected(ComponentName name, IBinder service) 
 {
     mxxxRemoteService =  IxxxRemoteService.Stub.asInterface(service);
     try {
  mxxxRemoteService.sumabc(5, 5, 5);    
     } 
            catch (RemoteException e) 
            {
         e.printStackTrace();
            }
 }
   
 public void onServiceDisconnected(ComponentName name) 
 {
     mxxxRemoteService = null;
 }
    };
  
    @Override
    public void onReceive(Context context, Intent intent) 
    {
 Log.e(TAG, "===onReceive()===");
 if(intent.getAction().equals("com.wandroid.servicedemo.Play_MUSIC"))
 {
     Intent i  = new Intent();
     //i.setClass(context, xxxRemoteService.class);
     //context.bindService(i, mServiceConnection, BIND_AUTO_CREATE);
     i.setClass(context, xxxService.class);
     context.startService(i);
 }
    }
}