2013/04/30

ComicsDownloader v2.3.3


本軟體線上功能僅為網頁瀏覽器供使用者瀏覽特定網站, 不提供任何漫畫圖源.
使用者或漫畫網站之任何行為, 本軟體一概不負責.


ComicsDownloader 是一個支援線上瀏覽並且支援離線下載觀看的軟體
特色:
* 解析各大線上漫畫網站, 可線上瀏覽或者下載(目前支援6個線上網站)
* 支援我的最愛, 使用者可以把喜歡的漫畫加入最愛
* 支援忽略清單, 使用者可以把沒興趣的漫畫隱藏起來
* 支援閱讀紀錄以及下載紀錄
* 支援漫畫強制單頁顯示
* 支援自動檢查 SD 卡並加入我的書櫃
* 支援格式: png, jpg, bmp 和 zip

Box: 2.3.3


主畫面 - 使用者可以滑動會者點擊上方選單切換頁面




線上漫畫頁面 -
點擊漫畫名稱後會顯示此漫畫的所有話數或者集數
點擊漫畫封面可選取此漫畫, 並且加入我的最愛




內建漫畫瀏覽器 -
左邊往右拉, 會出現頁數預覽, 頁數預覽僅在此漫畫有快取過後才會顯示.
選單可以作一些細項設定, 包含畫面大小顯示, 頁面切換模式, 頁面顯示模式等

在漫畫瀏覽器主畫面主要有幾個功能:
* 左右兩邊單擊分別可切換下一頁或上一頁
* 左右下角雙擊分別可切換至下一集(話)或上一集(話)
* 長按畫面畫面右上角會出現縮放圖示, 往上可放大, 往下縮小
* 點擊畫面中間, 上方會出現提示列, 包含頁數,總頁數以及時間
* 點擊畫面中間上下方, 可縮放圖片, 縮放圖片比例可設定
* 畫面放大時, 點擊左右上角或左右下角分別可直接拖曳到對應的角落, 省略拖曳圖片的時間
* 畫面放大時, 點擊畫面左右分別可直接拖曳到對應的左右邊界, 省略拖曳圖片的時間.
* 畫面放大時, 雙擊畫面中間, 可縮放到原始設定的畫面大小顯示模式




ComicsDownloader 設定 -
使用者可以設定漫畫下載的位置, 且也可以設定漫畫同時下載的線程, 下載失敗重試次數, 以及其他一些設定

論壇瀏覽器 v2.1.0

v 2.1.0 -

* 增加以下論壇

> 機峰論壇

> 台灣城市


**BUG:**

* 修正部份感謝失效的問題
* 修正部份 FC 問題
* 修正 APK 下載附件失敗問題


Google play store: https://play.google.com/store/apps/details?id=tw.clotai.forumreader

2013/04/27

論壇瀏覽器 v2.0.9

v 2.0.9 -

* 增加搜尋功能

**BUG:**

* 修正前一版本導致回覆按鈕不見的問題

* 修正部份論壇顯示的問題


Google play store: https://play.google.com/store/apps/details?id=tw.clotai.forumreader

2013/04/24

論壇瀏覽器 v2.0.8

v 2.0.8 -

** 由於新設定的關係, 此版本會移除之前所設定好的設定值, 包含 cookies **
** 已知問題 PIL 文內回覆後, 部份文內回覆會不見, 必須 refresh **

* 修改部份 UI

* 修改 Theme mode 切換方式

* 字體可以個別網站設定, 論壇跟內文也可分開設定

* 點擊畫面空白可隱藏側邊選單

* 增加以下論壇支援

> 隋棠Sonia Sui粉絲後援會

* 顯示部份論壇的更多資訊, 包含點評, 文內回覆, 獎勵等等.

* 增加選項使用瀏覽器開啟連結


**BUG:**

* 修正 A4TW 顯示問題

* 修正部份外部連結導致 FC 問題

* 修正部份 FC 的問題

* 修改部份登入問題


Google play store: https://play.google.com/store/apps/details?id=tw.clotai.forumreader





2013/04/22

XGallery v1.0.5

v 1.0.5

- Fix some actions will cause FC problem.


