軟體開發(軟件開發)

網智數位主要提供套裝及客製化的軟體系統解決方案,專為客戶量身訂做客製化的軟體,達成客製化、智慧化及網路化的管理功能。

室內設計、裝潢、窗簾報價估算軟體

網智數位主要提供套裝及客製化的軟體系統解決方案,針對室內設計師、木工、裝潢業產業,量身訂做客製化的軟體,達成客製化、智慧化及網路化的商用軟體。

商用軟體-客製化設計

網智數位主要提供套裝及客製化的軟體系統解決方案,專為客戶量身訂做客製化的軟體,達成客製化、智慧化及網路化的管理功能。

IOT 物聯網-系統開發

根據客戶實際狀況,結合雲端與載具進行客製化物聯網IOT導入與軟體開發

雲端VPS虛擬主機租用

我們的雲端VPS虛擬主機是採用雲端(虛擬化)技術所開發之全新雲端伺服器服務,可以選擇多種作業系統(Windows、Linux等),客戶可載入自訂的應用環境,執行自己所要提供的網路服務,我們的雲端服務可為您的網站提供最完美的解決方案。

ERP軟體客製化導入

ERP軟體客製化導入,室內設計、營造業、裝潢、木作工程、系統櫃工程、會計系統,全面提升公司管理營運效率。

搜尋引擎最佳化SEO

搜尋引擎最佳化(SEO)不僅能提高網站在搜尋結果的排名,更能帶來大量對我們產品或服務真正有需求的訪客。SEO 最棒的特質之一就是不像廣告一樣亂槍打鳥而導致用戶的反感,反而更能提升點閱率跟成交率喔。

服務宗旨

網智數位主要提供套裝及客製化的軟體系統解決方案,專為客戶量身訂做客製化的軟體,達成客製化、智慧化及網路化的管理功能。

我們的成立宗旨就是要以最猛的IT技術讓這個世界更Smart,在我們貫徹我們裡想的同時,我們希望可以把我們所開發的系統帶給台灣的中小企業,除了要推薦好的東西之外,我們也希望做點改變,所以我們的第一目標就是要使用最好用的系統再加上您寶貴的創意,不僅僅可以節省你大量的荷包,還可以有一個像樣的網站。我們可以幫你做的有

企業管理
  • 策略管理
  • 目標管理
  • 行銷管理
  • 財會管理
  • ERP導入
  • 企業流程自訂
資訊管理
  • 網站架設
  • 虛擬化/雲端架設
  • 主機代管
  • 私有雲建制與導入
軟體開發
  • UML設計
  • 版本控管
  • 企業軟體開發
  • APP開發
  • 網頁設計
資訊安全
  • 網頁弱點掃描
  • 主機弱點掃描
  • 木馬檢測
  • 資安鑑識
  • 設計網路架構
  • 資安監控
行銷
  • 關鍵字SEO
  • 社群網路行銷
  • 部落格行銷
  • FaceBook 粉絲團
其他
  • 協助企業申請Google Email
好玩工具開發

講出你的創意吧!沒有甚麼是資訊辦不到的

顯示具有 程式教學 標籤的文章。 顯示所有文章
顯示具有 程式教學 標籤的文章。 顯示所有文章

2018年11月21日 星期三

Android APP 非同步下載圖片實作(背景服務)-APP開發教學

  此篇文章主要是示範教學如何開發Android APP時,利用背景服務來進行比較耗時的工作,使得使用者可以不會覺得APP停頓當掉的錯覺。

   背景服務程式(背景執行緒)主要在比較複雜的APP應用程式,它在執行運作時,例如從網路下載檔案、讀取後端資料庫的資料、讀取手機記憶卡的資料時,會需要較多時間,所以系統畫面沒辦法即時回應,甚至出現【應用程式沒有回應】的對話視窗,詢問使用者是否繼續等待或結束APP程式。

 

    而透過在背後另外建立自己的執行緒,去獨立執行比較耗時的工作任務,跟主畫面的執行緒沒有關聯,完全不會影響主畫面的更新與停頓狀態.

     這類性質的工作就適合利用 Android API 提供的 AyncTask 執行緒.

