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);
            }
        }
    }
}

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


  

2013年7月11日 星期四

for VirtualBox Host 如何跟 Guest 自成一套域內對連的兩個系統

假設,目前是在win7上面的virutalbox之中安裝了windows server 2012
今欲讓兩者間有獨立的網路而非透過其他外在網路對連

1.先在win7自行安裝Loopback網卡,並把他的ip設為10.10.10.10,mask 255.255.255.0
   (請以win7,loopback等關鍵字查,這不是難的事)

2,安裝完VirtualBox後,在「控制台\網路和網際網路\網路連線」會出現網卡:「VirtualBox Host-Only Network」,他的預設ip是dhcp,請改成10.10.10.12,mask同上

3,安裝好了win server 2012 guest後,在Oracle VM Virtualbox Manager的畫面中設定vm時,網卡預設第一組是 NAT,不要動他
這時,請再加一張介面卡2,附加到「僅限主機」介面卡,名稱會對應到「VirtualBox Host-Only Ethernet Adapater」
(混合模式我是選允許全部,有沒有差我就不知道了)

4,win server 2012 guest重開後( 因為加網卡是要在vm開機時才能做的)
會偵測到這網卡,這時請到 win server 2012 "控制台\所有控制台項目\網路和共用中心"設定那張新的網卡的ip為10.10.10.11

之後,從win7 ping win server 2012,或是從 win server 2012 ping win7 看看
應該都沒問題,至少在我這裡是ok的

 加油

關於virtualbox的硬碟常用指令--搬移及延伸大小

因為vdi裡面有UUID,不是直接copy & move就可以了,這是需要用到他的指令來完成
VBoxManage clonevdi /my/path/to/one.vdi /my/path/to/two.vdi
另外最常問到的是硬碟空間不夠大,如果加大?
VBoxManage modifyhd "C:\Users\autosun\VirtualBox VMs\ArchLinux\ArchLinux.vdi" --resize 50000 

(數字單位是mega)改完後再到作業系統內去修改調整磁區分割大小
PS. Giga to Mega convertion ref:
https://www.conversion-metric.org/filesize/gigabytes-to-megabytes


加油了

2013年7月8日 星期一

EditText 類別setText遇到數字型態會出錯?

EditText 類別setText遇到數字型態會出錯?
嗯,因為....setText(int)指的是從resource的id找出string對應物件出來設定文字的
沒給你出現亂碼已經很客氣了
那如何定「數字」進去?
跟javascript一樣,在前面加個空字元就可以了,ex: editTxt.setText(""+number);
就是這麼簡單.

For Android: How to setup checked radio button in RadioGroup programmatically

注意順序,是先加入RadioGroup再設定其checked Id.
===============================================
 LinearLayout.LayoutParams param4RdoGrp=new LinearLayout.LayoutParams(
 ViewGroup.LayoutParams.WRAP_CONTENT,
 ViewGroup.LayoutParams.WRAP_CONTENT
 );
 param4RdoGrp.setMargins(16, 0, 0, 0);
 radioGroup=new RadioGroup(activityContex);
 radioGroup.setOrientation(RadioGroup.HORIZONTAL);
 radioGroup.setLayoutParams(param4RdoGrp);
 currentView.addView(radioGroup);
      int checkId=-1;
 for(int i=0;i<options.length;i++){
          RadioButton rdoBtn=new RadioButton(activityContex);
          rdoBtn.setText(options[i]);
          radioGroup.addView(rdoBtn);  <--先加入有了id再決定怎麼做
          if(options[i].equals(selectedOption)){
        // rdoBtn.setChecked(true);   <--這樣不行,會把radio button 卡住!!
         checkId=rdoBtn.getId();
          }
         
 }
 if(checkId!=-1){
 radioGroup.check(checkId);   <--這時才能設定check!!
 }
=======================================

2013年7月7日 星期日

SharedPreferences無法儲存!?

