2013年11月12日 星期二

team foundation server 2010 初次見面(設定)

因為這次是有用不同的MSQQL instance,所以不是用預設的方式
開啟tfs configuration center,選用「Advanced」


第二步驟,選擇server instance,別忘了加入我們手動設定的instance

Account方面,用預設的 Local Service就可以了

Analysis service單元,老樣子,別忘了 sql server instance 全名要加上去,按"test"試過才可以哦


Report service方面,別忘了指定帳號,也要test一下卡保險:

Sharepoint service,請用內建的吧:

 先看一下設定有沒有漏勾去:

好,最重要的一點,先verify(驗證看看再說,有錯誤一定要修正)

恭喜,都過了,那就Configue吧


如何create team project 呢?

 裝好了,來到vs2012的開發介面,找一下小組->連接到Team foundation server


右邊就會出現 Team explorer功能區,點一下「連結」
這時,要加入我們剛才設定好的tfs2010 server

 連上去,並選擇Team project collection.


目前只是連接到Team project collection,現在重點來了,要create team project
一樣是在Team Explorer功能表區,點一下插頭icon(連接到Team 專案),

看到下面的「新增Team 專案」了吧?點一下就可以定義team project了

沒意外的話,專案就新建完成了:


這時,再回到tfs server的Administration Console介面中,看一下「Team Project Collections」
看一下Team Proeject Collection下面的「Team Proejcts」就可以看到我們所create的Team Project了


 以上,大家加油了


2013年10月31日 星期四

老生常談--MVC action result 如何輸出檔案?

基本上asp.net web form 方式的檔案下載大家應該很熟了
======例,在某列中找出下載的檔案資料===============
 protected void DownloadDoc_Click(object sender, EventArgs e) {
            ImageButton imageButton = (ImageButton)sender;
            TableCell tableCell = (TableCell)imageButton.Parent;
            GridViewRow row = (GridViewRow)tableCell.Parent;
            ;
            //GridView1.SelectedIndex = row.RowIndex;
            //doc path is found by the datakey attribute of grid and corresponding field/column
            string docPath = GridView1.DataKeys[row.RowIndex]["DOC_PATH"].ToString();
            //trigger the download process.
            string filename = Path.GetFileName(docPath);
            System.IO.Stream stream = null;
            try
            {
                // Open the file into a stream.
                stream = new FileStream(docPath, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read);
                // Total bytes to read:
                long bytesToRead = stream.Length;
                Response.ContentType = "application/octet-stream";
                string fileExt = Path.GetExtension(docPath);
                Response.AddHeader("Content-Disposition", "attachment; filename=" +
                    util.MisFunc.ConvertDateTimeToJavaMilliSecond(System.DateTime.Now) + fileExt);
                   
                // Read the bytes from the stream in small portions.
                while (bytesToRead > 0)
                {
                    // Make sure the client is still connected.
                    if (Response.IsClientConnected)
                    {
                        // Read the data into the buffer and write into the
                        // output stream.
                        byte[] buffer = new Byte[10000];
                        int length = stream.Read(buffer, 0, 10000);
                        Response.OutputStream.Write(buffer, 0, length);
                        Response.Flush();
                        // We have already read some bytes.. need to read
                        // only the remaining.
                        bytesToRead = bytesToRead - length;
                    }
                    else
                    {
                        // Get out of the loop, if user is not connected anymore..
                        bytesToRead = -1;
                    }
                }
            }
            catch (Exception ex)
            {
                Response.Write(ex.Message);
                // An error occurred..
            }
            finally
            {
                if (stream != null)
                {
                    stream.Close();
                }
            }
        }
====================================================
那ASP.net MVC4呢?
==============MVC4的寫法更簡潔======================
using System.Net.Mime;
using System.IO;
...
...
 public FileStreamResult getPdfFile(string path) {
                        string path = (string)recFile["DOC_PATH"];
                        var contentDisposition = new ContentDisposition
                        {
                            FileName = "doc.pdf",
                            Inline = true
                        };
                        Response.AppendHeader("Content-Disposition", contentDisposition.ToString());
                        byte[] bytes = System.IO.File.ReadAllBytes(path); //ReportStore.GetProfileInByte(path);
                        MemoryStream ms = new MemoryStream(bytes);
                        return new FileStreamResult(ms, MediaTypeNames.Application.Pdf);
 
}
================================================

2013年10月27日 星期日

for sencha-touch store 載入一堆空白的資料列!! 那會安爾!?

