public class BaseActivity extends FragmentActivity {
	static final int LOGIN_REQUEST = 1;	
	static final int OPEN_TAOBAO = 2;	

	private long lastPressback = 0;
	protected final int TOAST_MSG = 2;
	protected FmeiClient client = null;
	protected boolean isRunning = false;
	protected ProgressDialog loading = null;
	
	//处理一个蛋疼的问题。回复Tab状态和
	protected int tabIndex = -1;
	
    protected Handler handler = new Handler(){
    	
    	public void handleMessage(final Message msg) {
    		String message = null;
    		if(msg.what == TOAST_MSG && msg.obj != null){
    			message = msg.obj.toString();
    			if(message != null){
    				Toast.makeText(BaseActivity.this, message, Toast.LENGTH_SHORT).show();
    			}
    		}
    	}

    };
    
	protected void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
        client = FmeiClient.getInstance(this, false);         
	}
	
    protected void onResume (){
    	super.onResume();
    	StatService.onResume(this);
    	isRunning = true;
    	client.appImgLoader.clear();
    	MainTabActivity tab = (MainTabActivity)this.getParent();    	
    	if(tab != null){
    		if(tabIndex < 0){
    			tabIndex = tab.tabHost.getCurrentTab();
    			Log.d("emop", "save cur tab index:"  + tabIndex);
    		}else {
    			Log.d("emop", "update tab to:"  + tabIndex);
    			tab.activeTab(tabIndex);
    		}
    	}    	
    }
    
    protected void onPause (){
    	super.onPause();
    	StatService.onPause(this);
    	isRunning = false;
    }
    
    protected void showToast(String msg){
    	Message obj = handler.obtainMessage(TOAST_MSG, msg);
    	handler.sendMessage(obj);
    }
    
    public void onBackPressed() {
    	Log.d(com.emop.client.Constants.TAG_EMOP, "on back pressed  on base view");
    	
    	if(this.getParent() == null){
    		finish();
    	}else { // in Tab
        	if(System.currentTimeMillis() - this.lastPressback > 3000){
        		this.lastPressback = System.currentTimeMillis(); 
        		Toast.makeText(this,"再按一次退出!", Toast.LENGTH_SHORT).show();
        	} else {
        		finish();
        	}
    	}
    	
		return;
    }
    
    public void doFinish(View v){
    	onBackPressed();
    }
    
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
        	//Log.d(com.taidian.lookmash.Constants.TAG_FMEI, "on key pressed  on base view");
        	onBackPressed();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
    
    public void doLogin(View v){
		Intent intent = new Intent();			
		intent.setClass(this, LoginActivity.class);
		this.startActivityForResult(intent, LOGIN_REQUEST);    	
    }
    
	public void onFinish(View v){
		finish();
	}
	
	public void startActivityView(int viewId, Uri data, Bundle param){
		Intent intent = new Intent();			
		intent.setClass(this, MutilFragmentActivity.class);	
		
		intent.putExtra("view_id", new int[]{viewId});
		if(param != null){
			intent.putExtras(param);
		}
		if(data != null){
			intent.setData(data);
		}
		
		startActivity(intent);	
	}
	
	public void showLoading(String msg){
    	if(loading == null){
            loading = new ProgressDialog(this);
            loading.requestWindowFeature(Window.FEATURE_NO_TITLE);
    	}
    	loading.setMessage(msg);    		
    	loading.show();		
	}
	
	public void closeLoading(){
		if(loading != null && loading.isShowing()){
			loading.cancel();
		}
	}
	
	public boolean isLoading(){
		return loading != null && loading.isShowing();
	}
}
 public class Constants {
	public static final String APP_ID = "";
	public static final String TAG_EMOP = "emop";
	
	public static final String PREFS_NAME = "taodianhuo_perfs";
	
	public static final String PREFS_OAUTH_ID = "fmei_user_id";
	public static final String PREFS_TRACK_ID = "track_user_id";
	
	public static final String PREFS_SINA_ACCESS_TOKEN = "sina_access_token";
	public static final String PREFS_SINA_EXPIRES_IN = "sina_expires_in";
	
	public static final String PREFS_SINA_UID = "sina_uid";
	public static final String PREFS_SINA_NICK = "sina_nick";	
	
	public static final String PREFS_TAOBAO_UID = "taobao_uid";
	public static final String PREFS_TAOBAO_NICK = "taobao_nick";	

	public static final String PREFS_QQ_UID = "qq_uid";
	public static final String PREFS_QQ_NICK = "qq_nick";	

	public static final String PREFS_SINA_FRIENDS = "sina_friends";
	
	public static final String WEB_LINK = "http://taodianhuo.sinaapp.com/weixin/app/%s/%s/%s";
	public static final String WEB_SHOP_LINK = "http://taodianhuo.sinaapp.com/weixin/app_shop/%s/%s/%s";

	
	public static final String TAOBAO_APPID = "21354558";
	public static final String TAOBAO_APPKEY = "c98beaf78fe3d66e69461a1e33724755";
	public static final String SINA_APPID = "746315760";
	public static final String SINA_APPKEY = "8f4f1311a7de7edb3ff4a1f059ead530";
	public static final String SINA_CALLBACK = "https://api.weibo.com/oauth2/default.html";
	
	
	public static final String AUTH_REF_SINA = "sina";
	public static final String AUTH_REF_TAOBAO = "taobao";
	public static final String AUTH_REF_QQ = "qq";

	
}
 public class WebViewActivity extends BaseActivity {
	public final static int WEB_DONE = 1;
	public final static int WEB_MSG = 2;
	public final static int WEB_LOADING = 3;
	public final static int WEB_LOADED = 4;	
	
	private ProgressBar processBar = null;
	private WebView web = null;
	private TextView titleView = null;
	private String curURL = "";
    
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.web_view);
        
        this.web = (WebView)findViewById(R.id.web);
        this.processBar = (ProgressBar)findViewById(R.id.progressbar_loading);
        
        web.setVerticalScrollBarEnabled(false);
        web.setHorizontalScrollBarEnabled(false);
        //web.getSettings().s
        web.getSettings().setJavaScriptEnabled(true);
        web.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
        web.setDownloadListener(new DownloadListener(){
			@Override
			public void onDownloadStart(String url, String userAgent, String contentDisposition,
					String mimetype, long contentLength) {
	            Uri uri = Uri.parse(url);  
	            Intent intent = new Intent(Intent.ACTION_VIEW, uri);  
	            startActivity(intent); 
			}
        });
        
        CookieSyncManager.createInstance(this);
        
        //web.setWebViewClient(new TaokeWebViewClient());
        
        titleView = (TextView)findViewById(R.id.title);
        
        titleView.setLongClickable(true);        
        titleView.setOnLongClickListener(new OnLongClickListener(){
			@Override
			public boolean onLongClick(View arg0) {
				if(curURL != null && curURL.length() > 1){
		            Uri uri = Uri.parse(curURL);  
		            Intent intent = new Intent(Intent.ACTION_VIEW, uri);  
		            startActivity(intent); 
				}
				return false;
			}			
        });        
    }
	
    protected void onResume (){
    	super.onResume();
    	
    	Intent intent = this.getIntent();
    	String title = intent.getStringExtra("title");
    	if(title != null && title.trim().length() > 0 && titleView != null){
    		titleView.setText(title);
    	}
    	if(intent.getBooleanExtra("taobaoLogin", false)){
    		web.setWebViewClient(new TaobaoLoginWebClient(this, processBar));
    		if(processBar != null){
    			processBar.setVisibility(View.INVISIBLE);
    		}
    	}else {
    		web.setWebViewClient(new TaokeWebViewClient());
    	} 	
    	//Uri dataUri = intent.getData();    
    	String http_url = intent.getStringExtra("http_url");
    	String num_iid = intent.getStringExtra("taoke_num_iid");

    	boolean autoMobile = autoConvertMobileLink(num_iid);
    	if(!autoMobile && http_url != null && http_url.startsWith("http")){
    		Log.d(Constants.TAG_EMOP, "loading url:" + http_url);
    		web.loadUrl(http_url);
    	}
    	
    	/**
    	 * 如果是淘宝商品，在客户端转换后跳转。
    	 */
    	if(autoMobile){
    		loadTaoboItem(num_iid, http_url);
    	}
    }
    
    /**
     * 判断是否需要自动转换，移动版链接。只有冒泡自己的帐号才需要转换链接。
     * @param num_iid
     * @return
     */
    protected boolean autoConvertMobileLink(String num_iid){
    	if(num_iid == null) return false;
    	if(client.trackUserId != null && !client.trackUserId.equals("11")){
    		return false;
    	}
    	return true;
    }
    
    protected void loadTaoboItem(final String numiid, final String shortUrl){
    	final TopAndroidClient client = TopAndroidClient.getAndroidClientByAppKey(Constants.TAOBAO_APPID);
    	TopParameters param = new TopParameters();
    	
    	param.setMethod("taobao.taobaoke.widget.items.convert");
    	param.addFields("click_url","num_iid");
    	param.addParam("is_mobile", "true");
    	param.addParam("num_iids", numiid);    	
		
    	TopApiListener listener = new TopApiListener(){

			@Override
			public void onComplete(JSONObject json) {
				// TODO Auto-generated method stub
				String click = null;
				
				try{
					JSONArray items = json.getJSONObject("taobaoke_widget_items_convert_response").
						getJSONObject("taobaoke_items").getJSONArray("taobaoke_item");
					JSONObject item = items.getJSONObject(0);
					click = item.getString("click_url");
					Log.i("emop", "num iid:" + numiid + ", convert click url:" + click);
				}catch(Exception e){
					Log.w("emop", "error e:" + e.toString(), e);
				}finally{
					if(click != null){
						loadMobileUrl(click);
					}else {						
						loadShortUrl(shortUrl);
					}
					
				}
			}

			@Override
			public void onError(ApiError error) {
				Log.w("emop", "error e:" + error.toString());
				loadShortUrl(shortUrl);
			}

			@Override
			public void onException(Exception e) {
				Log.w("emop", "error e:" + e.toString(), e);
				loadShortUrl(shortUrl);
			}
			
			private void loadMobileUrl(String url){
				web.loadUrl(url);
			}

			private void loadShortUrl(String url){
				web.loadUrl(url);
			}
			
    	};
    	client.api(param, null, listener, true);
    }
    
    public void onFinish(View v){
    	onBackPressed();
    }
    
    public void onBackPressed() {
    	if(web.canGoBack()){
    		web.goBack();
    	}else {
    		finish();
    	}
    }
    
    public Handler handler = new Handler(){
    	
    	public void handleMessage(final Message msg) {
    		String message = null;
    		if(msg.obj != null){
    			message = msg.obj.toString();
    			if(message != null){
    				Toast.makeText(WebViewActivity.this, message, Toast.LENGTH_LONG).show();
    			}
    		}
    		if(msg.what == WEB_DONE){
    			finish();
    		}else if(msg.what == WEB_LOADING){
    			processBar.setVisibility(View.VISIBLE);
    		}else if(msg.what == WEB_LOADED){
    			processBar.setVisibility(View.INVISIBLE);
    		}
    	}

    };    
    
    private class TaokeWebViewClient extends WebViewClient {
    	private boolean inTaobao = false;

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            super.onPageStarted(view, url, favicon);
            Log.d("xx", "url:" + url);
            curURL = url;
            //mSpinner.show();
            processBar.setVisibility(View.VISIBLE);
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            Log.d("xx", "done url:" + url);
            //curURL = url;
            
            /**
             * 刚进入宝贝详情页时，清空回退记录。这样在点回退的时候才能退出详情页。
             * 不然是退回到短网址页面，会再次进入详情页。
             */
            if((!inTaobao && isProductUrl(url)) || url.endsWith("taobao.com/")){
            	inTaobao = true;
            	web.clearHistory();
            }            
            processBar.setVisibility(View.INVISIBLE);
        }
        
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            Log.d(TAG_EMOP, "Redirect URL: " + url);
            
            int i = url.indexOf("m.taobao.com");
        	if(i > 0 && i < 15 && isAvilible(getApplicationContext(), "com.taobao.taobao")){
        		Intent intent = new Intent();			
        		//intent.setClass(this, LoginActivity.class);
        		url = url.replaceFirst("http:", "itaobao:");
        		intent.setAction(Intent.ACTION_VIEW);
        		intent.setData(Uri.parse(url));
        	//	intent.setComponent(ComponentName.unflattenFromString("com.taobao.taobao/com.taobao.tao.detail.DetailActivity"))
        		startActivityForResult(intent, OPEN_TAOBAO);    	
        		finish();
        		return true;
        	}else {
        		return false;
        	}
        }
        
        public boolean isProductUrl(String url){
        	if(url.indexOf("s.click") > 0 || url.indexOf("view_shop.htm") > 0){
        		return false;
        	}
        	if(url.indexOf("tmall.com") > 0 || url.indexOf("m.taobao.com") > 0){
        		return true;
        	}
        	return false;
        }
    }
    
    private boolean isAvilible(Context context, String packageName){ 
        final PackageManager packageManager = context.getPackageManager();//获取packagemanager 
        List<PackageInfo> pinfo = packageManager.getInstalledPackages(0);//获取所有已安装程序的包信息 
        List<String> pName = new ArrayList<String>();//用于存储所有已安装程序的包名 
        //从pinfo中将包名字逐一取出，压入pName list中 
        if(pinfo != null){ 
            for(int i = 0; i < pinfo.size(); i++){ 
                String pn = pinfo.get(i).packageName; 
                if(pn.startsWith(packageName)){
                	return true;
                }
                //pName.add(pn); 
            } 
        } 
        return false; //pName.contains(packageName);//判断pName中是否有目标程序的包名，有TRUE，没有FALSE 
  } 
}
 public class CreditAdapter implements ListAdapter{
	private int creditLevel = 0;
	private int imageId = R.drawable.shop_level1;
	private Context context;
	//private LayoutInflater inflater = getLayoutInflater(null);
	public CreditAdapter(Context context, int c){
		this.context = context;
		creditLevel = c - 1;
		int level = creditLevel / 5 + 1;
		if(context != null && context.getResources() != null){
			imageId = context.getResources().getIdentifier("shop_level" + level, "drawable", "com.emop.client");
		}
	}
	@Override
	public int getCount() {
		return creditLevel % 5 + 1;
	}
	@Override
	public Object getItem(int arg0) {
		return arg0;
	}
	@Override
	public long getItemId(int arg0) {
		return creditLevel;
	}
	@Override
	public int getItemViewType(int arg0) {
		return 0;
	}
	@Override
	public View getView(int arg0, View arg1, ViewGroup arg2) {
		//GridLayout.LayoutParams lp = new GridLayout.LayoutParams(GridLayout.LayoutParams.FILL_PARENT,
		//		GridLayout.LayoutParams.FILL_PARENT);
		ImageView im = new ImageView(context);
		//ImageView im = (ImageView)inflater.inflate(R.layout.credit_level_image, null);
		//im.setLayoutParams(lp);
		im.setScaleType(ScaleType.FIT_CENTER);
		//Log.d("emop", "lp:" + im.getLayoutParams());
		im.setImageResource(imageId);			
		return im;
	}
	@Override
	public int getViewTypeCount() {
		return 1;
	}
	@Override
	public boolean hasStableIds() {
		// TODO Auto-generated method stub
		return false;
	}
	@Override
	public boolean isEmpty() {
		// TODO Auto-generated method stub
		return false;
	}
	@Override
	public void registerDataSetObserver(DataSetObserver arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void unregisterDataSetObserver(DataSetObserver arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public boolean areAllItemsEnabled() {
		// TODO Auto-generated method stub
		return false;
	}
	@Override
	public boolean isEnabled(int arg0) {
		// TODO Auto-generated method stub
		return false;
	}
} public class ApiResult {
	public static final String ERR_JSON_PARSE = "err_json_parse";
	public static final String ERR_NETWORKING_UNKOWN = "err_networking_unkown";
	
	public JSONObject json = null;
	public boolean isOK = false;
	public String errorMsg = "";
	public String errorCode = "";
	

	
	public String getString(String key){
		String str = null;
		if(json != null){
			try {
				JSONObject v = json;
				Object o = null;
				for(String k: key.split("\\.")){
					if(!v.has(k)) {
						v = null;
						break;
					}
					o = v.get(k);
					if(o instanceof JSONObject){
						v = (JSONObject)o;
					}else{
						str = o.toString();
					}
				}
			} catch (JSONException e) {
				//e.printStackTrace();
				Log.e(TAG_EMOP, "JSONException error:" + e.toString(), e);
			}
		}
		return str;
	}
	
	public JSONObject getJSONObject(String key){
		JSONObject data = null;
		if(json != null){
			try {
				JSONObject v = json;
				Object o = null;
				for(String k: key.split("\\.")){
					if(!v.has(k)) {
						v = null;
						break;
					}
					o = v.get(k);
					if(o instanceof JSONObject){
						v = (JSONObject)o;
						data = v;
					}
				}
			} catch (JSONException e) {
				//e.printStackTrace();
				Log.e(TAG_EMOP, "JSONException error:" + e.toString(), e);
			}
		}
		return data;
	}	
	
	public String errorMsg(){		
		if(this.errorMsg != null && this.errorMsg.trim().length() > 0){
			return this.errorMsg.trim();
		}else{
			return this.errorCode;			
		}
	}
	
	//private String getString(String key, )
}
 public class FmeiClient {
	//public ImageCache cache = null;
	//需要长时间保存的图片，例如分类，热门。
	public ImageLoader appImgLoader = null;
	
	//临时图片加载，比如瀑布流图片。
	public ImageLoader tmpImgLoader = null;
	
	public String userId = null;
	//推荐应用下载的用户ID. 应用里面的链接都是包含这个用的PID
	public String trackUserId = null;
	public String trackPID = null;
	
	/**
	 * 收藏夹ID.
	 */
	public String favoriteId = null;
	public boolean isInited = false;

	private static FmeiClient ins = null;
	private TaodianApi api = null;
	private Context ctx = null;
	private AppConfig config = null;
	
	//private stai
	
	public FmeiClient(){
		this.api = new TaodianApi();
	}
	
	public static FmeiClient getInstance(Context ctx){
		return getInstance(ctx, false);
	}
	
	public static synchronized FmeiClient getInstance(Context ctx, boolean check_conn){
		if(ins == null){
			ins = new FmeiClient();
		}
		if(ctx != null){
			ins.ctx = ctx;
			ins.api.ctx = ctx;
		}
		if(ins.appImgLoader == null && ctx != null){
			File picDir = null;
			if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
				try{
					picDir = ctx.getExternalFilesDir("doudougou");
				}catch(Throwable e){
					Log.w(TAG_EMOP, "Error:" + e.toString(), e);
				}
				if(picDir == null){
					picDir = new File(Environment.getExternalStorageDirectory(), "doudougou");
				}
				Log.i(TAG_EMOP, "App cache dir:" + picDir.getAbsolutePath());
				if(!picDir.isDirectory()){
					if(!picDir.mkdirs()){
						picDir = ctx.getCacheDir();
					}
				}
				if(!picDir.canWrite()){
					picDir = ctx.getCacheDir();
				}
			}else {
				Log.i(TAG_EMOP, "The external storage is disabled.");				
				picDir = ctx.getCacheDir();				
			}
			Log.i(TAG_EMOP, "App image dir:" + picDir.getAbsolutePath());
			ins.appImgLoader = new ImageLoader(ctx, picDir, 
					0, 8); 
			ins.tmpImgLoader = ins.appImgLoader;
		}
		
		if(check_conn){
			ins.check_networking(ctx);
		}
		return ins;
	}
	
	public boolean isLogined(){
		return this.userId != null && this.userId.length() > 0 && Integer.parseInt(this.userId) > 0;
	}
	
	/**
	 * 链接一下taodian API看看网络是否正常。
	 * @param ctx
	 * @return
	 */
	public ApiResult check_networking(Context ctx){
		return this.api.connect(ctx);
	}
	
	/*
	 * 取得专题列表.
	 */
	public Cursor getTopicList(ContentResolver contentResolver){
		Cursor c = contentResolver.query(Schema.TOPIC_LIST, 
				new String[] {BaseColumns._ID, Topic.TITLE, Topic.ITEM_COUNT,
				Topic.DESC, 
				Topic.FRONT_PIC, 
				Topic.UPDATE_TIME,
				Topic.VIEW_ORDER
		}, null, null, null);
		return c;
	}
	
	/*
	 * 取得分类列表.
	 */
	public Cursor getCateList(ContentResolver contentResolver){
		Cursor c = contentResolver.query(Schema.CATE_LIST, 
				new String[] {BaseColumns._ID, Topic.TITLE, Topic.ITEM_COUNT,
				Topic.DESC, 
				Topic.FRONT_PIC, 
				Topic.UPDATE_TIME
		}, null, null, null);
		return c;
	}
	
	/*
	 * 取得热门分类列表.
	 */
	public Cursor getHotCateList(ContentResolver contentResolver){
		Cursor c = contentResolver.query(Schema.HOT_CATE_LIST, 
				new String[] {BaseColumns._ID, Topic.TITLE, Topic.ITEM_COUNT,
				Topic.DESC, 
				Topic.FRONT_PIC, 
				Topic.UPDATE_TIME
		}, null, null, null);
		return c;
	}	

	/*
	 * 取得专题列表.
	 */
	public Cursor getItemList(ContentResolver contentResolver, Uri uri){
		Log.d(com.emop.client.Constants.TAG_EMOP, "on getItemList:" + uri.toString());
		
		Cursor c = contentResolver.query(uri, 
				new String[] {BaseColumns._ID, Item.SHORT_KEY, Item.PIC_URL,
				Item.ITEM_CONTENT_TYPE, 
				Item.UPDATE_TIME, Item.WEIBO_ID,
				Item.PRICE,
				Item.MESSAGE,
				Item.RECT_RATE
		}, null, null, null);
		
		return c;
	}
	
	/**
	 * 通过uri地址更新内容列表。
	 * @param contentResolver
	 * @param uri
	 * @return
	 */
	public ApiResult refreshDataByUri(ContentResolver contentResolver, Uri uri){
		return refreshDataByUri(contentResolver, uri, TaodianApi.STATUS_NORMAL);
	}
	
	/**
	 * 通过uri地址更新内容列表。
	 * @param contentResolver
	 * @param uri
	 * @param async -- 是否异步返回结果。 如果为true数据在后台线程保存到数据库。网络返回后
	 * @return
	 */	
	public ApiResult refreshDataByUri(ContentResolver contentResolver, Uri uri, int status){
		return refreshDataByUri(contentResolver, uri, status, false);
	}	
	
	public ApiResult refreshDataByUri(ContentResolver contentResolver, Uri uri, int status, boolean sync){
		Log.e(Constants.TAG_EMOP, "refresh uri:" + uri.toString());
		ApiResult r = null;
        switch (Schema.FmeiUriMatcher.match(uri)) {
        	case Schema.TYPE_CATE_ITEM_LIST:
        	case Schema.TYPE_HOT_ITEM_LIST:
        	case Schema.TYPE_TOPIC_ITEM_LIST:
        		r = refreshTopicItemList(contentResolver, uri, sync, null);
        		break;
        	case Schema.TYPE_TOPICS:
        		r = this.refreshTopicList(contentResolver, status, "");
        		break;
        	case Schema.TYPE_CATES:
        		r = this.refreshCateList(contentResolver, status);
        		break;
        	case Schema.TYPE_HOTS:
        		r = this.refreshHotCatList(contentResolver, status);
        	case Schema.TYPE_ACT_ITEM_LIST:
        		r = this.refreshActivityItemList(contentResolver);
        	case Schema.TYPE_MYFAV_ITEM_LIST:
        		r = this.refreshMyFavoriteItemList(contentResolver);
        }
		
		return r;
	}
	
	/**
	 * 
	 * @param contentResolver
	 * @param uri
	 */
	public void refreshUri(ContentResolver contentResolver, Uri uri){
		
	}
	
	public ApiResult refreshTopicList(ContentResolver contentResolver){
		return refreshTopicList(contentResolver, TaodianApi.STATUS_NORMAL, "");
	}
	/**
	 * 刷新专题列表。
	 * @param contentResolver
	 */
	public ApiResult refreshTopicList(ContentResolver contentResolver, int status, String noCache){
		Log.e(Constants.TAG_EMOP, "refreshList....");
		ApiResult r = this.api.getTopicList(10, status, noCache);
		if(r.isOK){
			JSONObject json = null;
			try {
				json = r.json.getJSONObject("data");
				JSONArray jarray = json.getJSONArray("items");
				for(int i = 0; i < jarray.length(); i++){
					contentResolver.update(Schema.TOPIC_LIST, 
							Topic.convertJson(jarray.getJSONObject(i)), 
							null, null);
				}
				//contentResolver.notifyChange(Schema.TOPIC_LIST, null);
			} catch (JSONException e) {
			}
		}else {
			Log.d(Constants.TAG_EMOP, "Failed to refresh list:" + r.errorMsg());
		}
		return r;
	}
	
	public ApiResult refreshCateList(ContentResolver contentResolver, int status){
		Log.e(Constants.TAG_EMOP, "refresh cate List....");
		ApiResult r = this.api.getCateList(10, status);
		if(r.isOK){
			JSONObject json = null;
			try {
				json = r.json.getJSONObject("data");
				JSONArray jarray = json.getJSONArray("items");
				for(int i = 0; i < jarray.length(); i++){
					contentResolver.update(Schema.CATE_LIST, 
							Topic.convertJson(jarray.getJSONObject(i)), 
							null, null);
				}
				contentResolver.notifyChange(Schema.CATE_LIST, null);
			} catch (JSONException e) {
			}
		}else {
			Log.d(Constants.TAG_EMOP, "Failed to refresh list:" + r.errorMsg());
		}
		return r;
	}
	
	public ApiResult refreshHotCatList(ContentResolver contentResolver, int status){
		Log.e(Constants.TAG_EMOP, "refresh hot cate List....");
		ApiResult r = this.api.getHotCateList(10, status);
		if(r.isOK){
			JSONObject json = null;
			try {
				json = r.json.getJSONObject("data");
				JSONArray jarray = json.getJSONArray("items");
				for(int i = 0; i < jarray.length(); i++){
					contentResolver.update(Schema.HOT_CATE_LIST, 
							Topic.convertJson(jarray.getJSONObject(i)), 
							null, null);
				}
				contentResolver.notifyChange(Schema.CATE_LIST, null);
			} catch (JSONException e) {
			}
		}else {
			Log.d(Constants.TAG_EMOP, "Failed to refresh list:" + r.errorMsg());
		}
		return r;
	}
	
	public ApiResult refreshActList(ContentResolver contentResolver){
		Log.e(Constants.TAG_EMOP, "refresh act topic List....");
		ApiResult r = this.api.getActList(1, TaodianApi.STATUS_NORMAL);
		if(r.isOK){
			JSONObject json = null;
			try {
				json = r.json.getJSONObject("data");
				JSONArray jarray = json.getJSONArray("items");
				for(int i = 0; i < jarray.length(); i++){
					contentResolver.update(Schema.ACTIVITY_LIST, 
							Topic.convertJson(jarray.getJSONObject(i)), 
							null, null);
				}
			} catch (JSONException e) {
			}
		}else {
			Log.d(Constants.TAG_EMOP, "Failed to refresh list:" + r.errorMsg());
		}
		return r;
	}	
	
	/**
	 * 刷新专题图片列表。
	 * @param contentResolver
	 */
	public ApiResult refreshTopicItemList(ContentResolver contentResolver, int topic_id){
		Uri topicList = Uri.parse("content://" + Schema.AUTHORITY + "/topic/" + topic_id + "/list");
		
		return this.refreshTopicItemList(contentResolver, topicList);
	}
	
	/**
	 * 刷新活动图片列表。
	 * @param contentResolver
	 */
	public ApiResult refreshActivityItemList(ContentResolver contentResolver){
		ApiResult r = null;
		int topicId = getActivityTopicId(contentResolver);
		Uri topicList = Uri.parse("content://" + Schema.AUTHORITY + "/act/" + topicId + "/list");		
		r = this.refreshTopicItemList(contentResolver, topicList);
		return r;
	}	
	
	/**
	 * 刷新我的收藏活动图片列表。
	 * @param contentResolver
	 */
	public ApiResult refreshMyFavoriteItemList(ContentResolver contentResolver){
		ApiResult r = null;
		if(this.isLogined()){
			String fid = this.getFavoriteId();
			Uri topicList = Uri.parse("content://" + Schema.AUTHORITY + "/myfav/" + fid + "/list");	
			Log.e(Constants.TAG_EMOP, "refresh myfav item list:" + fid);
			r = this.api.getMyFavoriteItemList(fid, this.userId);
			if(r.isOK){
				JSONObject json = null;
				try {
					json = r.json.getJSONObject("data");
					JSONArray jarray = json.getJSONArray("items");
					for(int i = 0; i < jarray.length(); i++){
						contentResolver.update(topicList, 
								Item.convertJson(jarray.getJSONObject(i)), 
								null, null);
					}
				} catch (JSONException e) {
				}
			}else {
				Log.d(Constants.TAG_EMOP, "Failed to refresh list:" + r.errorMsg());
			}		
		}
		return r;
	}		
	
	/**
	 * 链接活动页，也是一个特殊的专题活动。取到专题的ID.
	 * @return
	 */
	public int getActivityTopicId(ContentResolver contentResolver){
		int topicId = 0;
		Cursor c = contentResolver.query(Schema.ACTIVITY_LIST, 
				new String[] {BaseColumns._ID }, null, null, null);
		if(c.getCount() == 0){
			this.refreshActList(contentResolver);
			if(c != null)c.close();
			c = contentResolver.query(Schema.ACTIVITY_LIST, 
					new String[] {BaseColumns._ID }, null, null, null);			
		}
		if(c.getCount() > 0){
			c.moveToFirst();
			int topic = c.getColumnIndex(BaseColumns._ID);
			topicId = c.getInt(topic);			
		}
		if(c != null)c.close();
		return topicId;
		
	}
	
	public ApiResult refreshTopicItemList(ContentResolver contentResolver, Uri topicList){
		return refreshTopicItemList(contentResolver, topicList, false, null);
	}
	public ApiResult refreshTopicItemList(final ContentResolver contentResolver, final Uri topicList, boolean sync, String force){
		int topic_id = Integer.parseInt(topicList.getPathSegments().get(1)); // (int) ContentUris.parseId(uri);
		String cate = topicList.getPathSegments().get(0);
		Log.e(Constants.TAG_EMOP, "refresh item list:" + topic_id);
		String pageSize = topicList.getQueryParameter("pageSize");
		String pageNo = topicList.getQueryParameter("pageNo");
		String noCache = topicList.getQueryParameter("no_cache");
		if(force != null && force.equals("y")){
			noCache = "y";
		}
		
		int size = 100;
		try{
			size = Integer.parseInt(pageSize);
		}catch(Throwable e){}
		final ApiResult r;
		if(cate.equals("act")){
			r = this.api.getTopicItemList(topic_id, size, pageNo);
		}else if(cate.equals("shop")){
			r = this.api.getShopItemList(topic_id, size, pageNo, trackUserId, noCache);
		}else {
			r = this.api.getTopicPidItemList(topic_id, size, pageNo, trackUserId, noCache);
		}
		if(r != null && r.isOK){
			Runnable task = new Runnable(){
				@Override
				public void run() {
					try {
						JSONObject json = r.json.getJSONObject("data");
						JSONArray jarray = json.getJSONArray("items");
						for(int i = 0; i < jarray.length(); i++){
							contentResolver.update(topicList, 
									Item.convertJson(jarray.getJSONObject(i)), 
									null, null);
						}
						contentResolver.notifyChange(topicList, null);
					} catch (JSONException e) {
						e.printStackTrace();
					}					
				}
				
			};
			
			if(sync){
				new Thread(task).start();
			}else {
				task.run();
			}
		}else {
			Log.d(Constants.TAG_EMOP, "Failed to refresh list:" + r.errorMsg());
		}
		return r;
	}
	
	/**
	 * 通过网络查询当前应用的最新版本。
	 * @return
	 */
	public ApiResult checkUpgradeVersion(){
		ApiResult r = this.api.call("cms_app_version_check", null);		
		//PackageManager packageManager = ctx.getPackageManager();
		//PackageInfo packInfo packageManager.getp		
		return r;
	}

	public ApiResult addFavorite(String weiboId, String desc, String picUrl, String numId,  String shopId, String short_url_key){
		return addFavorite(weiboId, desc, picUrl, numId, shopId, short_url_key, "taoke");
	}
	
	public ApiResult addFavorite(String weiboId, String desc, String picUrl, String numId,  String shopId, String short_url_key, String contentType){
		Log.d(TAG_EMOP, "add fav, weiboId:" + weiboId + ", numId:" + numId + ", shopId:" + shopId + ", picUrl:" + picUrl);
		ApiResult r = null;
		String fid = getFavoriteId();
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("user_id", userId);
		param.put("topic_id", fid);
		param.put("item_id", weiboId);
		param.put("pic_url", picUrl);
		param.put("content_type", contentType);
		param.put("num_iid", numId);
		param.put("shop_id", shopId);
		param.put("short_url_key", short_url_key);
		
		param.put("item_text", desc);
		r = api.call("tuji_topic_add_item", param);
		return r;
	}
	
	public ApiResult removeFavorite(String weiboId){
		Log.d(TAG_EMOP, "remove fav, weiboId:" + weiboId);
		ApiResult r = null;
		String fid = getFavoriteId();
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("user_id", userId);
		param.put("topic_id", fid);
		param.put("item_id", weiboId);

		r = api.call("tuji_topic_remove_items", param);
		return r;
	}
	
	
	/**
	 * 加载应用配置信息，例如：sina key,什么的。
	 * @return
	 */
	public AppConfig config(){
		if(config == null){
			config = new AppConfig();
			ApiResult r = api.call("cms_app_config_info", null);
			if(r != null && r.isOK){
				config.json = r.getJSONObject("data");
			}
		}
		return config;
	}
	
	/**
	 * 绑定外部登录用户信息，到美觅网系统。
	 * @param source
	 * @param userId
	 * @param token
	 * @return
	 */
	public ApiResult bindUserInfo(String source, String userId, String token){
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("source", source);
		param.put("ref_id", userId);
		param.put("access_token", token);
		if(this.userId != null){
			param.put("user_id", this.userId);
		}
		
		ApiResult r = api.call("user_bind_login", param);
		
		return r;
	}
	
	public ApiResult registerUser(Map<String, Object> param){	
		/**
		 * 有user_id是通过，第三方帐号绑定过来。已经生成了user_id.
		 * 没有user_id是在应用里面，直接注册的。
		 */
		ApiResult r = null;
		Object user_id = param.get("user_id");
		if(user_id != null && user_id.toString().length() > 0){
			r = api.call("user_update_info", param);
		}else {
			r = api.call("user_register_new", param);
		}
		
		return r;
	}
	
	public ApiResult login(String email, String password){	
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("email", email);
		param.put("password", password);
		
		ApiResult r = api.call("user_login", param);
		
		return r;
	}
	
	public void saveLoginUser(Activity ctx, String userId){
		this.userId = userId;
		SharedPreferences settings = ctx.getSharedPreferences(Constants.PREFS_NAME, 0);
    	SharedPreferences.Editor editor = settings.edit();
    	editor.putString(Constants.PREFS_OAUTH_ID, userId);
    	editor.commit();
    	Log.d(TAG_EMOP, "save user:" + userId);
	}

	public void saveRefUser(Activity ctx, String source, String userId, String nick){
		//this.userId = userId;
		SharedPreferences settings = ctx.getSharedPreferences(Constants.PREFS_NAME, 0);
    	SharedPreferences.Editor editor = settings.edit();
    	if(source.equals(Constants.AUTH_REF_SINA)){
    		editor.putString(Constants.PREFS_SINA_UID, userId);
        	editor.putString(Constants.PREFS_SINA_NICK, nick);
    	}else if(source.equals(Constants.AUTH_REF_TAOBAO)){
    		editor.putString(Constants.PREFS_TAOBAO_UID, userId);
        	editor.putString(Constants.PREFS_TAOBAO_NICK, nick);    		
    	}else if(source.equals(Constants.AUTH_REF_QQ)){
    		editor.putString(Constants.PREFS_QQ_UID, userId);
        	editor.putString(Constants.PREFS_QQ_NICK, nick);      		
    	}
    	editor.commit();
    	Log.d(TAG_EMOP, "save user:" + userId);
	}

	public void removeRefUser(Activity ctx, String source){
		//this.userId = userId;
		SharedPreferences settings = ctx.getSharedPreferences(Constants.PREFS_NAME, 0);
    	SharedPreferences.Editor editor = settings.edit();
    	if(source.equals(Constants.AUTH_REF_SINA)){
    		editor.remove(Constants.PREFS_SINA_UID);
    		editor.remove(Constants.PREFS_SINA_NICK);
    		editor.remove(Constants.PREFS_SINA_ACCESS_TOKEN);
    	}else if(source.equals(Constants.AUTH_REF_TAOBAO)){
    		editor.remove(Constants.PREFS_TAOBAO_UID);
    		editor.remove(Constants.PREFS_TAOBAO_NICK);
    	}else if(source.equals(Constants.AUTH_REF_QQ)){
    		editor.remove(Constants.PREFS_QQ_UID);
    		editor.remove(Constants.PREFS_QQ_UID);
    	}
    	editor.commit();
    	String sina = settings.getString(Constants.PREFS_SINA_UID, "");
    	String taobao = settings.getString(Constants.PREFS_TAOBAO_UID, "");
    	String qq = settings.getString(Constants.PREFS_QQ_UID, "");
    	
    	if((sina == null || sina.trim().length() == 0) &&
    	   (taobao == null || taobao.trim().length() == 0) &&
    	   (qq == null || qq.trim().length() == 0)
    	){
    		logout(ctx);
    	}    	
    	Log.d(TAG_EMOP, "save user:" + userId);
	}
	
	
	public void logout(Activity ctx){
		this.userId = null;
		SharedPreferences settings = ctx.getSharedPreferences(Constants.PREFS_NAME, 0);
    	SharedPreferences.Editor editor = settings.edit();
    	editor.putString(Constants.PREFS_OAUTH_ID, "0");
    	editor.commit();
    	Log.d(TAG_EMOP, "logout:" + userId);		
	}
	
	/**
	 * 我的收藏夹Id.
	 * @return
	 */
	public String getFavoriteId(){
		if((this.favoriteId == null || this.favoriteId.length() == 0) &&
				this.isLogined()){
			Map<String, Object> param = new HashMap<String, Object>();
			param.put("user_id", userId);
			param.put("cate", 1);
			param.put("topic_name", "收藏夹");
			param.put("item_head_count", 0);
			param.put("status", TaodianApi.STATUS_NORMAL);
			
			ApiResult r = api.call("tuji_user_topic_list", param);
			if(r.isOK){
				 int count = Integer.parseInt(r.getString("data.item_count").toString());
				 if(count > 0){
					 JSONObject obj = r.getJSONObject("data");
					 JSONArray items;
					try {
						items = obj.getJSONArray("items");
						this.favoriteId = items.getJSONObject(0).getString("id");
					} catch (JSONException e) {
						Log.e(TAG_EMOP, "Get favoriate ID error:" + e.toString(), e);
					}
				 }
			}
			if(this.favoriteId == null || this.favoriteId.length() == 0){
				r = api.call("tuji_create_topic", param);
				if(r.isOK){
					this.favoriteId = r.getString("data.topic_id");
				}			
			}
		}
		return this.favoriteId;
	}
	
	/**
	 * 检查用户PID是否合法。先跳过不检查。
	 * @param id
	 * @return
	 */
	public ApiResult checkTrackId(String id){
		ApiResult r = new ApiResult();
		r.isOK = true;
		return r;
	}
	
	public void cleanExpiredData(ContentResolver contentResolver){
		Log.d(Constants.TAG_EMOP, "cleanExpiredData....");
		contentResolver.delete(Schema.TOPIC_LIST, Item.LOCAL_UPDATE_TIME + " < ?", 
				new String[]{(System.currentTimeMillis() - 1000 * 60 * 60 * 24 * 15) + ""});
		contentResolver.delete(Schema.ITME_LIST, Item.LOCAL_UPDATE_TIME + " < ?", 
				new String[]{(System.currentTimeMillis() - 1000 * 60 * 60 * 24 * 5) + ""});	
		
		contentResolver.delete(Schema.REBATE_LIST, Item.LOCAL_UPDATE_TIME + " < ?", 
				new String[]{(System.currentTimeMillis() - 1000 * 60 * 60 * 24 * 15) + ""});
		contentResolver.delete(Schema.SHOP_LIST, Item.LOCAL_UPDATE_TIME + " < ?", 
				new String[]{(System.currentTimeMillis() - 1000 * 60 * 60 * 24 * 15) + ""});		
	}
	
	/**
	 * 更加ID加载单条内容。主要用在，应用从外部启动后。直接进入详情页面。
	 * @param uuid
	 * @return
	 */
	public ApiResult getWeiboInfo(String uuid){		
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("uuid", uuid);
		param.put("user_id", userId);
		
		ApiResult r = api.call("cms_get_uuid_content", param);		

		return r;
	}

	public ApiResult getTrackPid(){		
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("uid", this.trackUserId);
		ApiResult r = api.call("emop_user_pid", param);		
		this.trackPID = r.getString("data.pid");
		
		return r;
	}
	
	/**
	 * @param uuid
	 * @return
	 */
	public ApiResult updateTrackId(){
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("user_id", userId);
		param.put("track_user_id", trackUserId);
		
		ApiResult r = api.call("user_update_track_id", param);	
		if(r != null && r.isOK){
			String tid = r.getString("data.track_user_id");
			if(tid != null && tid.trim().length() > 0){
				trackUserId = tid;
				SharedPreferences settings = ctx.getSharedPreferences(Constants.PREFS_NAME, 0);
		    	SharedPreferences.Editor editor = settings.edit();
		    	editor.putString(Constants.PREFS_TRACK_ID, tid);
		    	editor.commit();
			}
			Log.d("xx", "update task as:" + tid);
		}
		return r;
	}
	
	/**
	 * 1. 读取sd卡
	 * 2. 读取应用meta
	 */
	public void updateLocalTrackId(){
		boolean writeSetting = false;
		SharedPreferences settings = ctx.getSharedPreferences(Constants.PREFS_NAME, 0);
		trackUserId = settings.getString(Constants.PREFS_TRACK_ID, null);
		if(trackUserId == null || trackUserId.trim().equals("")){
			writeSetting = true;
			trackUserId = readTrackIdFromSD();
		}
		if(trackUserId == null || trackUserId.trim().equals("")){
			trackUserId = getMetaDataValue("emop_track_id");
			//测试模式下，track id还没有替换时。默认是EMOP_USER
			if(trackUserId != null && trackUserId.equals("EMOP_USER")){
				trackUserId = "11";
			}
			Log.d(TAG_EMOP, "read track from meta:" + trackUserId);
		}
		if(trackUserId != null && trackUserId.trim().length() > 0){
			if(writeSetting){
				saveSettings(Constants.PREFS_TRACK_ID, trackUserId);
			}
			WriteTrackIdToSD(trackUserId);
		}
	}

	private void WriteTrackIdToSD(String tid){
		File track = null;
		String pid = null;
		OutputStream os = null;
		try{
			if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
				track = new File(Environment.getExternalStorageDirectory(), "taodianhuo.pid");
			}else {
				track = new File(ctx.getExternalFilesDir(null), "taodianhuo.pid");
			}
			Log.d(TAG_EMOP, "write track user pid:'" + tid + "' to:" + track.getAbsolutePath());
			os = new FileOutputStream(track);
			if(os != null){
				os.write(tid.getBytes());
			}
		}catch(Throwable e){
			Log.d(TAG_EMOP, "write error:" + e.toString(), e);
		}finally{
			if(os != null){
				try {
					os.close();
				} catch (IOException e) {
				}
			}
		}
	}
		
	private String readTrackIdFromSD(){
		File track = null;
		String pid = null;
		BufferedReader input = null;
		try{
			if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
				track = new File(Environment.getExternalStorageDirectory(), "taodianhuo.pid");
			}else {
				track = new File(ctx.getExternalFilesDir(null), "taodianhuo.pid");
			}
			Log.d(TAG_EMOP, "read track user from:" + track.getAbsolutePath());
			if(track.isFile()){
				input = new BufferedReader(new InputStreamReader(new FileInputStream(track)));
				pid = input.readLine();
			}
			Log.d(TAG_EMOP, "read pid in sdcard:" + pid);
		}catch(Throwable e){
			Log.e(TAG_EMOP, "read pid error:" + e.toString(), e);
		}finally{
			if(input != null){
				try {
					input.close();
				} catch (IOException e) {
				}
			}
		}
		return pid;
	}
	
    private String getMetaDataValue(String name) {
        Object value = null;
        PackageManager packageManager = ctx.getPackageManager();
        ApplicationInfo applicationInfo;
        try {
            applicationInfo = packageManager.getApplicationInfo(ctx.getPackageName(), PackageManager.GET_META_DATA);
            if (applicationInfo != null && applicationInfo.metaData != null) {
                value = applicationInfo.metaData.get(name);
            }
        } catch (NameNotFoundException e) {
            throw new RuntimeException(
                    "Could not read the name in the manifest file.", e);
        }
        if (value == null) {
            throw new RuntimeException("The name '" + name
                    + "' is not defined in the manifest file's meta data.");
        }
        return value.toString();
    }	
		
	public String getSettings(String key){
		SharedPreferences settings = ctx.getSharedPreferences(Constants.PREFS_NAME, 0);
		return settings.getString(key, null);
	}

	public String saveSettings(String key, String value){
		SharedPreferences settings = ctx.getSharedPreferences(Constants.PREFS_NAME, 0);
    	SharedPreferences.Editor editor = settings.edit();
    	editor.putString(key, value);
    	editor.commit();	
		return settings.getString(key, null);
	}	
	public String removeSettings(String key){
		SharedPreferences settings = ctx.getSharedPreferences(Constants.PREFS_NAME, 0);
    	SharedPreferences.Editor editor = settings.edit();
    	editor.remove(key);
    	editor.commit();	
		return settings.getString(key, null);
	}
}
 public class TaodianApi {
	public static final int STATUS_NORMAL = 1001;
	public static final int STATUS_ALL = -1;
	
	private String appSecret = "298cd2d9700b08f7bab6f6a28647c8eb";
	private String appKey = "11";
	private HttpTransport http = null;
	public Context ctx = null;
	
	public TaodianApi(){
		//http = new HttpTransport(appKey, appSecret);
	}
	
	public ApiResult connect(Context ctx){
		http = new HttpTransport(ctx, appKey, appSecret);
		this.ctx = ctx;
		return http.ping();		
	}
	
	/*
	 * 直接调用底层Taodian API.
	 */
	public ApiResult call(String api, Map<String, Object> param){
		if(this.http == null){
			this.connect(ctx);
		}
		return this.http.call(api, param);
	}
	
	public ApiResult getTopicList(int size, int status, String noCache){
		ApiResult r = null;
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("no_cache", noCache);		
		param.put("user_id", 2);
		param.put("item_head_count", 0);
		param.put("cate", 3);
		param.put("status", status + "");
		param.put("scope", "site");
		param.put("fields", "topic_name,description,create_time,update_time,item_count,front_pic,view_order,status");
		
		return 	call("tuji_user_topic_list", param);
	}
	
	public ApiResult getCateList(int size, int status){
		ApiResult r = null;
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("user_id", 2);
		param.put("item_head_count", 0);
		param.put("cate", 4);
		param.put("status", status + "");
		param.put("scope", "site");
		
		param.put("fields", "topic_name,description,create_time,update_time,item_count,front_pic,view_order,status");
		
		return 	call("tuji_user_topic_list", param);
	}
	
	public ApiResult getHotCateList(int size, int status){
		ApiResult r = null;
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("user_id", 2);
		param.put("item_head_count", 0);
		param.put("cate", 5);
		param.put("status", status + "");
		param.put("scope", "site");
		
		param.put("fields", "topic_name,tags,description,create_time,update_time,item_count,front_pic,view_order,status");
		
		return 	call("tuji_user_topic_list", param);
	}	
	
	public ApiResult getActList(int size, int status){
		ApiResult r = null;
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("user_id", 2);
		param.put("item_head_count", 0);
		param.put("cate", 6);
		param.put("status", status + "");
		param.put("scope", "site");
		
		param.put("fields", "topic_name,description,create_time,update_time,item_count,front_pic,view_order,status");
		
		return 	call("tuji_user_topic_list", param);
	}		
	
	public ApiResult getTopicPidItemList(int topic, int page_size, String pageNo, String uid, String noCache){
		ApiResult r = null;
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("topic_id", topic);
		param.put("page_size", page_size);
		param.put("page_no", pageNo);
		param.put("user_id", 2);
		param.put("track_user_id", uid);
		param.put("content_type", "taoke");
		param.put("no_cache", noCache);		
		param.put("fields", "id,pic_url,price,content_type,num_iid,shop_id,short_url_key,item_id,update_time,status");
		
		return 	call("tuji_topic_convert_item_click_url", param);
	}

	public ApiResult getShopItemList(int shopId, int page_size, String pageNo, String uid, String noCache){
		ApiResult r = null;
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("shop_id", shopId);
		param.put("page_size", page_size);
		param.put("page_no", pageNo);
		param.put("user_id", 2);
		param.put("track_user_id", uid);
		param.put("content_type", "taoke");
		param.put("no_cache", noCache);		
		param.put("fields", "id,pic_url,price,content_type,num_iid,shop_id,short_url_key,item_id,update_time,status");
		
		return 	call("tuji_topic_convert_item_click_url", param);
	}
	
	public ApiResult getTopicItemList(int topic, int page_size, String pageNo){
		ApiResult r = null;
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("topic_id", topic);
		param.put("page_size", page_size);
		param.put("page_no", pageNo);
		param.put("user_id", 2);
		param.put("fields", "id,text,pic_url,price,content_type,num_iid,shop_id,short_url_key,item_id,update_time,status");
		
		return 	call("tuji_topic_item_list", param);
	}
	
	public ApiResult getShopList(String uid, String cate, int page_size, int pageNo){
		ApiResult r = null;
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("track_user_id", uid);
		param.put("cate", cate);
		
		param.put("page_size", page_size + "");
		param.put("page_no", pageNo + "");
		param.put("fields", "shop_id,root_tag,user_nick,pic_path,shop_title,shop_url,short_url_key,shop_type,shop_desc,seller_credit");
		
		return 	call("shop_taoke_link_get", param);
	}	
	
	public ApiResult getOneShop(String uid, String shopId, int page_size, int pageNo){
		ApiResult r = null;
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("track_user_id", uid);
		param.put("cate", "11");
		param.put("shop_ids", shopId);
		
		param.put("page_size", page_size + "");
		param.put("page_no", pageNo + "");
		param.put("fields", "shop_id,root_tag,user_nick,pic_path,shop_title,shop_url,short_url_key,shop_type,shop_desc,seller_credit");
		
		return 	call("shop_taoke_link_get", param);
	}	
	
	public ApiResult getRebateList(String uid, String cate, int page_size, int pageNo){
		ApiResult r = null;
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("track_user_id", uid);
		param.put("cate", cate);
		
		param.put("page_size", page_size + "");
		param.put("page_no", pageNo + "");
		param.put("fields", "num_iid,root_tag,nick,title,price,pic_url,coupon_rate,coupon_price,coupon_start_time,coupon_end_time,taoke_click_url,short_url_key");
		
		return 	call("rebate_taoke_link_get", param);
	}
	
	public ApiResult getRebateCateList(int size, int status){
		ApiResult r = null;
		Map<String, Object> param = new HashMap<String, Object>();

		param.put("fields", "topic_name,description,create_time,update_time,item_count,front_pic,view_order,status");
		
		return 	call("rebate_cate_list_get", param);
	}	
	
	public ApiResult getMyFavoriteItemList(String topic, String userId){
		ApiResult r = null;
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("topic_id", topic);
		param.put("page_size", 40);
		param.put("user_id", userId);
		
		param.put("fields", "id,text,pic_url,price,content_type,num_iid,shop_id,short_url_key,item_id,update_time,status");
		
		return 	call("tuji_topic_item_list", param);
	}	

	public ApiResult getMyFavoriteShopList(String topic, String userId){
		ApiResult r = null;
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("topic_id", topic);
		param.put("page_size", 40);
		param.put("user_id", userId);
		
		param.put("fields", "id,text,pic_url,price,content_type,num_iid,shop_id,short_url_key,item_id,update_time,status");
		
		return 	call("tuji_topic_item_list", param);
	}	

} public class Schema {
	public static final UriMatcher FmeiUriMatcher;

	public static final String AUTHORITY = "com.emop.client.provider.Fmei";
	
	/*
	 * 专题列表。
	 */
    public static final Uri TOPIC_LIST = Uri.parse("content://" + AUTHORITY + "/topics/");
	
    /*
	 * 我的收藏。
	 */
    public static final Uri MYFAV_LIST = Uri.parse("content://" + AUTHORITY + "/myfav/");

    /*
     * 分类列表
     */
    public static final Uri CATE_LIST = Uri.parse("content://" + AUTHORITY + "/cates/");

    public static final Uri REBATE_CATE_LIST = Uri.parse("content://" + AUTHORITY + "/rebate_cates/");
    
    

    /*
     * 店铺列表
     */
    public static final Uri SHOP_LIST = Uri.parse("content://" + AUTHORITY + "/shops/");
    
    /*
     * 热门分类列表
     */
    public static final Uri HOT_CATE_LIST = Uri.parse("content://" + AUTHORITY + "/hots/");

    /*
     * 外链活动列表
     */
    public static final Uri ACTIVITY_LIST = Uri.parse("content://" + AUTHORITY + "/acts/");
    
    
    /*
     * 内容列表
     */
    public static final Uri ITME_LIST = Uri.parse("content://" + AUTHORITY + "/items/");

    /*
     * 折扣列表
     */
    public static final Uri REBATE_LIST = Uri.parse("content://" + AUTHORITY + "/rebates/");

    
    public static final int TYPE_TOPICS = 1001;
    public static final int TYPE_TOPIC_ID = 1002;
    public static final int TYPE_TOPIC_ITEM_LIST = 1003;
    
    public static final int TYPE_CATES = 2001;
    public static final int TYPE_CATE_ID = 2002;
    public static final int TYPE_CATE_ITEM_LIST = 2003;

    public static final int TYPE_HOTS = 3001;
    //public static final int TYPE_CATES_ID = 4;
    public static final int TYPE_HOT_ITEM_LIST = 3003;

    public static final int TYPE_ACTS = 4001;    
    public static final int TYPE_ACT_ITEM_LIST = 4003;

    public static final int TYPE_MYFAVS = 5001;    
    public static final int TYPE_MYFAV_ITEM_LIST = 5003;
    
    
    public static final int TYPE_ITEMS = 5001;
    public static final int TYPE_ITEM_ID = 5002;
    
    public static final int TYPE_SHOPS = 6001;
    public static final int TYPE_SHOPS_CATE = 6002;
    public static final int TYPE_SHOP_ID = 6003;
    public static final int TYPE_SHOP_TAOKE_LSIT = 6004;
    
    public static final int TYPE_REBATES = 7001;
    public static final int TYPE_REBATES_CATE = 7002;

    public static final int TYPE_REBATE_CATES = 8001;
    public static final int TYPE_REBATE_CATE_ID = 8002;
    public static final int TYPE_REBATE_CATE_ITEM_LIST = 8002;
    
    
    static {
    	FmeiUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        FmeiUriMatcher.addURI(Schema.AUTHORITY, "topics", Schema.TYPE_TOPICS);
        FmeiUriMatcher.addURI(Schema.AUTHORITY, "topic/#",  Schema.TYPE_TOPIC_ID);
        FmeiUriMatcher.addURI(Schema.AUTHORITY, "topic/#/list",  Schema.TYPE_TOPIC_ITEM_LIST);
        
        FmeiUriMatcher.addURI(Schema.AUTHORITY, "cates", Schema.TYPE_CATES);
        FmeiUriMatcher.addURI(Schema.AUTHORITY, "cate/#", Schema.TYPE_CATE_ID);
        FmeiUriMatcher.addURI(Schema.AUTHORITY, "cate/#/list", Schema.TYPE_CATE_ITEM_LIST);

        FmeiUriMatcher.addURI(Schema.AUTHORITY, "hots", Schema.TYPE_HOTS);
        FmeiUriMatcher.addURI(Schema.AUTHORITY, "hot/#/list", Schema.TYPE_HOT_ITEM_LIST);
        
        FmeiUriMatcher.addURI(Schema.AUTHORITY, "acts", Schema.TYPE_ACTS);
        FmeiUriMatcher.addURI(Schema.AUTHORITY, "act/#/list", Schema.TYPE_ACT_ITEM_LIST);

        FmeiUriMatcher.addURI(Schema.AUTHORITY, "rebate_cates", Schema.TYPE_REBATE_CATES);
        FmeiUriMatcher.addURI(Schema.AUTHORITY, "rebate_cates/#", Schema.TYPE_REBATE_CATE_ID);
        FmeiUriMatcher.addURI(Schema.AUTHORITY, "rebate_cates/#/list", Schema.TYPE_REBATE_CATE_ITEM_LIST);        
        
        FmeiUriMatcher.addURI(Schema.AUTHORITY, "myfavs", Schema.TYPE_MYFAVS);
        FmeiUriMatcher.addURI(Schema.AUTHORITY, "myfav/#/list", Schema.TYPE_MYFAV_ITEM_LIST);        
        
        FmeiUriMatcher.addURI(Schema.AUTHORITY, "items", Schema.TYPE_ITEMS);
        FmeiUriMatcher.addURI(Schema.AUTHORITY, "item/#", Schema.TYPE_ITEM_ID);

        FmeiUriMatcher.addURI(Schema.AUTHORITY, "shops", Schema.TYPE_SHOPS);
        FmeiUriMatcher.addURI(Schema.AUTHORITY, "shops/cate/#/list", Schema.TYPE_SHOPS_CATE);
        FmeiUriMatcher.addURI(Schema.AUTHORITY, "shop/#", Schema.TYPE_SHOP_ID);
        FmeiUriMatcher.addURI(Schema.AUTHORITY, "shop/#/taoke_list", Schema.TYPE_SHOP_TAOKE_LSIT);

        FmeiUriMatcher.addURI(Schema.AUTHORITY, "rebates", Schema.TYPE_REBATES);
        FmeiUriMatcher.addURI(Schema.AUTHORITY, "rebates/cate/#/list", Schema.TYPE_REBATES_CATE);        
    }    
    
}
 public class Item {
	public static final String DB_TABLE_NAME = "item";
    public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.fmei.items";
    public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.fmei.item";

	public static final String LOCAL_CATE = "local_cate";
	public static final String SHORT_KEY = "short_key";
	public static final String WEIBO_ID = "weibo_id";
	public static final String MESSAGE = "message";
	public static final String PIC_URL = "pic_url";
	public static final String ROOT_CATE = "root_cate";
	public static final String ITEM_CONTENT_TYPE = "content_type";
	public static final String NUM_IID = "num_iid";
	public static final String SHOP_ID = "shop_id";
	public static final String PRICE = "price";
	public static final String TITLE = "title";
	public static final String STATUS = "status";
	public static final String UPDATE_TIME = "update_time";
	public static final String LOCAL_UPDATE_TIME = "local_update";
	public static final String WEIGHT = "weight";
	
	
	//长宽比例.
	public static final String RECT_RATE = "rect_rate";
	
	
	public static void buildQuery(SQLiteQueryBuilder builder, Uri uri,
			QueryParam param){
		builder.setTables(DB_TABLE_NAME);
		List<String> seg = uri.getPathSegments();
		String cate = seg.get(0) + "_" + seg.get(1);
		builder.appendWhere(LOCAL_CATE + "='" + cate + "'");
		builder.appendWhere(" and " + STATUS + "='0'");
		param.sortOrder = UPDATE_TIME + " " + "desc";
	}

	public static void buildShopQuery(SQLiteQueryBuilder builder, Uri uri,
			QueryParam param){
		builder.setTables(DB_TABLE_NAME);
		List<String> seg = uri.getPathSegments();
		builder.appendWhere(SHOP_ID + "='" + seg.get(1) + "'");
		builder.appendWhere(" and " + STATUS + "='0'");
		param.sortOrder = UPDATE_TIME + " " + "desc";
	}
	
	public static void buildQueryId(SQLiteQueryBuilder builder, Uri uri,
			QueryParam param){
		builder.setTables(DB_TABLE_NAME);
		List<String> seg = uri.getPathSegments();
		builder.appendWhere(BaseColumns._ID + "='" + seg.get(1) + "'");
	}	
		
	public static Uri insert(SQLiteDatabase db, ContentValues values){
		return null;
	};	
	public static Uri update(SQLiteDatabase db, Uri uri, ContentValues values){
		String taskId = values.getAsString("id");
		if(taskId == null){
			updateItem(db, uri, values);
		}else {
			values.remove("id");
			List<String> seg = uri.getPathSegments(); //.get(1);
			values.put(LOCAL_CATE, seg.get(0) + "_" + seg.get(1));
			values.put(LOCAL_UPDATE_TIME, System.currentTimeMillis());
	        int count = db.update(DB_TABLE_NAME, values, BaseColumns._ID + "=?", new String[]{taskId});
			if(count == 0){
				//Log.d(Constants.TAG_EMOP, String.format("insert new item '%s:%s, shop:%s'", taskId,
				//		values.getAsString(WEIBO_ID), values.getAsString(SHOP_ID)));
				values.put(BaseColumns._ID, taskId);
				db.insert(DB_TABLE_NAME, WEIBO_ID, values);
			}else {
				//Log.d(Constants.TAG_EMOP, String.format("update item '%s:%s, shop:%s'", taskId,
				//		values.getAsString(WEIBO_ID), values.getAsString(SHOP_ID)));
			}		
		}
		return null;		
	};		
	
	public static Uri updateItem(SQLiteDatabase db, Uri uri, ContentValues values){
		String taskId = values.getAsString("num_iid");
		if(taskId != null){
			values.remove("num_iid");
			Log.d(Constants.TAG_EMOP, "Update item by num id:" + taskId);
			List<String> seg = uri.getPathSegments(); //.get(1);
	        db.update(DB_TABLE_NAME, values, NUM_IID + "=?", new String[]{taskId});
		}
		return null;		
	};		
	
	
	
	public static ContentValues convertJson(JSONObject obj){
		ContentValues v = new ContentValues();
		try{
			if(obj.has("id")){
				v.put("id", obj.getInt("id"));
			}
			if(obj.has("short_url_key")){
				v.put(SHORT_KEY, obj.getString("short_url_key"));
			}
			if(obj.has("item_id")){
				v.put(WEIBO_ID, obj.getString("item_id"));
			}
			if(obj.has("text")){
				v.put(MESSAGE, obj.getString("text"));
			}	
			if(obj.has(PIC_URL)){
				v.put(PIC_URL, obj.getString(PIC_URL));
			}
			if(obj.has(ITEM_CONTENT_TYPE)){
				v.put(ITEM_CONTENT_TYPE, obj.getString(ITEM_CONTENT_TYPE));
			}		
			if(obj.has(UPDATE_TIME)){
				v.put(UPDATE_TIME, obj.getString(UPDATE_TIME));
			}	
			if(obj.has(PRICE)){
				v.put(PRICE, obj.getString(PRICE));
			}			
			if(obj.has(NUM_IID)){
				v.put(NUM_IID, obj.getString(NUM_IID));
			}			
			if(obj.has(SHOP_ID)){
				v.put(SHOP_ID, obj.getString(SHOP_ID));
			}		
			if(obj.has(STATUS)){
				v.put(STATUS, obj.getString(STATUS));
			}
			if(obj.has(RECT_RATE)){
				v.put(RECT_RATE, obj.getString(RECT_RATE));
			}	
			if(obj.has(WEIGHT)){
				v.put(WEIGHT, obj.getString(WEIGHT));
			}			
		}catch (JSONException e) {
			Log.e(Constants.TAG_EMOP, e.toString());
		}
		
		return v;	
	}
}
 public class Shop {
    public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.fmei.shops";
    public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.fmei.shop";
	
	public static final String DB_TABLE_NAME = "shop";
	
	public static final String LOCAL_CATE = "local_cate";
	public static final String SHORT_KEY = "short_url_key";
	public static final String SHOP_ID = "shop_id";

	public static final String ROOT_CATE = "root_tag";
	public static final String USER_NICK = "user_nick";
	public static final String SHOP_TYPE = "shop_type";	
	public static final String GOOD_COMMENT = "good_comment";

	public static final String SHOP_TITLE = "shop_title";
	public static final String SHOP_DESC = "shop_desc";
	public static final String SHOP_LOGO = "pic_path";

	public static final String SHOP_CREDIT = "seller_credit";
	
	public static final String STATUS = "status";
	public static final String UPDATE_TIME = "update_time";
	public static final String LOCAL_UPDATE_TIME = "local_update";
	public static final String WEIGHT = "weight";
	
	public static Uri update(SQLiteDatabase db, Uri uri, ContentValues values){
		
		String taskId = values.getAsString(SHOP_ID);
		//values.remove("id");
		List<String> seg = uri.getPathSegments(); //.get(1);
		values.put(LOCAL_UPDATE_TIME, System.currentTimeMillis());
        int count = db.update(DB_TABLE_NAME, values, BaseColumns._ID + "=?", new String[]{taskId});
		if(count == 0){
			//Log.d(Constants.TAG_EMOP, String.format("insert new item '%s:%s'", taskId,
			//		values.getAsString(WEIBO_ID)));
			values.put(BaseColumns._ID, taskId);
			db.insert(DB_TABLE_NAME, SHOP_ID, values);
		}else {
			//Log.d(Constants.TAG_EMOP, String.format("update shop info'%s:%s'", taskId,
			//		values.getAsString(SHORT_KEY) + ", cate:" + values.getAsString(ROOT_CATE)));
		}		
		
		return null;			
	}
	
	
	public static void buildShopListQuery(SQLiteQueryBuilder builder, 
			String[] fileds, QueryParam param, Uri uri){
		builder.setTables(Shop.DB_TABLE_NAME);	
		String cate = uri.getQueryParameter("cate");
		
		if(cate != null){
			builder.appendWhere(ROOT_CATE + "='" + cate + "'");
		}
	}
	
	public static void buildQueryId(SQLiteQueryBuilder builder, Uri uri,
			QueryParam param){
		builder.setTables(DB_TABLE_NAME);
		List<String> seg = uri.getPathSegments();
		builder.appendWhere("shop_id='" + seg.get(1) + "'");
	}
	
	public static ContentValues convertJson(JSONObject obj){
		ContentValues v = new ContentValues();
		try{
			if(obj.has("id")){
				v.put("id", obj.getInt("id"));
			}
			if(obj.has(SHORT_KEY)){
				v.put(SHORT_KEY, obj.getString(SHORT_KEY));
			}
			
			if(obj.has(SHOP_LOGO)){
				v.put(SHOP_LOGO, obj.getString(SHOP_LOGO));
			}
			
			if(obj.has(SHOP_TITLE)){
				v.put(SHOP_TITLE, obj.getString(SHOP_TITLE));
			}
	
			if(obj.has(UPDATE_TIME)){
				v.put(UPDATE_TIME, obj.getString(UPDATE_TIME));
			}	
			
			if(obj.has(USER_NICK)){
				v.put(USER_NICK, obj.getString(USER_NICK));
			}	

			if(obj.has(SHOP_TYPE)){
				v.put(SHOP_TYPE, obj.getString(SHOP_TYPE));
			}			
			
			if(obj.has(SHOP_ID)){
				v.put(SHOP_ID, obj.getString(SHOP_ID));
			}		
			if(obj.has(STATUS)){
				v.put(STATUS, obj.getString(STATUS));
			}
			if(obj.has(ROOT_CATE) && obj.getString(ROOT_CATE) != null){
				v.put(ROOT_CATE, obj.getString(ROOT_CATE));
			}	
			if(obj.has(WEIGHT)){
				v.put(WEIGHT, obj.getString(WEIGHT));
			}	
			if(obj.has(SHOP_DESC)){
				v.put(SHOP_DESC, obj.getString(SHOP_DESC));
			}	
			if(obj.has(SHOP_CREDIT)){
				v.put(SHOP_CREDIT, obj.getString(SHOP_CREDIT));
			}			
		}catch (JSONException e) {
			Log.e(Constants.TAG_EMOP, e.toString());
		}
		
		return v;	
	}	
}
 public class TopAndroidClient {
	private static final ConcurrentHashMap<String, TopAndroidClient> CLIENT_STORE = new ConcurrentHashMap<String, TopAndroidClient>();

	private static final String OAUTH_CLIENT_ID = "client_id";
	private static final String OAUTH_REDIRECT_URI = "redirect_uri";
	private static final String OAUTH_CLIENT_SECRET = "client_secret";
	private static final String OAUTH_REFRESH_TOKEN = "refresh_token";

	private static final String SDK_TRACK_ID = "track-id";
	private static final String SDK_DEVICE_UUID = "device-uuid";
	private static final String SDK_TIMESTAMP = "timestamp";
	private static final String SDK_CLIENT_SYSVERSION = "client-sysVersion";
	private static final String SDK_CLIENT_SYSNAME = "client-sysName";
	private static final String SDK_VERSION = "sdk-version";

	private static final String SYS_NAME = "Android";
	private static final String SESSION_DIR = "top.session";
	private static final String LOG_TAG = "TopAndroidClient";

	private String appKey;
	private String appSecret;
	private String redirectURI;
	private ConcurrentHashMap<Long, AccessToken> tokenStore = new ConcurrentHashMap<Long, AccessToken>();
	private Context context;
	private Env env;
	private int connectTimeout = 10000;// 10秒
	private int readTimeout = 30000;// 30秒

	/**
	 * 注册client所需信息。appKey/appSecret/redirectURI的值必须和开放平台开发者中心里注册的信息保持一致
	 * 
	 * @param context
	 * @param appKey
	 * @param appSecret
	 * @param redirectURI
	 */
	public static void registerAndroidClient(Context context, String appKey,
			String appSecret, String redirectURI) {
		registerAndroidClient(context, appKey, appSecret, redirectURI,
				Env.PRODUCTION);
	}

	/**
	 * 注册client所需信息。appKey/appSecret/redirectURI的值必须和开放平台开发者中心里注册的信息保持一致
	 * @see Env
	 * @param context
	 * @param appKey
	 * @param appSecret
	 * @param redirectURI
	 * @param env
	 *            appKey对应的运行环境
	 */
	public static void registerAndroidClient(Context context, String appKey,
			String appSecret, String redirectURI, Env env) {
		if (context == null) {
			throw new IllegalArgumentException("context must not null.");
		}
		if (TextUtils.isEmpty(appKey) || TextUtils.isEmpty(appSecret)
				|| TextUtils.isEmpty(redirectURI)) {
			throw new IllegalArgumentException(
					"appKey,appSecret and redirectURI must not null.");
		}
		TopAndroidClient client = new TopAndroidClient();
		client.setAppKey(appKey);
		client.setAppSecret(appSecret);
		client.setRedirectURI(redirectURI);
		client.setContext(context);
		if (env == null) {
			env = Env.PRODUCTION;
		}
		client.setEnv(env);

		client.revertAccessToken();

		CLIENT_STORE.put(appKey, client);
	}

	/**
	 * 获得事先已经注册的client对象。如果事先没有注册的话返回null
	 * 
	 * @see #registerAndroidClient(Context, String, String, String)
	 * @see #registerAndroidClient(Context, String, String, String, Env)
	 * @param appKey
	 * @return
	 */
	public static TopAndroidClient getAndroidClientByAppKey(String appKey) {
		return CLIENT_STORE.get(appKey);
	}

	private TopAndroidClient() {
	}

	/**
	 * 刷新access token的操作。
	 * 
	 * @see #authorize(Activity)
	 * @see #addAccessToken(AccessToken)
	 * @see AuthorizeListener
	 * @param userId
	 *            不能为null，通过userId确定需要刷新哪个access token。如果对应的access
	 *            token不存在会抛出IllegalArgumentException
	 * @param listener
	 *            不能为null，处理刷新结果的回调函数。
	 * @param async
	 *            是否是异步执行刷新操作
	 * @throws IllegalArgumentException
	 */
	public void refreshToken(Long userId, final AuthorizeListener listener,
			boolean async) {
		if (userId == null) {
			throw new IllegalArgumentException("userId must not null.");
		}
		if (listener == null) {
			throw new IllegalArgumentException("listener must not null.");
		}
		final AccessToken token = this.tokenStore.get(userId);
		if (token == null) {
			throw new IllegalArgumentException("userId:" + userId
					+ " can't found access token.");
		}

		if (async) {
			new Thread() {
				@Override
				public void run() {
					doRefresh(token, listener);
				}
			}.start();
		} else {// 同步
			doRefresh(token, listener);
		}
	}

	/**
	 * 调用浏览器显示授权页面。
	 * 
	 * @param activity
	 *            通过{@code Intent}方式在浏览器上打开授权页面的{@code Activity}，不能为null
	 */
	public void authorize(Activity activity) {
		if (activity == null) {
			throw new IllegalArgumentException("activity must not null.");
		}
		Map<String, String> params = getProtocolParams();
		params.put(OAUTH_CLIENT_ID, appKey);
		params.put(OAUTH_REDIRECT_URI, redirectURI);
		Random random = new Random();
		params.put("rand", String.valueOf(random.nextInt()));

		String str = "";
		try {
			URL url = WebUtils.buildGetUrl(env.getAuthUrl(), params, null);
			str = url.toString();
		} catch (IOException e) {
			throw new RuntimeException(e);// won't happen
		}
		Uri uri = Uri.parse(str);
		Intent it = new Intent(Intent.ACTION_VIEW, uri);
		try {
			ComponentName name = new ComponentName("com.android.browser",
					"com.android.browser.BrowserActivity");
			// 判断系统自带浏览器是否安装
			context.getPackageManager().getActivityInfo(name,
					PackageManager.GET_INTENT_FILTERS);
			it.setComponent(name);
		} catch (Exception e) {
			/*
			 * if an activity with the given class name can not be found on the
			 * system
			 */
			Log.e(LOG_TAG, e.getMessage(), e);
		}
		activity.startActivity(it);
	}
	
	public String getAuthorizeLink(){
		Map<String, String> params = getProtocolParams();
		params.put(OAUTH_CLIENT_ID, appKey);
		params.put(OAUTH_REDIRECT_URI, redirectURI);
		Random random = new Random();
		params.put("rand", String.valueOf(random.nextInt()));

		String str = "";
		try {
			URL url = WebUtils.buildGetUrl(env.getAuthUrl(), params, null);
			str = url.toString();
		} catch (IOException e) {
			throw new RuntimeException(e);// won't happen
		}
		return str;
	}

	/**
	 * 调用TOP API
	 * 
	 * @see TopApiListener
	 * @param params
	 *            系统及业务参数
	 * @param userId
	 *            需要使用哪个用户授权的access token来调用api，当API不需要session key时此参数可以为null
	 * @param listener
	 *            api调用回调处理监听器，不能为null
	 * @param async
	 *            true:异步调用；false:同步调用。Android 3.0以后会限制在UI主线程中同步访问网络，使用同步方式需谨慎
	 * @throws IllegalArgumentException
	 *             当参数<code>params</code>或<code>listener</code>为null时
	 */
	public void api(final TopParameters params, final Long userId,
			final TopApiListener listener, final boolean async) {
		if (params == null) {
			throw new IllegalArgumentException("params must not null.");
		}
		if (listener == null) {
			throw new IllegalArgumentException("listener must not null.");
		}
		final AccessToken tk = getStoredAccessToken(userId);
		if (async) {// 异步调用
			new Thread() {
				@Override
				public void run() {
					invokeApi(params, listener, tk);
				}
			}.start();
		} else {// 同步
			invokeApi(params, listener, tk);
		}

	}

	/**
	 * useId为null时返回null，如果userId对应的access token不存在则抛出异常
	 * 
	 * @param userId
	 * @return
	 * @throws IllegalArgumentException
	 */
	private AccessToken getStoredAccessToken(final Long userId) {
		AccessToken token = null;
		if (userId != null) {
			token = this.tokenStore.get(userId);
			if (token == null) {
				throw new IllegalArgumentException("userId:" + userId
						+ " can't found access token.");
			}
		}
		return token;
	}

	/**
	 * 调用TQL服务
	 * 
	 * @see TopApiListener
	 * @param ql
	 * @param userId
	 *            需要使用哪个用户授权的access token来调用api，当API不需要session key时此参数可以为null
	 * @param listener
	 *            tql调用回调处理监听器，不能为null
	 * @param async
	 *            true:异步调用；false:同步调用。Android 3.0以后会限制在UI主线程中同步访问网络，使用同步方式需谨慎
	 * @throws IllegalArgumentException
	 *             当参数<code>ql</code>或<code>listener</code>为null时
	 */
	public void tql(final String ql, final Long userId,
			final TopTqlListener listener, final boolean async) {
		if (TextUtils.isEmpty(ql)) {
			throw new IllegalArgumentException("ql must not null.");
		}
		if (listener == null) {
			throw new IllegalArgumentException("listener must not null.");
		}
		final AccessToken token = getStoredAccessToken(userId);

		if (async) {// 异步调用
			new Thread() {
				@Override
				public void run() {
					invokeTql(ql, token, listener);
				}
			}.start();
		} else {// 同步
			invokeTql(ql, token, listener);
		}

	}

	private void invokeTql(final String ql, AccessToken token,
			TopTqlListener listener) {
		TreeMap<String, String> params = new TreeMap<String, String>();
		params.put("ql", ql);
		params.put("app_key", appKey);
		params.put("sign_method", "hmac");
		params.put("top_tql_seperator","true");
		if (token != null) {
			params.put("session", token.getValue());
		}
		String sign;
		try {
			sign = TaobaoUtils.signTopRequestNew(params, appSecret);
			params.put("sign", sign);

			String jsonStr = WebUtils.doPost(context, env.getTqlUrl(), params,
					this.getProtocolParams(), connectTimeout, readTimeout,
					false);
			Log.d(LOG_TAG, jsonStr);
			listener.onComplete(jsonStr);
		} catch (Exception e) {
			Log.e(LOG_TAG, e.getMessage(), e);
			listener.onException(e);
		}
	}

	/**
	 * 获取淘宝系统时间
	 * 注意这里使用的是同步的方式调用api
	 * 
	 * @return
	 */
	public Date getTime() {
		TopParameters params = new TopParameters();
		params.setMethod("taobao.time.get ");
		final List<Date> list = new ArrayList<Date>();

		this.api(params, null, new TopApiListener() {
			@Override
			public void onComplete(JSONObject json) {
				JSONObject j = json.optJSONObject("time_get_response");
				if (j != null) {
					String timeStr = j.optString("time");
					if (!TextUtils.isEmpty(timeStr)) {
						SimpleDateFormat sdf = new SimpleDateFormat(
								"yyyy-MM-dd HH:mm:ss");
						try {
							Date date = sdf.parse(timeStr);
							list.add(date);
						} catch (ParseException e) {
							Log.e(LOG_TAG, e.getMessage(), e);
						}
					}
				}

			}

			@Override
			public void onError(ApiError error) {
			}

			@Override
			public void onException(Exception e) {
			}
		}, false);
		if (list.size() > 0) {
			return list.get(0);
		}
		return new Date();
	}

	private void doRefresh(AccessToken accessToken, AuthorizeListener listener) {
		Map<String, String> header = getProtocolParams();
		Map<String, String> params = new HashMap<String, String>();
		params.put(OAUTH_CLIENT_ID, appKey);
		params.put(OAUTH_CLIENT_SECRET, appSecret);
		params.put(OAUTH_REDIRECT_URI, redirectURI);
		params.put(OAUTH_REFRESH_TOKEN, accessToken.getRefreshToken()
				.getValue());

		try {
			String jsonStr = WebUtils.doPost(context, env.getRefreshUrl(),
					params, header, connectTimeout, readTimeout, true);
			JSONObject json = new JSONObject(jsonStr);
			String error = json.optString("error");
			if (!TextUtils.isEmpty(error)) {
				Log.e(LOG_TAG, jsonStr);

				AuthError authError = new AuthError();
				authError.setError(error);
				authError.setErrorDescription(json
						.optString("error_description"));
				listener.onError(authError);
			} else {
				AccessToken token = TOPUtils.convertToAccessToken(json);
				token.setStartDate(this.getTime());
				addAccessToken(token);
				listener.onComplete(token);
			}
		} catch (Exception e) {
			Log.e(LOG_TAG, e.getMessage(), e);
			listener.onAuthException(new AuthException(e));
		}

	}

	private void invokeApi(TopParameters params, TopApiListener listener,
			AccessToken token) {
		try {
			String jsonStr = WebUtils.doPost(context, env.getApiUrl(),
					this.generateApiParams(params, token),
					this.getProtocolParams(), params.getAttachments(),
					connectTimeout, readTimeout);
			Log.d(LOG_TAG, jsonStr);
			handleApiResponse(listener, jsonStr);
		} catch (Exception e) {
			Log.e(LOG_TAG, e.getMessage(), e);
			listener.onException(e);
		}
	}

	private void handleApiResponse(TopApiListener listener, String jsonStr)
			throws JSONException {
		JSONObject json = new JSONObject(jsonStr);
		ApiError error = this.parseError(json);
		if (error != null) {// failed
			Log.e(LOG_TAG, jsonStr);
			listener.onError(error);
		} else {
			listener.onComplete(json);
		}
	}

	private ApiError parseError(JSONObject json) throws JSONException {
		JSONObject resp = json.optJSONObject("error_response");
		if (resp == null) {
			return null;
		}
		String code = resp.optString("code");
		String msg = resp.optString("msg");
		String sub_code = resp.optString("sub_code");
		String sub_msg = resp.optString("sub_msg");
		ApiError error = null;
		if (!TextUtils.isEmpty(code) || !TextUtils.isEmpty(sub_code)) {
			error = new ApiError();
			error.setErrorCode(code);
			error.setMsg(msg);
			error.setSubCode(sub_code);
			error.setSubMsg(sub_msg);
		}
		return error;
	}

	private Map<String, String> generateApiParams(TopParameters topParameters,
			AccessToken token) throws IOException {
		TreeMap<String, String> params = new TreeMap<String, String>();
		params.put("timestamp", String.valueOf(System.currentTimeMillis()));
		params.put("v", "2.0");
		params.put("app_key", appKey);
		params.put("partner_id", "top-android-sdk");
		params.put("format", "json");
		if (token != null) {
			params.put("session", token.getValue());
		}
		params.put("sign_method", "hmac");
		params.put("method", topParameters.getMethod());

		Map<String, String> map = topParameters.getParams();
		if (map != null) {
			Set<Entry<String, String>> set = map.entrySet();
			for (Entry<String, String> entry : set) {
				params.put(entry.getKey(), entry.getValue());
			}
		}
		List<String> list = topParameters.getFields();
		if (list != null) {
			String fileds = TextUtils.join(",", list);
			if (!TextUtils.isEmpty(fileds)) {
				params.put("fields", fileds);
			}
		}
		String sign = TaobaoUtils.signTopRequestNew(params, appSecret);
		params.put("sign", sign);
		return params;
	}

	private Map<String, String> getProtocolParams() {
		String sign = JNIUtils.getTrackId(context, appKey, appSecret);
		String trackId = sign.substring(0, sign.indexOf("|"));
		String timestamp = sign.substring(sign.indexOf("|") + 1);

		Map<String, String> params = new HashMap<String, String>();
		params.put(SDK_CLIENT_SYSNAME, SYS_NAME);
		params.put(SDK_CLIENT_SYSVERSION, android.os.Build.VERSION.RELEASE);
		params.put(SDK_DEVICE_UUID, TOPUtils.getDeviceId(context));
		params.put(SDK_TRACK_ID, trackId);
		params.put(SDK_TIMESTAMP, timestamp);
		params.put(SDK_VERSION, JNIUtils.getSDKVersion());

		return params;
	}

	private void revertAccessToken() {
		File sessionDir = new File(context.getFilesDir(), SESSION_DIR);
		if (!sessionDir.exists()) {
			return;
		}

		File[] tokenFiles = sessionDir.listFiles(new FilenameFilter() {
			public boolean accept(File dir, String name) {
				String prefix = new StringBuilder(appKey).append("_")
						.toString();
				return name.startsWith(prefix);
			}
		});

		if (tokenFiles != null && tokenFiles.length > 0) {
			for (File tokenFile : tokenFiles) {
				FileInputStream in = null;
				ObjectInputStream objIn = null;
				try {
					in = new FileInputStream(tokenFile);
					objIn = new ObjectInputStream(in);
					AccessToken token = (AccessToken) objIn.readObject();

					Long userId = getUserIdFromAccessToken(token);
					if (userId != null) {
						tokenStore.put(userId, token);
					}
				} catch (Exception e) {
					// 出现异常先跳过，只记录日志
					Log.e(LOG_TAG, e.getMessage(), e);
				} finally {
					if (objIn != null) {
						try {
							objIn.close();
						} catch (IOException e) {
							Log.e(LOG_TAG, e.getMessage(), e);
						}
					}
					if (in != null) {
						try {
							in.close();
						} catch (IOException e) {
							Log.e(LOG_TAG, e.getMessage(), e);
						}
					}
				}

			}
		}
	}

	private void persistenceAccessToken(String appkey, AccessToken token)
			throws IOException {
		if (TextUtils.isEmpty(appkey)) {
			throw new IllegalArgumentException("appkey must not empty.");
		}
		if (token == null) {
			throw new IllegalArgumentException("token must not null.");
		}
		File sessionDir = new File(context.getFilesDir(), SESSION_DIR);
		if (!sessionDir.exists()) {
			sessionDir.mkdir();
		}
		Long userId = getUserIdFromAccessToken(token);
		String fileName = new StringBuilder(appkey).append("_").append(userId)
				.toString();
		File tokenFile = new File(sessionDir, fileName);

		FileOutputStream output = null;
		ObjectOutputStream objOutput = null;
		try {
			output = new FileOutputStream(tokenFile);
			objOutput = new ObjectOutputStream(output);
			objOutput.writeObject(token);
			objOutput.flush();
		} finally {
			if (output != null) {
				output.close();
			}
			if (objOutput != null) {
				objOutput.close();
			}
		}
	}

	private Long getUserIdFromAccessToken(AccessToken accessToken) {
		String idStr = accessToken.getAdditionalInformation().get(
				AccessToken.KEY_SUB_TAOBAO_USER_ID);
		Long userId = idStr == null ? null : Long.valueOf(idStr);
		if (userId == null) {
			idStr = accessToken.getAdditionalInformation().get(
					AccessToken.KEY_TAOBAO_USER_ID);
			userId = idStr == null ? null : Long.parseLong(idStr);
		}
		return userId;
	}

	public String getAppKey() {
		return appKey;
	}

	public void setAppKey(String appKey) {
		this.appKey = appKey;
	}

	public String getAppSecret() {
		return appSecret;
	}

	public Context getContext() {
		return context;
	}

	public void setContext(Context context) {
		this.context = context;
	}

	public void setAppSecret(String appSecret) {
		this.appSecret = appSecret;
	}

	public String getRedirectURI() {
		return redirectURI;
	}

	public void setRedirectURI(String redirectURI) {
		this.redirectURI = redirectURI;
	}

	public AccessToken getAccessToken(Long userId) {
		return tokenStore.get(userId);
	}
	
	/**
	 * 保存access token在内存和文件系统中
	 * @see #getAccessToken(Long)
	 * @param accessToken
	 * @throws IOException
	 */
	public void addAccessToken(AccessToken accessToken) throws IOException {
		Long userId = getUserIdFromAccessToken(accessToken);
		if (userId == null) {
			return;
		}

		tokenStore.put(userId, accessToken);
		persistenceAccessToken(appKey, accessToken);
	}

	public int getConnectTimeout() {
		return connectTimeout;
	}

	public void setConnectTimeout(int connectTimeout) {
		this.connectTimeout = connectTimeout;
	}

	public int getReadTimeout() {
		return readTimeout;
	}

	public void setReadTimeout(int readTimeout) {
		this.readTimeout = readTimeout;
	}

	public ConcurrentHashMap<Long, AccessToken> getTokenStore() {
		return tokenStore;
	}

	public void setTokenStore(ConcurrentHashMap<Long, AccessToken> tokenStore) {
		this.tokenStore = tokenStore;
	}

	public Env getEnv() {
		return env;
	}

	public void setEnv(Env env) {
		this.env = env;
	}
	
	/**
	 * client运行环境枚举值
	 * @author junyan.hj
	 *
	 */
	public static enum Env {
		/**
		 * 生产环境
		 */
		PRODUCTION,
		/**
		 * 沙箱环境
		 */
		SANDBOX,
		/**
		 * 淘宝内部测试环境，isv禁止使用
		 */
		DAILY;

		private static final Map<String, String> URL_CONFIG = new HashMap<String, String>();
		static {
			URL_CONFIG.put("CONTAINER_URL_PRODUCTION",
					"https://oauth.taobao.com");
			URL_CONFIG.put("CONTAINER_URL_SANDBOX",
					"https://oauth.tbsandbox.com");
			URL_CONFIG.put("CONTAINER_URL_DAILY",
					"https://oauth.daily.taobao.net");

			URL_CONFIG.put("TOP_URL_PRODUCTION", "http://gw.api.taobao.com");
			URL_CONFIG.put("TOP_URL_SANDBOX", "http://gw.api.tbsandbox.com");
			URL_CONFIG.put("TOP_URL_DAILY", "http://10.232.127.144");
		}

		private String getConfigedValue(String keyPrefix) {
			String key = new StringBuilder(keyPrefix).append(toString())
					.toString();
			String url = URL_CONFIG.get(key);
			return url;
		}

		public String getApiUrl() {
			String url = getConfigedValue("TOP_URL_");
			return new StringBuilder(url).append("/router/rest").toString();
		}

		public String getTqlUrl() {
			String url = getConfigedValue("TOP_URL_");
			return new StringBuilder(url).append("/tql/2.0/json").toString();
		}

		public String getAuthUrl() {
			String url = getConfigedValue("CONTAINER_URL_");
			return new StringBuilder(url).append(
					"/authorize?response_type=token&view=wap").toString();
		}

		public String getRefreshUrl() {
			String url = getConfigedValue("CONTAINER_URL_");
			return new StringBuilder(url).append(
					"/token?grant_type=refresh_token").toString();
		}
	}
}
 public class TopParameters {

	private String method;
	private List<String> fields=new ArrayList<String>();
	private Map<String,String> params=new HashMap<String,String>();
	private Map<String,FileItem> attachments=new HashMap<String,FileItem>();
	
	/**
	 * 添加返回数据字段
	 * 
	 * @param value
	 */
	public void addFields(String... value){
		if(value!=null){
			for(String v:value){
				fields.add(v);
			}
		}
	}
	/**
	 * 添加业务参数
	 * @param key
	 * @param value
	 */
	public void addParam(String key,String value){
		params.put(key, value);
	}
	/**
	 * 获取已添加的业务参数
	 * @param key
	 * @return
	 */
	public String getParam(String key){
		return params.get(key);
	}
	/**
	 * 删除已添加的业务参数
	 * @param key
	 */
	public void removeParam(String key){
		params.remove(key);
	}
	/**
	 * 添加附件
	 * @param key
	 * @param file
	 */
	public void addAttachment(String key,FileItem file){
		if(file==null){
			return;
		}
		attachments.put(key, file);
	}
	/**
	 * 获取已添加的附件
	 * @param key
	 * @return
	 */
	public FileItem getAttachment(String key){
		return attachments.get(key);
	}
	/**
	 * 删除已添加的附件
	 * @param key
	 */
	public void removeAttachment(String key){
		attachments.remove(key);
	}
	
	public String getMethod() {
		return method;
	}
	/**
	 * 设置准备调用的api名字
	 * @param method
	 */
	public void setMethod(String method) {
		this.method = method;
	}
	public List<String> getFields() {
		return fields;
	}
	public void setFields(List<String> fields) {
		this.fields = fields;
	}
	public Map<String, String> getParams() {
		return params;
	}
	public void setParams(Map<String, String> params) {
		this.params = params;
	}
	public Map<String, FileItem> getAttachments() {
		return attachments;
	}
	public void setAttachments(Map<String, FileItem> attachment) {
		this.attachments = attachment;
	}
	
}
 public class ApiError {
	private String errorCode;
	private String msg;
	private String subCode;
	private String subMsg;

	public String getErrorCode() {
		return errorCode;
	}

	public void setErrorCode(String errorCode) {
		this.errorCode = errorCode;
	}

	public String getMsg() {
		return msg;
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}

	public String getSubCode() {
		return subCode;
	}

	public void setSubCode(String subCode) {
		this.subCode = subCode;
	}

	public String getSubMsg() {
		return subMsg;
	}

	public void setSubMsg(String subMsg) {
		this.subMsg = subMsg;
	}
	
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("errorCode:").append(this.errorCode).append(" msg:")
				.append(this.msg).append(" subCode:").append(subCode)
				.append(" subMsg:").append(this.subMsg);
		return builder.toString();
	}
}
 public interface TopApiListener {
	/**
	 * API调用成功后返回值以json对象方式通知监听器
	 * @param json
	 */
	void onComplete(JSONObject json);
	/**
	 * 出现业务错误时通知监听器错误码及字错误码等信息
	 * @param error
	 */
	void onError(ApiError error);
	/**
	 * 出现网络问题等未知异常时会回调此方法
	 * @param e
	 */
	void onException(Exception e);
}

