分類
Uncategorized

Customize style for checkbox

1.
首先建立 Selector(customize_checkbox_selector.xml),以套用到checkbox上

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/press"
        android:state_checked="true" android:state_focused="true"/>
    <item android:drawable="@drawable/press"
        android:state_checked="false" android:state_focused="true"/>
    <item android:drawable="@drawable/press" android:state_checked="true"/>
    <item android:drawable="@drawable/normal" android:state_checked="false"/>
</selector>

注意:
press的圖片就是點擊checkbox顯示的圖片, normal的圖片就是未點擊checkbox的圖片
把customize_checkbox_selector.xml放到res/drawable/中
 
2.
建立Style, 和 Button 不同,checkbox必須另外建立一個style,並在style中引入第一步驟建立的Selector, 最後才在checkbox的xml中套用style

<style name="customize_checkbox_style"
        parent="@android:style/Widget.CompoundButton.CheckBox">
        <item name="android:button">@drawable/customize_checkbox_selector</item>
</style>

 
3.
在checkbox xml中套用

<CheckBox
            android:id="@+id/test_checkbox"
            style="@style/customize_checkbox_style"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@color/customize_bg"
            android:text="@string/teststring">
</CheckBox>

注意: 若checkbox的文字已經有設定了但在畫面上還是看不出來,請小心checkbox的字體顏色是否和背景顏色相同
 

分類
Uncategorized

更改ActionBar background color

更改ActionBar的background color
 
直接在程式碼中設定

//取得色碼
String color = getResources().getString(R.color.mycolor);
//注意Color.parseColor必須帶入8碼色碼,如#FF3D3D3D,若帶入4碼顏色會不正確
getActionBar().setBackgroundDrawable(new ColorDrawable(Color.parseColor(color)));

 

分類
Uncategorized

WifiInfo 紀錄

WifiInfo wifiInfo = WifiManager.getConnectionInfo(); 可取得目前wifi連線的資訊
wifiInfo.getBSSID(); 可取得目前連結AP的BSSID, BSSID等同於MAC address
wifiInfo.getMacAddress()); 可取得目前device的MAC address
wifiInfo.getSSID(); 可取得SSID名稱

 

分類
Uncategorized

安裝並設定 Synergy on ubuntu12.04

1. 安裝 synergy

sudo apt-get install synergy
Note : 安裝完成後 synergy 的執行檔位於 /usr/bin/synergys
 

2. 檢查配置檔(config file)是否位於以下2個位置,不存在可自行新增於~/.synergy.conf,新增內容參考3-3。

~/.synergy.config or ~/.config/Synergy/Synergy.conf
Note : 測試 config file 是否設定正確,可在 console 輸入 synergys,設定錯誤顯示如下訊息

2016-01-14T11:36:10 ERROR: cannot read configuration "/home/foxx/.synergy.conf":
read error: line 1: found data outside section
/build/buildd/synergy-1.3.8/src/cmd/synergys/synergys.cpp,1130
synergys: no configuration available

 
設定完成後必須重新啟動 synergys。
 

3. 編輯 synergy config file 來設定快速鍵

3-1. 使用 /usr/bin/synergys 來啟動 synergy, 不要使用 quicksynergy
3-2. Synergy的config檔位於 ~/.synergy.conf , 可修改其對應的熱鍵設定
3-3.以下是目前設定檔,參考用

section: screens
	section_center:
	section_left:
end
section: links
	section_center:
		left = section_left
	section_left:
		right = section_center
end
section: options
	keystroke(alt+KP_1) = switchToScreen(section_left)
	keystroke(alt+KP_2) = switchToScreen(section_center)
end

KP_1為右方小鍵盤(KeyPad)數字鍵1, KP_2為右方小鍵盤(KeyPad)數字鍵2
所以只要按下alt + keypad_1 和 alt + keypad_2 即可切換不同螢幕,不必使用滑鼠移來移去了
注意:可使用的熱鍵大小寫有區別
更多的設定參考官網

分類
Uncategorized

轉換密碼內容為暗碼或明碼