今天在實作下拉載入分頁的List時
(好吧,先分享一下最短的實作好了,也不過是從書上抄來的)
====sample as below=======================
     Ext.Viewport.setMasked({xtype:'loadmask',message:'Loading Data....'});
      var storeFiles=Ext.create('Ext.data.Store', {
                autoDestroy:true,
                model: 'TocMobile.model.FileMdl',
                pageSize:4,
                //storeId: 'Store4Files',
                autoLoad:false,
                proxy: {
                    type: 'ajax',
                    actionMethods: {
                        create: 'POST',
                        read: 'POST',
                        update: 'POST',
                        destroy: 'POST'
                    },
                    extraParams: {
                        icNo: icNo,
                        password: password
                    },
                    url: 'http://'+SERVER_IP+'/TocMobile/.....',
                    reader: {
                        type: 'json',
                        rootProperty: 'rows'
                    }
                }
           
        });  
   
    storeFiles.load(
        function(){
               Ext.Viewport.setMasked(false);
                var fileTemplate=new Ext.XTemplate(
                    '<tpl for=".">',
                    '<div class="File2Download" >',
                    '  <span class="icondownlaod" >',
                    '      <img src="./Adobe_PDF_Icon.svg.png" width="40" height="40" />',
                    '  </span>',
                    '    <span class="UploadDate">{uploadDate}</span>',
                    '  <br>',
                    '      <span class="UploadDetail">{uploadRemark}</span>',
                    '</div>',                  
                    '</tpl>'
                );
                var list=Ext.create('Ext.List',{
                    store:storeFiles,
                    height:'100%',
                    itemTpl:fileTemplate,
                    plugins:[
                        {
                            xclass:'Ext.plugin.ListPaging',
                            autoPaging:true,
                            loadMoreText:'Next...'
                        }
                    ],
                    emptyText:'No Data!!'
                 
                });
                    var pnlFileList= Ext.getCmp('PnlMain4FileListUnit');
                    pnlFileList.getComponent('lblFileListStatus').setHtml("  File Listing");
                    pnlFileList.getComponent('pnlListFiles').removeAll();
                    pnlFileList.getComponent('pnlListFiles').add(list);
           
        }
    );
============end of sample code============================
在測試時,卻一直發生load時來了5百多筆的空白資料!!!
明明別人的程式都正常的啊
John組長眉頭一皺,案情並不單純是client的問題
原來.....是出在server side沒事把資料列用「new JavaScriptSerializer().Serialize(...)」
變成「json內的字串格式」
==============以下是錯誤的,小心!!=================
                        List<File2Download> listfile=new List<File2Download>();
                        ...
                       ...
                        var result = new
                        {
                            success = true,
                            total=toalRowCount,
                            rows =new JavaScriptSerializer().Serialize(listfile)
                        };
                      JsonResult jResult = new JsonResult();
                      jResult.Data = result;
                      jResult.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
            return jResult;
  
==============================================
吐出來的字串就成了
   "{"success":true,"total":30,"rows":[{\"uploadDate\":\"2013-08-29\",\"docPath\":\"test path\",\"uploadRemark\":\"test remark\"},...]}";

  哎,既然是用「JsonResult」,就給他放心去轉換成字串就是了嘛
  =======以下才是正確的==========================
                        List<File2Download> listfile=new List<File2Download>();
                        ...
                       ...
                        var result = new
                        {
                            success = true,
                            total=toalRowCount,
                            rows =listfile  //--->就這樣,別手賤!!
                        };
                      JsonResult jResult = new JsonResult();
                      jResult.Data = result;
                      jResult.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
            return jResult;
=========================================
吐出來的就成了:
  {"success":true,"total":30,"rows":[{"uploadDate":"2012-10-15","docPath":"test path","uploadRemark":"test remark"},...]}
 神奇的是Sencha Touch 的store物件會解開那堆字變成文字的成為一堆空白資料列而且還不會給你出現exception/error才叫麻煩吧
Anyway,總之,別隨便用「JavaScriptSerializer().Serialize(...)」方法就是了


2013年10月20日 星期日

Android包html5網頁,用到定位權限時的設定

最近先用動態網頁寫好再用android / ios去包成app的開發方式頗為流行
所以順勢把之前的掌上商城andriod版一點一點地改成mobile web來包看看
不過光是在定位時發生問題.
WebView要如何使用Goelocation的權限呢?
步驟1,在 AndroidManifest.xml 指定以下權限:
   ======================================
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_GPS" />
<uses-permission android:name="android.permission.ACCESS_ASSISTED_GPS" />
<uses-permission android:name="android.permission.ACCESS_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />  
=============================================
步驟二,在WebView的setting中設定以下權限:
   (假設Activity中有個「mWebView.」WebView型態的變數)
    =============================================
        mWebView.getSettings().setGeolocationEnabled(true);
        mWebView.getSettings().setAppCacheEnabled(true);
        mWebView.getSettings().setDatabaseEnabled(true);
        mWebView.getSettings().setDomStorageEnabled(true);        
   =============================================
步驟三,在遇到請求權限時,包裝的app如何應對?
   ===========================================
          mWebView.setWebChromeClient(new WebChromeClient() {
        public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
           callback.invoke(origin, true, false);
        }
        });        
=====================================
以上,其他的就照大家最常看到的webview應用來做了


2013年10月18日 星期五

好文轉貼使用ASP.NET SimpleMembership 提供者