中文說明







v 1.0.5
- 修正正在做動作時, 畫面旋轉會導致 FC 的問題

2013/04/17

論壇瀏覽器 v2.0.7

v 2.0.7 -

* 增加可看最新文章, 回覆等(這個會因為網站而顯是有所不同)


**BUG:**

* 修正 Eyny 的 Warning 錯誤

* 修正 Xoom 在 UI 顯示上的問題

* 修正下載時可能導致 FC 以及錯誤的問題

* 修正不會跳至最後回覆的問題

* 修改部份導致 FC 的問題


Google play store: http://goo.gl/jdHf5

2013/04/15

論壇瀏覽器 v2.0.6

太累時不能寫 Code, 不然就錯誤一堆 :~
修正 v2.0.5 版本所帶來的 bugs

v 2.0.6 -

**BUG:**

* 修正登入失敗誤判登入成功的問題.

* 修正部份 v2.0.5 所導致的 bug.

Google play store: http://goo.gl/jdHf5



Box: v2.0.6

Youtube 影片轉 mp3

在 linux 底下, 下載 youtube 影片實在是簡單到不行, 強推薦 youtube-dl 這個 script.

使用方法更是簡單.
// 列出此網址所有的影片格式
youtube-dl -F http://www.youtube.com/watch?v=17ozSeGw-fY 

// 結果如下
Available formats:
37      :       mp4     [1080x1920]
46      :       webm    [1080x1920]
22      :       mp4     [720x1280]
45      :       webm    [720x1280]
35      :       flv     [480x854]
44      :       webm    [480x854]
34      :       flv     [360x640]
18      :       mp4     [360x640]
43      :       webm    [360x640]
5       :       flv     [240x400]
17      :       mp4     [144x176]

// 選擇要下載的格式
youtube-dl -f 44 http://www.youtube.com/watch?v=17ozSeGw-fY 


就是這麼簡單好用. 詳細可以看 youtube-dl --help


下載後要轉成 mp3 也很簡單.
使用 aconv
avconv -i input.mp4 -vn -c:a libmp3lame -q:a 2 output.mp3

或者使用 ffmpeg
ffmpeg -i input.mp4 -vn -c:a libmp3lame -q:a 2 output.mp3

參考網址:
[1] http://superuser.com/questions/96290/extracting-audio-from-mp4-video-into-mp3

2013/04/14

論壇瀏覽器 v2.0.5

v 2.0.5 -

* 從這個版本不再記憶帳號密碼, 只保留 cookies.

* 增加 Sort 的功能

* 修改部份 UI

* 增加顯示簽名

* 增加黑色佈景(只對論壇畫面有效, 有顯示問題請在回報連結)

* 增加文字大小設定(只對內文有效)

* 增加下載可設定自訂檔名的功能

* 增加保持螢幕開啟的功能(只在閱讀內文時有效)

**BUG:**

* 修改部份導致 FC 的問題
* 修正因為不同 Android 版本, 跳出視窗顏色不對的問題

Google play store: http://goo.gl/jdHf5

2013/04/12

論壇瀏覽器 v2.0.4

v 2.0.4 -

* 網路論壇增加版本顯示, 此版本顯示此論壇從那個版本有比較完整支援,
例如支援下載, 回文, 感謝等.

* 增加下載附件功能, 以下論壇部份測試 OK, 如有問題請再幫忙回報.

1. APK
2. CK101
3. EYNY
4. FastZone
5. FDZone
6. P2P101

* 增加圖片瀏覽功能, 點擊圖片會跳出圖片瀏覽畫面, 並且可以下載與分享.

> 如果載入失敗, 點擊會再重新載入一次

* 增加以下論壇支援

1. Post76


** BUG: **

* 修正部份 Bugs.


剛上傳, 所以 google play store 通常會 delay 一下.
Google play store: http://goo.gl/jdHf5



Box: v2.0.4

2013/04/11

WebView with jsoup html parser

Jsoup 真的非常好用, 尤其搭配 WebView 使用.
以下範例為使用 Jsoup 並且將解悶有漫畫這網站顯示成我所想要的樣子.

Layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ProgressBar
        android:id="@+id/progress"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="100"
        android:indeterminate="true"
        style="@android:style/Widget.ProgressBar.Horizontal"
        android:layout_alignParentBottom="true" 
        android:visibility="gone"/>

    <WebView
        android:id="@+id/webview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@id/progress" />

</RelativeLayout>

要將網頁顯示成我們所要的格式, 最要下苦工的就是查看網頁的 html 原始檔, 幸好現在大部分網站的 html 都很有規格,
所以要解析也變得相當容易.
如果透過 WebView 載入畫面, 那麼資料將無法處理, 所以改成透過 HttpURLConnection 來連結網站, 並且處理資料.

 class LoadTask extends AsyncTask<String, Void, String> {

@Override
protected String doInBackground(String... params) {
StringBuilder sb = new StringBuilder();

String url = params[0];

try {

Document doc = HttpConnection
.connect(url)
.followRedirects(true)
.get();
if (doc == null) {
return null;
}

Element el = doc.select("ul#framemain_1").first();
if (el == null) {
return null;
}

Elements lis = el.select("li");

/** parse html data and create our own html file **/
sb.append("<html>");
sb.append("<title>WebViewExample Test</title>");
sb.append("<head></head>");
sb.append("<body style='margin: 0px; padding: 0px;'>");
sb.append("<table width='100%' border='1' cellspacing='0' cellpadding='5'><tbody>");
for (Element li: lis) {
Element cover = li.select("a > img").first();
if (cover != null) {
cover.parent().remove();
cover.attr("width", "100px");
cover.attr("height", "136px");
}
sb.append("<tr>");
if (cover == null) {
sb.append("<td colspan='2'>"+li.html()+"</td>");
} else {
sb.append("<td width='100px' height='136px'>"+cover.outerHtml()+"</td>");
sb.append("<td>"+li.html()+"</td>");
}
sb.append("</tr>");
}
sb.append("</body></html>");
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}

@Override
protected void onPostExecute(String result) {
if (result == null) {
Toast.makeText(MainActivity.this, R.string.msg_fail, Toast.LENGTH_SHORT).show();
} else {
mWebView.loadDataWithBaseURL(null, result, "text/html", "UTF-8", null);
}
}
}

主要工作就這麼簡單, 讀取 html, parse 出想要的, 然後寫一份所想要顯示的 html. 完成 !
結果如下:




原始碼: WebViewExample_3

參考 :
[1] Jsoup
[2] 怎麼使用 android 的 webview
[3] WebView with Progressbar

WebView with Progressbar

在 WebView 加上 progressbar 讓使用者知道目前載入進度,

主要利用 WebViewClient 和 WebChromeClient

WebViewClient 可以知道載入開始和載入結束, 可用來判斷是否該顯示 ProgressBar 或者該隱藏
WebChromeClient 可用來知道載入進度

Layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<ProgressBar
android:id="@+id/progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="100"
android:indeterminate="true"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_alignParentBottom="true" 
android:visibility="gone"/>

<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/progress" />

</RelativeLayout>

主程式碼
package tw.clotai.webviewexample;

import tw.clotai.webviewexample.R;
import android.app.Activity;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.View;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;

public class MainActivity extends Activity {

WebView mWebView = null;
ProgressBar mBar = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

mWebView = (WebView)findViewById(R.id.webview);
mBar = (ProgressBar)findViewById(R.id.progress);

mWebView.setWebViewClient(mWebViewClient);
mWebView.setWebChromeClient(mWebChromeClient);
mWebView.loadUrl("http://tw.yahoo.com");
//mWebView.loadUrl("file:///android_asset/example.html");
}

WebViewClient mWebViewClient = new WebViewClient() {

@Override
public void onPageFinished(WebView view, String url) {
mBar.setVisibility(View.GONE);
}

@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
mBar.setVisibility(View.VISIBLE);
}

@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
};

WebChromeClient mWebChromeClient = new WebChromeClient() {

@Override
public void onProgressChanged(WebView view, int newProgress) {
mBar.setIndeterminate(false);
mBar.setProgress(newProgress);
}

@Override
public void onReceivedTitle(WebView view, String title) {
if ((title != null) && (title.trim().length() != 0)) {
setTitle(title);
}
}
};
}




