2012年8月5日 星期日

Android:利用MediaRecorder錄音

在Manifest要記得將錄音以及寫入內部SD卡權限打開
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>




package com.example.androidrecoder;

import....

public class MainActivity extends Activity {
     //MediaRecorder物件
     MediaRecorder recorder;
     String filepath="/abcd/";
     String filename="audio.3gp";
     File file;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
     
        //Environment.getExternalStorageDirectory()傳回File物件,
        //File.getAbsolutePath()取得SD卡路徑字串
        String sdcardpath=Environment.getExternalStorageDirectory().getAbsolutePath();
      //建立存放錄音檔的資料夾
        if(!new File(sdcardpath+filepath).exists()){
        new File(sdcardpath+filepath).mkdir();
        Toast.makeText(this, "建立資料夾...", Toast.LENGTH_SHORT).show();
        }
        file=new File(sdcardpath+filepath+filename);
     
    }

  public void but1_onclick(View V){
 recorder=new MediaRecorder();
 //設定聲音來源
      recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
      //設定輸出錄音檔格式
      recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
      //設定錄音檔存放位置
      recorder.setOutputFile(file.getAbsolutePath());
      //設定錄音的編碼方式
      recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
     // prepare()完成錄音之準備工作,必須在try catch下完成
      try {
recorder.prepare();
recorder.start();

} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
  }

 public void but2_onclick(View V){
//記得停止撥放時要釋放資源
if(recorder!=null){
 recorder.stop();
 recorder.release();
 }
  }
 
}

2012年8月4日 星期六

Android: AudioManager控制音量&MediaPlayer


package com.myaudiomgt;

import....

public class MainActivity extends Activity {
SeekBar sb;
AudioManager mger;
MediaPlayer mp;
int max, cur;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sb = (SeekBar) findViewById(R.id.seekBar1);
//取得AudioManager物件,由於此方法回傳為Object物件,因此要轉型
mger = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
//音樂放在專案檔內,因此使用此方法取得MediaPlayer物件
mp = MediaPlayer.create(this, R.raw.music);
//利用AudioManager的方法取得最大音量以及目前音量
max = mger.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
cur = mger.getStreamVolume(AudioManager.STREAM_MUSIC);
//將最大音量以及目前音量設給SeekBar
sb.setMax(max);
sb.setProgress(cur);
//SeekBar監聽物件
sb.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
//調整音量
mger.setStreamVolume(AudioManager.STREAM_MUSIC, progress, 0);
}

public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub

}

public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub

}

});
}

public void but1_onclick(View v) throws IllegalStateException, IOException {
//這個If判斷式很重要,要記得判斷MediaPlayer的狀態
if (mp != null)
mp.stop();
mp.prepare();
mp.start();

}

public void but2_onclick(View v) {
mp.pause();

}

public void but3_onclick(View v) {
mp.stop();

}

@Override
//加上這段讓Activity在Pause階段,MediaPlayer釋放掉資源,不會一直撥放音樂
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
mp.release();
}

}

2012年7月31日 星期二

Android:VideoView以及MediaPlayer撥放音訊

音訊檔以及影片檔要放置專案 res/raw

package com.mediaplayer;

import ...

public class mediaPlayer extends Activity {
ListView lv;
Spinner sp;
CharSequence[] activity = { "播放影片", "播放音樂從專案", "播放音樂從SD卡" };

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

lv = (ListView) findViewById(R.id.listView1);
                //建立以及設定接口
ArrayAdapter ada = new ArrayAdapter(this,
android.R.layout.simple_list_item_1, activity);
lv.setAdapter(ada);
                //建立監聽物件
lv.setOnItemClickListener(new OnItemClickListener() {

public void onItemClick(AdapterView<?> arg0, View arg1,
int position, long id) {
// TODO Auto-generated method stub
switch (position) {
case 0:
Intent vintent = new Intent(mediaPlayer.this,
video.class);
startActivity(vintent);
break;
case 1:
Intent aintent = new Intent(mediaPlayer.this, Audio.class);
startActivity(aintent);
break;
case 2:
Intent a2intent = new Intent(mediaPlayer.this, Audio2.class);
startActivity(a2intent);
break;
}

}

});

}


}
package com.mediaplayer;