最近有遇到asp.net MVC4.5的 權限整合問題:
 原來的前後台版本是用WebMatrix/WebSecurity,
 而如今前台要改版成為行動版,而VS2012的mobile的範本的membership機制是用「Universal Provider」,這下子麻煩大了
所幸,前人已經踢過鐵板了,參考這篇連結吧
使用ASP.NET SimpleMembership 提供者
以及
To call this method, the “Membership.Provider” property must be an instance of “ExtendedMembershipProvider”

另外,以下摘錄實作程序(真的是我實過也試過可以run)
步驟一,修改web.config,加入原本auth的db connection
   =====================
  <connectionStrings>
    <add name="memberConnection" ........ providerName="System.Data.SqlClient" />
  </connectionStrings>
   =====================

步驟二.在web.config中,把原本的
==========================
   <profile defaultProvider="DefaultProfileProvider">
    ...
    ...
  </roleManager>
==============================
 改成以下的設定:
  ==============================================
 <profile defaultProvider="SimpleProfileProvider">
      <providers>
        <add name="SimpleProfileProvider" type="WebMatrix.WebData.SimpleMembershipProvider, WebMatrix.WebData" connectionStringName="DefaultConnection" applicationName="/" />
      </providers>
    </profile>
    <membership defaultProvider="SimpleMembershipProvider">
      <providers>
        <add name="SimpleMembershipProvider" type="WebMatrix.WebData.SimpleMembershipProvider, WebMatrix.WebData" />
      </providers>
    </membership>
    <roleManager defaultProvider="SimpleRoleProvider">
      <providers>
        <add name="SimpleRoleProvider" type="WebMatrix.WebData.SimpleRoleProvider, WebMatrix.WebData" />
      </providers>
    </roleManager>    
  ==============================================

步驟三,,安裝套件「WebMatrix.WebData」

步驟四,到Gloabal.aspx.cs的 Application_Start函數,加上webSecurity的起始設定
 (當然這是基於你已經把role/user_profile...等其他資料表都開好的假設)
  ==========================
 protected void Application_Start()
        {
          //memberConnection是我們在web.config中設定的connection string.
            WebSecurity.InitializeDatabaseConnection("memberConnection", "StoreManager", "UserId", "UserName", autoCreateTables: true);

            AreaRegistration.RegisterAllAreas();
            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }
  ==========================
步驟五,修改model中,RegisterModel等其他model的欄位,有的非必要的就把他的[Required]拿掉
步驟六.修改Account Controller--基本上都不必改,唯一要改的是「新建用戶帳號」那段
  因為實作是委託給WebSecurity,所以小改一下才會成功:
  =======原本========================
  public ActionResult Register(RegisterModel model)
        {
            if (ModelState.IsValid)
            {
                // 嘗試註冊使用者
                MembershipCreateStatus createStatus;
                Membership.CreateUser(model.UserName, model.Password, model.Email, passwordQuestion: null, passwordAnswer: null, isApproved: true, providerUserKey: null, status: out createStatus);

                if (createStatus == MembershipCreateStatus.Success)
                {
                    FormsAuthentication.SetAuthCookie(model.UserName, createPersistentCookie: false);
                    return RedirectToAction("Index", "Home");
                }
                else
                {
                    ModelState.AddModelError("", ErrorCodeToString(createStatus));
                }
               
            }

            // 如果執行到這裡,發生某項失敗,則重新顯示表單
            return View(model);
        }
  ==============改為==================================
public ActionResult Register(RegisterModel model)
        {
            if (ModelState.IsValid)
            {
                try {
                    WebMatrix.WebData.WebSecurity.CreateUserAndAccount(model.UserName, model.Password);
                    //自己再加入user & Role mapping table--「webpages_UsersInRoles」的inser動作吧...
                    FormsAuthentication.SetAuthCookie(model.UserName, createPersistentCookie: false);
                    return RedirectToAction("Index", "Home");
                }catch(Exception exp)
                {
                    ModelState.AddModelError("", exp.Message);
                }
            }

            // 如果執行到這裡,發生某項失敗,則重新顯示表單
            return View(model);
        }
======================================================
其他登入/改變密碼都沒問題.這樣算是大功告成了!!

以上,誌於 2013.10.19

2013年10月11日 星期五

for android:最小的取得經緯度函數

import java.util.List;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;

import com.neotech.goingtvmall.frontend.R.id;
import com.neotech.goingtvmall.frontend.SubStoreTypeListActivity.MyAdapter;

import android.content.Context;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.ListView;
import android.widget.TextView;