可藉由 HideReturnsTransformationMethod 物件來轉換明碼 以及 PasswordTransformationMethod 物件來轉換成暗碼
建立物件後再呼叫 EditText 的 setTransformationMethod(), 傳入剛剛產生的物件即可完成轉換
Source Code

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.text.method.HideReturnsTransformationMethod;
import android.text.method.PasswordTransformationMethod;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
public class MainActivity extends ActionBarActivity
{
    private EditText mInputPassword;
    private CheckBox mShowPassword;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initLayoutComponents();
    }
    private void initLayoutComponents()
    {
        mInputPassword = (EditText) findViewById(R.id.password);
        mShowPassword = (CheckBox) findViewById(R.id.switchPassword);
        mShowPassword.setOnCheckedChangeListener(new OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
            {
                if (isChecked) {
                    mInputPassword.setTransformationMethod(new HideReturnsTransformationMethod());
                } else {
                    mInputPassword.setTransformationMethod(new PasswordTransformationMethod());
                }
            }
        });
    }
}

第33行及35行即為轉換的過程
 
R.layout.activity_main.xml

<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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.changepasswordtostar.MainActivity" >
    <EditText
        android:id="@+id/password"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:hint="@string/input_password_hint"
        android:inputType="textPassword"/>
    <CheckBox
        android:id="@+id/switchPassword"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/password"
        android:layout_alignLeft="@+id/password"
        android:text="@string/showPasswrod"/>
</RelativeLayout>

 

分類
Uncategorized

使用自定義Menu

Activity 在預設的情況中按下選單鍵是沒有反應的, 要讓選單鍵產生作用相當簡單,只要注意以下兩點
1. 複寫 activity的 onCreateOptionsMenu 方法, 在方法中加入想要顯示的選單項目(MenuItem)
2. 複寫 activity的 onOptionsItemSelected 方法, 在方法中加入點選各選單項目(MenuItem)要對應的動作
實作程式碼如下

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends Activity
{
    public static final int ADD_ID = 0;
    public static final int DELETE_ID = 1;
    public static final int ABOUT_ID = 2;
    public static final int EXIT_ID = 3;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        super.onCreateOptionsMenu(menu);
        addMenuItems(menu);
        return true;
    }
    private void addMenuItems(Menu menu)
    {
        menu.add(Menu.NONE, ADD_ID, Menu.NONE, R.string.menu_add);
        menu.add(Menu.NONE, DELETE_ID, Menu.NONE, R.string.menu_delete);
        menu.add(Menu.NONE, ABOUT_ID, Menu.NONE, R.string.menu_about);
        menu.add(Menu.NONE, EXIT_ID, Menu.NONE, R.string.menu_exit);
    }
    public boolean onOptionsItemSelected(MenuItem item)
    {
        selectMenuItemEvents(item);
        return super.onOptionsItemSelected(item);
    }
    private void selectMenuItemEvents(MenuItem item)
    {
        switch (item.getItemId()) {
            case ADD_ID:
                setTitle(getResources().getString(R.string.menu_add));
                break;
            case DELETE_ID:
                setTitle(getResources().getString(R.string.menu_delete));
                break;
            case ABOUT_ID:
                setTitle(getResources().getString(R.string.menu_about));
                break;
            case EXIT_ID:
                break;
        }
    }
}

 
main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
</LinearLayout>

 
strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">MENU</string>
    <string name="menu_add">add item</string>
    <string name="menu_delete">delete item</string>
    <string name="menu_about">about</string>
    <string name="menu_exit">exit</string>
    <string name="menu_about_msg">message for about...</string>
    <string name="str_ok">OK</string>
    <string name="str_cancel">Cancel</string>
    <string name="menu_exit_msg">exit system?</string>
</resources>

 
 
 

分類
Uncategorized

使用 AlertDialog.Builder 建立多重選項選單(MultiChoiceItems)

建立多重選單必須使用AlertDialog.Builder 來達成, 如下

package com.example.layout;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.DialogInterface.OnMultiChoiceClickListener;
import android.os.Bundle;
import android.util.Log;
public class MultiChoiceItemsActivity extends Activity
{
    protected static final String TAG = "MultiChoiceItemsActivity";
    private String[] mItems = new String[] {
            "item1", "item2", "item3", "item4", "item5"
    };
    private boolean[] mCheckItems = new boolean[mItems.length];
    private void showAlertDialog()
    {
        Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("Title");
        builder.setMultiChoiceItems(mItems, mCheckItems, new OnMultiChoiceClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which, boolean isChecked)
            {
                if (isChecked) {
                    mCheckItems[which] = true;
                }
            }
        });
        builder.setNegativeButton("Negative", new OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which)
            {
                String checkItemsResult = "";
                int checkItemslength = mCheckItems.length;
                for (int i = 0; i < checkItemslength; ++i) {
                    if (mCheckItems[i]) {
                        checkItemsResult = checkItemsResult + mItems[i];
                    }
                }
                Log.d(TAG, checkItemsResult);
            }
        });
        builder.show();
    }
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_multi_choice_items);
        showAlertDialog();
    }
}

 
第17行為多重選項的內容
第21行為紀錄哪些選項被選擇
第27行設定多重選項並傳入顯示的選項內容
第32行藉由isChecked判斷哪些選項被勾選,並紀錄在mCheckItems中
第38行加入Button
第43~50行為顯示被勾選的選項