import ...
//使用VideoView撥放影片
public class video extends Activity {
VideoView vv;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.videoview);
vv=(VideoView)findViewById(R.id.videoView1);
//影片檔在SD Card寫法
//Uri uri=Uri.parse("file:///sdcard/navy.3gp");
//影片在專案檔中
Uri uri=Uri.parse("android.resource://com.mediaplayer/" + R.raw.navy);
//設定路徑
vv.setVideoURI(uri);
//建立媒體控制器
MediaController mc=new  MediaController(this);
//將媒體控制器設給VideoView
vv.setMediaController(mc);
vv.requestFocus();
//播放
vv.start();
}

}


package com.mediaplayer;

import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.widget.TextView;
//撥放於專案內之音訊檔
public class Audio extends Activity {
// 宣告MediaPlayer類別變數
MediaPlayer medi;
String path;
TextView tex;

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.audio);
tex = (TextView) findViewById(R.id.textView1);
//撥放音訊檔來自於專案內較簡單,只要使用MediaPlayer.create(Content, 
                 R.raw.XX)建立物件
//再start()播放即可
medi = MediaPlayer.create(this, R.raw.aa);
medi.start();

tex.setText("playing...");

}

@Override
//記得要在 onDestroy()時將MediaPlayer物件給release掉
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
medi.release();

}

}
package com.mediaplayer;

import ...

public class Audio2 extends Activity {
TextView tex;
// SD卡上音訊檔的路徑
final private String path = "/sdcard/song11.mp3";
MediaPlayer mp;

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.audio2);
tex = (TextView) findViewById(R.id.textView1);

// 建立物件,方法與音訊檔在專案內不同
mp = new MediaPlayer();
try {
// 設定路徑
mp.setDataSource(path);
// 狀態由Initialized到Prepare狀態
mp.prepare();
// 狀態由prepare狀態到start狀態
mp.start();
tex.setText("playing...");
} catch (Exception e) {
Toast.makeText(this, "無法撥放音訊", Toast.LENGTH_SHORT).show();

}

}

@Override
// 記得release MediaPlayer
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
mp.release();
}

}




2012年7月25日 星期三

Android:SQLite 新增 修改 刪除 列表 查詢

SQLite會用到兩個很重要的類別物件,SQLiteOpenHelper負責建立資料庫以及資料表
以及SQLiteDatabase負責資料的新增 修改 刪除 等操作

首先要新建一個class extends SQLiteOpenHelper


package com.sqltest;

import ....
public class Mydbhelper extends SQLiteOpenHelper {
static String dbname = "mydb";
static int version = 1;
static String dbtableSQL = "CREATE TABLE mytable ( _id integer primary key not null,"
+ "name text not null,sex text,addr text)";

// 內建的建構子,用來建立資料庫,但要傳入的參數有點多,所以我們改用自己的
public Mydbhelper(Context context, String name, CursorFactory factory,
int version) {
super(context, name, factory, version);
// TODO Auto-generated constructor stub
}
    //我們自己的建構子只需傳入Context頁面即可
public Mydbhelper(Context context) {
super(context, dbname, null, version);
// TODO Auto-generated constructor stub
}
    //建立資料表
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL(dbtableSQL);

}
    //更新資料表
@Override
public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
// TODO Auto-generated method stub

}

}

主頁面程式

package com.sqltest;

import ...
public class MainActivity extends Activity {
EditText etname, etsex, etaddr;
TextView show;

SQLiteDatabase dbwr;

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

etname = (EditText) findViewById(R.id.editText1);
etsex = (EditText) findViewById(R.id.editText2);
etaddr = (EditText) findViewById(R.id.editText3);
show = (TextView) findViewById(R.id.textView4);
        /*建立繼承SQLiteOpenHelper之類別物件,主要用來建構
出用於修改資料之SQLiteDatabase類別物件*/
Mydbhelper helper = new Mydbhelper(this);
dbwr = helper.getWritableDatabase();
Toast.makeText(this, "建立資料庫成功", 3000).show();
}
    //記得結束資料串流,避免資料遺失
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
dbwr.close();
}
        //修改
public void renewbut(View v) {
if (!etname.getText().toString().equals("")
&& !etaddr.getText().toString().equals("")) {
//ContentValues物件用來攜帶資料進資料表裡
ContentValues cv = new ContentValues();
//ContentValues.put("資料庫欄位",value)
cv.put("addr", etaddr.getText().toString());
//更新資料使用內建的API,SQLiteDatabase相關資料庫操作都會回傳一個long,可用來判斷是否有操作成功
//update(String table, ContentValues values, String whereClause, String[] 
whereArgs)
                        //whereClause 對應到SQL語法: name='XXX',SQL是用單引號
long check = dbwr.update("mytable", cv, "name='"
+ etname.getText().toString() + "'", null);
if (check > 0)
Toast.makeText(this, "修改成功", 3000).show();
else
Toast.makeText(this, "修改失敗", 3000).show();

} else {

Toast.makeText(this, "清輸入姓名以及地址", 3000).show();
}

}
       //刪除
public void delbut(View v) {
if (!etname.getText().toString().equals("")) {
long check = dbwr.delete("mytable", "name='"
+ etname.getText().toString() + "'", null);
if (check > 0) {
Toast.makeText(this, "刪除成功", 3000).show();
} else {
Toast.makeText(this, "刪除失敗", 3000).show();
}

} else {
Toast.makeText(this, "請輸入刪除資料之姓名", 3000).show();
}

}
       //新增
public void newbut(View v) {
ContentValues cv = new ContentValues();
cv.put("name", etname.getText().toString());
cv.put("sex", etsex.getText().toString());
cv.put("addr", etaddr.getText().toString());
long check = dbwr.insert("mytable", null, cv);
if (check > 0) {
Toast.makeText(this, cv.toString() + "新增成功", Toast.LENGTH_SHORT)
.show();

} else {
Toast.makeText(this, "新增失敗", Toast.LENGTH_SHORT).show();
}
}
       //查詢
public void querybut(View v) {
if (!etname.getText().toString().equals("")) {
//宣告一個Cursor變數,類似ResultSet,像是一個從資料表中得到的資料表單
Cursor c = null;
//Cursor表單中,擁有的欄位,必須與原資料表欄位名稱符合
String[] colum = { "name", "sex", "addr" };
c = dbwr.query("mytable", colum, "name='"
+ etname.getText().toString() + "'", null, null, null, null);
//針對Cursor變數進行操作,用迴圈將裡面的資料提領出來
if (c.getCount() > 0) {
String st1 = "";
//移動到第一筆
c.moveToFirst();
for (int i = 0; i < c.getCount(); i++) {
st1 = ("姓名:  " + c.getString(0) + "性別:  " + c.getString(1)
+ "地址:  " + c.getString(2) + "\n");
//移動到下一筆
c.moveToNext();
}
show.setText(st1);
Toast.makeText(this, "共有" + c.getCount() + "筆紀錄", 3000).show();
} else {
Toast.makeText(this, "沒有資料...", 3000).show();
}

} else {
Toast.makeText(this, "請輸入欲查詢之姓名", 3000).show();
}
}

//展示
            public void showbut(View v) {

Cursor c = null;
String[] colum = { "name", "sex", "addr" };
c = dbwr.query("mytable", colum, null, null, null, null, null);
if (c.getCount() > 0) {
String st1 = "";

c.moveToFirst();
for (int i = 0; i < c.getCount(); i++) {
st1 += ("姓名:  " + c.getString(0) + "性別:  " + c.getString(1)
+ "地址:  " + c.getString(2) + "\n");
c.moveToNext();
}
show.setText(st1);

Toast.makeText(this, "共有" + c.getCount() + "筆紀錄", 3000).show();
} else {
Toast.makeText(this, "沒有資料...", 3000).show();
}

}

}

2012年7月24日 星期二

Android:儲存資料到SD卡

與JAVA中儲存資料至File以及取回概念以及用法相同

<Android Manifest>
要記得將SD卡寫取資料的權限打開
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

<Source Code>

package com.savesdtest;

import ....