import java.util.HashMap;
import java.util.Map;
import org.json.JSONArray;
import org.json.JSONObject;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Intent;
import android.content.res.TypedArray;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.provider.SyncStateContract.Columns;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.baidu.mobstat.StatService;
import com.emop.client.BaseActivity;
import com.emop.client.Constants;
import com.emop.client.R;
import com.emop.client.WebViewActivity;
import com.emop.client.fragment.adapter.CreditAdapter;
import com.emop.client.io.ApiResult;
import com.emop.client.io.FmeiClient;
import com.emop.client.io.TaodianApi;
import com.emop.client.provider.Schema;
import com.emop.client.provider.model.Item;
import com.emop.client.provider.model.Shop;
import com.taobao.top.android.TopAndroidClient;
import com.taobao.top.android.TopParameters;
import com.taobao.top.android.api.ApiError;
import com.taobao.top.android.api.TopApiListener;

package com.emop.client.fragment;





public class ShopSummaryFragment extends Fragment {
	private View root = null;
	private Items items = null;
    protected Handler handler = new Handler();	
    private String shopId = null;
    private String dataFrom = "";
    private boolean isRunning = false;
    private int shopRefreshTimes = 0;
    private String shortUrl = null;
    private boolean loaded = false;
    
    
	public void onResume(){
		super.onResume();
		isRunning = true;
	}
	
