2012年10月5日 星期五

Android 開發筆記 - Unable to resume activity : android.database.StaleDataException: Attempted to access a cursor after it has been closed.

以前常在操作 DBHelper 時,常常因為沒有把 mCursor.close() 而常常出現一些錯誤訊息,後來就很習慣每次取一個 mCursor 出來,用完後就執行 mCursor.close() 來當做完整的收尾,結果開始出現這種訊息並且完全不知道是自己哪一行程式出錯:


FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to resume activity {com.example/com.example.YourActivity}: android.database.StaleDataException: Attempted to access a cursor after it has been closed.
       at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2444)
       at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2472)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1173)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loop(Looper.java:137)
       at android.app.ActivityThread.main(ActivityThread.java:4424)
       at java.lang.reflect.Method.invokeNative(Native Method)
       at java.lang.reflect.Method.invoke(Method.java:511)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
       at dalvik.system.NativeStart.main(Native Method)
 Caused by: android.database.StaleDataException: Attempted to access a cursor after it has been closed.
        at android.database.BulkCursorToCursorAdaptor.throwIfCursorIsClosed(BulkCursorToCursorAdaptor.java:75)
        at android.database.BulkCursorToCursorAdaptor.requery(BulkCursorToCursorAdaptor.java:144)
        at android.database.CursorWrapper.requery(CursorWrapper.java:186)
        at android.app.Activity.performRestart(Activity.java:4505)
        at android.app.ActivityThread.performRestartActivity(ActivityThread.java:2875)
        at android.app.LocalActivityManager.moveToState(LocalActivityManager.java:168)
        at android.app.LocalActivityManager.dispatchResume(LocalActivityManager.java:523)
        at android.app.ActivityGroup.onResume(ActivityGroup.java:61)
        at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1154)
        at android.app.Activity.performResume(Activity.java:4539)
        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2434)
        ... 10 more


追到最後,終於發現問題的所在點了,因為我的 mCursor 是從 Activity.managedQuery 產生的,在 Activity.managedQuery 有提到:


Warning: Do not call close() on a cursor obtained using this method, because the activity will do that for you at the appropriate time. However, if you call stopManagingCursor(Cursor) on a cursor from a managed query, the system will not automatically close the cursor and, in that case, you must call close().


這應該就是不懂 Android 架構的關係 Orz 果真懂一點不如不懂 XDD


2012年10月4日 星期四

GPS 座標轉換 NE 常用格式與度分秒

找旅遊資料之餘,發現官方單位給的資料都是類似 N25 02 1.25 E121 33 53.01 這種座標型態,查了一下資料才知道這是度分秒單位。


可以把上述那串丟進 Google Maps 一樣可以通啦。


例如台北 101 GPS 座標為 25.033681,121.564726:


25.033681:


25 度


02 分 = 0.33681 * 60 的整數位 = 2.02086


1.25 秒 = 0.02086 * 60 = 1.2516


121.564726:


121 度


33 分 = 0.564726 * 60 的整數位 = 33.88356


53.01 秒 = 0.88356 * 60 = 53.0136


同理,要從分度秒變成常用的 GPS 座標:


25 度 02 分 1.25 秒:


25 + ( 2 + 1.25 / 60 ) / 60 = 25.0336806


121 度 33 分 53.01 秒:


121 + ( 33 + 53.01 / 60 ) / 60 = 121.564725


後來,大學同學的前東家在做導航機,就說這就像 10進位跟 60 進位的單位轉換囉 :D


[OSX] Adium - 因為 Switchboard 發生錯誤,所以訊息無法送出 @ Mac OS X 10.8

adium

網路上還滿常看到 MAC 上使用 MSN 問題的,在 Mac OS X 上頭,雖然微軟有出 Messenger for Mac,但是我還是滿常碰到 Switchboard 的問題。此問題本身應該是傳訊雙方的網路狀態,例如公司有擋 msn 、防火牆等等,則會常出現這類的問題。

網路上的解法很多是調整 msn 設定,如 "透過HTTP連線" 、 "允許直接連線" 、"連線埠" 等等,這些都可以在微軟的官網也能查到對應的資訊 Windows Live Messenger 使用的網路連接埠與 URL

然而,怎樣設定也解決不了問題 Orz 連改用 Messenger for Mac 也都一樣,最後就換回好用的 Adium ,暫時的解法是…一旦出現 "因為 Switchboard 發生錯誤,所以訊息無法送出" 時,就重新登入,一登入完時可以正常發送訊息。只是每次重新登入也很麻煩,最後想到一招可以 reset Switchboard 了,那就是封鎖對方後,再解除封鎖,也能短暫解除這種問題囉。

Updated: 現在 Skype 6.0 for Mac 已經可以支援 MSN 登入囉!用 Skype 後沒有在碰到這種問題了!