分類
Uncategorized

使用 ant 手動產生 signed apk

相反於此篇(使用ant手動產生unsign apk), 現在必須使用ant手動產生 sign apk, 以步驟為說明
 
Step1. Generate keystore by command

keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 10000

Note:alias_name 為 key 名稱, 必須相同於Step3. 的alias_name, 10000為有效時間(天數),官方建議25年以上
執行後還需要填入相關訊息如下

輸入 keystore 密碼:  xxxabcdefg
重新輸入新密碼: xxxabcdefg
您的名字與姓氏為何?
  [Unknown]:  test
您的編制單位名稱為何?
  [Unknown]:  test
您的組織名稱為何?
  [Unknown]:  test
您所在的城市或地區名稱為何?
  [Unknown]:  test
您所在的州及省份名稱為何?
  [Unknown]:  test
該單位的二字國碼為何
  [Unknown]:  test
CN=test, OU=test, O=test, L=test, ST=test, C=test 正確嗎?
  [否]:  y
針對 CN=test, OU=test, O=test, L=test, ST=test, C=test 產生有效期為 10,000 天的 2,048 位元 RSA 金鑰對以及自我簽署憑證 (SHA1withRSA)
輸入 <alias_name> 的主密碼
	(RETURN 如果和 keystore 密碼相同):

完成後在當前目錄下會產生名稱為 my-release-key 的 keystore, 注意此keystore必須小心保存放在本機端
 
 
Step2. Create build.xml
(move to root folder of your project and type follow command)

android update project -p .

Note :
1.”android” means android tool at sdk, maybe need to indicate path like /android_sdk/tools/android
2. build.xml is for ant to build project
 
 
Step3. Create ant.properties and type follow content inside
(move to root folder of your project and type follow content)

key.store=/your-keystore-path/my-release-key.keystore
key.alias=alias_name

Note:
1. alias_name must the same with Step1.
2. ant.properties be used by build.xml
 
 
Step4. Create custom_rules.xml
(move to root folder of your project and type follow content)

<?xml version="1.0" encoding="UTF-8"?>
<project name="custom_rules" default="help">
  <property file="/path_of_secure.properties/secure.properties" />
</project>

Note:
1. custom_rules.xml be used by build.xml
 
 
Step5. Create  secure.properties reference follow content

key.store.password=xxxabcdefg
key.alias.password=xxxabcdefg

Note:
1. password must equal to Step1. 的 “輸入 keystore 密碼”
2. path of secure.properties must the same with Step4. “/path_of_secure.properties/secure.properties”
3. this file maybe can put the same folder with my-release-key.keystore
 
 
Step6. type follow command

ant release

Note:
1. xxx-release.apk will be created at /project/bin/ when build process is success
2. build error :
/bin/AndroidManifest.xml:2: error: Error: String types not allowed (at ‘versionCode’ with value ‘${MAJOR_NUMBER}’).
solution:
Type normal string value e.g. “0” for vsersionCode and “0.1” for versionName at /bin/AndroidManifest.xml
 

分類
Uncategorized

ant build error: [aapt] invalid resource directory name: /project/bin/res/crunch

Description:

Use Ant to build apk and show error message at Terminal

[aapt] invalid resource directory name: /project/bin/res/crunch

 

Root Caused:

Ant can’t handle crunch directory
 

Solution:

Move to root director of project and type follow command
ant clean debug

分類
Uncategorized

ant build error: sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable.

Root Caused:
sdk.dir is missing. Make sure to generate local.properties using ‘android update project’ or to inject it through the ANDROID_HOME environment variable.
Solution:
Move to root director of project and type follow command
android update project -p .