public class GeolocationFunc {


public static String getAddress(Location location,Context ctxOfActivity)throws Exception{
        Geocoder geocoder;
        geocoder = new Geocoder(ctxOfActivity, Locale.getDefault());
List<Address> addresses=
geocoder.getFromLocation(location.getLatitude(),
                location.getLongitude(), 1);
//geocoder.getFromLocation(currentlocation.getLatitude(),currentlocation.getLongitude(), 1);
StringBuffer sb=new StringBuffer();
for(Address address : addresses){
   String addressLine = address.getAddressLine(0);
       String city = address.getAddressLine(1);
       String country = address.getAddressLine(2);
       Log.v("addr",addressLine+" "+city+" "+country);
       if(city==null)city="";
       if(country==null)country="";
       sb.append(addressLine+" "+city+" "+country+"附近");
}
return sb.toString();
}

public static Location getBestLocation(Context ctxt) {
   Location gpslocation = getLocationByProvider(
       LocationManager.GPS_PROVIDER, ctxt);
   Location networkLocation = getLocationByProvider(
       LocationManager.NETWORK_PROVIDER, ctxt);
   Location fetchedlocation = null;
   // if we have only one location available, the choice is easy
   if (gpslocation != null) {
       Log.i("New Location Receiver", "GPS Location available.");
       fetchedlocation = gpslocation;
   } else {
       Log.i("New Location Receiver",
           "No GPS Location available. Fetching Network location lat="
               + networkLocation.getLatitude() + " lon ="
               + networkLocation.getLongitude());
       fetchedlocation = networkLocation;
   }
   return fetchedlocation;
}

/**
* get the last known location from a specific provider (network/gps)
*/
private static Location getLocationByProvider(String provider, Context ctxt) {
   Location location = null;
   // if (!isProviderSupported(provider)) {
   // return null;
   // }
   LocationManager locationManager = (LocationManager) ctxt
           .getSystemService(Context.LOCATION_SERVICE);
   try {
       if (locationManager.isProviderEnabled(provider)) {
           location = locationManager.getLastKnownLocation(provider);
       }
   } catch (IllegalArgumentException e) {
       Log.i("New Location Receiver", "Cannot access Provider " + provider);
   }
   return location;
}
}

2013年10月2日 星期三

Windows Server 2012 評估版與延長使用期限

延長使用期限

跟 Windows Server 2008 延長使用天數的方法一樣,都可以重設授權 5 次,差別在於,執行重設授權並重新開機之後,Windows 就自動啟用了,不會先有 10 天的寬限期。
我們先用這個指令查看剩下的天數,以及可以重設授權 (Rearm) 的次數:
slmgr.vbs -dlv
在 180 天的使用天數即將到期前一、兩天,你需要再執行:
slmgr.vbs -rearm
重新開機後 Windows 又會有 180 天的試用期了。而重設授權的次數會少一次。經由重覆執行重設授權的步驟,理論上 Windows Server 2012 可以讓你合法試用 1080 天。
須注意的是,一定要在到期日前去重設授權,否則你會無法登入 Windows,只能重新安裝或輸入自己購買的 Windows 序號來啟用。而你如果有去更改系統時間,也有可能會造成這 180 天的試用期失效,如果發現試用期失效的話,也必須立即執行重設授權才行。

繼續延長使用期限

如果 1080 天的試用期到了,而你的機器還沒壞、公司還沒倒、你還在當 MIS,而你還是不想花錢要繼續 "試用" Windows Server 2012 的話,跟 Windows Server 2008 一樣,透過修改機碼來增加重設授權次數的技巧依然有用。
執行 "regedit",進到:
"HKEY_LOCAL_MACHINE" -> "SOFTWARE" -> "Microsoft" -> "Windows NT" -> "CurrentVersion" -> "Software" -> "ProtectionPlatform"

將 "SkipRearm" 的鍵值修改為 "1",改完又可以再用 "slmgr.vbs -rearm" 一次,據說此步驟可以用 8 次。


詳細內容:
http://www.vixual.net/blog/archives/180

2013年10月1日 星期二

win8 (64)之下,怎麼修改MAC Address

為什麼要修改MAC address?
有時某些遠端遙控軟體過了期用試之後,就可以用這方式重新得到一組新的id

在win8 (server 2012) 64中,如何修改?

請去 http://www.gorlani.com/portal/projects/macmakeup-for-vista-seven-2008-windows-8
下載「mcmkup.ps1」
用powershell 去執行
事實些就是一個指令「s 0 20Fe3092yz」
其中的0,指的是第0張網卡,
後面的20Fe3092xyz就是MAC address型態20:Fe:30:92:yz之意
當然你以用 「c」指令還原到初始值再指定其他Mac address
指令成功時會出現
Here is the list of  physical NICs on this host
0) Ethernet,[網卡型態],spoofed : xxxxxx <---你指定的Mac Address.
...
...

這樣就成功了
如此,重新啟動那個遠端遙控軟後,就會有新的id了
試看看吧

2013年9月30日 星期一

win7 Aero 動畫效果的速度,可以調整嗎?