	public void onPause(){
		super.onPause();
		isRunning = false;
	}    
	
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState){				
		if(dataFrom != null && dataFrom.equals("taoke_detail")){
			root = inflater.inflate(R.layout.taoke_detail_shop_header, container, false);
		}else {
			root = inflater.inflate(R.layout.shop_detail_header, container, false);			
		}	
		
		items = new Items(root);
		
		Log.d("emop", "onCreateView data from:" + dataFrom);

		root.setClickable(true);
		root.setOnClickListener(new OnClickListener(){
			public void onClick(View arg){
				Log.d("emop", "click shop in item detail");
				ItemActionBar bar = (ItemActionBar)getFragmentManager().findFragmentById(R.id.nav_footer);
				if(bar != null){
					bar.goBuy();
				}else {
					goShopBuy();
				}
			}
		});
		
		return root;
	}
	
    @Override 
    public void onInflate(Activity activity, AttributeSet attrs,

            Bundle savedInstanceState) {

        super.onInflate(activity, attrs, savedInstanceState);
        TypedArray a = activity.obtainStyledAttributes(attrs, R.styleable.FragmentArguments);
        dataFrom = a.getString(R.styleable.FragmentArguments_data_source);
        a.recycle();  
        
		Log.d("emop", "onInflate data from:" + dataFrom);

    }	
    
    public void goShopBuy(){
    	if(shopId != null && shopId.length() > 1 && shopId.length() < 10 && loaded){
    		String url = String.format("http://shop%s.taobao.com/", shopId);
    		if(shortUrl != null && shortUrl.length() > 0){
    			url = "http://c.emop.cn/c/" + shortUrl + "?from=app";
    		}
	    	StatService.onEvent(getActivity(), "go_shop", shopId + "_" + "no_short", 1);
	    	Intent intent = new Intent().setClass(getActivity(), WebViewActivity.class);
	    	intent.putExtra("http_url", url);
	    	this.startActivity(intent);    	
    	}else {
    		Toast.makeText(getActivity(), "店铺信息加载中，稍后再试。", Toast.LENGTH_SHORT).show();
    	}
    }
	
	public void loadShop(String id, String numIId){
		this.shopId = id;
		boolean isOk = false;
		if(shopId != null){
			long tempId = Long.parseLong(shopId);
			if(tempId > 0 && tempId < 1000000000){
				isOk = true;
				handler.post(new Runnable(){
					public void run(){
						if(isRunning){
							getLoaderManager().initLoader(0, null, callbacks);	
						}
					}
				});
			}
		}
		if(!isOk && numIId != null){
			Log.d("emop", "load shop info for num iid:" + numIId);

			FmeiClient.getInstance(null).appImgLoader.runTask(new ShopIdFixPatch(numIId));
