《第一行代码》读书笔记(八)----多媒体

来源:互联网 发布:vip域名被百度收录 编辑:程序博客网 时间:2024/06/04 22:24

使用通知

需求:当某个应用程序希望向用户发送一些提示信息又不在前台运行时.

通知的基本用法

新建一个项目, 修改 activity_main.xml, 添加一个按钮, 用来弹出通知.
新建布局文件 notification_layout.xml, 作为点击通知后出现的活动的布局. 相对布局, 含有一个局中显示的 TextView.
新建活动 NotificationActivity , 代码:

public class NotificationActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.notification_layout);        //通知图标消失        NotificationManager manager =                 (NotificationManager) getSystemService(NOTIFICATION_SERVICE);        manager.cancel(1);//1为通知的id    }}

别忘了在 清单文件 中注册这个活动.

然后修改 MainActivity 的代码:

public class MainActivity extends Activity implements View.OnClickListener {    private Button sendNotice;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        sendNotice = (Button) findViewById(R.id.send_notice);        sendNotice.setOnClickListener(this);    }    @Override    public void onClick(View v) {        switch (v.getId()) {            case R.id.send_notice:                NotificationManager manager =                        (NotificationManager) getSystemService(NOTIFICATION_SERVICE);                Notification notification = new Notification(R.mipmap.ic_launcher,                        "This is ticker text", System.currentTimeMillis());                Intent intent = new Intent(this, NotificationActivity.class);                PendingIntent pi = PendingIntent.getActivity(this, 0,                        intent, PendingIntent.FLAG_CANCEL_CURRENT);                notification.setLatestEventInfo(this, "This is content title",                        "This is content text", pi);                manager.notify(1, notification);                break;            default:                break;        }    }}

可见, 创建通知的步骤:
* 调用 Context 的 getSystemService() 方法得到 NotificationManager 对象, 来对通知进行管理.
* 创建一个 Notification 对象. 该类的有参构造函数需要三个参数, 第一个指定通知的图标, 传入图片id, 第二个指定通知的 ticker 内容, 第三个指定通知的创建时间, 以毫秒为单位.
* 对通知的布局进行设定, 调用 Notification 的 setLatestEventInfo() 方法, 该方法接受四个参数, 第一个 Context, 第二个指定标题内容, 第三个指定通知正文内容, 第四个指定 PendingIntent 对象.
* PendingIntent, 可理解为延迟指定的 Intent. 提供了几个静态方法用于获取它的实例, 比如 getActivity(), getBroadcast(), getService(). 这几个方法要的参数都一样, 第一个是 Context, 第二个是请求码, 一般传入0, 第三个是 Intent 对象, 使用这个Intent对象来构建出 PendingIntent 的”意图”. 第四个参数用于确定 PendingIntent 的行为, 有四个值可以选: FLAG_ONE_SHOT, FLAG_NO_CREATE, FLAG_CANCEL_CURRENT, FLAG_UPDATE_CURRENT.
* 将通知显示出来. 调用 NotificationManager 的 notify() 方法. 该方法两个参数, 第一个是id, 第二个是 Notification 对象.

通知的高级技巧

  • 播放声音
Uri soundUri = Uri.fromFile(new File("/system/media/audio/ringtones/Basic_tone.ogg"));notification.sound = soundUri;
  • 让手机震动
    使用 vibrate属性. 这个一个长整形数组, 用于设置手机静止和震动的时常, 以毫秒为单位. 下标为0的值表示手机静止的时长, 下标为1的表示震动的时长, 下标为2的又表示静止的时长, 以此类推. 例如, 如果想要手机在通知到来的时候立刻震动1秒, 然后静止1秒, 再震动1秒, 代码:
long[] vibrates = {0, 1000, 1000, 1000};notification.vibrate = vibrates;
  • 控制手机的LED灯
    ledARGB: 控制LED灯的颜色
    ledOnMS:指定LED灯亮起的时长
    ledOffMS:指定LED灯暗去的时长
    flags:指定通知的一些行为
    例如, 想要实现LED灯以绿色的灯光一闪一闪的效果:
notification.ledARGB = Color.GREEN;notification.ledOnMS = 1000;notification.ledOffMS = 1000;notification.flags = Notification.FLAG_SHOW_LIGHTS;

如果不想进行这么多设置, 可以直接使用通知的默认效果, 会根据当前手机的环境来决定播放什么铃声以及如何震动, 写法:

notification.defaults = Notification.DEAFAULT_ALL;

接受和发送短信

接受短信

新建一个项目, 修改布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <LinearLayout        android:layout_width="match_parent"        android:layout_height="50dp">        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="center_vertical"            android:padding="10dp"            android:text="From" />        <TextView            android:id="@+id/sender"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="center_vertical" />    </LinearLayout>    <LinearLayout        android:layout_width="match_parent"        android:layout_height="50dp">        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="center_vertical"            android:padding="10dp"            android:text="Cotent" />        <TextView            android:id="@+id/content"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="center_vertical" />    </LinearLayout></LinearLayout>

修改 MainActivity , 利用广播机制接受短信:

public class MainActivity extends Activity {    private TextView sender;    private TextView content;    private IntentFilter receiveFilter;    private MessageReceiver messageReceiver;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        sender = (TextView) findViewById(R.id.sender);        content = (TextView) findViewById(R.id.content);        receiveFilter = new IntentFilter();        receiveFilter.addAction("android.provider.Telephony.SMS_RECEIVED");        messageReceiver = new MessageReceiver();        registerReceiver(messageReceiver, receiveFilter);    }    class MessageReceiver extends BroadcastReceiver {        @Override        public void onReceive(Context context, Intent intent) {            Bundle bundle = intent.getExtras();            //使用pdu密钥来提取一个 SMS pdus 数组, 每一个pdu都表示一条短信消息            Object[] pdus = (Object[]) bundle.get("pdus");            SmsMessage[] messages = new SmsMessage[pdus.length];            for (int i = 0; i < messages.length; i++) {                messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);            }            //获取发送方号码            String address = messages[0].getOriginatingAddress();            //获取短信内容            String fullMessage = "";            for (SmsMessage message : messages) {                fullMessage = fullMessage + message.getMessageBody();            }            sender.setText(address);            content.setText(fullMessage);        }    }    @Override    protected void onDestroy() {        super.onDestroy();        unregisterReceiver(messageReceiver);    }}

最后, 在清单文件中声明权限:

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

拦截短信

很简单, 只需要两步.
onCreate()方法中, 给 receiveFilter添加好动作之后加入:

receiveFilter.setPriority(100);

在内部类的onReceive()方法中, 最后添加拦截广播的代码:

abortBroadcast();

发送短信

修改 activity_main.xml :

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <LinearLayout        android:layout_width="match_parent"        android:layout_height="50dp">        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="center_vertical"            android:padding="10dp"            android:text="From" />        <TextView            android:id="@+id/sender"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="center_vertical" />    </LinearLayout>    <LinearLayout        android:layout_width="match_parent"        android:layout_height="50dp">        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="center_vertical"            android:padding="10dp"            android:text="Cotent" />        <TextView            android:id="@+id/content"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="center_vertical" />    </LinearLayout>    <LinearLayout        android:layout_width="match_parent"        android:layout_height="50dp">        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="center_vertical"            android:padding="10dp"            android:text="To:" />        <EditText            android:id="@+id/to"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_gravity="center_vertical"            android:layout_weight="1" />    </LinearLayout>    <LinearLayout        android:layout_width="match_parent"        android:layout_height="50dp">        <EditText            android:id="@+id/msg_input"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_gravity="center_vertical"            android:layout_weight="1" />        <Button            android:id="@+id/send"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="center_vertical"            android:text="Send" />    </LinearLayout></LinearLayout>

修改 MainActivity :

public class MainActivity extends Activity {    private TextView sender;    private TextView content;    private IntentFilter receiveFilter;    private MessageReceiver messageReceiver;    private EditText to;    private EditText msgInput;    private Button send;    private IntentFilter sendFilter;    private SendStatusReceiver sendStatusReceiver;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        sender = (TextView) findViewById(R.id.sender);        content = (TextView) findViewById(R.id.content);        receiveFilter = new IntentFilter();        receiveFilter.addAction("android.provider.Telephony.SMS_RECEIVED");        receiveFilter.setPriority(100);        messageReceiver = new MessageReceiver();        registerReceiver(messageReceiver, receiveFilter);        to = (EditText) findViewById(R.id.to);        msgInput = (EditText) findViewById(R.id.msg_input);        send = (Button) findViewById(R.id.send);        sendFilter = new IntentFilter();        sendFilter.addAction("SENT_SMS_ACTION");        sendStatusReceiver = new SendStatusReceiver();        registerReceiver(sendStatusReceiver, sendFilter);        send.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                SmsManager smsManager = SmsManager.getDefault();                Intent sentIntent = new Intent("SENT_SMS_ACTION");                PendingIntent pi =                        PendingIntent.getBroadcast(MainActivity.this, 0, sentIntent, 0);                smsManager.sendTextMessage(to.getText().toString(), null,                        msgInput.getText().toString(), pi, null);            }        });    }    class MessageReceiver extends BroadcastReceiver {        @Override        public void onReceive(Context context, Intent intent) {            Bundle bundle = intent.getExtras();            //使用pdu密钥来提取一个 SMS pdus 数组, 每一个pdu都表示一条短信消息            Object[] pdus = (Object[]) bundle.get("pdus");            SmsMessage[] messages = new SmsMessage[pdus.length];            for (int i = 0; i < messages.length; i++) {                messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);            }            //获取发送方号码            String address = messages[0].getOriginatingAddress();            //获取短信内容            String fullMessage = "";            for (SmsMessage message : messages) {                fullMessage = fullMessage + message.getMessageBody();            }            sender.setText(address);            content.setText(fullMessage);            abortBroadcast();//拦截广播        }    }    class SendStatusReceiver extends BroadcastReceiver {        @Override        public void onReceive(Context context, Intent intent) {            if (getResultCode() == RESULT_OK) {                Toast.makeText(context, "Send succeeded", Toast.LENGTH_SHORT).show();            } else {                Toast.makeText(context, "Send failed", Toast.LENGTH_SHORT).show();            }        }    }    @Override    protected void onDestroy() {        super.onDestroy();        unregisterReceiver(messageReceiver);        unregisterReceiver(sendStatusReceiver);    }}

别忘了最后添加发送短信的权限:

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

调用摄像头和相册

调用摄像头拍照并从相册中选取照片

新建一个项目, 修改布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <Button        android:id="@+id/take_photo"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="Take Photo" />    <Button        android:id="@+id/choose_from_album"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="Choose From Album" />    <ImageView        android:id="@+id/picture"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_gravity="center_horizontal" /></LinearLayout>

修改 MainActivity , 加入逻辑:

public class MainActivity extends Activity {    //定义 startActivityForResult 的请求码    public static final int TAKE_PHOTO = 1;    public static final int CROP_PHOTO = 2;    private Button takePhoto;    private Button chooseFromeAlbum;    private ImageView picture;    private Uri imageUri;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        takePhoto = (Button) findViewById(R.id.take_photo);        chooseFromeAlbum = (Button) findViewById(R.id.choose_from_album);        picture = (ImageView) findViewById(R.id.picture);        takePhoto.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                //创建 File 对象, 用于存储拍照后的图片, 存储在 SD卡根目录下                File outputImage =                        new File(Environment.getExternalStorageDirectory(), "output_image.jpg");                if (outputImage.exists()) {                    outputImage.delete();                }                try {                    outputImage.createNewFile();                } catch (IOException e) {                    e.printStackTrace();                }                imageUri = Uri.fromFile(outputImage);                Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");                intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);                startActivityForResult(intent, TAKE_PHOTO);            }        });        chooseFromeAlbum.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                File outputImage =                        new File(Environment.getExternalStorageDirectory(), "output_image.jpg");                if (outputImage.exists()) {                    outputImage.delete();                }                try {                    outputImage.createNewFile();                } catch (IOException e) {                    e.printStackTrace();                }                imageUri = Uri.fromFile(outputImage);                Intent intent = new Intent("android.intent.action.GET_CONTENT");                intent.setType("image/*");                intent.putExtra("crop", true);                intent.putExtra("scale", true);                intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);                startActivityForResult(intent, CROP_PHOTO);            }        });    }    @Override    protected void onActivityResult(int requestCode, int resultCode, Intent data) {        switch (requestCode) {            case TAKE_PHOTO:                if (resultCode == RESULT_OK) {                    Intent intent = new Intent("com.android.camera.action.CROP");                    intent.setDataAndType(imageUri, "image/*");                    intent.putExtra("scale", true);                    intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);                    startActivityForResult(intent, CROP_PHOTO);                }                break;            case CROP_PHOTO:                if (resultCode == RESULT_OK) {                    try {                        Bitmap bitmap = BitmapFactory.decodeStream                                (getContentResolver().openInputStream(imageUri));                        picture.setImageBitmap(bitmap);//裁剪后的照片显示出来                    } catch (FileNotFoundException e) {                        e.printStackTrace();                    }                }                break;            default:                break;        }    }}

最后, 添加权限:

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

播放多媒体文件

播放音频

使用 MediaPlayer 来实现.
新建一个项目, 修改 activity_main.xml :

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent">    <Button        android:id="@+id/play"        android:layout_width="0dp"        android:layout_height="wrap_content"        android:layout_weight="1"        android:text="Play" />    <Button        android:id="@+id/pause"        android:layout_width="0dp"        android:layout_height="wrap_content"        android:layout_weight="1"        android:text="Pause" />    <Button        android:id="@+id/stop"        android:layout_width="0dp"        android:layout_height="wrap_content"        android:layout_weight="1"        android:text="Stop" /></LinearLayout>

修改 MainActivity :

public class MainActivity extends Activity implements View.OnClickListener {    private Button play;    private Button pause;    private Button stop;    private MediaPlayer mediaPlayer = new MediaPlayer();    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        play = (Button) findViewById(R.id.play);        pause = (Button) findViewById(R.id.pause);        stop = (Button) findViewById(R.id.stop);        play.setOnClickListener(this);        pause.setOnClickListener(this);        stop.setOnClickListener(this);        initMediaPlayer();//初始化    }    private void initMediaPlayer() {        try {            File file = new File(Environment.getExternalStorageDirectory(), "1.mp3");            mediaPlayer.setDataSource(file.getPath());            mediaPlayer.prepare();        } catch (Exception e) {            e.printStackTrace();        }    }    @Override    public void onClick(View v) {        switch (v.getId()) {            case R.id.play:                if (!mediaPlayer.isPlaying()) {                    mediaPlayer.start();                }                break;            case R.id.pause:                if (mediaPlayer.isPlaying()) {                    mediaPlayer.pause();                }                break;            case R.id.stop:                if (mediaPlayer.isPlaying()) {                    mediaPlayer.reset();                    initMediaPlayer();                }                break;            default:                break;        }    }    @Override    protected void onDestroy() {        super.onDestroy();        if (mediaPlayer != null) {            mediaPlayer.stop();            mediaPlayer.release();        }    }}

最后, 添加权限:

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

播放视频

新建一个项目, 布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <VideoView        android:id="@+id/video_view"        android:layout_width="match_parent"        android:layout_height="370dp" />    <LinearLayout        android:layout_width="match_parent"        android:layout_height="match_parent"        android:orientation="horizontal">        <Button            android:id="@+id/play"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:text="Play" />        <Button            android:id="@+id/pause"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:text="Pause" />        <Button            android:id="@+id/replay"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:text="Replay" />    </LinearLayout></LinearLayout>

修改 MainActivity :

public class MainActivity extends Activity implements View.OnClickListener {    private VideoView videoView;    private Button play;    private Button pause;    private Button replay;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        play = (Button) findViewById(R.id.play);        pause = (Button) findViewById(R.id.pause);        replay = (Button) findViewById(R.id.replay);        videoView = (VideoView) findViewById(R.id.video_view);        play.setOnClickListener(this);        pause.setOnClickListener(this);        replay.setOnClickListener(this);        initVideoPath();    }    private void initVideoPath() {        File file = new File(Environment.getExternalStorageDirectory(), "movie.3gp");        videoView.setVideoPath(file.getPath());//指定视频文件的路径    }    @Override    public void onClick(View v) {        switch (v.getId()) {            case R.id.play:                if (!videoView.isPlaying()) {                    videoView.start();                }                break;            case R.id.pause:                if (videoView.isPlaying()) {                    videoView.pause();                }                break;            case R.id.replay:                if (videoView.isPlaying()) {                    videoView.resume();                }                break;        }    }    @Override    protected void onDestroy() {        super.onDestroy();        if (videoView != null) {            videoView.suspend();//释放资源        }    }}

添加权限:

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

注意, 其实 VideoView只是对 MediaPlayer 进行了很好的封装, 它的背后仍然是使用 MediaPlayer 来对视频文件进行控制的. 而且, VideoView 并不是一个万能的视频播放工具类, 在视频格式和播放效率都存在不足. 对于播放一些游戏的片头动画或者某个应用的视频宣传, 使用 VideoView 还是比较靠谱的.

0 0