這次重灌系統之後(沒有灌win8,因為有些案子還是win32的案子,64位元的交給內部的win server 2012  64 bit VM)
所有GUI中有關的動畫元素都會變慢,連firefox的頁籤出現消失也一樣
這問題,就算是重灌了driver還是一樣
OK,答案是出在機碼上面
請到
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced
加上一個機碼「
DesktopLivePreviewHoverTime」
資料型態是DoubleWord,值看你怎麼給(我是給Decimal 100)
設定完之後重開機就可以看到效果了

2013年9月14日 星期六

android: 在ScrollView->relativelayout中的背景圖無法延伸涵蓋整個大螢幕!?

layout:
=================================
 <ScrollView xmlns:....
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
      <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scaleType="fitXY"
        android:background="@drawable/welcome_bg"
        android:gravity="fill_vertical|fill_horizontal">
        ....
        ....
        ...
     </RelativeLayout>
</ScrowView>
=================================
在手機上沒這問題,在大平版上就會出現穿迷你裙的窘態
這時只差一個屬性就可以了:
=================================
 <ScrollView xmlns:....
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
   android:fillViewport="true">
     ...
      ....其他不必改
    .....
================================

2013年9月12日 星期四

android : 回上一頁之外還要求其再執行create函數

有時在查詢結果頁後,帶到明細去修改再回去時,你會發現查詢結果頁還是之前暫存的狀態
(因為只是執行resume...那類的activity函數),如何解決這問題?
除了在原先的明細修改中用了 this.finish(); 回上一頁之外,
還是要用到intent 的串頁方式
參考如下:
=================================================
  class QueryResultList extends Activity{
   
  void gotoDetail(){
        intent it....
        startActivity(it);
       
  }
 }

  class DetailItemEditor extends Activity{
     ...
     ...
     ....
    void back(){
        //回上一頁
  Intent itBack2List=new Intent();
        //把以下的串接放在intent queue的最上面,別把目前的activity放上去,
        //不然在QueryResultList 頁的「回上頁」又會跑到目前的activity了.
           itBack2List.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
           itBack2List.setClass(查詢條件頁.ctx4Back ,
                                           QueryResultList.class);
          ((Activity)me).finish();      
 startActivity(itBack2List);

    }
 }
=======================================
這樣,在DetailItemEditor 執行back時,就會重新執行create動作了
加油囉!!

2013年9月4日 星期三

Android : repeat (hold) button

