2015年9月30日 星期三

Android-Appium 自動化測試 ( 一 )_說明

專案或者應用程式 告一個段落
我進行一連串的測試
但是光測試流程就得要花上半天的時間
然後又修改 Bug
然後又跑流程測試
然後就無限迴圈
這不知道是工程師的宿命還是個人的命運( 嘆

現在有 Appium 就可以幫我們做測試的動作了
這款工具可以支援 : ios 、 Android
今天就簡單介紹這款自動化測試工具
此篇解說 : Android 部分

1 . Appium 簡介 : 
( 有空補 )
----------------------------------------------------------------------
2 . Appium 架構( 這張圖只是簡化詳情請查Google ) :












先不要管 Appium,先想像如果要拍一部電影需要的是 ?
1 . 陽光 ?
2 . 空氣 ?
3 . 水 ?

都錯 !!!
1 . 待命好的演員( App . apk )
2 . 完美的劇本( TestCode )
3 . 多功能的場景( Appium )

有了這些,我想信你也能演出好的電影。
----------------------------------------------------------------------
3 . Appium 工具 :
( 有空補 )

4 . Appium 用法 :
( 有空補 )

5 . Appium 限制 :
Android SDK API >= 17

參考資訊 : Android UI Testing with Appium

歡迎轉載,請註明出處。

2015年9月29日 星期二

Python-基本運算( 四 )_List

上一篇提到 : 邏輯的判斷

這篇我們要提到的是 : List
在程式裡頭 List 是不可或缺的儲存空間
首先,我們先開啟 Python 環境
宣告方法

list = [123, 45, 841, 112, "asd", 'ase']

就可以用以下的方法來測試囉~
這裡就先列出最常用的幾個方法 :

新增list.append( item)
插入參數list.insert( index, item )
刪除( 參數 )list.remove( item )
刪除( 位置 )list.pop( index )
參數位置list.index( index )
排序( 小到大 )list.sort()
排序( 大到小 )list.reverse()
參數存在個數list.count( value )
陣列大小lenI( list )

* : item ( 參數( 字串 / 數字 皆可 ) )、index( 索引 )
* : Python 是直譯式語言


以下是執行畫面 :


















參考資料 : python Doc
歡迎轉載,請註明出處。

Python-基本運算( 三 )_判斷

上一篇有提到 : 變數宣告

在整的程式運作流程中
判斷 是最不可缺少!!!
比如 : 3 小於 5 會印出資訊...等。

1 . 參數直接比較取得結果


關係、邏輯運算子用法
>、<、==、>=、<=3 >2
and、orTrue and/or False

執行畫面 :











2 . If ... else ...

if 後面一定要加上 " : "
elif 後面一定要加上 " : "
else 後面一定要加上 " : "

if 3 > 2 :
    print("True") //四格空白
// 按Enter

if 3 > 2 :
    print("True") // 四格空白
else :
    print("False") // 四格空白
// 按 Enter

執行畫面 :











歡迎轉載,請註明出處。

Python-基本運算( 二 )_變數宣告

上一篇有提到 : 運算元、字串

這篇提到有關變數 !!!
Python 的變數宣告沒有像是 Java 嚴謹
但最好要在腦袋中仔細分類,以免錯亂

Javapython
字元
char a = 'A';a = 'A'
整數
int b = 10;b = 10
浮點數
float c = 10.0f;c = 10.0
double d = 10.0;d = 10.0
字串
String e = "Apple";e = "Apple"
布林值
boolean f = true;f = True
boolean g = false;g = False

注意 :
1 . 布林值第一個字大寫 !!!
2 . 布林值第一個字大寫 !!!
3 . 布林值第一個字大寫 !!!

以下是執行畫面 :




















歡迎轉載,請註明出處。

Python-基本運算( 一 )_運算元

上一篇有提到安裝 : Python for Window
我們直接使用命令提示字元進行簡單的 Demo
再命令提示字元輸入 : python

基本運算字串

運算子
加法2 + 24
減法2 - 20
乘法2 * 24
除法2 / 21
餘數5 % 21

字串
字串"Apple"'Apple'
字串(大寫)"Apple".upper()'APPLE'
字串(小寫)"Apple".lower'apple'
字串(長度)len("Apple")5

以下是執行的畫面 :


















參考資料 : 初試 Python
歡迎轉載,請註明出處。

2015年9月22日 星期二

Android-取得裝置時間 Get Device Date



public void String getStringData(){  
    final Calendar c = Calendar.getInstance();  
    c.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));
    String mYear = String.valueOf(c.get(Calendar.YEAR));
    String mMonth = String.valueOf(c.get(Calendar.MONTH) + 1);  
    String mDay = String.valueOf(c.get(Calendar.DAY_OF_MONTH)); 
    String mWay = String.valueOf(c.get(Calendar.DAY_OF_WEEK));  
    if("1".equals(mWay)){  
        mWay ="Sun";
    }else if("2".equals(mWay)){  
        mWay ="Mon";
    }else if("3".equals(mWay)){  
        mWay ="Tue";
    }else if("4".equals(mWay)){  
        mWay ="Wed";
    }else if("5".equals(mWay)){  
        mWay ="Thu";
    }else if("6".equals(mWay)){  
        mWay ="Fri";
    }else if("7".equals(mWay)){  
        mWay ="Sat";
    } 
    return mYear + "/"+mMonth + "/" + mDay + "/"  + mWay;
}

