[Mooc][Android]Programming Mobile Aplication on Android Platform(week5) - Notification and Threads

image

前言:

來到第五週,其實作業已經越來越花時間.需要好好把握時間趕快做完才行.

筆記:

  • 關於 Broadcast:
    • 可以是有順序的(利用setPriority來設定),其中Priority 越高順序越前面.
    • 一個broadcast 可以同時被多個broadcast receiver 接收.
    • 其中一個Broadcast receiver 可以透過abortBroadcast 來強迫其他receiver來收取broadcast.
    • 關於sticky broadcast 比較需要注意的是:
      • 接收 sticky broadcast可以收到在註冊前發生的變動.
  • 關於 Threads:
    • Java的thread 建立之後不會馬上執行.需要跑start()
    • 背景的thread無法執行UI的相關動作.(這個地方跟 WinApp 跟 iOS App都一樣)
      • 需要執行要跑 runOnUIThread()
      • 或是每一個UI物件都有自己的View的post函式.View.post(Runnable action)

image

  • 關於AsyncTask:
    • 流程:
      • OnPreExecute -> doInBackground() -> publishProgress() -> OnPostExecute()
      • 其中如同上圖,有相對應的UI thread method OnProgressUpdate()最後 ObPostExecute() 也可以執行UI的更新.
  • 關於Alarm:
    • 註冊後,就送機器進入睡眠模式一樣可以收到.(除非關機)
    • 要取用Alarm需要使用 getSystemService(Context.ALARM_SERVICE) 來取得.
    • Kitkat (API 19) 之後,Alarm的使用變成inexact,也就是說他會盡量把幾個差不多時間的Alarm收集起來一起發送,即時他們時間有些許的差異.透過這個方式來節省電源的使用. (詳細可以參考這段)
  • 關於Networking: (Socket, JSON, URLRequest)
    • 要做網路溝通使用 HttpURLConnection 而不要使用 AndroidHttpClient 跟 DefaultHttpClient,由於Android team在 Android 2.3之後就不太積極開發
    • JSON的取用方式:
      • 要先用ResponseHandler 接回 client的 response 之後再逐一分解.
      • data array 可以用 JSONObject.getJSONArray
      • 每個mapping key/value 可以使用JSONObject.get(key)
    • XML的取用方式:
      • 主要有三種存取的方式: (DOM, SAX, PULL)
      • 其中記憶體消耗最高的是DOM,因為讀取的時候會把所有的XML樹狀資料全部載入.
      • SAX與PULL都是屬於event callback的方式,而PULL提供更多的彈性可以逐一的存取,並且可以控制event的結束.

參考資料:

[iOS][Python]手機掃描條碼下載相關的登入帳號數據

image

記錄一些關於開發這個的一些心得,主要就是手機會透過掃QR-code的方式,來讀取一些帳號資料讓手機可以登錄到相關的服務. 也就是說, 其實手機不用再透過手動的輸入帳號與密碼.而是使用QR-Code掃描.

所以流程就是:

  • 手機打開App
  • 掃描QR-code
  • 連接到某個Json網頁
  • 分析json 資料變成登入帳號密碼
  • 登入某些服務.

剛好遇到我切換到xcode6.1,這裡有一些筆記:

  • Xcode 6.1 GM似乎不太穩定,遇到問題有以下兩個:
    • Random crash: 而且Mac App會收起來(?)真百思不得其解.
      • 主要發生crash 在用滑鼠去點執行或是停止,但是用快捷鍵 Cmd + R 跟 Cmd + . 是沒問題的.
    • Storyboard 物件,變更大小的時候,某些物件會消失.
  • 關於使用的PAAS Server
    • 之前架設django的資料庫管理,當然還沒有連到外在的資料庫,而是使用SQLlite.所以當服務被重啟(PAAS每個30分鐘到一個小時會把你的服務設定維修棉.需要重啟大概要30 sec的啟動時間). 服務重啟~檔案會恢復當初上傳的狀態.
    • 暫時解決方式,先把需要測試的資料上傳SQLlite檔案上去.
    • 之後會把資料移到MongoDB HQ
  • XCode 6.1使用到不知道 X64的toolkit

相關資料:

[Mooc][Python]開始上課Interactive Programming in Python(第一部分) week 0~week5

image

前言:

其實這堂課之前有開始學,不過因為之前卡著學Scala而放棄.這次希望能一併學完它.先放上前五週的心得跟筆記.