原文出處:
http://stackoverflow.com/questions/7938516/continuously-increase-integer-value-as-the-button-is-pressed
為了怕被移除,先抄個備份吧:
============================================
private boolean mAutoIncrement = false;
private boolean mAutoDecrement = false;
public int mValue;
private Handler repeatUpdateHandler = new Handler();
EditText txtQty;
class RptUpdater implements Runnable {
   public void run() {
       if( mAutoIncrement ){
           increment();
           repeatUpdateHandler.postDelayed( new RptUpdater(), 100 );
       } else if( mAutoDecrement ){
           decrement();
           repeatUpdateHandler.postDelayed( new RptUpdater(), 100 );
       }
   }
}
public void decrement(){
if(mValue==0)return;
   mValue--;
   txtQty.setText( ""+mValue );
}
public void increment(){
   mValue++;
   txtQty.setText( ""+mValue );
}
@Override protected void onCreate(Bundle savedInstanceState) {
           ...
          ...
          ....
         txtQty=(EditText)findViewById(id.txtProdQtyInDialog);
mValue=prod2Proc.orderQty;
txtQty.setText(""+mValue);
Button btnQtyAdd=(Button)findViewById(id.btnQtyPlus);
Button btnQtyMinus=(Button)findViewById(id.btnQtyMinus);

btnQtyAdd.setOnClickListener(
        new OnClickListener(){
@Override
public void onClick(View arg0) {
      increment();
}
         
        }
        );
btnQtyAdd.setOnLongClickListener( 
           new View.OnLongClickListener(){
               public boolean onLongClick(View arg0) {
                   mAutoIncrement = true;
                   repeatUpdateHandler.post( new RptUpdater() );
                   return false;
               }
           }
   );   

btnQtyAdd.setOnTouchListener( new View.OnTouchListener() {
       public boolean onTouch(View v, MotionEvent event) {
           if( (event.getAction()==MotionEvent.ACTION_UP || event.getAction()==MotionEvent.ACTION_CANCEL) 
                   && mAutoIncrement ){
               mAutoIncrement = false;
           }
           return false;
       }
   });  
btnQtyMinus.setOnClickListener(
        new OnClickListener(){
@Override
public void onClick(View arg0) {
      decrement();
}
         
        }
        );
btnQtyMinus.setOnLongClickListener( 
           new View.OnLongClickListener(){
               public boolean onLongClick(View arg0) {
                   mAutoDecrement = true;
                  repeatUpdateHandler.post( new RptUpdater() );
                   return false;
               }
           }
   );   

btnQtyMinus.setOnTouchListener( new View.OnTouchListener() {
       public boolean onTouch(View v, MotionEvent event) {
           if( (event.getAction()==MotionEvent.ACTION_UP || event.getAction()==MotionEvent.ACTION_CANCEL) 
                   && mAutoDecrement ){
               mAutoDecrement = false;
           }
           return false;
       }
   });  
         ...
           ...
          ...
==============================================================
     以上,加油

2013年9月1日 星期日

Properties.System.Media.Duration.Value在 server 2012會成為null !?

在製做多媒體後台時,一定會使用到一些媒體相關的函數
最常在問的就是該媒體播放時間多久(以供廣告成本推估參考)
c#在這方面是有範例
參考這個連結
總之就是下載WindowsAPICodePack,呼叫shell
--------------------------------------------------------------
ShellFile so = ShellFile.FromFilePath(file);
double nanoseconds = 0;
Double.TryParse(so.Properties.System.Media.Duration.Value.ToString(), nanoseconds );
注意這裡取得的 nanoseconds 的單位是 100 nanoseconds,所以要換算成秒的話,可以將變數 nanoseconds 乘以 0.0001 再除以 1000。
--------------------------------------------------------------
很簡單吧,那我幹嘛寫這篇?
以上是在win7 ultimate ,vs2012跑的,很正常,也很稱職
問題來了,如果是在windows server 2012 的vs2012呢?
對不起,Properties.System.Media.Duration.Value.ToString()會出現null
最基本的原因是server 2012預設是不灌media player的,而上述的函數靠的就是呼叫shell去叫media player功能.
所以在server 2012要執行這程式時,請安裝media player
怎麼裝?參考這連結 
裝完就沒事嗎?代志不是這樣就收工去領便當了
請把之前下載的WindowsAPICodePack的「source\WindowsAPICodePack」下的「WindowsAPICodePack」方案(solution)下的core、shell等專案(project)的建置目標都改為64位元平台,build一下,再把你之前要呼叫Properties.System.Media.Duration.Value的專案參考到你build出來的dll(Microsoft.WindowsAPICodePack.Shell.dll & Microsoft.WindowsAPICodePack.dll)

以上,加油了

2013年8月29日 星期四

android:在設備旋轉後,不要再執行create

請在到AndroidManifest.xml中,找到那個Activity的定義
加上這個參數:
            android:configChanges="orientation|screenSize" 
(如果是在tab host中的activity,則請在tabhost所在的activity加上這參數)

2013年8月13日 星期二

For Extjs4,如果是各別欄位設定初值的話 ,如何正確重設dirty flag ?


步驟1.在你的form panle中設定「trackResetOnLoad:true」之,
 

步驟2.
form.ffindField(....).setValue(.....);
...
...
...
...

form.setValues(form.getValues());
form.reset();   <--這時dirty flag就完成重設了


2013年8月2日 星期五

for android ,accept ssl (any host)

1.u need a trust manager
===================code====================
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;


import javax.net.ssl.SSLSession;



public class _FakeX509TrustManager implements X509TrustManager {

    private static TrustManager[] trustManagers;
    private static final X509Certificate[] _AcceptedIssuers = new
X509Certificate[] {};

    @Override
    public void checkClientTrusted(X509Certificate[] chain, String
authType) throws CertificateException {
    }

    @Override
    public void checkServerTrusted(X509Certificate[] chain, String
authType) throws CertificateException {
    }

    public boolean isClientTrusted(X509Certificate[] chain) {
            return true;
    }

    public boolean isServerTrusted(X509Certificate[] chain) {
            return true;
    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
            return _AcceptedIssuers;
    }

    public static void allowAllSSL() {
            HttpsURLConnection.setDefaultHostnameVerifier(
            new HostnameVerifier(){
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
                            return true;
                    }

            });

            SSLContext context = null;
            if (trustManagers == null) {
                    trustManagers = new TrustManager[] { new _FakeX509TrustManager() };
            }

            try {
                    context = SSLContext.getInstance("TLS");
                    context.init(null, trustManagers, new SecureRandom());
            } catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
            } catch (KeyManagementException e) {
                    e.printStackTrace();
            }

   
   HttpsURLConnection.setDefaultSSLSocketFactory(
  context.getSocketFactory());
    }
}
====================================================
2nd,u need a  SSL socket factory:
================code=====================================
import android.net.SSLCertificateSocketFactory;
import android.net.SSLSessionCache;
import android.os.Build;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.params.HttpParams;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManager;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;

public class NeoTechSSLSocketFactory extends SSLSocketFactory{

    SSLContext sslContext = SSLContext.getInstance("TLS");

    public NeoTechSSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
        super(truststore);
        TrustManager tm=new _FakeX509TrustManager();
        sslContext.init(null, new TrustManager[] { tm }, null);
    }

    public NeoTechSSLSocketFactory(SSLContext context) throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException {
       super(null);
       sslContext = context;
    }

    @Override
    public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
        return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
    }

    @Override
    public Socket createSocket() throws IOException {
        return sslContext.getSocketFactory().createSocket();
    }
}
=======================================
 3nd, u need create httpClient from the SSLSocketFacotry
======function  create HttpClient=======================
 private static HttpClient sslClient(HttpClient client) {
   try {
       X509TrustManager tm = new X509TrustManager() {
           public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException {
           }

           public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException {
           }

           public X509Certificate[] getAcceptedIssuers() {
               return null;
           }
       };
       SSLContext ctx = SSLContext.getInstance("TLS");
       ctx.init(null, new TrustManager[]{tm}, null);
       SSLSocketFactory ssf = new NeoTechSSLSocketFactory(ctx);
       ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
       ClientConnectionManager ccm = client.getConnectionManager();
       SchemeRegistry sr = ccm.getSchemeRegistry();
       sr.register(new Scheme("https", ssf, 443));
       return new DefaultHttpClient(ccm, client.getParams());
   } catch (Exception ex) {
       return null;
   }
}
====================================================
4th,now u can use it
=====================caller example==========================
     _FakeX509TrustManager.allowAllSSL();
HttpClient httpclient =  sslClient(new DefaultHttpClient());
   HttpPost httppost = new HttpPost("https://"+SERVER_ADDRESS+destPath);
                            ....其他照舊....
=========================================================

不錯的連結:windows server 2012 IIS8 基礎 設定 教學網站

網址:
http://www.dotblogs.com.tw/jerry710822/archive/2012/08/02/73785.aspx
如果你用到SSL,SSL集中管理、IP 限制....都有教到
給他讚一下吧

2013年7月25日 星期四

android 在 「左側listview fragment+ 右側 Detail Fragment」型態中的master-detail flow中,如何做到切換左側的master時,先執行右側 detail的防呆?

好長的文章抬頭是吧
不知道你有沒有用過android 4.x的平板中「系統設定」中的master & detail介面?
等你實作時,一定會遇到detail fragment 防呆沒跑就切換master item的問題了
這兩天試出來的很笨的方式--當笑話看一下也無妨 ,畢竟codding如果沒有熱情,會是種煎熬
(如果你有更好的更簡潔的solution,麻煩教一下)
以下的架構是由ADK creaete activity 選用 master/detail flow所產生的架構改寫
片段如下:
============================================================
 */
public class xxxxxItemListActivity extends FragmentActivity implements
xxxxxItemListFragment.Callbacks {

         ....
         ...
         ...
static String lastSelectId="-1";
       static  Fragment currentFagment=null;
@Override
public void onItemSelected(String id) {   //<---id是從DummyContent定義的,"1"開始
if(currentFagment!=null && currentFagment.isInValide()){
          
   ListView lv=((SpotInfoItemListFragment) getSupportFragmentManager()
.findFragmentById(R.id.spotinfoitem_list)).getListView();

   lv.setItemChecked(Integer.parseInt(lastSelectId)-1, true); //<--setItemChecked is zero                                                                                                                         //based
onItemSelected(lastSelectId);   //<--switch to last select item
return;
}
if(lastSelectId.equals(id)){
return;     //<--remains what we input,
}
lastSelectId=id;  //<--update variable.
if (mTwoPane) {
                       ...   
                         //show the fragment
                       ...
                       ...
               }
              ....
        }
       ......
}
============================================================

2013年7月19日 星期五