public class MainActivity extends Activity {
//datapath為SD卡底下目的資料夾,mydata為儲存資料的TXT檔
        String datapath = "/data1";
String mydata = "note.txt";
File file;

EditText edi;
Button save, get;
TextView show;

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

edi = (EditText) findViewById(R.id.editText1);
save = (Button) findViewById(R.id.button1);
get = (Button) findViewById(R.id.button2);
show = (TextView) findViewById(R.id.textView2);
        //利用Environment查看外部儲存空間的狀態是否可讀寫
if (!Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {

} else {
           /*Environment.getExternalStorageDirectory()傳回File,File.getAbsolutePath()
得到SD卡路徑*/
String path = Environment.getExternalStorageDirectory()
.getAbsolutePath() + datapath;
//建立這一個暫時的File物件主要是要用在底下的if判斷式,File.mkdir()
File sdcardPath = new File(path);
if (!sdcardPath.exists()) {
sdcardPath.mkdir();
Toast.makeText(this, path + "已建立", Toast.LENGTH_SHORT).show();
}
file = new File(path + mydata);
}
save.setOnClickListener(new OnClickListener() {

public void onClick(View v) {
// TODO Auto-generated method stub

try {
//JAVA io包裝,位元->字元->字串
FileOutputStream fos = new FileOutputStream(file, true);
OutputStreamWriter osw = new OutputStreamWriter(fos);
BufferedWriter bw = new BufferedWriter(osw);
bw.write(edi.getText().toString());
bw.flush();

bw.close();

} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

});

get.setOnClickListener(new OnClickListener() {

public void onClick(View v) {
// TODO Auto-generated method stub
String str1 = "", str2 = "";
try {
FileInputStream fis = new FileInputStream(file);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr);
while ((str1 = br.readLine()) != null) {
str2 += str1;
}
show.setText("結果" + str2);
br.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

});
}

}

2012年7月19日 星期四

Android:利用FileOutputStream & FileInputStream儲存資料


package com.savefile;

import....

public class MainActivity extends Activity {
Button saveBut,getBut;
EditText edi;
TextView show;
String filename="my.file";
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        saveBut=(Button)findViewById(R.id.button1);
        getBut=(Button)findViewById(R.id.button2);
        edi=(EditText)findViewById(R.id.editText1);
        show=(TextView)findViewById(R.id.textView1);
        saveBut.setOnClickListener(new OnClickListener(){

public void onClick(View arg0) {
// TODO Auto-generated method stub
try {
//openFileOutput(儲存的檔名,字串連接模式),MODE_APPEND不會覆蓋
                                         掉之前儲存值
FileOutputStream fos=openFileOutput(filename,MODE_APPEND);
//位元組串流轉換為字元組串流,不一定要寫,
//有書會用BufferOutputStream,但雖然會提升效能,但此法會將資料寫
                                           進陣列中,使用上較麻煩
OutputStreamWriter osw=new OutputStreamWriter(fos);
//在這邊我們用BufferedWriter來提升效能
BufferedWriter bw=new BufferedWriter(osw);
bw.write(edi.getText().toString());
bw.flush();
bw.close();
Toast.makeText(MainActivity.this,edi.getText().toString()+"is saved..." , Toast.LENGTH_SHORT).show();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
       
        });
        getBut.setOnClickListener(new OnClickListener(){

public void onClick(View arg0) {
// TODO Auto-generated method stub
try {
FileInputStream fis=openFileInput(filename);
InputStreamReader isr=new InputStreamReader(fis);
//使用BufferedReader可以使用readLine()方法非常好用,並可以提升效率
BufferedReader br=new BufferedReader(isr);
String str1="",str2="";
//Java常見用法
while((str1=br.readLine())!=null){
str2+=str1;
show.setText("儲存之值"+str2);
      br.close( );
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
       
        });
    }

 
 
}

Android:SharedPreference儲存資料

一般來說,在設計上也常將寫入檔案的動作寫在onPause( )中
而取值動作則寫在onCreate( )中,在UI介面程式設定完之後


package ....;

import ....
public class SharePreActivity extends Activity {
/** Called when the activity is first created. */
SharedPreferences sp;
EditText show;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// MODE_PRIVATE=0,可以直接以0表示
//getSharedPreferences()會回傳一個SharedPreferences物件
sp = getSharedPreferences("DATA", MODE_PRIVATE);
show = (EditText) findViewById(R.id.editText1);
}

public void saveonclick(View v) {
int data = Integer.parseInt(show.getText().toString());
//SharedPreferences.edit()取得Editor物件,
//使用Editor的putXXX()寫入,而此方法都會再回傳Editor物件,因此用串鏈寫法
//結束要加上commit()方法
sp.edit().putInt("datakey", data).commit();
Toast.makeText(this, String.format("%d is saved...", data),
Toast.LENGTH_LONG).show();

}

public void page2onclick(View v) {
startActivity(new Intent(this, Page2.class));

}
}

package com.wu;

import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

public class Page2 extends Activity {
SharedPreferences sp;
TextView show;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.page2);
//如果是在不同的活動頁面,必須在宣告並取得SharedPreferences物件
//0=MODE_PRIVATE
sp = getSharedPreferences("DATA", 0);
show=(TextView)findViewById(R.id.textViewpage2);
}
public void readonclick(View v){
//sp.getInt("datakey", 0):使用getXXX(Key,default values)取回儲存之值
show.setText(String.format("取回之值為%d",sp.getInt("datakey", 0) ));
}
}