歡迎轉載,請註明出處。

2015年9月21日 星期一

Android-Toast 基本 綜合 說明

多個頁面如有要重複使用


import android.content.Context;
import android.widget.Toast;

/**
 * Toast 工具
 */
public class ToastTool {

    /**
     * R.id & ShortTime
     * @param context
     * @param messageId
     */
    public static void showToastShort(Context context, int messageId) {
        Toast.makeText(context, messageId, Toast.LENGTH_SHORT).show();
    }

    /**
     * String & ShortTime
     * @param context
     * @param message
     */
    public static void showToastShort(Context context, String message) {
        Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
    }

    /**
     * R.id & LongTime
     * @param context
     * @param messageId
     */
    public static void showToastLong(Context context, int messageId) {
        Toast.makeText(context, messageId, Toast.LENGTH_LONG).show();
    }

    /**
     * String & LongTime
     * @param context
     * @param message
     */
    public static void showToastLong(Context context, String message) {
        Toast.makeText(context, message, Toast.LENGTH_LONG).show();
    }

}

用法 :

@Override
public void onClick(View view) {
    switch(view.getId())
    {
    case R.id.button1:
        ToastTool.showToastShort(MainActivity.this, "HelloWorld");
        break;
    case R.id.button2:
        ToastTool.showToastShort(MainActivity.this, R.string.hello_world);
        break;
    case R.id.button3:
        ToastTool.showToastLong(MainActivity.this, "HelloWorld");
        break;
    case R.id.button4:
        ToastTool.showToastLong(MainActivity.this, R.string.hello_world);
        break;
    }
}

歡迎轉載,請註明出處。

2015年9月18日 星期五

Android-讀寫文字檔案( Read / Write String in the file )

將文字資料寫入手機的方法

1 . 將字串寫入對應的檔案
/** 將資料寫入記憶卡內 */
public void writeInfo(String fileName, String strWrite)
{
    try {

        String fullPath = Environment.getExternalStorageDirectory().getAbsolutePath();
        String savePath = fullPath + File.separator + "/"+fileName+".txt";

        File file = new File(savePath);

        if (!file.exists()) {
            file.createNewFile();
        }

        FileWriter fw = new FileWriter(file.getAbsoluteFile());
        BufferedWriter bw = new BufferedWriter(fw);
        bw.write(strWrite);
        bw.write(aa);

        bw.close();

    } catch (IOException e) {
        e.printStackTrace();
    }
}

2 . 讀取檔案內的字串
/** 讀取記憶卡資料 */
public String readInfo(String fileName){

    BufferedReader br = null;
    String response = null;

    try {
        StringBuffer output = new StringBuffer();
        String fullPath = Environment.getExternalStorageDirectory().getAbsolutePath();
        String savePath = fullPath + File.separator + "/"+fileName+".txt";

        br = new BufferedReader(new FileReader(savePath));
        String line = "";
        while ((line = br.readLine()) != null) {
            output.append(line +"\n");
        }
        response = output.toString();
        br.close();

    } catch(FileNotFoundException e) {
        e.printStackTrace();
        return null;
    } catch (IOException e) {
        e.printStackTrace();
        return null;

    }
    return response;
}

3 . 權限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>


歡迎轉載,請註明出處。

2015年9月14日 星期一

Android-Bluetooth Low Energy(BLE) 連線操作( 二 )

在上一篇有提到 Android-Bluetooth Low Energy(BLE) 基本操作( 一 )

每種BLE裝置都有它自己的功能
現在我們就針對他的功能做延伸
官方有簡單的 Sample

------ 以下尚未整理
( 如果有任何錯誤,請別吝嗇,歡迎留言討論 )
不過我們還是要從最基本的開始
BLE有分 主、從方
/*
BLE 最主要是看他的 Profile 我的才能進行下去
何謂的 Bluetooth Profile?
他是對藍芽裝置的一個說明、用途。
*/
所以此功能....(等待更改)

1 . 判斷裝置是否支援BLE
2 . 判斷裝置是否開啟BLE
3 . 掃描BLE周邊
4 . 連線到指定 MAC