GCM client 試出來了,問題是server 如何傳送中文資料 (by c#)?

GCM client如果有按照google API console 開設好server key 及GCM enable

還有在 在 Cloud Console中 點「Get Started With Sample Application」 對

「mobile backedn app」開啟及設定, 並依需要改寫gcm_client (參考git 連結 2013/06/05版,2012版比較繁瑣還要自己架server)

應該都是可以連入 (取得client device Id就應該不是問題了 )

但,是如果從C#要推播訊息怎麼做?
其本上一堆範例是直接向 「http://android.googleapis.com/gcm/send」做請求,丟一堆參數就可以了
問題是卡在中文訊息的問題,這時雙方需要encode & decode一下了
先就c# console sample為例
==========================================================
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Util;
namespace ConsoleGcmPushTest {
    class Program {
        static void Main(string[] args) {
            string deviceId = "APA91xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxZ1iLspAdBM";
            string msg = "16:15 建國的腳步漸漸逼近!!\n咱得愛有信心!!";
            string result = SendNotification(deviceId, msg);
            Console.WriteLine("respone is " + result);
            Console.WriteLine("");
            Console.WriteLine("Press anykey to continue");
            Console.ReadKey();
        }

        public static string SendNotification(string deviceId, string message) {
            string GoogleAppID = "AIzaSyBxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxpNxo";
            var SENDER_ID = "685########7580";
            var value = System.Web.HttpUtility.UrlEncode(message, System.Text.UTF8Encoding.GetEncoding("UTF-8"));

            WebRequest tRequest;
            tRequest = WebRequest.Create("https://android.googleapis.com/gcm/send");
            tRequest.Method = "post";
            tRequest.ContentType = " application/x-www-form-urlencoded;charset=UTF-8";
            tRequest.Headers.Add(string.Format("Authorization: key={0}", GoogleAppID));

            tRequest.Headers.Add(string.Format("Sender: id={0}", SENDER_ID));

            string postData = "collapse_key=score_update&time_to_live=1080&delay_while_idle=1&data.message=" + value + "&data.time=" + System.DateTime.Now.ToString() + "&registration_id=" + deviceId + "";
            Console.WriteLine(postData);

            Encoding encoding = new UTF8Encoding ();
            Byte[] byteArray = encoding.GetBytes(postData);


            tRequest.ContentLength = byteArray.Length;

            Stream dataStream = tRequest.GetRequestStream();
            dataStream.Write(byteArray, 0, byteArray.Length);
            dataStream.Close();

            WebResponse tResponse = tRequest.GetResponse();

            dataStream = tResponse.GetResponseStream();

            StreamReader tReader = new StreamReader(dataStream);

            String sResponseFromServer = tReader.ReadToEnd();


            tReader.Close();
            dataStream.Close();
            tResponse.Close();
            return sResponseFromServer;
        }
    }
}
===========================以上是推播的動作===================
以下是手機收到訊息時如何解碼
====================in GcmBroadcastReceiver================
 public void onReceive(Context context, Intent intent){
       ...
       ...
       ....
       msg = new String( intent.getExtras().getString("message").getBytes(), "UTF-8");
     //這才是之前data.message的內容......
    
}
======================================================

以上,大家加油了

2013年7月13日 星期六

如何允許SQL Express 2012 由外部連入

照之前上篇說的,把「SQL server Configuration Manger 」準備好之後,進入,
請到「SQL Server 網路組態」,找到「SQLEXPRESS」通訊協定 確認 「TCP/IP」啟用
如下圖:

double click 「TCP/IP」協定後,切到對話窗的「IP」頁簽,設定自己的ip及port


設定好之後,重新啟動SQL server服務(一樣在這個介面操作,左邊第一個節點就是了)

那,client怎麼連?當然是你的SQL server  驗證模式先設好「SQL Server  及windows驗證模式」之外,client那裡的Sql Manager連入是要用「ip,port」的方式,如下圖:

當然你的asp.net /entity connection string 也別忘了比照這方式

加油了!!


For SQL 2012 express:要用SQL Server 組態管理員時,遇到「無法連結WMI提供者」(0x80041010) )的錯誤訊息!?









很麻煩厚,怎麼解決?
到你的programe file SQL目錄 「 C:\Program Files (x86)\Microsoft SQL Server\110\Shared」
執行以下指令:「mofcomp sqlmgmproviderxps p2up.mof」

這樣WMI就回來了!!
參考連結
加油

2013年7月12日 星期五

Microsoft.Web.WebSockets serer and it's client connection

一,一定要有要IIS 8也就是你要灌win8/win2012以上
二,IIS支援設定,參考此文
三server side  pacakge,連結在此 
工作原理影音,請參考此連結 ,第三段中間開始,5707站台的程式集是asp.net4.5 +管線整合模式
四,如果你要用非網頁型態的client的話,用以下的程式碼:
========================================
using System;
using System.Linq;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace WebSocketClient
{
    class Program
    {
        static void Main(string[] args)
        {
            new Program().Start().Wait();
        }

        public async Task Start()
        {
            Console.Write("Name please: ");
            string name = Console.ReadLine();

            Console.Write("Connecting....");
            var cts = new CancellationTokenSource();
            var socket = new ClientWebSocket();
            string wsUri = string.Format("ws://10.10.10.11:5707/WebSocketsServer2.ashx?chatName={0}", name);
            await socket.ConnectAsync(new Uri(wsUri), cts.Token);
            Console.WriteLine(socket.State);

            Task.Factory.StartNew(
                async () =>
                {
                    var rcvBytes = new byte[128];
                    var rcvBuffer = new ArraySegment<byte>(rcvBytes);
                    while (true)
                    {
                        WebSocketReceiveResult rcvResult = await socket.ReceiveAsync(rcvBuffer, cts.Token);
                        byte[] msgBytes = rcvBuffer.Skip(rcvBuffer.Offset).Take(rcvResult.Count).ToArray();
                        string rcvMsg = Encoding.UTF8.GetString(msgBytes);
                        Console.WriteLine("Received: {0}", rcvMsg);
                    }
                }, cts.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default);

            while (true)
            {
                var message = Console.ReadLine();
                if (message == "Bye")
                {
                    cts.Cancel();
                    return;
                }
                byte[] sendBytes = Encoding.UTF8.GetBytes(message);
                var sendBuffer = new ArraySegment<byte>(sendBytes);
                await socket.SendAsync(sendBuffer, WebSocketMessageType.Text, endOfMessage: true, cancellationToken: cts.Token);
            }
        }
    }
}

========================================
以上,加油了