原始碼: WebViewExample_2

參考:
[1] 基本使用 webview

怎麼使用 android 的 webview

怎麼使用 android 的 webview, 很簡單, 不過這邊我一樣紀錄一下如何使用.


模擬器: android os 版本 2.3.3
SDK: android-17

以下是我的 Layout 檔案.
且記得在 AndroidManifest.xml 裡面加上網路權限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <WebView 
        android:id="@+id/webview"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:layout_alignParentTop="true" />

</RelativeLayout>


我的 MainActivity 裡面內容如下:
public class MainActivity extends Activity {

 WebView mWebView = null;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  mWebView = (WebView)findViewById(R.id.webview);
  
  mWebView.loadUrl("http://tw.yahoo.com");
 }
}

這樣基本上就會載入畫面了, 可是如果實際測試, 會發現會使用外部的瀏覽器開啟.
原因是因為當載入時, yahoo 判斷是 Mobile 所以轉址, 而這轉址的動作我們並沒有處理, 所以就會開啟預設的瀏覽器瀏覽.
解決方式如下 :
public class MainActivity extends Activity {

 WebView mWebView = null;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  mWebView = (WebView)findViewById(R.id.webview);
  
  mWebView.setWebViewClient(mWebViewClient);
  mWebView.loadUrl("http://tw.yahoo.com");
 }
 
 
 WebViewClient mWebViewClient = new WebViewClient() {
  @Override
  public boolean shouldOverrideUrlLoading(WebView view, String url) {
   view.loadUrl(url);
   return true;
  }
 };
}
顯示結果如下 :



2013/04/10

論壇瀏覽器 v2.0.3

v 2.0.3 -
* 部份 UI 調整

* 網路論壇裡的論壇全部支援回文, 感謝功能(如有問題請回報)

** BUG: **

* 修正 Gphonefans 回文驗證碼失敗問題

* 修正從未登入到登入後所導致圖示消失的問題

* 修正 ck101 論壇顯示的問題

* 修正感謝功能失效的問題

* 修正論壇文章一直顯示 NEW 的問題

* 修正 cookie 處理錯誤的問題

* 修正頁碼 UI 顯示錯誤的問題


剛上傳, 所以 google play store 通常會 delay 一下.
Google play store: http://goo.gl/jdHf5



Box: https://www.box.com/s/x36zafubhwgwe5nwkt2u

2013/04/08

Youtube 卡卡卡 !

原本看 youtube 沒有什麼問題, 但最近看 youtube 卻卡到要死.
不然就是影片撥到一半就直接跳到結束, google 了一下, 有人說可能是 hinet 快取 server(210.71.222.0/24)的問題.
設定了一下 iptables, 發現真的差別很大.
下面是設定方式:
sudo iptables -A OUTPUT -d 210.71.222.0/24 -j DROP

這樣就可以了.

2013/04/06

動態顯示隱藏密碼

一般作登入畫面, 都會輸入使用者名稱跟密碼.
但是有時為了方便使用者檢查密碼是否打錯, 會多一個 checkbox 讓使用者顯示所輸入的密碼,
避免密碼不小心輸入錯誤.
Android 達成方式很簡單, 以下提出兩種方式.

這是我使用的 Layout, 很簡單, 一個使用者名稱, 一個密碼, 兩個 checkbox 分別用不同方式顯示隱藏密碼
<?xml version="1.0" encoding="utf-8"?>
<Linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp" >

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:gravity="center_vertical"
android:text="@string/username"
android:textSize="18sp" ></TextView>

<EditText
android:id="@+id/user"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="15dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:gravity="center_vertical"
android:inputType="text"
android:padding="3dp"
android:singleLine="true"
android:textSize="20sp" ></EditText>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:gravity="center_vertical"
android:text="@string/password"
android:textSize="18sp" ></TextView>

<EditText
android:id="@+id/pass"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="15dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:gravity="center_vertical"
android:inputType="textPassword"
android:singleLine="true"
android:textSize="20sp" ></EditText>

