2013年12月19日 星期四

android.os.NetworkOnMainThreadException的問題

自從將 Android 升級成 4.2 之後,httpRequest 就出現了 android.os.NetworkOnMainThreadException 這個問題

在網路上查過之後才發現原來 Android 為了怕開發者將 HTTP 傳送請求放在主程式中,如果 HTTP 這個要求一直持續的話很有可能會卡死整個程式,造成應用程式的 crash 因此 Android 非常貼心的幫助開發者判斷 httpRequest 這個方法是否是在主程式中運行,如果是的話便會拋出錯誤

而如果想要解決這問題就是要將 httpRequest 寫在多執行緒中,以下是其中一種解法

public class MainActivity extends Activity{
 
 private EditText txtMessage;
    private Button sendBtn;
    private String uriAPI = "你要傳送要求的網址";
    String msg = null;
    @Override

    public void onCreate(Bundle savedInstanceState){

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        txtMessage = (EditText) findViewById(R.id.txt_message);
        sendBtn = (Button) findViewById(R.id.send_btn);
        sendBtn.setOnClickListener(sendlistener);
        
    }
    private Runnable mutiThread = new Runnable(){
      public void run(){
      // 運行網路連線的程式
      msg = txtMessage.getEditableText().toString();
      String r = sendPostDataToInternet(msg);
      if (r != null)
      Log.d("first0.0", r);

    }
  };
  public OnClickListener sendlistener = new OnClickListener(){
    public void onClick(View v){
      if (v == sendBtn){
        if (txtMessage != null){
              /* 
               * 這邊要用 Thread 是因為 Android 改版之後
               * 會對在主程式裡跑網路連接的程式碼做 Exception 的意外排除動作
               * 因此要把網路連線使用多執行緒的方式去運行,才不會被當成例外錯誤拋出
               */
               Thread thread = new Thread(mutiThread);
               thread.start();
         }
       }
     }
   };
    
    
    private String sendPostDataToInternet(String strTxt){

        /* HTTP Post */
        HttpPost httpRequest = new HttpPost(uriAPI);

        /* 將 Post 值存為一個 NameValuePair[],在這邊去添加自己想要的值 */
        List params = new ArrayList();

        params.add(new BasicNameValuePair("APIMethod", "phoneTest"));
        /* 這邊 PHP 端的接法就是用 $_POST['data']就接的到這邊的 strTxt 這個變數值了 */
        try{
         
            /* 設定 HTTP request */
            httpRequest.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));

            /* 傳送 HTTP response */
            HttpResponse httpResponse = new DefaultHttpClient().execute(httpRequest);
            
            /* 如果回傳值為 200 即為傳送 ok */
            if (httpResponse.getStatusLine().getStatusCode() == 200){

             /* 接收回傳字串,這邊接的值就是在 PHP 那邊 echo 的值 */ 
             /* hellow.php 這隻程式碼的寫法:
              * if($_POST['data']!=null) echo $_POST['data']; */
              
                String strResult = EntityUtils.toString(httpResponse.getEntity());
            
                return strResult;
            }
            else{
                Log.d("sss", "no message");
            }
        } catch (ClientProtocolException e){
         Log.d("@@", e.toString());
        } catch (IOException e){
         Log.d("@@", e.toString());
        } catch (Exception e){
         Log.d("@@", e.toString());
        }
        return null;
    }
}

2013年8月13日 星期二

Facebook API Heroku

登入: heroku login

金鑰重新加入的解法: heroku keys:add





https://devcenter.heroku.com/articles/facebook

因為每次都會忘記,所以稍微記錄一下

2013年4月21日 星期日

android facebook api

此處將我使用過的 facebook android api 記錄下來,持續增加中

1. 取得 facebook 朋友清單
//取得朋友清單需要的權限 read_friendlists


public void GetFriendsList(){
//取得朋友清單方法
try {
//facebook.request("me/Friends") 取回來的資料是 json 格式,直接轉 json 比較方便
//要用字串也行,使用方式為 String data = facebook.request("me/Friends");
//只是直接用字串的話就是一整堆資料,要切
JSONObject json = new JSONObject(facebook.request("me/Friends"));
//取回來的資料是包在 data 裡,所以將 data 裡的資料放進 array 裡面
JSONArray array = json.getJSONArray("data");

if(array != null){
for(int i=0;i<array.length();i++){
String id = array.getJSONObject(i).getString("id");
String name = array.getJSONObject(i).getString("name");
Toast.makeText(this, name, Toast.LENGTH_LONG).show();
}
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}


2. 將訊息自動發佈到塗鴉牆上


//發佈到塗鴉牆上需要的權限 publish_stream



public void postToWall() {
    //此處是會自動發佈至塗鴉牆的寫法
    //另外還有一種寫法是會跳出一訊息框讓使用者自行填寫要發布的消息
   Bundle params = new Bundle();

   params.putString("message", "此處為發佈至塗鴉牆上的訊息" );
   try {
facebook.request("/me/feed", params, "POST");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}