這問題花了我幾小時,最後還是在另一本書上看到的
先看一下錯誤的寫法:
   =============以下是錯誤的,小心==============
  SharedPreferences prefer= PreferenceManager.getDefaultSharedPreferences(
 GeneralLib.APPLICATION_CONTEXT);
   prefer.edit().putString("xxxxxValue",xxxx);
   prefer.edit().putString("bbbbValue",bbb);
   prefer.edit().commit();
==========================================
這看起來是對的,不過值一直都沒存入

那,什麼才是正確寫法?
用pipe方式接力下去就可以了
===========正確寫法====================
   prefer.edit().putString("xxxxxValue",xxxx).putString("bbbbValue",bbb).commit();
================================
為什麼? 因為每次「prefer.edit()」會產生一個「新的」edit的內容
所以才會有這樣的現象,小心


2013年7月5日 星期五

how to calculate the height of ListView ?

since ScrcollView is not  allow to add a scrollable listview
so you have to findout the listview hieght after it's created.
here is  is the usefull LINK
see the code snippet:
==================================

        public static void setListViewHeightBasedOnChildren(ListView listView) {
            ListAdapter listAdapter = listView.getAdapter(); 
            if (listAdapter == null) {
                // pre-condition
                return;
            }

            int totalHeight = 0;
            for (int i = 0; i < listAdapter.getCount(); i++) {
                View listItem = listAdapter.getView(i, null, listView);
                listItem.measure(0, 0);
                totalHeight += listItem.getMeasuredHeight();
            }

            ViewGroup.LayoutParams params = listView.getLayoutParams();
            params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
            listView.setLayoutParams(params);
        }
    
===================================

how to scroll to top after showing a long big ScrollView?

    
=======in your activity,override the  onWindowFocusChanged event=============
    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        ScrollView scrollView = (ScrollView) findViewById(R.id.someScrollView);
        scrollView.scrollTo(0, 0);
    }
======================================================================

2013年7月4日 星期四

如何取得extjs4 容器物件中的items內容?

有時我們必須列舉容器(container/panel)的內容
但items不是個陣列而已,是個「AbstractMixedCollection」
所以要用他的方法取得
        var attrItem = Ext.getCmp('xxxxx').items;
        for (var i = 0; i < attrItem.getCount() ; i++) {
           var panel=attrItem.getAt(i);
                panel.....
        }
====以上,加油了=====

for extjs4 一個有關動態resize window案例


請注意其中的「autoHeight」「resizable」「layout」等設定
還有「fire resize event」的動作
================================
Ext.define('GtmExtjs.view.WinEditProduct', {
    ...
    ....
     ....
    autoHeight: true,
    resizable :true,
    width: 428,
    layout: {
        type: 'fit'
    },
    title: 'Product Information',
    modal: true,
    ....
    ....
    ....
    initComponent: function () {
        var me = this;
        me.initialConfig = Ext.apply({
            trackResetOnLoad: true
        }, me.initialConfig);
        Ext.applyIf(me, {
            items: [
                {
                    xtype: 'form',
                    region: 'center',
                    itemId: 'formProdInfo',
                    method: 'POST',
                    trackResetOnLoad: true,
                    url: '/GoingTvMall/Product/handleProduct',

                    layout: {
                        columns: 3,
                        type: 'table'
                    },
                    autoHeight: true,
                    resizable: true,
                    bodyPadding: 10,
                    items: [
                              ....
                               ....
                        {
                            xtype: 'button',
                            margin: 5,
                            text:'add attr',
                            width: 100,
                            handler: function () {
                                var attrEditor = Ext.create('GtmExtjs.view.PnlAttrEditor',
                                    { parentPnl: Ext.getCmp('pnl4Attr') });
                                Ext.getCmp('pnl4Attr').add(attrEditor);
                                Ext.getCmp('pnl4Attr').updateLayout();
                                var xntHeight = me.height;
                                me.fireEvent('resize', me, 428, xntHeight, null);
                               
                            }
                        },
============================================