筆記:

  • 好用的codeskulptor http://www.codeskulptor.org/
    • 這個東西真的很方便,可以step debugging 之外,還可以視覺化目前(Viz Mode)的記憶體的狀況.
    • 使用方法: 點下Viz Mode -> 按下設定的按鈕 -> 按下單步執行的按鈕.
  • 應該知道的基本常識:
    • 除法要保留小數點,記得要把被除數變成浮點數. (ex: 1/4 = 0 –> 1.0/4 = 0.25)
  • Python也是具有類似指標意義的,可以兩個變數名稱指向同一份資料
    a = b = [1,2,3,4,5]
  • 關於Global 與 Local 的筆記:
    • Valraible 需要加上Global才能存取到Global
    • List 不需要加上Global 可以存取某個元素
    • 但是如果是給值整個list 不使用Global會存取到新的List
  • 關於List的操作
    • 可以用 my_list + [1,2] 來做list 操作
    • append,extend 跟 reverse 都會改變source list
    • 取出可以使用pop (會變動),或是使用 my_list[index].其中index 若為負值是由最後開始算.
  • 關於Dictionary 的操作:
    • Key 可以是 tuple,number,string.但是不可使用list (但是可以使用list的value)
    • Value 可以是 tuple,number,string.甚至是list或是dictionary
    • Key跟Value都不能包含,另外一個Dict
    • dict travesal 可以使用以下的方式
lista = [1, 2, 3, 4]
dict = { 1: 'x', 'x':2, lista[2]: lista, (2,3):(5,2), 77: {1:2, 2:3} }
'''
Using key to find dictionary value
'''
for key in dict:
    print dict[key]

'''
Using tuple ()key,value) to find dictionary items
'''
for key,value in dict.items():        
    print "(", key, ",", value,")"

關於作業:

作業都偏向跟使用者UI互動有關,其中跟Python原理應用比較少.大多圍繞在simplegui

  • 第二週: 一個比猜拳更複雜的猜拳遊戲:
    • 總共有五個型態,考驗random 跟判斷
  • 第三週: 猜數字
    • 就是0~100猜一個數字,然後告訴你太高或是太低
  • 第四週: stopclock
    • 重點是在timer的應用
  • 第五週: pong (乒乓球)
    • 一樣是考驗timer 與碰撞的畫圖部分應用

[Moocs]Programming Mobile Aplication on Android Platform(week4) - All about UI

image

第四個禮拜主要就是介紹如何使用各種UI Control,比如說 Button,Ratio Control,以及這種Layout的使用方式. 而第四個禮拜的作業也相當有趣,就是寫一個基本的TODO item App.裡面包含了許多的關於 inflate與 findViewById的用法,也有講到如何控制各種簡單的TextView或是Radio 控制,更可以了解到利用Intent傳送資料的方法.

挺有趣的章節….

筆記:

inflate() 與 findViewById()的差異

  • inflate是用來找尋layout的,可以利用他去找出整個Layout的內容,內容如下
    View view1=View.inflate(this,R.layout.dialog_layout,null);  
  • 之後就可以利用 view1 繼續去把每一個button 或是 control 透過 findViewById()找出來
    Button action_buttion = (Button)view1.findViewById(R.id.acton_button);

如何新增footerview到listview

  • 使用以下的方式
    getListView().addFooterView(footerView);

參考資料:

[Moocs]Programming Mobile Aplication on Android Platform(2) - Intent/Permission/Fragment

image

上到第三周了,開始有一些重點出來.主要有提到Intent,Permission跟 Fragment.

關於Intent:

  • Intetn可以分為 Implicit Intent 跟Explicit Intent,差別如下:
    • Implicit 是使用系統內建(或是有登陸的Activity/App)
    • Explicity 是可以讓你呼叫自己定義的Activity
  • 可以有許多”動作”(Action)選擇,比如說 ACTION_DIAL… 等等, 使用SetAction()來呼叫
  • URI 是幫助你傳遞一些需要的小資料,比如說: 電話號碼, 地圖經緯度.. 等等 使用SetData()來呼叫.
  • Extra 可以指定為EXTRA_EMAIL,或是改為字串會是變數
    • 需要多加變數可以用 putExtra(KEY, VALUE) 跟 getExtras() 來傳遞
  • 關於OnActivityResult部分,要用setResult(Activity.RESULT_OK, Intent) 來傳遞
  • 如果要跟系統註冊為一種 ImplicitAcitivity的瀏覽器就一定要在AndroidManifest.xml裡面加上:
            < intent-filter >
                < action android:name="android.intent.action.MAIN" />
                < category android:name="android.intent.category.LAUNCHER" />
            < /intent-filter>  
            < intent-filter>
                < action android:name="android.intent.action.VIEW" />
				< category android:name="android.intent.category.DEFAULT" />
                < data android:scheme="http" />
            < /intent-filter>    