下面我在 res/laylout 設計一個簡單的APP主畫

繪圖

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="#607D8B">

<!-- 顯示圖片的元件 -->

<ImageView

android:id="@+id/imageview"

android:layout_width="match_parent"

android:layout_height="match_parent" />

<!-- 開始下載圖片的按鈕元件 -->

<Button

android:id="@+id/download_btn"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_alignParentTop="true"

android:layout_margin="6sp"

android:onClick="clickDownLoadButton"

android:text="背後執行下載圖片"

android:textSize="24sp" />

<LinearLayout

android:id="@+id/op_panel"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_alignBottom="@id/imageview"

android:layout_centerInParent="true"

android:background="@drawable/operation_drawable"

android:orientation="horizontal"

android:padding="6sp"

android:visibility="invisible">

<!-- 顯示前一張圖片 -->

<ImageButton

android:id="@+id/previous"

android:layout_width="0dp"

android:layout_height="wrap_content"

android:layout_weight="1"

android:onClick="clickMoveButton"

android:src="@drawable/ic_keyboard_arrow_left_white_48dp" />

<!-- 顯示下一張圖片 -->

<ImageButton

android:id="@+id/next"

android:layout_width="0dp"

android:layout_height="wrap_content"

android:layout_weight="1"

android:onClick="clickMoveButton"

android:src="@drawable/ic_keyboard_arrow_right_white_48dp" />

</LinearLayout>

</RelativeLayout>



程式解說:

上面主要畫面配置檔,提供一個按鈕,可以下載7張圖片,並將下載的圖片依序可以輪流顯示每張圖片,每張圖片都是透過背後執行緒進行下載,檔執行任務完成後,在將 LinearLayout容器顯示出來,這個容器很簡單放入兩個 ImageButton ,用來切換上一

張與下一張圖片。

現在回到 Java 主程式,宣告一個繼承

AppCompatActivity 的類別,

public class AsyncTaskDemo extends AppCompatActivity {

private ImageView imageview;

private LinearLayout op_panel;

private Bitmap[] images;

// 目前畫面顯示的圖片編號

private int position = 0;

// 顯示下載進度用的進度對話框

private ProgressDialog progressDialog;




程式解說:

在上面主要宣告幾個欄位 Fields , 用來對應之前的配置畫面元件,還有 Bitmap[] 陣列,存放下載的圖片,以及一個進度用的是從 PrgressDialog。

然後重點在 Button 圖片下載的程式碼邏輯:

public void clickDownLoadButton(View view) {

// 這邊可以讓下載按鈕消失

findViewById(R.id.download_btn).setVisibility(View.INVISIBLE);

// 建立下載圖片的AsyncTask物件

final DownloadImageTask downloadImageTask = new DownloadImageTask();

// 顯示 進度對話框

progressDialog = new ProgressDialog(this);

progressDialog.setTitle("Download");

progressDialog.setMessage("Please wait for download...");

progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);

progressDialog.setProgress(0);

progressDialog.setCancelable(false);

// 加入取消工作的按鈕

progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel",

new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

// 取消AsyncTask的工作,參數指定為true,表示取消正在執行的工作

// 呼叫這個方法的AsyncTask物件,在結束doInBackground方法後,

// 不會呼叫onPostExecute方法,改為呼叫onCancelled方法

downloadImageTask.cancel(true);

}

});

// 顯示進度對話框

progressDialog.show();

// 啟動AsyncTask物件

downloadImageTask.execute();

}



上面程式主要宣告一個 DownloadImageTask ,
這個程式主要是繼承了 AsyncTask 類別

// 呼叫這個物件的execute方法後就會執行這個方法

// 參數是AsyncTask泛型指定的第一個型態的陣列

@Override

