●補充說明和程式說明--存取網路資源
=>先開啟網路權限
<uses-permission android:name="android.permission.INTERNET" />
 
(一)程式流程:當button按下時,抓取google資料,並用log讀出來
public void click1(View view) {
new Thread(){
@Override
public void run()
{
try {
URL url = new URL("http://google.com.tw");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.connect();
InputStream is = conn.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
StringBuilder sb = new StringBuilder();
String str;
while ((str=br.readLine()) != null)
{
sb.append(str);
}
String result = sb.toString();
Log.d("mynet","read:"+result);
br.close();
isr.close();
is.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
**說明:
1.android規定,抓取網路資料要在不同的執行緒,所以要用Thread&override run method
2.起一個URL物件(網址)=>這邊要用try...catch
 
3.建立連線:HttpURLConnection=>A URLConnection with support for HTTP-specific features.
Obtain a new HttpURLConnection by calling URL.openConnection() and casting the result to HttpURLConnection.(用openConnection取得的是OpenConnection物件,要轉成HttpURLConnection物件)
4.openConnection():Returns a URLConnection instance that represents a connection to the remote object referred to by the URL.
5.setRequestMethod(String method):Set the method for the URL request,ex:GET,POST,設定資料傳送方法,一般上網抓資料或看網頁都是用GET,填寫表單傳送是用POST
6.連線 :connect():Opens a communications link to the resource referenced by this URL, if such a connection has not already been established.
7.URLConnection.getInputStream:InputStream getInputStream=>Returns an input stream that reads from this open connection.
=>取到連線物件後,只提供轉成輸入串流的方法
 
8.透過InputStream(位元組串流)產生InputStreamReader物件,An InputStreamReader is a bridge from byte streams to character streams: It reads bytes and decodes them into characters using a specified charset
9.BufferedReader的建構式是BufferedReader(Reader in),而InputStreamReade和FileReader都繼承Reader,所以都可以用來new BufferedReader=>把InputStreamReader轉為BufferedReader,即把網路資料轉成String,這樣就可以使用readLine()
10.最後就是透過while把讀取到的每一行資料放到StringBuilder中,再轉成string,用log顯示,最後就可以看到google網頁的資料如下:
 
(二)抓取台銀日幣賣出的即期匯率
=>利用String下的indexOf()和substring()來做

Snap1.png

=>indexOf
1.public int indexOf(int ch)
Returns the index within this string of the first occurrence of the specified character. If a character with value ch occurs in the character sequence represented by this String object, then the index (in Unicode code units) of the first such occurrence is returned.
2.public int indexOf(int ch,int fromIndex)
Returns the index within this string of the first occurrence of the specified character, starting the search at the specified index.
 
=>substring
public String substring(int beginIndex,int endIndex)=>(起始點,終止點的下一個)
Returns a new string that is a substring of this string. The substring begins at the specified beginIndex and extends to the character at index endIndex - 1. Thus the length of the substring is endIndex-beginIndex.
public void click1(View view) {
new Thread(){
@Override
public void run()
{
try {
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.connect();
InputStream is = conn.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
StringBuilder sb = new StringBuilder();
String str;
while ((str=br.readLine()) != null)
{
sb.append(str);
}
String result = sb.toString();
int loc1 = result.indexOf("0.2805");
Log.d("LOC1", "loc1:" + loc1);
int loc2 = result.indexOf("日圓 (JPY)");
Log.d("LOC2", "loc2:" + loc2);
int loc3 = result.indexOf("本行現金賣出", loc2);
Log.d("LOC3", "loc3:" + loc3);
 
int locJPY = loc3 + 56;
String jpy = result.substring(locJPY, locJPY + 6);
Log.d("LOC", "JPY:" + jpy);
br.close();
isr.close();
is.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
**說明:
1.前面和抓googl一樣,只是網址換成台銀匯率網頁
2.不能直接用indexof抓匯率數字的位置,因為當網頁調整增加一行或甚至只是整數去0,都會影響位置的改變,所以要用別的方法
3.先用while迴圈把所有文字抓近來,再來定位JPY,做法是先找日圓=>再找本行現金賣出=>再推算位置
4.測試(用LOG)0.2805這個匯率的位置(loc1)為27339,如果indexof出來結果為-1,就代表沒讀到資料,可能是因為匯率改變要重查
5.再測試日圓 (JPY)的位置(loc2)為26985,測試從loc2的位置開始找"本行現金賣出"的位置(loc3)為27386(因為每個匯率都有"本行現金賣出",要找日圓後面的)
6.如此就可以計算書從"本行現金賣出"到"日圓即期匯率"的位置距離為loc1-loc3=56(loc3+56),這個是固定的不會被改變
7.因為匯率0.2805總共6個字元,所以當使用substring取字時,就要從locJPY開始取,到(locJPY+6)-1這六個字元
=>上述做法就不用擔心位置會跑掉
 
**結果:

Snap3.png

 

●程式參考(GitHub):利用HttpURLConnection、InputStream、BufferReader存取網路資源

 

文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

●補充說明和程式說明
(一)讀寫外部空間資料--在規劃好的資料夾中
1.寫入
=>用android device moniter看檔案位置會在如下圖的地方,這裡不需要使用權限,但當別的程式有完整讀取sd卡的權限時,就可以讀取到這邊的檔案,隱私性安全較差
讀寫外部資料與設定讀寫外部資料權限
public void outWrite(View view) {
    String path = getExternalFilesDir("file").getAbsolutePath();
    String fname=path + File.separator "test1.txt";
    try {
        FileWriter fw = new FileWriter(fname);
        BufferedWriter bw = new BufferedWriter(fw);
        bw.write("happy to find you");
        bw.newLine();
        bw.write("it is sad");
        bw.close();
        fw.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
**說明:
1. 取得外部存檔的資料夾位置:getExternalFilesDir(檔案類型):參數的檔案類型可以自訂
=>File getExternalFilesDir (String type)
=>Returns absolute paths to application-specific directories on all shared/external storage devices where the application can place persistent files it owns.
2.後面做法都跟之前(BufferReader and BufferWriter)一樣
 
2.讀取
public void outRead(View view) {
String path = getExternalFilesDir("file").getAbsolutePath();
String fname=path + File.separator + "test1.txt";
try {
FileReader fr = new FileReader(fname);
BufferedReader br = new BufferedReader(fr);
String str;
while ((str=br.readLine()) != null)
{
Log.d("FNAME", "Read:" + str);
}
br.close();
fr.close();
 
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
 
(二)讀寫外部空間資料(自由的尋覽sd卡)
=>但現在android不建議如此做,基於隱私的考量以及避免在外部空間製造很多垃圾
=>先在AndroidManifest.xml設定權限(只要想要存取規劃的資料夾外的資料都要設定權限)
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 
1.android6(api<23)以前的寫入
File f = Environment.getExternalStorageDirectory();
Log.d("FNAME","read"+f.getAbsolutePath());
File f2 = new File(f.getAbsolutePath() 
              + File.separator "mydata");
f2.mkdir();
File txtFile = new File(f2.getAbsolutePath() 
                 + File.separator "data5.txt");
try {
    FileWriter fw = new FileWriter(txtFile);
    BufferedWriter bw = new BufferedWriter(fw);
    bw.write("this is test");
    bw.newLine();
    bw.write("This is test2");
    bw.close();
    fw.close();
catch (IOException e) {
    e.printStackTrace();
}
**說明
1.Environment.getExternalStorageDirectory():取得sd卡路徑
=>File getExternalStorageDirectory ()
=>Return the primary shared/external storage directory.
=>前面兩筆是使用getExternalFilesDir("file").getAbsolutePath();取得的路徑=>是android指定的不需要授權的資料夾
=>後面一筆是使用Environment.getExternalStorageDirectory().getAbsolutePath();取得的路徑
 讀寫外部資料與設定讀寫外部資料權限
 
2.mkdir()=>Creates the directory named by this abstract pathname.(建立資料夾mydata)
3.建立資料夾內容
4.android6以前的權限設定如上即可,使用早期版本的模擬器測試,只要有上面權限設定,寫入後就會在sdcard資料夾中產生我們要的資料夾
讀寫外部資料與設定讀寫外部資料權限
 
 
2.android6(api<23)以前的讀取
File f = Environment.getExternalStorageDirectory();
Log.d("FNAME", f.getAbsolutePath());
File f2 = new File(f.getAbsolutePath() 
           + File.separator "mydata");
File txtFile = new File(f2.getAbsolutePath() 
          + File.separator "data5.txt");
try {
    FileReader fr = new FileReader(txtFile);
    BufferedReader br = new BufferedReader(fr);
    String str;
    while ((str=br.readLine()) != null)
    {
        Log.d("FNAME""Read:" + str);
    }
    br.close();
    fr.close();
 
catch (FileNotFoundException e) {
    e.printStackTrace();
catch (IOException e) {
    e.printStackTrace();
}
**說明:
1.當使用android6以後的模擬器,只在AndroidManifest.xml設定權限會不夠,用android6以後的模擬器測試這段讀取程式,就會出現下列exception:FileNotFoundException,因為在android6以後的模擬器寫入不成功,所以也讀不到檔案
讀寫外部資料與設定讀寫外部資料權限
2.做法有兩種一種是讓使用者自己設定,在手機=>設定=>app設定=>app permisssions=>storage permissions=>我們app開啟讀寫外部資料與設定讀寫外部資料權限
但這是不好的做法,應該是把設定寫在程式裡
 
3.android6以後的寫入與讀取
=>程式的流程應該是在每次要使用時,都會檢查程式是否有被授予權限,如果沒有就要跳出視窗詢問使用者是否授予權限,且這個跳出的視窗是android訂好的規格,我們不能改變或自訂
=>使用者決定允許或拒絕後,callback結果
=>參考檔案可以發現WRITE和READ是同一類權限,有開WRITE則READ就會有開
=>實際上讀取應該也要加權限,否則若是還沒有授權寫入或是被取消授權後直接按讀取就會有問題
 public void nolimitwrite(View view) {
    int permission = ActivityCompat.checkSelfPermission(this,
            WRITE_EXTERNAL_STORAGE);
    if (permission != PackageManager.PERMISSION_GRANTED) {
        //未取得權限,向使用者要求允許權
       //因為要辨別使用者允許的是寫入還是讀取所以這邊的string只放write
        ActivityCompat.requestPermissions(this, new String[]{WRITE_EXTERNAL_STORAGE},
                REQUEST_EXTERNAL_STORAGE); 
    }else{
        //已有權限,可進行檔案存取
        sdwrite();

    }
}

@Override
public void onRequestPermissionsResult
    (int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if(requestCode==REQUEST_EXTERNAL_STORAGE){
        if (grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            //取得權限,進行檔案存取
            String str=permissions[0];
             //這邊用if判斷時要用equals(),不能用==
            if(str.equals("android.permission.WRITE_EXTERNAL_STORAGE") ){  
                sdwrite();
            }else {
                sdread();
            }

        } else {
            //使用者拒絕權限,停用檔案存取功能
        }
    }
}

private void sdwrite(){
    File f = Environment.getExternalStorageDirectory();
    Log.d("FNAME","read"+f.getAbsolutePath());
    File f2 = new File(f.getAbsolutePath() + File.separator + "mydata");
    f2.mkdir();
    File txtFile = new File(f2.getAbsolutePath() + File.separator + "data5.txt");
    try {
        FileWriter fw = new FileWriter(txtFile);
        BufferedWriter bw = new BufferedWriter(fw);
        bw.write("this is test");
        bw.newLine();
        bw.write("This is test2");
        bw.close();
        fw.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public void nolimitread(View view) {
    int permission = ActivityCompat.checkSelfPermission(this,
            READ_EXTERNAL_STORAGE);
    if (permission != PackageManager.PERMISSION_GRANTED) {
        //未取得權限,向使用者要求允許權
        ActivityCompat.requestPermissions(this, new String[]{READ_EXTERNAL_STORAGE},
                REQUEST_EXTERNAL_STORAGE);
    }else{
        //已有權限,可進行檔案存取
        sdread();
    }
}

private void sdread(){
    File f = Environment.getExternalStorageDirectory();
    Log.d("FNAME", f.getAbsolutePath());
    File f2 = new File(f.getAbsolutePath() + File.separator + "mydata");
    File txtFile = new File(f2.getAbsolutePath() + File.separator + "data5.txt");
    try {
        FileReader fr = new FileReader(txtFile);
        BufferedReader br = new BufferedReader(fr);
        String str;
        while ((str=br.readLine()) != null)
        {
            Log.d("FNAME", "Read:" + str);
        }
        br.close();
        fr.close();

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
**說明
1.先檢查是否已經取得使用者的授權,檢查權限語法:int checkSelfPermission(Context context, String permission)
=>Determine whether you have been granted a particular permission.
=>String: The name of the permission being checked.
=>return int:PERMISSION_GRANTED if you have the permission, or PERMISSION_DENIED if not.
=>PackageManager.PERMISSION_GRANTED
int PERMISSION_GRANTED
Permission check result: this is returned by checkPermission(String, String) if the permission has been granted to the given package.
Constant Value: 0 (0x00000000)
=>PackageManager.PERMISSION_DENIED
int PERMISSION_DENIED
Permission check result: this is returned by checkPermission(String, String) if the permission has not been granted to the given package.
Constant Value: -1 (0xffffffff)
 
2.如果沒有取得權限,跳出允許授權對話框
=>requestPermissions:void requestPermissions (Activity activity, String[] permissions, int requestCode)
=>第一個參數是context,第二個參數是要求允許的權限,第三個參數是本次請求的辨識編碼(因為callback時要辨認是哪裡callback的)
=>因為後面要辨別這邊帶入的權限是write還是read,所以兩個click放的參數不同
 
3.把寫入和讀取的程式寫成兩個method,當授權ok或是已經有授權的時候直接呼叫這兩個方法
 
4.當跳出授權對話框後,對使用者的確認與取消授權做處理,用onRequestPermissionsResult
=>void onRequestPermissionsResult (int requestCode, String[] permissions, int[] grantResults)
Callback for the result from requesting permissions. 
=>requestCodeint: The request code passed in requestPermissions(android.app.Activity, String[], int)
=>permissionsString: The requested permissions. Never null.
=>grantResultsint: The grant results for the corresponding permissions which is either PERMISSION_GRANTED or PERMISSION_DENIED. Never null.
 
5.先確認requestCode正確,再確認授權結果必須為GRANTED,再判斷傳回的permission為哪一個,來決定下一步是要寫入還是讀取,這邊的permissions陣列判斷不可以用==而是要用equals,因為在前面有new String,是不同物件不能用==,==兩邊必須是相同的參考物件,相關資訊可以參考說明:https://ppt.cc/fam5fx
 
6.如果想要查詢pemissions字串中的內容,可以用log看
Log.d("permission","read:"+permissions[0]);
讀寫外部資料與設定讀寫外部資料權限
 

 

●程式參考(GitHub):讀寫外部資料與設定讀寫外部資料權限

 

文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

●補充說明和程式說明

(一) 檔案的讀取使用FileReader比較不好用,因為讀出來會是字元陣列,一般會使用BufferedReader和BufferedWriter=>可以直接處理字串

(二)BufferedReader和BufferedWriter
public void write(View view) {
    String path = getFilesDir().getAbsolutePath();
    File fname = new File(path + File.separator "test.txt");
    try {
        FileWriter fw = new FileWriter(fname);
        BufferedWriter bw = new BufferedWriter(fw);
        bw.write("Hello World");
        bw.newLine();
        bw.write("This is android");
        bw.close();
        fw.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
**說明:
1.BufferedWriter要透過FileWriter來建立,所以要先建立FileWriter物件
2..newLine()是換行
3.關閉兩個檔案
 
 
public void read(View view) {
String path = getFilesDir().getAbsolutePath();
String fname=path + File.separator + "test1.txt";
try {
FileReader fr = new FileReader(fname);
BufferedReader br = new BufferedReader(fr);
String str;
while ((str=br.readLine()) != null)
{
Log.d("FNAME", "Read:" + str);
}
br.close();
fr.close();
 
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
**說明:
1.BufferedReader要透過FileReader來建立,所以要先建立FileReader物件
2..readLine()只讀取一行,把讀出來的內容存入字串str,如果讀不出來會是null,因為資料不是只有一行,而且有空行,所以可以用while來判斷,只要讀到的不是null就把資料寫入log中,就可以抓取所有資料
3.最後要記得關閉兩個檔案
 
(三)擺放資料的方法,要如何把整數陣列寫入資料並讀取
1.寫入
public void write2(View view) {
int[] data = {4,1,7,3,4,8,2,1};
StringBuilder sb = new StringBuilder();
for (int i : data)
{
sb.append(i + ",");
}
String path = getFilesDir().getAbsolutePath();
File fname = new File(path + File.separator + "test2.txt");
try {
FileWriter fw = new FileWriter(fname);
BufferedWriter bw = new BufferedWriter(fw);
bw.write(sb.toString());
bw.close();
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
 
 
}
**說明:
1.要利用StringBuilder,所以先建立StringBuilder物件
2.透過foreach迴圈,把i+","放入StringBuilder,此時sb已經成為整數+,的組合了
3.寫入時再把sb用toString();轉成字串寫入即可
 
2.讀取
public void read2(View view) {
    String path = getFilesDir().getAbsolutePath();
    File fname = new File(path + File.separator "test2.txt");
    ArrayList<Integer> mylist = new ArrayList();
    try {
        FileReader fr = new FileReader(fname);
        BufferedReader br = new BufferedReader(fr);
        String str;
        str = br.readLine();
        String strdata[] = str.split(",");
        for (String s : strdata)
        {
            if (s.length() > 0)
            {
                mylist.add(Integer.valueOf(s));
            }
        }
        br.close();
        fr.close();
 
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    for (int i : mylist)
    {
        Log.d("FNAME""data:" + i);
    }
}
**說明:
1.讀取時只要讀一次,要先建立一個arraylist來放資料陣列
2.把讀取進來的資料存入str中,因為前面寫入時每筆資料後面都有逗號,再用split()方法以逗號分割每筆資料放入陣列中
=>public String[] split(String regex)
=>Splits this string around matches of the given regular expression
=>Returns:the array of strings computed by splitting this string around matches of the given regular expression
3.因為最後一個逗號後面沒有資料,所以如果用,做區隔,最後會多一個空白,所以當跑foreach迴圈時,要判斷s.length>0
=>字串的長度=>public int length():Returns the length of this string. The length is equal to the number of Unicode code units in the string.
4.用foreach迴圈把每一個值轉成整數放入arraylist中
5.valueOf:Integer valueOf (String s)=>Returns an Integer object holding the value of the specified String.
=>把字串轉成Integer物件 
6.再用foreach迴圈配合log,看每一筆arraylist的資料內容
 
(四)如果資料存放在物件中(如自己做了一個類別存放資料),這種讀取方式後面會講
 
 
文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

想在痞客邦部落格的側欄產生自訂的圖片或文字連結其實不難,

因為痞客邦側邊欄位是支援HTML語法的

側邊欄位產生自訂圖片連結

以上圖為例,我放了兩個自訂圖片連結,作法如下:

(一)到痞客邦部落格後台,開啟側欄管理功能

側邊欄位產生自訂圖片連結
 

(二)在最右邊版位站存區,點新增版位

側邊欄位產生自訂圖片連結

就會跳出新增自訂欄位對話框

側邊欄位產生自訂圖片連結

 

(三)在標題輸入想要顯示的標題,內容則要將HTML語法貼入,

關於語法的說明,請參照最下方

Snap4.png

 

(四)完成以後,將自訂的側邊欄位拖曳到想要放置的位置就完成囉!

側邊欄位產生自訂圖片連結

 


HTML語法教學

1.插入圖片與連結

範例:

<a target="_blank" href="https://play.google.com/store/apps/details?id=com.maggie.flashcard_sql"><img border="0" width="150" height="150" src="https://pic.pimg.tw/muchone/1557887451-1848048953.jpg"></a>

說明:

如果覺得太複雜,直接用下面的方式就可以

<a target="_blank" href="要開啟的網站連結位址"><img src="圖片來源位址"></a>

下面是可自行選擇要不要加入的html語法:

target="_blank":這是要把連結另開新視窗的意思

border="0" :這是設定圖片不要有框

width="150" :設定圖片寬度為150

height="150":設定圖片高度為150

 

2.加入文字的一些小變化:

範例:

<div><FONT SIZE="3" COLOR="#007FFF">OCR文字辨識掃描與翻譯</FONT></div>

如果覺得太複雜,直接用下面的方式就可以

<div>"文字內容"</div>

=>使用<div></div>包住文字,可以讓文字換行

下面是可自行選擇要不要加入的html語法

FONT SIZE="3":設定文字大小

COLOCR="#007FFF":設定文字顏色

 

*如果想要做更多變化可以參考下列HTML語法網址

http://www.w3school.com.cn/html/index.asp

https://www.w3schools.com/html/

*顏色的16進位碼不知道,可以參考下面網站有一些列表

https://www.ebaomonthly.com/window/photo/lesson/colorList.htm

文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

6/1

Today's Taekwondo class starting time is changed to the 7:00 pm.

We can finally do everything we want to do on Saturday and don't have to be in a hurry to the class.

We made origame, played catch, read books and watch the Captain Marvel. 

 

6/2

My husband's going to Germany on business for a week.

On the way driving to the bus stop, my son kept talking 'I don't want to let you go, Dad'. 

And now, I start to miss my husband, too.

 

6/3

Again, I didn't sleep well last night and I thought that might becasue I was not used to my husband not by my side.

I've thought my boss and my supervisor don't communicate well with each other.

Therefore, I usually don't know whose decisions shold I obey.

 

6/4

We had a new coworker join our team yesterday.

I feel a little bit happy and worried.

I worry that I can't get along with him.

 

6/5

I stayed up late reading a novel last night.

I didn't sleep util 2:40 am and I could barely keep my eyes open this morning.

My son cried because he didn't get ready as fast as usual this morning.

 

6/6

I received the tv box bought from pchome this morning and finally could test my app.

And after that, my supervisor gave me a source code of face recognition and told me I was charge of maintaining and developing it. 

I think I'm going to be very busy soon.

 

6/7

I found my son's watch was gone again this morning and my son didn't remember where his watch was.

I felt very angry and helpless at that moment.

I want to know is there anything could help him understand he should  cherish his possessions.

 

6/8 

My husband came back from Germany yesterday afternoon.

His luggage was almost overweight because I gave a long shopping list of what I wanted him to buy for me.

Only two items of my shopping list he couldn't buy and I really appreciated it.

 

6/9

The Dragon Boat Festival long weekend is over, but I still can't get back into the work mode.

Sometimes I really want to take a day off to sleep all day long at home.

However, my job tenure is less than one year and I don't have enought annual leave.

 

6/10

My ex-coworker had a fight  with our HR specialist last Thursday

After a long weekend, our HR specialist is still not over it.

She was as mad as a wet hen because she thought we all spoke ill of her behind her back.

 

 

 

 


 

*be in a hurry to:趕著做..

* make origame:摺紙

*play catch:玩丟接球

*Captain Marvel:驚奇隊長

*go to somewhere on business:去somewhere出差

*it might because:可能因為

*obey:遵守

*get along with sb:和sb相處得很好

*stay up late:熬夜

*helpless:無助,無奈

*my luggage is overweight:我的行李超重

*shopping list:購物清單

*Dragon Boat Festival:端午節

*long weekend:包含周末的連假

*get back into the work mode:收心

*take a day off:請假

*job tenure:工作年資

*annual leave:特休

*be still not over it:耿耿於懷

*be as mad as a wet hen:氣得哇哇大叫

*speak ill of someone behind someone's head:在背後說someone的壞話

文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

●補充說明和程式說明---檔案存取

(一)在做檔案存取時
1.在本機下的data/data/packagename這個資料夾,會在install的時候產生,移除的時候刪除,這個資料夾下的所有內容可以不受限制任意存取
2.android 6以前,sdcard/data/packagename下的資料夾,跟上面一樣, 會在install的時候產生,移除的時候刪除,這個資料夾下的所有內容可以不受限制任意存取
3. android 6以後,sdcard下的資料夾只要app被授權,就可以任意存取sd卡中的內容
 
(二)android寫入
public void clickwrite(View view) {
 
String fname=getFilesDir().getAbsolutePath();
try {
FileWriter fw=new FileWriter(fname+ File.separator+"data.txt");
fw.write("android is fun");
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
**說明:
1. getFilesDir()和getCacheDir(),兩個不同資料夾(File和Cache),file放重要的資料,cache放暫時使用的資料,在手機設定裡面的app中,有兩個按鈕,clear data是清除file中的內容,clear cache是清除cache中的內容
2.用 getFilesDir().getAbsolutePath(); 取得內部儲存空間file資料夾名稱和絕對路徑位置
3.建立一個寫入資料的物件,寫入的資料檔案路徑和名稱為 fname+ File.separator+"data.txt"=> File.separator是分隔線, data.txt  是檔名
4.fw.write(寫入的內容)
 
設定/app/專案名稱
fileWriter and fileReader
完成後可以看到檔案成功寫入,可以匯出桌面看內容
fileWriter and fileReader
 
(三)android讀取
public void clickread(View view) throws FileNotFoundException {
    char [] ch=new char[100];
    String fname=getFilesDir().getAbsolutePath();
    try {
        FileReader fr=new FileReader(fname+File.separator+"data.txt");
        fr.read(ch);
        String str=new String(ch);
        Toast.makeText(this,str,Toast.LENGTH_SHORT).show();
    }catch (FileNotFoundException e){
        e.printStackTrace();
    }
    catch (IOException e) {
        e.printStackTrace();
    }
**說明:
1.因為 FileReader讀進來的是一個char array,所以要先建一個char array來儲存之
2.一樣要先抓到要讀取的檔案
3.read()=>int read (byte[] b) :Reads some number of bytes from the input stream and stores them into the buffer array b.
4. String str=new String(ch);=>把ch轉成String
=>在String類別中有一個建構式:String(char[] value)
=>Allocates a new String so that it represents the sequence of characters currently contained in the character array argument.
 

 

 

●程式參考(GitHub):使用FileWriter和FileReader做檔案(File)的讀取與寫入

muchone 發表在 痞客邦 留言(0) 人氣()

●畫面預覽
 
●補充說明--SettingsActivity
1.新增setting activity
SettingsActivity與PreferenceActivity
 
2.會建立兩個activity和4個xml layout,並自設很多範例程式,可以修改
ex:private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener ...
這段程式就是在監控summary有沒有改變 
SettingsActivity與PreferenceActivity
 
=>紅框部分就是summary
SettingsActivity與PreferenceActivity
 
3.到pref_general.xml新增一個EditTextPreference,並且在模擬器修改它的值
SettingsActivity與PreferenceActivity
 
4.開啟android device monitor,看設定資料寫入設定檔的名稱為packagename+_preferences.xml
(注意此處packagename已修改為SettingsActivityAndPreferenceActivity)
 
5.要把我們修改後的設定值抓回來,先確認要抓的那個設定欄位的key值
 
 
public void clickRead(View view) {
    SharedPreferences sp=getSharedPreferences(getPackageName()+"_preferences",MODE_PRIVATE);
    String str=sp.getString("edit_text_preference_1","");
    Toast.makeText(this,str,Toast.LENGTH_SHORT).show();
}
**說明:
1.取得的 SharedPreferences檔名為packagename+ _preferences
2.取得我們要的欄位的值,getString()第一個參數就要放那個欄位的key
3.用Toast秀出這個內容

 

●程式參考(GitHub):檔案存取(四)SettingsActivity與PreferenceActivity

 

文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

●畫面預覽

HashMap與SimpleAadapter

●補充說明

(一)Collection<E>=>一群東西的集合
 
(二)Set<E> interface=>有排序(ex:TreeSet Class)、沒有排序(ex:HashSet Class)
=>不可重複,用來計算不一樣資料的總筆數
HashSet<String> myset = new HashSet<>();
        myset.add("aa");
        myset.add("aa");
        myset.add("bb");
        myset.add("aa");
        myset.add("aa");
        for (String s : myset) {
            System.out.println(s);
        }
=>結果會只有aa和bb
 
(三)Map就是key對value的關係
=>Interface Map<k,v>,常用HashMap Class
=>Map就像一張表格
 
Key
Value
username
John
tel
123
HashMap<String, String> mymap = new HashMap();
mymap.put("username", "john");
mymap.put("tel", "0911111111");
System.out.println(mymap.get("tel"));
**說明:
1.結果是0911111111
2.new HashMap();在java7以後可以省略<>
3.mymap.put("username", "john");=>把key和value放入表格中
4.android中很多資料存取是用map關係
 
*Map的另一種寫法
 
Key
Value
TPE
TC
KH
02
04
07
=>把上面的做法改為下面三個,並且放入arraylist中
 
Key
Value
city
code
台北
02
 
Key
Value
city
code
台中
04
 
Key
Value
city
code
高雄
07
 
        ArrayList<Map<String, String>> mylist = new ArrayList();
        HashMap<String, String> m1 = new HashMap();
        m1.put("city", "台北");
        m1.put("code", "02");
        mylist.add(m1);
        
        HashMap<String, String> m2 = new HashMap();
        m2.put("city", "台中");
        m2.put("code", "04");
        mylist.add(m2);
        
        HashMap<String, String> m3 = new HashMap();
        m3.put("city", "高雄");
        m3.put("code", "07");
        mylist.add(m3);
        
        for(Map<String,String> m:mylist){
            System.out.println(m.get("city")+","+m.get("code"));
        }
**說明:
1.outputs為
HashMap與SimpleAadapter
2.這邊的get method為HashMap CLass下的get method而非arraylist下的get method
 
3.get():public V get(Object key):Returns the value to which the specified key is mapped, or null if this map contains no mapping for the key.
 
4.android可用這種結構=>simple adapter

 


●程式與說明--java code

public class MainActivity extends AppCompatActivity {
private ListView lv;
private SimpleAdapter sa;
ArrayList<Map<String,String>> mylist= new ArrayList<>();
 
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv=(ListView)findViewById(R.id.lv);
HashMap<String, String> m1 = new HashMap<>();
m1.put("city", "台北");
m1.put("code", "02");
mylist.add(m1);
HashMap<String, String> m2 = new HashMap<>();
m2.put("city", "台中");
m2.put("code", "04");
mylist.add(m2);
HashMap<String, String> m3 = new HashMap<>();
m3.put("city", "高雄");
m3.put("code", "07");
mylist.add(m3);
 
sa=new SimpleAdapter(MainActivity.this,
mylist,
android.R.layout.simple_list_item_2,
new String[]{"city","code"},
new int[]{android.R.id.text1,android.R.id.text2});
 
lv.setAdapter(sa);
 
 
}
}
**說明:
1.建立arraylist
2.把資料放進arraylist中
3.建立 SimpleAdapter()物件,放五個參數=>context(MainActivity.this),Map資料,listview的版型,Map的key值陣列,key要對應到的資源(這邊因為是使用內建的layout,所以也有內建的資源id)
4.使用simpleadapter的話,版型和資源id都可使用自訂的
 
*如果要加圖片並且用自己的layout
 
public class MainActivity extends AppCompatActivity {
private ListView lv;
private SimpleAdapter sa;
ArrayList<Map<String,Object>> mylist= new ArrayList<>();
 
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv=(ListView)findViewById(R.id.lv);
HashMap<String,Object> m1 = new HashMap<>();
m1.put("city", "台北");
m1.put("code", "02");
m1.put("img",R.drawable.taipei);
mylist.add(m1);
HashMap<String, Object> m2 = new HashMap<>();
m2.put("city", "台中");
m2.put("code", "04");
m2.put("img",R.drawable.taichun);
mylist.add(m2);
HashMap<String, Object> m3 = new HashMap<>();
m3.put("city", "高雄");
m3.put("code", "07");
m3.put("img",R.drawable.kaishon);
mylist.add(m3);
 
sa=new SimpleAdapter(MainActivity.this,
mylist,
R.layout.myitem, //如果是用自己的版型,R前面不用放android.
new String[]{"city","code","img"},
new int[]{R.id.t1,R.id.t2,R.id.iv});
 
lv.setAdapter(sa);
 
 
}
}
**說明:
1.先把MAP改為 Map<String,Object>,下面相對應的HashMap也要跟著改
2.把圖片放到m1/m2/m3中,key為img,value為id
3.最後的字串陣列要加入img key,資源陣列要放入img的id

 

●程式參考(GitHub):檔案存取(三)HashMap與SimpleAadapter

 

文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

5/22

I heard a piece of very good news this morning and I was so happy that I almost cried.

My son won the second prize of the English story-telling contest held by his school.

Today was really my son's day and I believed he would be happy all day long.

 

5/23

Today is a busy day.

I thought my boss would be in office this morning and be absent in the afternoon.

However, he was out of office this morning and came in office afternoon and that ruined my plan.

 

5/24

Every time my period is coming, I feel tired and have a headache.

More than that, I have cramps on my period almost every time.

At that moment, I always wish that I was a man.

 

5/25

My son lent his friend his Garmin watch on Friday and I didn't knew that until Saturday morning.

I was very angry at my son for his not cherishing his possessions.

Both my husband and I thought his watch might not be returned anyway.

 

5/26

My son always get up early on the weekend.

I feel very confused that he always looks tired on weekdays.

Why doesn't he sleep a bit longer on the weekend?

 

5/27

We went to see the Pokémon Detective Pikachu yesterday and that movie was really funny.

However, my son was still terrified of the bad guy in the movie.

He had a nightmare last night and I didn't want to take him to see movies in the movie theater  anymore.

5/28

As I expected, my son's watch wasn't returned by his classmate yesterday.

It has been cold one day and hot the next recently.

That makes me can't have good night's sleep.

 

5/29

My son's watch was returned by the woman who takes care of children on the school bus.

At that moment, I realized my son lied to me again.

He forgot ask his classmate to return his watch and he was afraid I gave him a piece of my mind.

 

5/30

It became so cold last night that I didn't sleep well.

I have had some difficulty developing app recently.

However, my boss wants me to demo the app everyday and that is a bit annoying.

 

5/31

Finally, I solved the problem of playing the rtsp on my Android application.

Hope today is a happy Friday and that means my boss will be out of office all day long.

I've been too busy to keep writing my blog posts recently.

 

 

 

 

 

 

 


 

*win the second prize:贏得第二名

*on one's period:生理期

*have cramps:生理痛

*be angry at sb. for sth.:為了某事對某人生氣

*cherish one's possessions:珍惜某人的財物

*on the weekend:在周末

*on weekdays:在平日

*be terrified of:很害怕

*It's cold one day and hot the next:天氣忽冷忽熱

*have good night's sleep:晚上睡得好

*give sb a piece of your mind:教訓sb.

*have some difficulty (in) Ving:在做...遇到一些困難

*write a blog post:寫部落格

文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

●畫面預覽

●補充說明

(一)Adapter=> 把資料和listview結合
An Adapter object acts as a bridge between an AdapterView and the underlying data for that view. The Adapter provides access to the data items. The Adapter is also responsible for making a View for each item in the data set.
 
(二)序列化:把資料儲存到物件
 
(三)Arraylist自己就可以直接序列化儲存
 
 
arraylist
 
(四)ArrayAdapter:是android內建的adapter,有內建的layout可以用,不需要另外自己寫layout
=>不能用2維陣列,只能用1維陣列和arraylist

 


●程式與說明--java code

lv = (ListView) findViewById(R.id.lv);
adp=new ArrayAdapter(MainActivity.this, android.R.layout.simple_list_item_1, ar);
registerForContextMenu(lv);
lv.setAdapter(adp);
lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
    @Override
    public boolean onItemLongClick
      (AdapterView<?> adapterView, View view, int i, long l) {
        index=i;
        //如果定return true就不會跳出contextmenu
        //true if the callback consumed the long click, false otherwise
        return false;
    }
});
**說明:
1.先建立一個陣列
2.直接new ArrayAdapter,給三個參數,第一個是context,第二個是layout的樣子,第三個是要放進去的資料陣列
3.把listView設定給ArrayAdapter

 

●程式參考(GitHub):檔案存取(二)Adapter與ListView 

文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()