2015年10月31日 星期六

Android Studio R 顯示紅色

當 R 顯示紅色如下時, 可按 Build -> Rebuild Project 解決

EditView txtWrite = (EditText) findViewById(R.id.editText);

2015年10月25日 星期日

android 讀取, 寫入及刪除檔案 (internal storage)

版面要加入一個editView, 一個textView及三個 Button (editView, textView, btnRead, btnWrite, btnDel)

MainActivity.java

import android.content.Context;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.view.View.OnClickListener;
import android.widget.Toast;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;


public class MainActivity extends ActionBarActivity {
    private Button btnTxtRead;
    private Button btnTxtWrite;
    private Button btnFileDel;
    private EditText txtWrite;
    private TextView txtRead;
    String fileName = "dateRec.dat";


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

        txtWrite = (EditText) findViewById(R.id.editText);
        txtRead = (TextView) findViewById(R.id.textView);

        btnTxtRead = (Button) findViewById(R.id.btnRead);
        btnTxtWrite = (Button) findViewById(R.id.btnWrite);
        btnFileDel = (Button) findViewById(R.id.btnDel);

        btnTxtRead.setOnClickListener(btnListener);
        btnTxtWrite.setOnClickListener(btnListener);
        btnFileDel.setOnClickListener(btnListener);


    }


    private void writer() {
        FileOutputStream fos = null;
        
        try {
            fos = openFileOutput(fileName, Context.MODE_PRIVATE);
            fos.write(txtWrite.getText().toString().getBytes());
            fos.close();

            File file = new File(getFilesDir() + "/" + fos);
            Toast.makeText(getApplicationContext(), file.getAbsolutePath(), Toast.LENGTH_SHORT).show();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private void reader() {
        FileInputStream fos = null;
        BufferedInputStream buffered = null;
        txtRead.setText("");

        try {
            fos = openFileInput(fileName);
            buffered = new BufferedInputStream(fos);
            byte[] buffbyte = new byte[200];
            txtRead.setText("");
            do {
                int flag = buffered.read(buffbyte);
                if (flag == -1) {
                    break;
                } else {
                    txtRead.append(new String(buffbyte), 0, flag);
                }
            }while (true);
            buffered.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void fileDel() {
        File file = new File(getFilesDir() + "/" + fileName);
        if (file.exists()){
            file.delete();
            Toast.makeText(getBaseContext(),
                    "File deleted",
                    Toast.LENGTH_SHORT).show();
        }else{
            Toast.makeText(getBaseContext(),
                    "File doesn't exist",
                    Toast.LENGTH_SHORT).show();
        }
    }

    private OnClickListener btnListener = new OnClickListener() {
            public void onClick(View v) {
                switch (v.getId()) {
                    case R.id.btnRead:
                        try {
                            Toast.makeText(getApplicationContext(),
                                    "Read button pressed", Toast.LENGTH_SHORT).show();
                            reader();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        break;
                    case R.id.btnWrite:
                        try {
                            Toast.makeText(getApplicationContext(),
                                    "Write button pressed", Toast.LENGTH_SHORT).show();
                            writer();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        break;
                    case R.id.btnDel:
                        try {
                            Toast.makeText(getApplicationContext(),
                                    "Del button pressed", Toast.LENGTH_SHORT).show();
                            fileDel();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        break;
                }


            }


        };
    }
 

2015年10月23日 星期五

android 有多個按鍵 (button) 時使用switch statement

版面要加入三個 Button (btnRead, btnWrite, btnDel)

MainActivity.java

import android.content.DialogInterface;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.view.View.OnClickListener;
import android.widget.Toast;


public class MainActivity extends ActionBarActivity {
    private Button btnTxtRead;
    private Button btnTxtWrite;
    private Button btnFileDel;

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

        btnTxtRead = (Button) findViewById(R.id.btnRead);
        btnTxtWrite = (Button) findViewById(R.id.btnWrite);
        btnFileDel = (Button) findViewById(R.id.btnDel);

        btnTxtRead.setOnClickListener(btnListener);
        btnTxtWrite.setOnClickListener(btnListener);
        btnFileDel.setOnClickListener(btnListener);
    }

    private OnClickListener btnListener = new OnClickListener() {
            public void onClick(View v) {
                switch (v.getId()) {
                    case R.id.btnRead:
                        try {
                            Toast.makeText(getApplicationContext(), "Read button pressed", Toast.LENGTH_SHORT).show();

                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        break;
                   case R.id.btnWrite:
                        try {
                            Toast.makeText(getApplicationContext(), "Write button pressed", Toast.LENGTH_SHORT).show();

                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        break 
                case R.id.btnDel:
                        try {
                            Toast.makeText(getApplicationContext(), "Del button pressed", Toast.LENGTH_SHORT).show();

                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        break;
                }


            }


        };
    }
 

2015年10月13日 星期二

android 螢幕旋轉時不重新執行onCreate()

預設中, 螢幕旋轉時會重新執行 onCreate(), 要制止重新執行, 可以有以下兩個方法:

1. 禁止螢幕旋轉
        於 AndroidManifest.xml 檔裡, 在 <activity> </activity> 中, 添加一條屬性資訊:

        android:screenOrientation="portrait"       (強制縱向)
        android:screenOrientation="landscape"  (強制橫向)

        如下:

        <activity android:name=".SomeActivity"
          android:label="@string/app_name"
          android:screenOrientation="portrait"> 


2. 螢幕旋轉時不重新執行onCreate()
        於 AndroidManifest.xml 檔裡, 在 <activity> </activity> 中, 添加一條屬性資訊:
   
        android:configChanges=”orientation|keyboardHidden”
       
        (如API 等級等於或高於13要加 screenSize)
        android:configChanges="orientation|keyboardHidden|screenSize

        如下:

        <activity android:name=".SomeActivity"
          android:label="@string/app_name"
          android:configChanges="orientation|keyboardHidden|screenSize">


        於 activity 中, 加入

        @Override
         public void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
         if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        }
        else {
        }
}




android 禁止螢幕旋轉 (強制設定為縱向或橫向)

於 AndroidManifest.xml 檔裡, 在 <activity> </activity> 中, 添加一條屬性資訊:

android:screenOrientation="portrait"       (強制縱向)
android:screenOrientation="landscape"  (強制橫向)

如下:

<activity android:name=".SomeActivity"
    android:label="@string/app_name"
    android:screenOrientation="portrait">

android 寫入檔案 (簡短文字) FileInputStream, FileOutputStream

寫入簡短文字可使用寫入文字檔方法, 如複雜便要用SQLite

版面要加入一個editView, 一個textView 及 兩個 Button (editView1, textView2, btnWrite, btnRead)

輸入字於 editView1, 按下 btnWrite 便會寫入檔案 output 及顯示檔案路徑 (toast), 按下 btnRead 便會讀出檔案及顯示於 textView2





注意: 讀取中文字, 中文字每個要 2 個 Byte.

MainActivity.java

import android.content.Context;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class MainActivity extends ActionBarActivity {

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

        final EditText txtWrite = (EditText) findViewById(R.id.editText1);
        final TextView txtRead = (TextView) findViewById(R.id.textView2);

        Button btnTxtRead = (Button) findViewById(R.id.btnRead);
        Button btnTxtWrite = (Button) findViewById(R.id.btnWrite);


        btnTxtWrite.setOnClickListener(new View.OnClickListener() {
            @Override            public void onClick(View arg0) {

                try {
                    FileOutputStream fos = openFileOutput("output", Context.MODE_PRIVATE);
                    fos.write(txtWrite.getText().toString().getBytes());
                    fos.close();

                    File file = new File(getFilesDir() + "/" + fos);
                    Toast.makeText(getApplicationContext(), file.getAbsolutePath(), Toast.LENGTH_SHORT).show();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });

        btnTxtRead.setOnClickListener(new View.OnClickListener() {
            @Override            public void onClick(View arg0) {

                FileInputStream fos = null;
                BufferedInputStream buffered = null;

                try {
                    fos = openFileInput("output");
                    buffered = new BufferedInputStream(fos);
                    byte[] buffbyte = new byte[200];
                    txtRead.setText("");
                    do {
                        int flag = buffered.read(buffbyte);
                        if (flag == -1) {
                            break;
                        } else {
                            txtRead.append(new String(buffbyte), 0, flag);
                        }
                    }while (true);
                    buffered.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

2015年9月24日 星期四

android 日期比較

版面要加入兩個 textView 及 一個 Button (textView1, textView2, ChooseDateBtn)
此例以按選擇日子與現時日子作相減, 日子以微秒計算, 所以用 getTimeInMillis() 取得微秒後相減, 得出結果後再轉為秒, 分, 時, 日.

1000微秒 = 1秒

如要將時分秒設定為 0 用作計算, 可用 clear, 以下面為例, 現時日子可加入以下三句便可將時分秒設定為 0.

rightNow.clear(Calendar.HOUR);
rightNow.clear(Calendar.MINUTE);
rightNow.clear(Calendar.SECOND);


import android.app.DatePickerDialog;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.TextView;
import java.util.Calendar;
import java.util.GregorianCalendar;

public class MainActivity extends ActionBarActivity {

    Calendar rightNow = Calendar.getInstance();
    TextView DisplayDate1;
    TextView DisplayDate2;
    int cmonth, rmonth;


    @Override    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button changeDate = (Button) findViewById(R.id.ChooseDateBtn);
        DisplayDate1 = (TextView) findViewById(R.id.textView1);
        DisplayDate2 = (TextView) findViewById(R.id.textView2);

        changeDate.setOnClickListener(new View.OnClickListener() {

            @Override            public void onClick(View arg0) {

                new DatePickerDialog(MainActivity.this, d,
                        rightNow.get(Calendar.YEAR), rightNow.get(Calendar.MONTH),
                        rightNow.get(Calendar.DAY_OF_MONTH)).show();

            }
        });
    }

    DatePickerDialog.OnDateSetListener d = new DatePickerDialog.OnDateSetListener() {

        @Override        public void onDateSet(DatePicker view, int year, int monthOfYear,
                              int dayOfMonth) {


            cmonth = monthOfYear + 1;
            rmonth = rightNow.get(Calendar.MONTH) + 1;



            Calendar c = new GregorianCalendar(year, monthOfYear, dayOfMonth,
                    rightNow.get(Calendar.HOUR_OF_DAY), rightNow.get(Calendar.MINUTE),
                    rightNow.get(Calendar.SECOND));

            long diff = c.getTimeInMillis() - rightNow.getTimeInMillis();
            long diffSec = diff / 1000;
            long diffMins = diff / (60 * 1000);
            long diffHrs = diff / (60 * 60 * 1000);
            long diffDays = diff / (24 * 60 * 60 * 1000);


            DisplayDate1.setText("Choosen date is :" + dayOfMonth + "/" + cmonth + "/" + year +
                    "  Millisecond is :" + c.getTimeInMillis() + "\n" + "Current date is :" +
                    rightNow.get(Calendar.DAY_OF_MONTH) + "/" +
                    rmonth + "/" + rightNow.get(Calendar.YEAR) +
                    "  Millisecond is :" + rightNow.getTimeInMillis());
            DisplayDate2.setText("Date difference in seconds: " + diffSec +"\n"+
                    "Date difference in minutes: "+diffMins+"\n"+ "Date difference in hours: "+
                    diffHrs +"\n"+"Date difference in days: " + diffDays);



        }
    };
}
 
 

2015年8月26日 星期三

android DatePickerDialog 彈出日期選擇

注意:

版面要加入一個 textView 及 一個 Button (textView1, ChooseDateBtn)




import android.app.DatePickerDialog;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.TextView;

import java.util.Calendar;

public class MainActivity extends ActionBarActivity {

    Calendar c = Calendar.getInstance();
    TextView DisplayDate;
    int cday, cmonth, cyear;

    @Override     
       protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button changeDate = (Button) findViewById(R.id.ChooseDateBtn);
        DisplayDate = (TextView) findViewById(R.id.textView1);

        changeDate.setOnClickListener(new OnClickListener() {

            @Override             
             public void onClick(View arg0) {

                new DatePickerDialog(MainActivity.this, d,
                        c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH)).show();

            }
        });
    }

    DatePickerDialog.OnDateSetListener d = new DatePickerDialog.OnDateSetListener() {

        @Override 
            public void onDateSet(DatePicker view, int year, int monthOfYear,
                              int dayOfMonth) {

            cday = dayOfMonth;
            cmonth = monthOfYear + 1;
            cyear = year;

            DisplayDate.setText("Choosen date is :" + cday + "/" + cmonth + "/" + cyear);
        }
    };
}
 
 


 

2015年8月22日 星期六

android DatePicker 日期選擇

以下是簡單日期選擇例子

注意:

版面要加入兩個 textView 及 一個 DatePick (textView1, textView2, datePicker1)

因 Bug 關係, DatePick 放置後會顯示 Rendering Problems, 及不會顯示 DatePick, 但 run app 後會在 app 顯示

預設日期
datepick.init(2016,1,4,onDateChanged);

月份係由 0 至 11, 當顯示數字時要加 1, array 係由 0 開始, 所以不須要
Integer.toString(monthOfYear+1)

加入此兩個可改變日期選擇為轉動選擇
datepick.setCalendarViewShown(false);
datepick.setSpinnersShown(true);
 

 
 
import android.app.Activity;
import android.os.Bundle;
import android.widget.DatePicker;
import android.widget.TextView;


public class MainActivity extends Activity {
    @Override    protected void onCreate(Bundle savedInstanceState)  {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        DatePicker datepick = (DatePicker)
                findViewById(R.id.datePicker1);
        datepick.init(2016,1,4,onDateChanged);
        //    datepick.setCalendarViewShown(false); 
        //    datepick.setSpinnersShown(true);    }

    DatePicker.OnDateChangedListener onDateChanged=
            new DatePicker.OnDateChangedListener() {
                @Override                 
              public void onDateChanged(
                        DatePicker view,
                        int year,
                        int monthOfYear,
                        int dayOfMonth) {
                    final String[] MMM = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
                    TextView tv1 = (TextView)findViewById(R.id.textView1);
                    TextView tv2 = (TextView)findViewById(R.id.textView2);
                    
                    tv1.setText(Integer.toString(dayOfMonth) +
                            "/"+Integer.toString(monthOfYear+1)+
                            "/"+Integer.toString(year) );

                    tv2.setText(Integer.toString(dayOfMonth) +
                            "/"+(MMM[monthOfYear])+
                            "/"+Integer.toString(year) );
                                    }
            };
}
 
 

2015年7月8日 星期三

旅行注意事項, 護照有效期, 旅遊保險, 匯率, 電壓、插頭

近日準備外遊, 為日後方便, 記下以下重要事項, 方便日後使用.

  • 護照有效期
    • 最少有六個月
  • 護照複印本, 以便護照被竊或遺失時, 迅速申請補發.

  • 注意隨身物品
    • 尤其是長途機, 重要物品要隨身攜帶, 小偷會在乘客睡眠及離開坐位, 偷去放於坐位, 前坐椅下, 椅下或坐椅上的行李置物櫃.


2015年6月11日 星期四

設定 blog 所顯示圖片大小

如發現預設圖片顯示有點小, 可從設定中統一圖片大小, 到 "範本" > "自訂"


再到 "進階" > "新增 CSS"


填寫如下:

.post-body img {
width: 500px;
height: auto; }

.post table.tr-caption-container img {
width: 500px;
height: auto;
}

當中 .post-body img 為沒有加標題的圖片, .post table.tr-caption-container 為加有標題的圖片, width 為闊, height 為高.

2015年5月27日 星期三

記朝代

發現記中國朝代可以用朝代歌, 但以廣東話記, 以下就容易得多啦.

三皇五帝夏商周,
春秋戰國亂悠悠,
秦漢三國西東晉,
南朝北朝是對頭,
隋唐五代又十國,
宋元明清帝王休。

2015年5月26日 星期二

Scratch 創造故事、遊戲、和動畫

Scratch, 是由麻省理工學院 (MIT) 終生幼兒園團隊底下的一個計畫, 可簡單地於網上或下載軟件來創作故事、遊戲、和動畫, 而它是免費的.

主頁
https://scratch.mit.edu/

下載離線編輯器
https://scratch.mit.edu/scratch2download/

可是它不能直接製作 flash 或影片用作分享, 而只可透過 Scratch 網站分享, 但學習時間短, 由其是對年幼者更是一個助幫思考、系統化推理的一個軟件, 以下是我用了很短的時間所製作



2015年5月25日 星期一

提交網站, 増加人流

 
  • 將您的網誌新增到Blogger 首頁和 Next Blog的清單中及讓搜尋引擎來尋找您的網誌
    • 於 "設定" > "基本"
      •  

Blogger 備份及還原

設計完的網誌, 最好是備份, 之後定時備份亦都是很重要, 備份及還原如下

"範本" 備份及還原, "範本" > "備份/還原"




網誌備份及還原, "設定" > "其他" > 然後匯入 (還原), 或 匯出(備份)


Blogger 文章分類 - 分類目錄

製作分類目錄 (如圖)之前, 須明白 "網誌分頁" 的製作

首先要有已發佈的文章

編輯想連結的文章, 在右方填寫 "標籤" (可作分類用)

及填寫 "永久連結", 可選 "自動產生永久連結" 或 "自訂永久連結" (填寫心目中的網頁名), 之後要記下連結網址 (http://............), 然後 "更新" 或 "發佈"

 建立網頁, 填寫標題 (即分類名稱), 內文填寫目錄標題, 然後將標題選取, 按 "連結"



填入之前所記下連結網址 (http://............)

如剛建立的網頁, 是未有建立成分頁的, 便可如圖按 "版面配置" > "編輯"

 勾選剛建立的網頁後, 右邊便會多了一個清單可供排序, 然後儲存


按下分頁便可看到目錄


Blogger 文章分類 - 網誌分頁

本文介紹製作如下圖的網誌分頁

首先往 "版面配置", 按 "新增小工具" (如圖)

加入 "網頁" (網頁功能, 適用於網誌上規劃「關於我」、「與我聯絡」、「分類目錄」或「廣告」等獨立部分)


於 "網頁", 按 "新網頁" (每個網誌最多可含 20 個網頁)

 填寫標題及內容

發佈後, 會在 "網頁" 顯示

於 "版面配置" > "網頁", 按 "編輯"

於 "設定網頁清單" 便會發現你之前所發佈網頁的標題, 勾選後, 右邊便會多了一個清單可供排序, 完成後便可儲存

此時便可顯示分頁, 你可看到 "網頁" 是沒有發表日期, 有別於 "文章"

2015年5月24日 星期日

建立 Blogger 帳戶及發表文章

首先要有一個 gmail 帳戶
於 Google 首頁, 按 Blogger

按 "開始使用 Blogger", 然後按 "新增網誌 (每個帳戶最多可擁有 100 個網誌)

填寫標題, 地址 (網址) 及選擇範本.  當中 "標題"及"範本" 可以往後修改, "標題" 要簡單, 簡短及準確形容網誌, 從而提高搜尋器排名, 詳情可於網上搜尋 "SEO" (search engine optimization) 相關資料, 如 https://support.google.com/webmasters/answer/35291?hl=tw

之後, 便跳到總覽, 你會看到 "標題", 在這你可按 "新文章" 發佈文章

填寫文章標題及內容, 完成後便可按 "發佈"

之後可提交評論

你會發現 "發表文章" 有你的文章

有了首篇文章便可方便修改網誌設計, 在左邊按 "範本", 然後按 "自訂"

按自已喜好選擇 "範本, 背景, 調整寬度, 版面配罝及進階"

 當中 "進階" 可設定字形及顏色

另外, 於 "總覽" > "設定" >"基本", 可填寫 "詳細介紹" 及修改 "標題" 等資料

最後於 "設定" > "語言和格式" 修改時區等資料



2015年5月23日 星期六