protected Void doInBackground(Void... args) {

// 讀取陣列資源,下載的圖片名稱

Resources res = getResources();

String[] imageNames =

res.getStringArray(R.array.android_icons_array);

// 讀取儲存圖片的網路位置

String baseUrl = getString(R.string.base_url);

// 設定進度對話框的最大進度數量

progressDialog.setMax(imageNames.length);

for (int i = 0; i < imageNames.length; i++) {

// 判斷是否取消工作

if (isCancelled()) {

break;

}

// 下載圖片的完整網址

String url = baseUrl + imageNames[i];

// 從網際網路下載圖片

downloads.add(loadBitmap(url));

// 執行進度處理,參數會傳送給onProgressUpdate方法

publishProgress(i + 1);

}

// 如果已經下載圖片

if (downloads.size() > 0) {

// 建立儲存圖片的Bitmap陣列

images = new Bitmap[downloads.size()];

// 把List物件轉換為陣列

downloads.toArray(images);

}

return null;

}



  

// 執行進度處理,參數是AsyncTask泛型指定的第二個型態的陣列

// 在doInBackground方法中,呼叫publishProgress方法後,

// 就會執行這個方法並接收放在publishProgress方法中的參數

@Override

protected void onProgressUpdate(Integer... values) {

// 設定進度對話框的進度

progressDialog.setProgress(values[0]);

// 設定ImageView使用的ImageView物件

imageview.setImageBitmap(downloads.get(downloads.size() - 1));

}

// doInBackground方法結束後就會執行這個方法

// 參數是AsyncTask泛型指定的第三個型態的陣列

// 接收doInBackground方法的回傳值

@Override

protected void onPostExecute(Void result) {

// 結束進度對話框

progressDialog.dismiss();

// 設定ImageView使用的ImageView物件

imageview.setImageBitmap(images[0]);

// 顯示上下張圖片的操作按鈕

op_panel.setVisibility(View.VISIBLE);

}

// 呼叫cancel方法後執行這個方法

// 參數是AsyncTask泛型指定的第三個型態的陣列

// 接收doInBackground方法的回傳值

@Override

protected void onCancelled(Void result) {

if (images != null) {

// 設定ImageView使用的ImageView物件

imageview.setImageBitmap(images[0]);

// 顯示上下張圖片的操作按鈕

op_panel.setVisibility(View.VISIBLE);

}

}

完成上面所有程式,就完成一個非同步的下載圖片實作案例,這邊我是預期看這篇實作教學的本身對 Android 開發有一定的經驗,如果對於這篇教學有任何問題,可以寄發郵件向我詢問。

程式執行結果

繪圖2

繪圖3


  





網智數位-軟體開發(軟件開發)
針對各特殊產業都可以量身定做符合貴公司的需求,別人無法克服的就是我們的挑戰
業務合作、軟體委外開發
業務窗口:allen@netqna.com
聯繫電話:0920-883-870
公司電話:02-55991310
公司地址(業務營運處):台北市中山區錦州街 25 號 5 樓
skype: netqna
line:netqna
微信:netqna
黃先生 Allen
my_qrcode_1519621481105

2018年7月25日 星期三

Xamarin 跨平台程式開發-訊息傳遞 - 軟體開發 教學

   在 Xamarin 開發 IOS、Android、UWP APP時,常常會遇到訊息接受與訊息傳遞,那麼這邊我想簡單示範如何在 Xamarin 實作一個訂閱訊息程式開發技巧。

Android 執行結果畫面
螢幕快照 2018-07-25 下午10.27.43螢幕快照 2018-07-25 下午10.28.49螢幕快照 2018-07-25 下午10.29.10


   Xamarin 透過 MessagingCenter 這個靜態類別來支援訂閱/通知訊息,這個類別主要需要知道三個 Methods ,分別為 Subscribe<TSender, TArgs> 與 Send<TSender, TArgs>、Unsubscribe<TSender, TArgs>。