關於Permission:

    	< uses-permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS" />
  • 如果permission 已經被提升(granted)的話,就必須要移除App才能測試移除permission的部分.
    < permission >
        android:name="course.examples.permissionexample.TEST_PERM"
        android:description="@string/test_perm_string"
        android:label="@string/test_permission_label_string" >
    < /permission >

關於Fragment

  • 使用的時機點:
    • 同一個App在tablet 與手機上,可以顯示不同畫面
    • Fragment 建立的方式有以下幾種:
      • Static Fragment: 將Fragment 定義在 layout裡面
      • Programmatically: 不用先將Fragment 寫死在Layout,而是動態讀取Fragment 然後貼在Frame上面.
      • Dynamic Fragment: 不僅僅可以用程式指定Fragment,更可以決定在某些狀況下才顯示Fragment
    • 一般而言,configuration change (手機直向或是橫向變化) 會Destroy Fragment然後重新建立,可以利用setRetainInstance(true) 去避免這個狀況.
      • 如接下來的 Life Cycle 所顯示,如果有加上 setRetainInstance OnDestroy 與 OnDetach不會執行到,相對的也不會跑 OnAttach跟 OnCreate.只會跑OnCreateView. 所以要控制外觀的部分(比如說記錄selected list index)需要加在OnActivityCreate這裡.
    • Fragment Life cycle :
    • Fragment 可以是動態加入(形成原本是單個frame的界面,按下後變成兩個frame的界面),並且利用加入onBackStackChanged來改變layout回單個frame
    • 一般而言,在旋轉手機的時候會觸發 configuration change 然後使得Fragment 重建.如果要保留Fragment的狀態需要加上setRetainInstance
    • 想要一開始只顯示左邊list,並且在選取後可以出現詳細在右邊.就可以先選取一個Fragment ID,然後在ListSelected 上面去讀取另外一個Fragment在產生transaction即可.
    
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
			
// Add the Fragment to the layout
fragmentTransaction.add(R.id.frag, mFragment);
			
// Add this FragmentTransaction to the backstack
fragmentTransaction.addToBackStack(null);
			
// Commit the FragmentTransaction
fragmentTransaction.commit();
			
// Force Android to execute the committed FragmentTransaction
// execute transaction now
getFragmentManager().executePendingTransactions();    

相關資料:

[Django][Python]寫出一個存放資料庫並且輸出qrcode的Django App

image

前言: 想要試著做做看一個簡單的相機資料管理系統,並且可以顯示QRCode到該相機資料庫並且顯示JSON資料. 主要也是趁個機會把Django再拿出來複習一下.雖然也是有打算用Golang來寫,但是Golang沒有找到比較方便的QRcode 模組就先緩些時間.

步驟:

  • 把相關的模組與設定加到原來的Django網站. 這部分可以參考Django toturial 恢復記憶
    source venv/bin/activate
    //Install related component
    pip install django-qrcode
    //Write back to requirement.ext
    pip freeze > requirements.txt
    //Crete new app for this website
    python manage.py startapp cam_qrcode
  • 接下來要設定資料庫,這裡資料庫相當簡單,相機就只有名稱而已.並且有一個XMPP 賬戶做IOT(Internet Of Thing)使用.
class Camera(models.Model):
    camera_id = models.IntegerField()
    camera_name = models.CharField(max_length=200)
    camera_xmpp_account = models.CharField(max_length=200)
    camera_xmpp_password = models.CharField(max_length=200)
    def was_published_recently(self):
        return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
    def __unicode__(self):
        return self.camera_name
  • 關於QRCode產生的部分,我使用的是 Django-qrcode.使用上相當簡單,而且很方便.
  • 可以顯示之後就是要準備產生Json,這裡我是用Simplejson 來使用
    cam = get_object_or_404(Camera, pk=cam_id)
    response_data = {}
    response_data['cam_id'] =  cam.camera_id
    response_data['camera_name'] = cam.camera_name
    response_data['camera_xmpp_account'] = cam.camera_xmpp_account
    response_data['camera_xmpp_password'] = cam.camera_xmpp_password
    out_obj = json2.dumps(response_data)

這樣就完成了,作品在Heroku上面.大概花費四五個小時…

image

遇到問題:

列出來所遇到的一些問題:

  • Django 升級後反而不能跑
    • 已試過把Django從1.6.2 升級到 1.7,就發現無法正常執行伺服器. 這部分先採取downgrade處理,之後有空再看.
     pip install django 1.6.2
  • ‘function’ object has no attribute ‘dumps’
    • 這個主要是json似乎跟某個版本搞混,所以無法獲得正常的json.
    • 我解決方法是使用simplejson 並且更改名稱到json2
    
import simplejson as json2

參考資料: