标签:
<LinearLayout 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:orientation="vertical" tools:context=".MainActivity" > <EditText android:id="@+id/et_path" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="请输入要播放文件的路径" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <Button android:id="@+id/bt_play" android:onClick="play" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:text="播放" /> <Button android:id="@+id/bt_pause" android:onClick="pause" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:text="暂停" /> <Button android:id="@+id/bt_stop" android:onClick="stop" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:text="停止" /> <Button android:id="@+id/bt_replay" android:onClick="replay" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:text="重播" /> </LinearLayout> </LinearLayout> <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima.musicplayer" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheima.musicplayer.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
package com.itheima.musicplayer; import java.io.File; import java.io.IOException; import android.app.Activity; import android.media.AudioManager; import android.media.MediaPlayer; import android.media.MediaPlayer.OnCompletionListener; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; public class MainActivity extends Activity { private EditText et_path; private MediaPlayer mediaPlayer; private Button bt_play, bt_pause, bt_stop, bt_replay; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); et_path = (EditText) findViewById(R.id.et_path); bt_play = (Button) findViewById(R.id.bt_play); bt_pause = (Button) findViewById(R.id.bt_pause); bt_stop = (Button) findViewById(R.id.bt_stop); bt_replay = (Button) findViewById(R.id.bt_replay); } /** * 播放 * * @param view */ public void play(View view) { String filepath = et_path.getText().toString().trim(); File file = new File(filepath); if (file.exists()) { try { mediaPlayer = new MediaPlayer(); mediaPlayer.setDataSource(filepath);// 设置播放的数据源。 mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.prepare();// 准备开始播放 播放的逻辑是c代码在新的线程里面执行。 mediaPlayer.start(); bt_play.setEnabled(false); mediaPlayer.setOnCompletionListener(new OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { bt_play.setEnabled(true); } }); } catch (Exception e) { e.printStackTrace(); Toast.makeText(this, "播放失败", 0).show(); } } else { Toast.makeText(this, "文件不存在,请检查文件的路径", 0).show(); } } /** * 暂停 * * @param view */ public void pause(View view) { if ("继续".equals(bt_pause.getText().toString())) { mediaPlayer.start(); bt_pause.setText("暂停"); return; } if (mediaPlayer != null && mediaPlayer.isPlaying()) { mediaPlayer.pause(); bt_pause.setText("继续"); } } /** * 停止 * * @param view */ public void stop(View view) { if (mediaPlayer != null && mediaPlayer.isPlaying()) { mediaPlayer.stop(); mediaPlayer.release(); mediaPlayer = null; } bt_pause.setText("暂停"); bt_play.setEnabled(true); } /** * 重播 * * @param view */ public void replay(View view) { if (mediaPlayer != null && mediaPlayer.isPlaying()) { mediaPlayer.seekTo(0); } else { play(view); } bt_pause.setText("暂停"); } }
<LinearLayout 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:orientation="vertical" tools:context=".MainActivity" > <EditText android:text="http://192.168.1.100:8080/hd.mp3" android:id="@+id/et_path" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="请输入要播放文件的路径" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <Button android:id="@+id/bt_play" android:onClick="play" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:text="播放" /> <Button android:id="@+id/bt_pause" android:onClick="pause" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:text="暂停" /> <Button android:id="@+id/bt_stop" android:onClick="stop" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:text="停止" /> <Button android:id="@+id/bt_replay" android:onClick="replay" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:text="重播" /> </LinearLayout> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima.musicplayer" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <uses-permission android:name="android.permission.INTERNET"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheima.musicplayer.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
package com.itheima.musicplayer; import java.io.File; import java.io.IOException; import android.app.Activity; import android.media.AudioManager; import android.media.MediaPlayer; import android.media.MediaPlayer.OnCompletionListener; import android.media.MediaPlayer.OnPreparedListener; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; public class MainActivity extends Activity { private EditText et_path; private MediaPlayer mediaPlayer; private Button bt_play,bt_pause,bt_stop,bt_replay; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); et_path = (EditText) findViewById(R.id.et_path); bt_play = (Button) findViewById(R.id.bt_play); bt_pause = (Button) findViewById(R.id.bt_pause); bt_stop = (Button) findViewById(R.id.bt_stop); bt_replay = (Button) findViewById(R.id.bt_replay); } /** * 播放 * @param view */ public void play(View view) { String filepath = et_path.getText().toString().trim(); //http:// if(filepath.startsWith("http://")){ try { mediaPlayer = new MediaPlayer(); mediaPlayer.setDataSource(filepath);//设置播放的数据源。 mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); //mediaPlayer.prepare();//同步的准备方法。 mediaPlayer.prepareAsync();//异步的准备 mediaPlayer.setOnPreparedListener(new OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mediaPlayer.start(); bt_play.setEnabled(false); } }); mediaPlayer.setOnCompletionListener(new OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { bt_play.setEnabled(true); } }); } catch (Exception e) { e.printStackTrace(); Toast.makeText(this, "播放失败", 0).show(); } }else{ Toast.makeText(this, "请检查文件的路径", 0).show(); } } /** * 暂停 * @param view */ public void pause(View view) { if("继续".equals(bt_pause.getText().toString())){ mediaPlayer.start(); bt_pause.setText("暂停"); return; } if(mediaPlayer!=null&&mediaPlayer.isPlaying()){ mediaPlayer.pause(); bt_pause.setText("继续"); } } /** * 停止 * @param view */ public void stop(View view) { if(mediaPlayer!=null&&mediaPlayer.isPlaying()){ mediaPlayer.stop(); mediaPlayer.release(); mediaPlayer = null; } bt_pause.setText("暂停"); bt_play.setEnabled(true); } /** * 重播 * @param view */ public void replay(View view) { if(mediaPlayer!=null&&mediaPlayer.isPlaying()){ mediaPlayer.seekTo(0); }else{ play(view); } bt_pause.setText("暂停"); } }
surfaceview : 完成单位时间内大量的界面变化。
视频播放器。
游戏。
双缓冲机制:内部有两个子线程。
A 解码图像--->前台显示--->解码图像---> 前台显示
B 解码图像--->前台显示---> 解码图像
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima.musicplayer" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheima.musicplayer.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
<LinearLayout 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:orientation="vertical" tools:context=".MainActivity" > <EditText android:id="@+id/et_path" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="请输入要播放文件的路径" /> <SeekBar android:id="@+id/seekBar1" android:layout_width="match_parent" android:layout_height="wrap_content" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <Button android:id="@+id/bt_play" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="play" android:text="播放" /> <Button android:id="@+id/bt_pause" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="pause" android:text="暂停" /> <Button android:id="@+id/bt_stop" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="stop" android:text="停止" /> <Button android:id="@+id/bt_replay" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="replay" android:text="重播" /> </LinearLayout> <SurfaceView android:id="@+id/sv" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout>
package com.itheima.musicplayer; import java.io.File; import java.io.IOException; import java.util.Timer; import java.util.TimerTask; import android.app.Activity; import android.media.AudioManager; import android.media.MediaPlayer; import android.media.MediaPlayer.OnCompletionListener; import android.os.Bundle; import android.view.SurfaceHolder; import android.view.SurfaceHolder.Callback; import android.view.SurfaceView; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; import android.widget.Toast; public class MainActivity extends Activity { private EditText et_path; private MediaPlayer mediaPlayer; private Button bt_play,bt_pause,bt_stop,bt_replay; private SurfaceView sv; private SurfaceHolder holder; private int position; private String filepath; private SeekBar seekBar1; private Timer timer; private TimerTask task; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); et_path = (EditText) findViewById(R.id.et_path); bt_play = (Button) findViewById(R.id.bt_play); bt_pause = (Button) findViewById(R.id.bt_pause); bt_stop = (Button) findViewById(R.id.bt_stop); bt_replay = (Button) findViewById(R.id.bt_replay); seekBar1 = (SeekBar) findViewById(R.id.seekBar1); seekBar1.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { @Override public void onStopTrackingTouch(SeekBar seekBar) { int postion = seekBar.getProgress(); mediaPlayer.seekTo(postion); } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { } }); //得到surfaceview sv = (SurfaceView) findViewById(R.id.sv); //得到显示界面内容的容器 holder = sv.getHolder(); //在低版本模拟器上运行记得加上下面的参数。不自己维护双缓冲区,而是等待多媒体播放框架主动的推送数据。 holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); holder.addCallback(new Callback() { @Override public void surfaceDestroyed(SurfaceHolder holder) { System.out.println("destoryed"); if(mediaPlayer!=null&&mediaPlayer.isPlaying()){ position = mediaPlayer.getCurrentPosition(); mediaPlayer.stop(); mediaPlayer.release(); mediaPlayer = null; timer.cancel(); task.cancel(); timer = null; task = null; } } @Override public void surfaceCreated(SurfaceHolder holder) { System.out.println("created"); if(position>0){//记录的有播放进度。 try { mediaPlayer = new MediaPlayer(); mediaPlayer.setDataSource(filepath);//设置播放的数据源。 mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.setDisplay(holder); mediaPlayer.prepare();//准备开始播放 播放的逻辑是c代码在新的线程里面执行。 mediaPlayer.start(); mediaPlayer.seekTo(position); bt_play.setEnabled(false); mediaPlayer.setOnCompletionListener(new OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { bt_play.setEnabled(true); } }); int max = mediaPlayer.getDuration(); seekBar1.setMax(max); timer = new Timer(); task = new TimerTask() { @Override public void run() { seekBar1.setProgress(mediaPlayer.getCurrentPosition()); } }; timer.schedule(task, 0, 500); } catch (IOException e) { e.printStackTrace(); } } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { System.out.println("changed"); } }); } /** * 播放 * @param view */ public void play(View view) { filepath = et_path.getText().toString().trim(); File file = new File(filepath); if(file.exists()){ try { mediaPlayer = new MediaPlayer(); mediaPlayer.setDataSource(filepath);//设置播放的数据源。 mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.setDisplay(holder); mediaPlayer.prepare();//准备开始播放 播放的逻辑是c代码在新的线程里面执行。 mediaPlayer.start(); //设置拖动进度条的最大值 int max = mediaPlayer.getDuration(); seekBar1.setMax(max); timer = new Timer(); task = new TimerTask() { @Override public void run() { seekBar1.setProgress(mediaPlayer.getCurrentPosition()); } }; timer.schedule(task, 0, 500); bt_play.setEnabled(false); mediaPlayer.setOnCompletionListener(new OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { bt_play.setEnabled(true); } }); } catch (Exception e) { e.printStackTrace(); Toast.makeText(this, "播放失败", 0).show(); } }else{ Toast.makeText(this, "文件不存在,请检查文件的路径", 0).show(); } } /** * 暂停 * @param view */ public void pause(View view) { if("继续".equals(bt_pause.getText().toString())){ mediaPlayer.start(); bt_pause.setText("暂停"); return; } if(mediaPlayer!=null&&mediaPlayer.isPlaying()){ mediaPlayer.pause(); bt_pause.setText("继续"); } } /** * 停止 * @param view */ public void stop(View view) { if(mediaPlayer!=null&&mediaPlayer.isPlaying()){ mediaPlayer.stop(); mediaPlayer.release(); mediaPlayer = null; } bt_pause.setText("暂停"); bt_play.setEnabled(true); } /** * 重播 * @param view */ public void replay(View view) { if(mediaPlayer!=null&&mediaPlayer.isPlaying()){ mediaPlayer.seekTo(0); }else{ play(view); } bt_pause.setText("暂停"); } }
//在低版本模拟器上运行记得加上下面的参数。不自己维护双缓冲区,而是等待多媒体播放框架主动的推送数据。 holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima.musicplayer" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <uses-permission android:name="android.permission.INTERNET"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheima.musicplayer.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
package com.itheima.musicplayer; import java.io.File; import java.io.IOException; import android.app.Activity; import android.media.AudioManager; import android.media.MediaPlayer; import android.media.MediaPlayer.OnCompletionListener; import android.os.Bundle; import android.view.SurfaceHolder; import android.view.SurfaceHolder.Callback; import android.view.SurfaceView; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; public class MainActivity extends Activity { private EditText et_path; private MediaPlayer mediaPlayer; private Button bt_play,bt_pause,bt_stop,bt_replay; private SurfaceView sv; private SurfaceHolder holder; private int position; private String filepath; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); et_path = (EditText) findViewById(R.id.et_path); bt_play = (Button) findViewById(R.id.bt_play); bt_pause = (Button) findViewById(R.id.bt_pause); bt_stop = (Button) findViewById(R.id.bt_stop); bt_replay = (Button) findViewById(R.id.bt_replay); //得到surfaceview sv = (SurfaceView) findViewById(R.id.sv); //得到显示界面内容的容器 holder = sv.getHolder(); //在低版本模拟器上运行记得加上下面的参数。不自己维护双缓冲区,而是等待多媒体播放框架主动的推送数据。 holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); holder.addCallback(new Callback() { @Override public void surfaceDestroyed(SurfaceHolder holder) { System.out.println("destoryed"); if(mediaPlayer!=null&&mediaPlayer.isPlaying()){ position = mediaPlayer.getCurrentPosition(); mediaPlayer.stop(); mediaPlayer.release(); mediaPlayer = null; } } @Override public void surfaceCreated(SurfaceHolder holder) { System.out.println("created"); if(position>0){//记录的有播放进度。 try { mediaPlayer = new MediaPlayer(); mediaPlayer.setDataSource(filepath);//设置播放的数据源。 mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.setDisplay(holder); mediaPlayer.prepare();//准备开始播放 播放的逻辑是c代码在新的线程里面执行。 mediaPlayer.start(); mediaPlayer.seekTo(position); bt_play.setEnabled(false); mediaPlayer.setOnCompletionListener(new OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { bt_play.setEnabled(true); } }); } catch (IOException e) { e.printStackTrace(); } } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { System.out.println("changed"); } }); } /** * 播放 * @param view */ public void play(View view) { filepath = et_path.getText().toString().trim(); //File file = new File(filepath); if(filepath.startsWith("http://")){ try { mediaPlayer = new MediaPlayer(); mediaPlayer.setDataSource(filepath);//设置播放的数据源。 mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.setDisplay(holder); mediaPlayer.prepare();//准备开始播放 播放的逻辑是c代码在新的线程里面执行。 mediaPlayer.start(); bt_play.setEnabled(false); mediaPlayer.setOnCompletionListener(new OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { bt_play.setEnabled(true); } }); } catch (Exception e) { e.printStackTrace(); Toast.makeText(this, "播放失败", 0).show(); } }else{ Toast.makeText(this, "文件不存在,请检查文件的路径", 0).show(); } } /** * 暂停 * @param view */ public void pause(View view) { if("继续".equals(bt_pause.getText().toString())){ mediaPlayer.start(); bt_pause.setText("暂停"); return; } if(mediaPlayer!=null&&mediaPlayer.isPlaying()){ mediaPlayer.pause(); bt_pause.setText("继续"); } } /** * 停止 * @param view */ public void stop(View view) { if(mediaPlayer!=null&&mediaPlayer.isPlaying()){ mediaPlayer.stop(); mediaPlayer.release(); mediaPlayer = null; } bt_pause.setText("暂停"); bt_play.setEnabled(true); } /** * 重播 * @param view */ public void replay(View view) { if(mediaPlayer!=null&&mediaPlayer.isPlaying()){ mediaPlayer.seekTo(0); }else{ play(view); } bt_pause.setText("暂停"); } }
package com.itheima.musicplayer; import java.io.File; import java.io.IOException; import java.util.Timer; import java.util.TimerTask; import android.app.Activity; import android.media.AudioManager; import android.media.MediaPlayer; import android.media.MediaPlayer.OnCompletionListener; import android.os.Bundle; import android.view.SurfaceHolder; import android.view.SurfaceHolder.Callback; import android.view.SurfaceView; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; import android.widget.Toast; public class MainActivity extends Activity { private EditText et_path; private MediaPlayer mediaPlayer; private Button bt_play,bt_pause,bt_stop,bt_replay; private SurfaceView sv; private SurfaceHolder holder; private int position; private String filepath; private SeekBar seekBar1; private Timer timer; private TimerTask task; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); et_path = (EditText) findViewById(R.id.et_path); bt_play = (Button) findViewById(R.id.bt_play); bt_pause = (Button) findViewById(R.id.bt_pause); bt_stop = (Button) findViewById(R.id.bt_stop); bt_replay = (Button) findViewById(R.id.bt_replay); seekBar1 = (SeekBar) findViewById(R.id.seekBar1); seekBar1.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { @Override public void onStopTrackingTouch(SeekBar seekBar) { int postion = seekBar.getProgress(); mediaPlayer.seekTo(postion); } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { } }); //得到surfaceview sv = (SurfaceView) findViewById(R.id.sv); //得到显示界面内容的容器 holder = sv.getHolder(); //在低版本模拟器上运行记得加上下面的参数。不自己维护双缓冲区,而是等待多媒体播放框架主动的推送数据。 holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); holder.addCallback(new Callback() { @Override public void surfaceDestroyed(SurfaceHolder holder) { System.out.println("destoryed"); if(mediaPlayer!=null&&mediaPlayer.isPlaying()){ position = mediaPlayer.getCurrentPosition(); mediaPlayer.stop(); mediaPlayer.release(); mediaPlayer = null; timer.cancel(); task.cancel(); timer = null; task = null; } } @Override public void surfaceCreated(SurfaceHolder holder) { System.out.println("created"); if(position>0){//记录的有播放进度。 try { mediaPlayer = new MediaPlayer(); mediaPlayer.setDataSource(filepath);//设置播放的数据源。 mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.setDisplay(holder); mediaPlayer.prepare();//准备开始播放 播放的逻辑是c代码在新的线程里面执行。 mediaPlayer.start(); mediaPlayer.seekTo(position); bt_play.setEnabled(false); mediaPlayer.setOnCompletionListener(new OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { bt_play.setEnabled(true); } }); int max = mediaPlayer.getDuration(); seekBar1.setMax(max); timer = new Timer(); task = new TimerTask() { @Override public void run() { seekBar1.setProgress(mediaPlayer.getCurrentPosition()); } }; timer.schedule(task, 0, 500); } catch (IOException e) { e.printStackTrace(); } } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { System.out.println("changed"); } }); } /** * 播放 * @param view */ public void play(View view) { filepath = et_path.getText().toString().trim(); File file = new File(filepath); if(file.exists()){ try { mediaPlayer = new MediaPlayer(); mediaPlayer.setDataSource(filepath);//设置播放的数据源。 mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.setDisplay(holder); mediaPlayer.prepare();//准备开始播放 播放的逻辑是c代码在新的线程里面执行。 mediaPlayer.start(); //设置拖动进度条的最大值 int max = mediaPlayer.getDuration(); seekBar1.setMax(max); timer = new Timer(); task = new TimerTask() { @Override public void run() { seekBar1.setProgress(mediaPlayer.getCurrentPosition()); } }; timer.schedule(task, 0, 500); bt_play.setEnabled(false); mediaPlayer.setOnCompletionListener(new OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { bt_play.setEnabled(true); } }); } catch (Exception e) { e.printStackTrace(); Toast.makeText(this, "播放失败", 0).show(); } }else{ Toast.makeText(this, "文件不存在,请检查文件的路径", 0).show(); } } /** * 暂停 * @param view */ public void pause(View view) { if("继续".equals(bt_pause.getText().toString())){ mediaPlayer.start(); bt_pause.setText("暂停"); return; } if(mediaPlayer!=null&&mediaPlayer.isPlaying()){ mediaPlayer.pause(); bt_pause.setText("继续"); } } /** * 停止 * @param view */ public void stop(View view) { if(mediaPlayer!=null&&mediaPlayer.isPlaying()){ mediaPlayer.stop(); mediaPlayer.release(); mediaPlayer = null; } bt_pause.setText("暂停"); bt_play.setEnabled(true); } /** * 重播 * @param view */ public void replay(View view) { if(mediaPlayer!=null&&mediaPlayer.isPlaying()){ mediaPlayer.seekTo(0); }else{ play(view); } bt_pause.setText("暂停"); } }
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima.camera" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheima.camera.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
<LinearLayout 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:orientation="vertical" tools:context=".MainActivity" > <Button android:onClick="click" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="拍照" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/iv" /> </LinearLayout>
package com.itheima.camera; import java.io.File; import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.provider.MediaStore; import android.view.View; import android.widget.ImageView; public class MainActivity extends Activity { private ImageView iv; private File file ; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); iv = (ImageView) findViewById(R.id.iv); } public void click(View view) { Intent intent = new Intent(); // 指定拍照的意图。 intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE); file = new File(Environment.getExternalStorageDirectory(),System.currentTimeMillis()+".jpg"); intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)); // 指定保存文件的路径 startActivityForResult(intent, 100); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if(requestCode==100){ iv.setImageURI(Uri.fromFile(file)); } super.onActivityResult(requestCode, resultCode, data); } }
偷拍神器
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima.camera2" android:versionCode="1" android:versionName="1.0" > <uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheima.camera2.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:orientation="vertical" android:layout_height="match_parent" tools:context=".MainActivity" > <Button android:onClick="click" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="拍照" /> <FrameLayout android:id="@+id/camera_preview" android:layout_width="100dip" android:layout_height="100dip" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/iv" /> </LinearLayout>
package com.itheima.camera2; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import android.hardware.Camera; import android.hardware.Camera.AutoFocusCallback; import android.hardware.Camera.PictureCallback; import android.hardware.Camera.ShutterCallback; import android.os.Bundle; import android.os.Environment; import android.os.SystemClock; import android.app.Activity; import android.view.Menu; import android.view.View; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.Toast; public class MainActivity extends Activity { private ImageView iv; private Camera mCamera; private CameraPreview mPreview; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); iv = (ImageView) findViewById(R.id.iv); // Create an instance of Camera mCamera = getCameraInstance(); // Create our Preview view and set it as the content of our activity. mPreview = new CameraPreview(this, mCamera); FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview); preview.addView(mPreview); } public void click(View view){ mCamera.autoFocus(new AutoFocusCallback() { @Override public void onAutoFocus(boolean success, Camera camera) { mCamera.takePicture(null, null, new PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { try { File file = new File(Environment.getExternalStorageDirectory(),SystemClock.uptimeMillis()+".jpg"); FileOutputStream fos = new FileOutputStream(file); fos.write(data); fos.close(); Toast.makeText(getApplicationContext(), "成功", 0).show(); mCamera.startPreview(); } catch (Exception e) { e.printStackTrace(); } } }); } }); } /** 获取一个照相机实例 */ public static Camera getCameraInstance(){ Camera c = null; try { c = Camera.open(); // attempt to get a Camera instance } catch (Exception e){ // Camera is not available (in use or does not exist) } return c; // returns null if camera is unavailable } @Override protected void onDestroy() { mCamera.stopPreview(); mCamera.release(); mCamera = null; super.onDestroy(); } }
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima.dialog" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheima.dialog.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
<LinearLayout 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:orientation="vertical" tools:context=".MainActivity" > <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:onClick="click1" android:text="确定取消对话框" /> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:onClick="click2" android:text="单选对话框" /> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:onClick="click3" android:text="多选对话框" /> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:onClick="click4" android:text="进度条对话框" /> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:onClick="click5" android:text="带进度的进度条对话框" /> </LinearLayout>
package com.itheima.dialog; import android.os.Bundle; import android.app.Activity; import android.app.AlertDialog; import android.app.AlertDialog.Builder; import android.app.ProgressDialog; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.DialogInterface.OnMultiChoiceClickListener; import android.view.Menu; import android.view.View; import android.widget.Toast; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void click1(View view){ //对话框的创建器 AlertDialog.Builder builder = new Builder(this); builder.setTitle("我是对话框"); builder.setMessage("对话框显示的内容"); builder.setPositiveButton("确定", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Toast.makeText(getApplicationContext(), "确定被点击了", 0).show(); } }); builder.setNegativeButton("取消", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //什么都不写默认实现就是关闭掉对话框 } }); builder.setCancelable(false); builder.create().show(); } /** * 单选对话框 * @param view */ public void click2(View view){ //对话框的创建器 AlertDialog.Builder builder = new Builder(this); builder.setTitle("请选择您的性别"); final String[] items = {"男","女","未知"}; builder.setSingleChoiceItems(items, 2, new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Toast.makeText(getApplicationContext(), "您的性别:"+items[which], 0).show(); dialog.dismiss(); } }); builder.create().show(); } /** * 多选对话框 * @param view */ public void click3(View view){ //对话框的创建器 AlertDialog.Builder builder = new Builder(this); builder.setTitle("请选择你最爱吃的水果"); final String[] items={"苹果","梨","菠萝","香蕉","黄瓜"}; final boolean[] result =new boolean[]{true,false,true,false,false}; builder.setMultiChoiceItems(items, result, new OnMultiChoiceClickListener() { @Override public void onClick(DialogInterface dialog, int which, boolean isChecked) { Toast.makeText(getApplicationContext(), items[which]+isChecked, 0).show(); result[which] = isChecked; } }); builder.setPositiveButton("提交", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { StringBuffer sb = new StringBuffer(); for(int i=0;i<result.length;i++){ if(result[i]){ sb.append(items[i]+","); } } Toast.makeText(getApplicationContext(), "您选中了,"+sb.toString(), 0).show(); } }); //builder.create().show(); builder.show(); } //进度条对话框 public void click4(View view){ ProgressDialog pd = new ProgressDialog(this); pd.setTitle("提醒"); pd.setMessage("正在加载数据...请稍等。"); pd.show(); } //带进度的进度条对话框 public void click5(View view){ final ProgressDialog pd = new ProgressDialog(this); pd.setTitle("提醒"); pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); pd.setMax(100); pd.setMessage("正在加载数据...请稍等。"); pd.show(); new Thread(){ public void run() { for(int i = 0;i<100;i++){ try { Thread.sleep(40); } catch (InterruptedException e) { e.printStackTrace(); } pd.setProgress(i); } pd.dismiss(); }; }.start(); } }
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima.notification" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <uses-permission android:name="android.permission.CALL_PHONE"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheima.notification.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
<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" tools:context=".MainActivity" > <Button android:onClick="click" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:text="点击显示通知" /> <Button android:onClick="click2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:text="新版点击显示通知" /> </RelativeLayout>
package com.itheima.notification; import android.annotation.SuppressLint; import android.app.Activity; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Intent; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Bundle; import android.view.View; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void click(View view){ NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); Notification notification = new Notification(R.drawable.notification, "我是一个通知", System.currentTimeMillis()); notification.flags = Notification.FLAG_AUTO_CANCEL; Intent intent = new Intent(); intent.setAction(Intent.ACTION_CALL); intent.setData(Uri.parse("tel:110")); PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0); notification.setLatestEventInfo(this, "我是标题", "我是内容", contentIntent); nm.notify(0, notification); } /** * 新版本的notification * @param view */ @SuppressLint("NewApi") public void click2(View view){ Notification noti = new Notification.Builder(this) .setContentTitle("我是标题") .setContentText("我是内容") .setSmallIcon(R.drawable.notification) .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher)) .build(); NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); nm.notify(0, noti); } }
样式和主题的区别,作用范围不同,样式都是作用在一个小控件,
主题作用一个activity,或者整个应用程序
样式都在布局文件里面配置,主题都在清单文件配置
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima.styletheme" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <application android:theme="@style/red_bg_theme" android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:name="com.itheima.styletheme.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
package com.itheima.styletheme; import android.os.Bundle; import android.app.Activity; import android.view.Menu; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.activity_main, menu); return true; } }
<LinearLayout 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:orientation="vertical" tools:context=".MainActivity" > <TextView style="@style/text_content_style" android:text="你好啊" /> <TextView style="@style/text_content_style" android:text="你好啊" /> <TextView style="@style/text_content_style" android:text="你好啊" /> <TextView style="@style/text_content_style" android:text="你好啊" /> <TextView style="@style/text_content_style" android:text="你好啊" /> <TextView style="@style/text_content_style" android:text="你好啊" /> <TextView style="@style/text_content_style" android:text="你好啊" /> <TextView style="@style/text_content_style" android:text="你好啊" /> <TextView style="@style/text_content_style" android:text="你好啊" /> <TextView style="@style/text_content_style" android:text="你好啊" /> <TextView style="@style/text_content_style" android:text="你好啊" /> <TextView style="@style/text_content_style" android:text="你好啊" /> </LinearLayout>
<resources xmlns:android="http://schemas.android.com/apk/res/android"> <!-- Base application theme, dependent on API level. This theme is replaced by AppBaseTheme from res/values-vXX/styles.xml on newer devices. --> <style name="AppBaseTheme" parent="android:Theme.Light"> <!-- Theme customizations available in newer API levels can go in res/values-vXX/styles.xml, while customizations related to backward-compatibility can go here. --> </style> <!-- Application theme. --> <style name="AppTheme" parent="AppBaseTheme"> <!-- All customizations that are NOT specific to a particular API-level can go here. --> </style> <style name="text_content_style"> <item name="android:layout_width">wrap_content</item> <item name="android:layout_height">wrap_content</item> <item name="android:textColor">#0000ff</item> <item name="android:textSize">20sp</item> </style> <!-- 样式和主题的区别,作用范围不同,样式都是作用在一个小控件, 主题作用一个activity,或者整个应用程序 样式都在布局文件里面配置,主题都在清单文件配置 --> <style name="red_bg_theme"> <item name="android:background">#33ff0000</item> </style> </resources>
D:\tools\AndroidSdk1119\adt-bundle-windows-x86-20140702\sdk\platforms\android-20\data\res\values\styles.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima.styleexample" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:theme="@style/BLUE_NoTitleBar.GREEN_NoTitleBar" android:name="com.itheima.styleexample.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
<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" tools:context=".MainActivity" > <ProgressBar style="@style/my_pb_style" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" /> </RelativeLayout>
<resources xmlns:android="http://schemas.android.com/apk/res/android"> <!-- Base application theme, dependent on API level. This theme is replaced by AppBaseTheme from res/values-vXX/styles.xml on newer devices. --> <style name="AppBaseTheme" parent="android:Theme.Light"> <!-- Theme customizations available in newer API levels can go in res/values-vXX/styles.xml, while customizations related to backward-compatibility can go here. --> </style> <!-- Application theme. --> <style name="AppTheme" parent="AppBaseTheme"> <!-- All customizations that are NOT specific to a particular API-level can go here. --> </style> <style name="my_pb_style"> <item name="android:indeterminateOnly">true</item> <item name="android:indeterminateDrawable">@drawable/progress_medium_white</item> <item name="android:indeterminateBehavior">repeat</item> <item name="android:indeterminateDuration">3500</item> <item name="android:minWidth">30dip</item> <item name="android:maxWidth">30dip</item> <item name="android:minHeight">30dip</item> <item name="android:maxHeight">30dip</item> </style> <style name="RED_NoTitleBar"> <item name="android:windowFullscreen">true</item> <item name="android:windowNoTitle">true</item> <item name="android:background">#ff0000</item> </style> <style name="BLUE_NoTitleBar" parent="@style/RED_NoTitleBar"> <item name="android:background">#0000ff</item> </style> <style name="BLUE_NoTitleBar.GREEN_NoTitleBar" > <item name="android:background">#00ff00</item> </style> </resources>
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima.frameanimation" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheima.frameanimation.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
<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" tools:context=".MainActivity" > <ImageView android:id="@+id/iv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" /> </RelativeLayout>
<?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false" > <item android:drawable="@drawable/girl_1" android:duration="200"/> <item android:drawable="@drawable/girl_2" android:duration="200"/> <item android:drawable="@drawable/girl_3" android:duration="200"/> <item android:drawable="@drawable/girl_4" android:duration="200"/> <item android:drawable="@drawable/girl_5" android:duration="200"/> <item android:drawable="@drawable/girl_6" android:duration="400"/> <item android:drawable="@drawable/girl_7" android:duration="400"/> <item android:drawable="@drawable/girl_6" android:duration="400"/> <item android:drawable="@drawable/girl_7" android:duration="400"/> <item android:drawable="@drawable/girl_6" android:duration="400"/> <item android:drawable="@drawable/girl_7" android:duration="400"/> <item android:drawable="@drawable/girl_8" android:duration="200"/> <item android:drawable="@drawable/girl_9" android:duration="200"/> <item android:drawable="@drawable/girl_10" android:duration="200"/> <item android:drawable="@drawable/girl_11" android:duration="200"/> </animation-list>
package com.itheima.frameanimation; import android.os.Bundle; import android.app.Activity; import android.graphics.drawable.AnimationDrawable; import android.view.Menu; import android.view.MotionEvent; import android.widget.ImageView; public class MainActivity extends Activity { private ImageView iv; private AnimationDrawable mAnimationDrawable; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); iv = (ImageView) findViewById(R.id.iv); // 把xml文件的动画资源设置为iv背景 iv.setBackgroundResource(R.drawable.girl); // 获取设置的动画资源。 执行可能需要花费一定的时间 mAnimationDrawable = (AnimationDrawable) iv.getBackground(); } public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { mAnimationDrawable.start(); return true; } return super.onTouchEvent(event); } }
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima.tween" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheima.tween.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
<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" tools:context=".MainActivity" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <Button android:onClick="rotate" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:text="旋转" /> <Button android:onClick="scale" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:text="缩放" /> <Button android:onClick="trans" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:text="位移" /> <Button android:onClick="alpha" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:text="透明度" /> <Button android:onClick="set" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:text="组合动画" /> </LinearLayout> <ImageView android:id="@+id/iv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:src="@drawable/ic_launcher" /> </RelativeLayout>
package com.itheima.tween; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.view.View; import android.view.animation.AlphaAnimation; import android.view.animation.Animation; import android.view.animation.AnimationSet; import android.view.animation.RotateAnimation; import android.view.animation.ScaleAnimation; import android.view.animation.TranslateAnimation; import android.widget.ImageView; public class MainActivity extends Activity { private ImageView iv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); iv = (ImageView) findViewById(R.id.iv); } //透明度动画 public void alpha(View view){ AlphaAnimation aa = new AlphaAnimation(0.0f, 1.0f); aa.setDuration(2000); aa.setRepeatCount(1); aa.setRepeatMode(Animation.REVERSE); aa.setFillAfter(true); iv.startAnimation(aa); } //位移动画 public void trans(View view){ TranslateAnimation ta = new TranslateAnimation(Animation.RELATIVE_TO_PARENT, -0.5f, Animation.RELATIVE_TO_PARENT, 0.5f, Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT, 0.0f); ta.setDuration(2000); ta.setRepeatCount(1); ta.setRepeatMode(Animation.REVERSE); iv.startAnimation(ta); } //缩放动画 public void scale(View view){ ScaleAnimation sa = new ScaleAnimation(0.1f, 2.0f, 0.1f, 2.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); sa.setDuration(2000); sa.setRepeatCount(1); sa.setRepeatMode(Animation.REVERSE); iv.startAnimation(sa); } //旋转动画 public void rotate(View view){ RotateAnimation ra = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f); ra.setDuration(2000); ra.setRepeatCount(1); ra.setRepeatMode(Animation.REVERSE); iv.startAnimation(ra); } //动画组合 public void set(View view){ AnimationSet set = new AnimationSet(false); TranslateAnimation ta = new TranslateAnimation(Animation.RELATIVE_TO_PARENT, -0.5f, Animation.RELATIVE_TO_PARENT, 0.5f, Animation.RELATIVE_TO_PARENT, -0.5f, Animation.RELATIVE_TO_PARENT, 0.5f); ta.setDuration(2000); ta.setRepeatCount(1); ta.setRepeatMode(Animation.REVERSE); ScaleAnimation sa = new ScaleAnimation(0.1f, 2.0f, 0.1f, 2.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); sa.setDuration(2000); sa.setRepeatCount(1); sa.setRepeatMode(Animation.REVERSE); RotateAnimation ra = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f); ra.setDuration(2000); ra.setRepeatCount(1); ra.setRepeatMode(Animation.REVERSE); set.addAnimation(ra); //set.addAnimation(ta); set.addAnimation(sa); iv.startAnimation(set); } }
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima.tween" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheima.tween.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
<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" tools:context=".MainActivity" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <Button android:onClick="rotate" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:text="旋转" /> <Button android:onClick="scale" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:text="缩放" /> <Button android:onClick="trans" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:text="位移" /> <Button android:onClick="alpha" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:text="透明度" /> <Button android:onClick="set" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:text="组合动画" /> </LinearLayout> <ImageView android:id="@+id/iv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:src="@drawable/ic_launcher" /> </RelativeLayout>
alpha.xml
<?xml version="1.0" encoding="utf-8"?> <alpha xmlns:android="http://schemas.android.com/apk/res/android" android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="2000" android:repeatCount="1" android:repeatMode="reverse" android:fillAfter="true" > </alpha>
rotate.xml
<?xml version="1.0" encoding="utf-8"?> <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:fromDegrees="0" android:toDegrees="360" android:pivotX="50%" android:pivotY="50%" android:duration="2000" android:repeatCount="1" android:repeatMode="reverse" > </rotate>
scale.xml
<?xml version="1.0" encoding="utf-8"?> <scale xmlns:android="http://schemas.android.com/apk/res/android" android:fromXScale="0.1" android:toXScale="2.0" android:fromYScale="0.1" android:toYScale="2.0" android:duration="2000" android:pivotX="50%" android:pivotY="50%" android:repeatCount="1" android:repeatMode="reverse" > </scale>
set.xml
<?xml version="1.0" encoding="utf-8"?> <set> <alpha xmlns:android="http://schemas.android.com/apk/res/android" android:duration="2000" android:fillAfter="true" android:fromAlpha="0.0" android:repeatCount="1" android:repeatMode="reverse" android:toAlpha="1.0" > </alpha> <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:duration="2000" android:fromDegrees="0" android:pivotX="50%" android:pivotY="50%" android:repeatCount="1" android:repeatMode="reverse" android:toDegrees="360" > </rotate> <scale xmlns:android="http://schemas.android.com/apk/res/android" android:duration="2000" android:fromXScale="0.1" android:fromYScale="0.1" android:pivotX="50%" android:pivotY="50%" android:repeatCount="1" android:repeatMode="reverse" android:toXScale="2.0" android:toYScale="2.0" > </scale> <translate xmlns:android="http://schemas.android.com/apk/res/android" android:duration="2000" android:fromXDelta="-50%p" android:fromYDelta="0" android:repeatCount="1" android:repeatMode="reverse" android:toXDelta="50%p" android:toYDelta="0" > </translate> </set>
trans.xml
<?xml version="1.0" encoding="utf-8"?> <translate xmlns:android="http://schemas.android.com/apk/res/android" android:fromXDelta="-50%p" android:toXDelta="50%p" android:fromYDelta="0" android:toYDelta="0" android:duration="2000" android:repeatCount="1" android:repeatMode="reverse" > </translate>
package com.itheima.tween; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.view.View; import android.view.animation.AlphaAnimation; import android.view.animation.Animation; import android.view.animation.AnimationSet; import android.view.animation.AnimationUtils; import android.view.animation.RotateAnimation; import android.view.animation.ScaleAnimation; import android.view.animation.TranslateAnimation; import android.widget.ImageView; public class MainActivity extends Activity { private ImageView iv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); iv = (ImageView) findViewById(R.id.iv); } //透明度动画 public void alpha(View view){ Animation aa = AnimationUtils.loadAnimation(this, R.anim.alpha); iv.startAnimation(aa); } //位移动画 public void trans(View view){ Animation ta = AnimationUtils.loadAnimation(this, R.anim.trans); iv.startAnimation(ta); } //缩放动画 public void scale(View view){ Animation sa = AnimationUtils.loadAnimation(this, R.anim.scale); iv.startAnimation(sa); } //旋转动画 public void rotate(View view){ Animation ra = AnimationUtils.loadAnimation(this, R.anim.rotate); iv.startAnimation(ra); } //动画组合 public void set(View view){ Animation set = AnimationUtils.loadAnimation(this, R.anim.set); iv.startAnimation(set); } }
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima.sensor" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheima.sensor.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
<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" tools:context=".MainActivity" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:text="@string/hello_world" /> </RelativeLayout>
package com.itheima.sensor; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.Bundle; import android.app.Activity; import android.view.Menu; public class MainActivity extends Activity { private SensorManager sm; private MyListener listener; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sm = (SensorManager) getSystemService(SENSOR_SERVICE); //光线传感器 Sensor sensor = sm.getDefaultSensor(Sensor.TYPE_LIGHT); listener = new MyListener(); sm.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_UI); } private class MyListener implements SensorEventListener{ @Override public void onSensorChanged(SensorEvent event) { float light = event.values[0]; System.out.println("light:"+light); } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } } @Override protected void onDestroy() { sm.unregisterListener(listener); listener = null; super.onDestroy(); } }
方向传感器
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima.sensor" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheima.sensor.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
<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:background="#000000" tools:context=".MainActivity" > <ImageView android:id="@+id/iv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:src="@drawable/zn" /> </RelativeLayout>
package com.itheima.sensor; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.view.animation.Animation; import android.view.animation.RotateAnimation; import android.widget.ImageView; public class MainActivity extends Activity { private SensorManager sm; private MyListener listener; private ImageView iv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sm = (SensorManager) getSystemService(SENSOR_SERVICE); iv = (ImageView) findViewById(R.id.iv); //方向传感器 Sensor sensor = sm.getDefaultSensor(Sensor.TYPE_ORIENTATION); listener = new MyListener(); sm.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_GAME); } private class MyListener implements SensorEventListener{ float lastangle = 0; @Override public void onSensorChanged(SensorEvent event) { // 0=North, 90=East, 180=South, 270=West float angle = event.values[0];//手机与正北方向的夹角 System.out.println("angle:"+angle); RotateAnimation ra = new RotateAnimation(-lastangle, angle, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); iv.startAnimation(ra); lastangle = angle; } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } } @Override protected void onDestroy() { sm.unregisterListener(listener); listener = null; super.onDestroy(); } }
退出应用程序
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima.exit" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheima.exit.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
package com.itheima.exit; import android.app.Activity; import android.app.AlertDialog; import android.app.AlertDialog.Builder; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.os.Bundle; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public void onBackPressed() { AlertDialog.Builder builder = new Builder(this); builder.setTitle("提醒"); builder.setMessage("确定退出当前应用程序吗?"); builder.setPositiveButton("立刻退出", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { finish();//关闭当前的activity。 //把自己的进程杀死。 //自杀的方法。 android.os.Process.killProcess(android.os.Process.myPid()); //System.exit(0); } }); builder.setNegativeButton("取消", null); builder.show(); } }
杀死进程
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima.killother" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheima.killother.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
<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" tools:context=".MainActivity" > <EditText android:hint="请输入要杀死的进程包名" android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/et_packname" /> <Button android:onClick="click" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:text="杀死进程" /> </RelativeLayout>
package com.itheima.killother; import android.app.Activity; import android.app.ActivityManager; import android.os.Bundle; import android.view.View; import android.widget.EditText; public class MainActivity extends Activity { private ActivityManager am;//相当于进程管理器 private EditText et_packname; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); am = (ActivityManager) getSystemService(ACTIVITY_SERVICE); et_packname = (EditText) findViewById(R.id.et_packname); } public void click(View view){ String packname = et_packname.getText().toString().trim(); am.killBackgroundProcesses(packname); //杀死空进程 和 后台进程 } }
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima.htmlui" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <uses-permission android:name="android.permission.INTERNET"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheima.htmlui.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
<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" tools:context=".MainActivity" > <!-- 嵌入的浏览器 --> <WebView android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/wv" /> </RelativeLayout>
package com.itheima.htmlui; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.view.Window; import android.webkit.WebView; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE);//去除标题栏 setContentView(R.layout.activity_main); WebView wv = (WebView) findViewById(R.id.wv); wv.loadUrl("http://192.168.101.138:2222/hello.c"); } }
Apktool
Apktool d xxx.apk
Android逆向助手_v2.0
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima.apkinstaller" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheima.apkinstaller.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
<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" tools:context=".MainActivity" > <EditText android:hint="请输入安装apk文件的路径" android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/et_path" /> <Button android:onClick="click" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:text="安装" /> </RelativeLayout>
package com.itheima.apkinstaller; import java.io.File; import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.View; import android.widget.EditText; public class MainActivity extends Activity { private EditText et_path; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); et_path = (EditText) findViewById(R.id.et_path); } public void click(View view){ String path = et_path.getText().toString().trim(); //安装apk // <intent-filter> // <action android:name="android.intent.action.VIEW" /> // <category android:name="android.intent.category.DEFAULT" /> // <data android:scheme="content" /> // <data android:scheme="file" /> // <data android:mimeType="application/vnd.android.package-archive" /> // </intent-filter> Intent intent = new Intent(); intent.setAction("android.intent.action.VIEW"); intent.addCategory("android.intent.category.DEFAULT"); intent.setDataAndType(Uri.fromFile(new File(path)), "application/vnd.android.package-archive"); startActivity(intent); } }
【黑马Android】(11)音乐播放器/视频播放器/照相机/常见对话框/notification通知/样式和主题/帧动画/传感器/应用程序反编译与安装
标签:
原文地址:http://blog.csdn.net/waldmer/article/details/51493728