<CheckBox
android:id="@+id/show_pass"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/show_password" ></CheckBox>

<CheckBox
android:id="@+id/show_pass2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/show_password2" ></CheckBox>

</LinearLayout>

主要程式部份很簡單
public class MainActivity extends Activity {

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  final EditText pass = (EditText)findViewById(R.id.pass);
  
  CheckBox b = (CheckBox)findViewById(R.id.show_pass);
  b.setOnCheckedChangeListener(new OnCheckedChangeListener() {

   @Override
   public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
    if (isChecked) {
     pass.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL);
    } else {
     pass.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
    }
   }
  }); 
  
  b = (CheckBox)findViewById(R.id.show_pass2);
  b.setOnCheckedChangeListener(new OnCheckedChangeListener() {

   @Override
   public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
    if (isChecked) {
     pass.setTransformationMethod(new PasswordTransformationMethod());
    } else {
     pass.setTransformationMethod(new HideReturnsTransformationMethod());
    }
   }
  });
 }

 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
  // Inflate the menu; this adds items to the action bar if it is present.
  getMenuInflater().inflate(R.menu.main, menu);
  return true;
 }

}


程式應該一看就懂, 效果如下,





範例程式碼下載點: https://www.box.com/s/0xdlxjqojaqlb6fxi0gx

2013/04/05

XGallery v1.0.4

vv 1.0.4

- Show video icon in the top-left if this is a video file.

- In image view, if this is a video file, it will show video icon, double click
will launch external player to play this video.

- Add ability to edit album, video or image title


**BUG FIX**

- Fix some bugs introduced by last version

- Fix some FCs problem


中文說明







v 1.0.4

- 增加影片提示圖片

- 瀏覽模式中, 影片圖示雙擊可執行外部軟體播放影片

- 可編輯相簿, 影片或者相片的名稱


**BUG FIX**

- 解決上個版本所導致的問題

- 修正部份導致 FCs 的問題

Gallery3 怎麼利用 REST API 得到 API Key

怎麼利用 REST API 得到 api key, 基本上得到 api key 是為了之後的動作不需要再次使用使用者名稱和密碼, 為了安全性.
要可以使用 REST API, Gallery3 必須開啟 REST Module.
以下使用 curl 當範例來使用 REST API.

假設我架設一個 gallery3 網站, 在
網址: http://www.test.com/gallery3/index.php
使用者: test
密碼: test
下面是使用方式
curl -A "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.91 Safari/537.11" -H "X-Gallery-Request-Method: post" --data-urlencode "user=test" --data-urlencode "password=test" "http://www.test.com/gallery3/index.php/rest"


這樣會得到你的 api key, 後面就可以繼續使用這 api key 作其他的 request 了.

2013/04/04

XGallery v1.0.3

v 1.0.3
* Fix in some cases, can't retrieve data from gallery hosted server.
* Fix some resources not free bug.


中文說明







v 1.0.3
* 修正無法解析部份網址而取不到資料
* 修正部份資源沒有釋放, 導致記憶體使用過高

論壇瀏覽器 v2.0.2

v 2.0.2 -

** 由於新功能關係, 所以從舊版本升級會導致書籤清除的現象 **

** Gphonefans 有時會有部份圖示無法看到, 目前還在想辦法解決中 **

* 調整 UI, 論壇顯示支援度更好.

> Eyny 和 Ck101 會比較不一樣, 因為此兩個論壇架構比較不同

* 新增可自訂論壇, 如果不知道論壇架構是哪一種, 請設定成預設的就可以.

> 自訂論壇有些或許不相容, 如需要更好支援, 請來信. Thanks

* 支援部份論壇簡單回覆文章(沒辦法完整測試, 所以有問題請回報, 並請告知有問題的論壇)

1. APK
2. EYNY
3. FDZone
4. FastZone
5. GPhonefans
5. P2p101
7. PalmIsLife

** BUG: **

* 修改部份 FC 問題
* 修正部份連結會開啟瀏覽器的問題

剛上傳, 所以 google play store 通常會 delay 一下.
Google play store: http://goo.gl/jdHf5