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

使用通知

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

通知的基本用法

新建一个项目, 修改 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);
    }
}

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

    

调用摄像头和相册

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

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

<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;
        }
    }
}

最后, 添加权限:


播放多媒体文件

播放音频

使用 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();
        }
    }
}

最后, 添加权限:

    

播放视频

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

<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();//释放资源
        }
    }
}

添加权限:

    

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

你可能感兴趣的:(Android)