Subscribe<TSender, TArgs> 方法用來訂閱訊息,當有訊息接受到時,可以通知使用者,例如出現對話訊息、畫面顯示訊息。
Send<TSender, TArgs> 方法用來通知訊息,已告知那些訂閱訊息者。
Unsubscribe<TSender, TArgs> 原先進行訂閱訊息接受,現在進行取消訂閱,後續如果有訊息通知,都不進行接受訊息。


程式範例示範
image

public class MainPageViewModel
    {
        public ObservableCollection<string> Greetings { get; set; }


        public MainPageViewModel ()
         {
            Greetings = new ObservableCollection<string> ();


           MessagingCenter.Subscribe<MainPage> (this, "哈嘍", (sender) => {
                Greetings.Add("哈嘍");
             });


            MessagingCenter.Subscribe<MainPage, string> (this, "哈嘍", (sender, arg) => {
                Greetings.Add("哈嘍 " + arg);
            });

        }
    }

在上面程式範例 宣告 一個 MainPageViewModel Class,這個作為 ViewModel 用途,在建構式裡實作訂閱服務,這個機制可以減少程式物件耦合度。


下面這行程式碼,主要是用於實作一個名叫 “哈嘍”的訂閱服務  MessagingCenter.Subscribe<MainPage> (this, "哈嘍", (sender) => {  Greetings.Add("哈嘍"); });





在底下的主程式 MainPage ,實作訂閱通知服務,主要程式邏輯,我透過註解程式說明

public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();


            //這邊我綁定一個ViewModel
            BindingContext = new MainPageViewModel();


            //宣告一個按鈕物件,當點選按鈕時,觸發一個發送訊息
            var button1 = new Button { Text = "Say 哈嘍" };
            button1.Clicked += (sender, e) =>
            {
                MessagingCenter.Send<MainPage>(this, "哈嘍");
            };


            //宣告一個按鈕物件,當點選按鈕時,觸發一個發送訊息,並傳遞內容參數,傳遞的內容是 Allen 

            var button2 = new Button { Text = "Say Hi to Allen" };
            button2.Clicked += (sender, e) =>
            {
                MessagingCenter.Send<MainPage, string>(this, "哈嘍", "Allen");
            };


            //宣告一個按鈕物件,當點選按鈕時,觸發一個取消訂閱服務,並取消對話視窗訊息!
            var button3 = new Button { Text = "取消訂閱服務,並取消對話視窗訊息!" };
            button3.Clicked += (sender, e) =>
            {
                MessagingCenter.Unsubscribe<MainPage, string>(this, "哈嘍");
                 DisplayAlert("取消訂閱服務",
                    "This page has stopped listening, so no more alerts; however the ViewModel is still receiving messages.",
                    "OK");
             };


            //訂閱服務(背後的ViewModel還是仍然保持本身實作的訂閱服務),並出現對話視窗訊息
            MessagingCenter.Subscribe<MainPage, string>(this, "哈嘍", (sender, arg) =>
            {
                DisplayAlert("訊息已接受", "參數訊息 為 " + arg, "OK");
            });

            //綁定接受到的訂閱訊息
            var listView = new ListView();
             listView.SetBinding(ListView.ItemsSourceProperty, "Greetings");

            //放置物件內容
            Content = new StackLayout
             {
                Padding = new Thickness(0, 20, 0, 0),
                Children = { button1, button2, button3, listView }
            };
        }




在 iPhone X 執行畫面如下
螢幕快照 2018-07-25 下午10.20.29螢幕快照 2018-07-25 下午10.20.46






網智數位-軟體開發(軟件開發)
針對各特殊產業都可以量身定做符合貴公司的需求,別人無法克服的就是我們的挑戰
業務合作、軟體委外開發
業務窗口:allen@netqna.com
聯繫電話:0920-883-870
公司電話:02-55991310
公司地址(業務營運處):台北市中山區錦州街 25 號 5 樓
skype: netqna
line:netqna
微信:netqna
黃先生 Allen
my_qrcode_1519621481105