2012年8月17日 星期五

IO --(5)讀出的檔案內容,套用TTS,將內容以機器合成聲音讀出


IO --(5)讀出的檔案內容,套用TTS,將內容以機器合成聲音讀出
                  設計讓練習英聽的學生使用


Manifest.xml:
加上:

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




***********************
main.java: 主程式



public class IO_TTSActivity extends Activity implements OnInitListener{
    /** Called when the activity is first created. */
private final String SDCARD_PATH = Environment.getExternalStorageDirectory().getAbsolutePath();
private final String FILE_PATH = "/fileio";
// private final String FILE_NAME = "test03.txt";
private final String ENCODING = "UTF-8";
private File mDataPath;
private FileInputStream fis = null;
TextView tv;
ListView lv;
String [] strings;
 
private TextToSpeech mTTS;
private Button listenBtn;
String result = "";
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        tv= (TextView) findViewById(R.id.textView01);
        tv.setMovementMethod(ScrollingMovementMethod.getInstance());
        
        mDataPath = new File (SDCARD_PATH + FILE_PATH);
        File [] filesArray = mDataPath.listFiles();
        
        String fileNames = ""; // to receive every single file name
        for (int i = 0; i < filesArray.length; i++) {
        if (filesArray[i].isFile()) { //get rid of directories
        String tempStr = ""; //會多出入境的字串
        tempStr = filesArray[i].toString();
        String strSub = ""; //to subtract the uneccessary part: /mnt/sdcard/fileio/ (19 個字元)
        strSub = tempStr.substring(19, tempStr.length()).toString();
        fileNames += strSub + "--";
        }
        }
        
        //Handle to subtraction of the final "--" in fileNames string
        String result = "";
        result = fileNames.substring(0, fileNames.length()-2);
        strings = TextUtils.split(result, "--");
        
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, strings);
        lv = (ListView) findViewById(R.id.listView1);
        lv.setAdapter(adapter);
        lv.setOnItemClickListener(listener);
        
        mTTS = new TextToSpeech(getApplicationContext(), this);//初始化
        listenBtn = (Button) findViewById(R.id.button1);
        listenBtn.setOnClickListener(btnListener);
        
    }// end of onCreate
    
    
    //選擇要唸出的檔案
    private OnItemClickListener listener = new OnItemClickListener() {

@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// TODO Auto-generated method stub
tv.setText(""); // clean tv in case of left-over
String aFileName = strings[position].toString();
readFile(aFileName);//Method: read the content of a file
//讀出所選檔案的內容;用QUEUE_ADD可以再接其他的字串;QUEUE_FLUSH將無法做到
mTTS.speak(result, TextToSpeech.QUEUE_ADD, null);
mTTS.playSilence(5000, TextToSpeech.QUEUE_ADD, null); //休息五秒
mTTS.speak(result, TextToSpeech.QUEUE_ADD, null); //又重複將內容朗誦一遍
}
};// end of listener
    
//看答案的按鈕
private OnClickListener btnListener = new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
tv.setText(result);

}
};
//讀出檔案的內容
private void readFile(String aFileName) {
try {
String mFileName = mDataPath + "/" + aFileName;
File fileContent = new File (mFileName);
fis = new FileInputStream(fileContent);
int length = fis.available();
byte [] buffer = new byte [length];
fis.read(buffer);
result = EncodingUtils.getString(buffer, ENCODING);
fis.close();
//tv.setText(result);
}catch (Exception e) {
e.printStackTrace();
}
} //end of readFile()


@Override
public void onInit(int status) {
// TODO Auto-generated method stub
if (status == TextToSpeech.SUCCESS) {
mTTS.speak("I'm ready", TextToSpeech.QUEUE_FLUSH, null);
}else {
System.out.println("Oops!");
}
}


@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
mTTS.shutdown();
}


@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
if (mTTS != null) {
mTTS.stop();
}
}
}

****************************************
res/layout/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" >

    <TextView
        
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:textColor="#FF0000"
        android:textSize="20dp"
        android:text="選擇下列檔案練習英聽:" />

    <TextView
        android:id="@+id/textView01"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:maxLines="15"
        android:scrollbarStyle="outsideInset"
        android:scrollbars="vertical"
        android:singleLine="false"
        android:text=""
        android:textColor="#00FF00"
        android:textSize="20dp" />
     <Button
        android:id="@+id/button1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="看答案!" />
    

    <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:layout_weight="0.85" >
    </ListView>

   
</LinearLayout>

2012年7月17日 星期二

IO: (2) SDCARD


IO: (2) 僅列出SDCARD裡檔案的名稱(不包括資料夾)


public class OnlyFileNamesInSDCardActivity extends Activity {
    /** Called when the activity is first created. */

private final String SD_PATH = Environment.getExternalStorageDirectory().getAbsolutePath();
private final String FILE_PATH = "/fileio";
private final String FILE_NAME = "test02.txt";
private final String ENCODING = "UTF-8";

FileInputStream fis = null;

TextView tv;
ListView lv;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
     
     
     
        //列出Sdcard 裡的夾子和檔案,放上LISTVIEW
        try {
                //找出SD的入徑
        File sdcardPATH = Environment.getExternalStorageDirectory();
               //用list(),將SD裡的資料夾和檔案以字串的方式收集在array
//         String [] fileNamesArrayStr = sdcardPATH.list(); 

        //listFiles()則會加上完整入徑,列出入徑及資料夾+檔名的集合,存在File格是的陣列
        File [] fileArray = sdcardPATH.listFiles();
         /*** 如果要制訂特別的入徑 ***/
        // File myDataPath = new File (sdcardPATH.getAbsolutePath() + "/fileio");
        // File [] fileArray = myDataPath.listFiles(); //不要忘了要計算、減掉入徑的字元數


        String  tempStr = ""; //初始化
       
        for (int i=0; i < fileArray.length; i++) {//只收集檔案,不要資料夾,但每筆資料會產生入徑(但無法用 fileNamesArrayStr來做,因為它是字串,無法判定是否為檔案還是資料夾
        if (fileArray[i].isFile()) {
                               //用來接收每一筆的檔案名字串,但是會包含前面的入徑:/mnt/sdcard/
        String str = "";
        str = fileArray[i].toString();
                               // 用來去除多餘的入徑字串:/mnt/sdcard/
        String strSub = "";
                                 //利用substring 去掉每筆最前面的12個字元:/mnt/sdcard/
        strSub = str.substring(12, str.length()).toString();
                                // 以 "--"為記號,分隔每筆處理好的資料,存成一筆字串
        tempStr += "--" + strSub;
       
        }
        }

         //設一變數來處理最後的"--"兩個字元,讓它不會在ListView上多產生一個空的cell
          String result = "";
          Result = tempStr.substring(0, tempStr.length()-2);
        //以"--"為分節點將整筆字串切割成數個字串儲存成字串陣列,以顯示在螢幕上
        String[] strings = TextUtils.split(reselt, "--");
       
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, strings);
        lv = (ListView) findViewById(R.id.listView1);
        lv.setAdapter(adapter);
       
        } catch (Exception e) {
        e.printStackTrace();
        }
 

     
    }// end of onCreate
 
 
}

2012年6月17日 星期日

ListView 圓角化







準備一個箭頭的.png 檔

main.java:


public class ListViewCorneredBgActivity extends Activity {
private ListView mListView = null;
    
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        ArrayList<String> list =new ArrayList<String>();
        list.add("1. 台北 (Taipei)");
        list.add("2. 台中 (Taichung)");
        list.add("3. 台南 (Tainan)");
        list.add("4. 基隆 (Keelung)");
        list.add("5. 台東 (Taitung)");
        list.add("6. 高雄 (Kaohsiung)");
        mListView =  (ListView)findViewById(R.id.list);
        mListView.setAdapter(new AppAdapter(this,list));
    }
    
    class AppAdapter extends BaseAdapter implements ListAdapter{

        Context context;
        ArrayList<String> list;
        AppAdapter(Context context,ArrayList<String> list){
            this.context=context;
            this.list=list;
        }
        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return list.size();
        }

        @Override
        public Object getItem(int position) {
            // TODO Auto-generated method stub
            return list.get(position);
        }

        @Override
        public long getItemId(int position) {
            // TODO Auto-generated method stub
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // TODO Auto-generated method stub
            TextView tv;
            if(convertView==null){
                convertView=LayoutInflater.from(context).inflate(R.layout.simple_item_2, null);
            }
            tv=(TextView)convertView.findViewById(R.id.name);
            tv.setText(list.get(position));
            return convertView;
        }
        
    }
}

*********************************************************
res/layout/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" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello"
         />
    <ListView android:id="@+id/list" 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content"
        android:layout_margin="20.0dip"
        android:cacheColorHint="@null" 
                android:listSelector="@drawable/shape_bg_listview"
        android:background="@drawable/shape_bg_listview"
        />

</LinearLayout>

res/layout/simple_item_2.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    >
    <TextView
        android:id="@+id/name"
        android:textSize="17.0sp"
        android:textColor="@android:color/black"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20.0dip"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"
        >
    </TextView>
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="20.0dip"
        android:src="@drawable/arrowright1"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        >
    </ImageView>
</RelativeLayout>

***********************
res/drawable/shape_bg_listview.xml::

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
       android:shape="rectangle"
       >
       <!--  
       <gradient  
       android:startColor="@android:color/white"  
       android:endColor="#FFCCCCCC"  
       android:angle="180" 
       />
        -->
          
       
       <stroke android:width="0px" 
       android:color="@android:color/white" 
       /> 
       <solid android:color="@android:color/white" 
       /> 
       <corners 
       android:bottomRightRadius="20px" 
       android:bottomLeftRadius="20px" 
       android:topLeftRadius="20px" 
       android:topRightRadius="20px" 
       />
</shape>


參考網站:http://www.cnblogs.com/shanzei/archive/2012/03/24/2415887.html




Context Menu

使用 CONTEXT MENU




在 onCreate 裡加上:


public void onCreate(Bundle savedInstanceState) {


registerForContextMenu(getExpandableListView());
}

然後加上:

 @Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
// TODO Auto-generated method stub
//super.onCreateContextMenu(menu, v, menuInfo);
    menu.setHeaderIcon(R.drawable.heart);
    menu.setHeaderTitle("親愛的 Tom");
    menu.add(0,0,0,R.string.hello);
}

Spannable 文章的每一個字顯示其義


希望按下一段英文文章的每一個字都能顯示其意思。

利用 Spannable 和 ClickableSpan




public class Cq_Spannable01Activity extends Activity {
    /** Called when the activity is first created. */

private TextView tv;
//private ListView lv;
private static Context ctx;

private String str = "I love you, but she doesn't love him.";
private String [] strings;

private String result = ""; //每個元素 加上 href 之後

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
     
   /** Test the displaying of the components in a string **/
       // lv = (ListView) findViewById(R.id.listView1);
        strings = TextUtils.split(str, " ");
        //clear the empty space
        for (int i = 0; i< strings.length; i++) {
        String temp = "";
        String temp02 = "";
        temp = strings[i].trim();
        if (temp.endsWith(".") || temp.endsWith(",")){
        temp02 = temp.substring(0, temp.length()-1);
        temp = temp02;
       
        }
        temp = "<a style='color:yellow' href='" + temp + "'> " + temp + "</a>";
       
        strings[i] = temp;
        }
     
//        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, strings);
//        lv.setAdapter(adapter);
        /** Test the displaying of the components in a string **/
     
     
        for (int i = 0; i<strings.length; i++) {
        result += strings[i];
        }
     
     
     
     
        tv = (TextView) findViewById(R.id.textview);
        tv.setTextSize(25);
        ctx = this;
     
        String htmlLinkText = "";
//        htmlLinkText = "aaaaaaaaaa"
//         + "<a style='color:red' href='我是超連結...'>請按超連結</a>"
//         + "aaaaaaaaaaaaaaaa";
     
     
     
        htmlLinkText = "aaaaaaaaaaa"
        + "<a style='color:yellow' href='我'> I</a>"
        + "<a style='color:red' href='愛'> love</a>"
        + "<a style='color:green' href='妳'> you. </a>"
        + "aaaaaaaaaaaaaaaa";
     
     
     
     
        //tv.setText(Html.fromHtml(htmlLinkText));
        tv.setText(Html.fromHtml(result));
        tv.setMovementMethod(LinkMovementMethod.getInstance());
     
        CharSequence text = tv.getText();
        if (text instanceof Spannable) {
        int end = text.length();
        Spannable sp = (Spannable) tv.getText();
        URLSpan[] urlspan = sp.getSpans(0, end, URLSpan.class);
       
        SpannableStringBuilder style = new SpannableStringBuilder(text);
        style.clearSpans();
        for (URLSpan url : urlspan) {
        MyURLSpan myURLSpan = new MyURLSpan(url.getURL());
        style.setSpan(myURLSpan, sp.getSpanStart(url), sp.getSpanEnd(url), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
       
        tv.setText(style);
        }
     
    }
 
 
    private static class MyURLSpan extends ClickableSpan {
    private String mUrl;
    private String temp;
   
    MyURLSpan(String url) {
    mUrl = url;
   
    }

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub

//widget.setBackgroundColor(Color.parseColor("#00000000"));

if (mUrl.equalsIgnoreCase("I")) {
mUrl = "我";
}else if (mUrl.equalsIgnoreCase("love")) {
mUrl = "愛";

}else if (mUrl.equalsIgnoreCase("you")) {
mUrl = "妳";
}else if (mUrl.equalsIgnoreCase("but")) {
mUrl = "但是";
}else if (mUrl.equalsIgnoreCase("she")) {
mUrl = "她";
}else if (mUrl.equalsIgnoreCase("doesn't")) {
mUrl = "不";
}else if (mUrl.equalsIgnoreCase("him")) {
mUrl = "他";
}

Toast.makeText(ctx, mUrl, Toast.LENGTH_SHORT).show();
}
   
    } //end of class myURLSpan
}