參考資料 : Android 讀取低功耗藍牙(BLE)程式初探
參考資料 : Android Ble简析
參考資料 : Android的BLE通信实现
參考資料 : Android BLE 蓝牙低功耗教程,中央BluetoothGatt和周边BluetoothGattServer的实现
參考資料 : Android 4.3 BLE how to write Characteristic
參考資料 : Android蓝牙BLE开发步骤

歡迎轉載,請註明出處。

2015年9月9日 星期三

Android-設定更換背景漸層顏色( Change BackgroundColor Gradient)

常常有人問背景只能設定單一色調嗎?
答案是否定的
以下有 Sample 提供各位參考
首先在 drawable 底下創立相關文件

















Gradient 漸層
startColor : 起始顏色
centerColor : 中間顏色
endColor : 結束顏色
angle : 頭尾( 建議 45 度為單位 )
( EX : 90 : 下到上 )


gradient_1.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <gradient
        android:startColor="#FFFFFF"
        android:endColor="#55AA00"
        android:angle="90"/>    
</shape>

gradient_2.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
    <gradient android:startColor="#0000FF" 
              android:centerColor="#CCDDFF"
              android:endColor="#0000FF" 
              android:angle="-90" />
</shape>

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linearLayout_background"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/gradient_1"
    >

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" />
   
</LinearLayout>

MainActivity.java
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;

public class MainActivity extends Activity implements OnClickListener{

    private LinearLayout linear_background;
    private Button btn01;
    private Button btn02;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        linear_background = (LinearLayout)findViewById(R.id.linearLayout_background);
        btn01 = (Button)findViewById(R.id.button1);
        btn02 = (Button)findViewById(R.id.button2);
        
        btn01.setOnClickListener(this);
        btn02.setOnClickListener(this);

    }

    @Override
    public void onClick(View view) {
        switch(view.getId()){
        
        case R.id.button1:
            linear_background.setBackgroundResource(R.drawable.gradient_1);
            
            break;
            
        case R.id.button2:
            linear_background.setBackgroundResource(R.drawable.gradient_2);
            
            break;
        }
    }
}

有朋友說為什麼不用
1 . BackgroundDrawable - 不建議使用
2 . Background - 最低版本為 : API 16
int sdk = android.os.Build.VERSION.SDK_INT;
if(sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) 
{
    linear_background.setBackgroundDrawable( getResources().getDrawable(R.drawable.gradient_1) );
} 
else 
{
    linear_background.setBackground( getResources().getDrawable(R.drawable.gradient_1));
}
參考連結 : Android中使用setBackgroundDrawable错误提示

------------------------------------------------
完成圖 :
gradient_1


gradient_2
























如果有關顏色內容不了解,請參考以下 :
參考資訊 : Android中shape的使用
參考資訊 : Android Debelopers-Drawable Resources
歡迎轉載,請註明出處。

Android-TabLayout

如何使用TabLayout
TabLayout of design support library

// set selected tab
viewPager.setCurrentItem(postion);
tabLayout.getTabAt(postion).select();

參考資料 : TabLayout使用setupWithViewPager()方法绑定Viewpager后不显示文字

Android-Picasso and Glide

Glide.with(mContext).load(_list.get(position)).diskCacheStrategy(DiskCacheStrategy.ALL).placeholder(R.drawable.loading).into(elements.image_cell_action_detail);

參考資料 : Android: Image loading libraries Picasso vs Glide
參考資料 : 如何使用Glide
參考資料 : Glide

------ Glide use bitmap
參考資料 : Glide — Callbacks: SimpleTarget and ViewTarget for Custom View Classes

2015年9月8日 星期二

Android-多國語系開發 Multiple Language

如果要開發多語系的 App 
不必再寫一樣的App
與需要將專案內的參數在複製一份
將檔案名稱改成相對應的語系
這樣就能依照使用者的需求直接更改

1 . 注意,請將專案內所有的文字寫在 value -> string 底下
( 這是一種好的習慣,如果只有2-3個頁面,但如果是10個以上,那就會有漏失的風險 )

2 . 複製所有的 value 後更改,將檔案名稱改成對應的語系名稱
















3 . 只要手機切換到對應的語系就能得到對應的頁面

中文( 正體字
























英文( US
























其他語系相關資料

歡迎轉載,請註明出處。

Android-Keyboard Listener


@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO) {
        Toast.makeText(getActivity(), "keyboard visible", Toast.LENGTH_SHORT).show();
    } else if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES) {
        Toast.makeText(getActivity(), "keyboard hidden", Toast.LENGTH_SHORT).show();
    }
}

用Layout高度判別
@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO) {
        Toast.makeText(getActivity(), "keyboard visible", Toast.LENGTH_SHORT).show();
    } else if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES) {
        Toast.makeText(getActivity(), "keyboard hidden", Toast.LENGTH_SHORT).show();
    }
}