例子:
布局文件,这边很简单的,就放一个Button和一个ImageView,Button用来启动拍照图片并截图,ImageView用来显示截图后的照片,代码如下所示:
<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/btn_photo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Take Photo" />
<ImageView
android:id="@+id/img_photo"
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_gravity="center_horizontal" />
LinearLayout>
Java代码:
package com.test.photo;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import com.test.R;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* Created by Administrator on 2016/5/4 0004.
*/
public class PhotoActivity extends Activity {
private static final int TAKE_PHOTO = 1;
private static final int CROP_PHOTO = 2;
private Button btnPhoto;
private ImageView imgPhoto;
private Uri imgUri;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_photo);
btnPhoto = (Button) findViewById(R.id.btn_photo);
imgPhoto = (ImageView) findViewById(R.id.img_photo);
btnPhoto.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//创建一个File对象,用于存储摄像头拍下的图片,这里命名为outputImg.jpg,并将它存放在手机SD卡的根目录下
//Environment.getExternalStorageDirectory()这个方法就是获取到手机SD卡的根目录
File outputImg = new File(Environment.getExternalStorageDirectory(), "tempImg.jpg");
try {
if (outputImg.exists()) {
outputImg.delete();
}
outputImg.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
//调用Uri.fromFile 将File对象转化成Uri对象,这个Uri对象标识着outputImg.jpg这张图片的唯一地址
imgUri = Uri.fromFile(outputImg);
//构建Intent对象,Intent的action指定为android.media.action.IMAGE_CAPTURE表示使用系统的拍照功能
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
//调用Intent的putExtra指定图片的输出地址,这边为刚刚得到的Uri(即imgUri)对象
intent.putExtra(MediaStore.EXTRA_OUTPUT, imgUri);
startActivityForResult(intent, TAKE_PHOTO); //启动活动
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case TAKE_PHOTO:
if (resultCode == RESULT_OK) {
//构建Intent对象,Intent的action指定为com.android.camera.action.CROP 表示使用系裁剪图片
Intent intent = new Intent("com.android.camera.action.CROP");
//查看类型为image的数据
intent.setDataAndType(imgUri, "image/*");
//设置该图片可缩放
intent.putExtra("scale", true);
//调用Intent的putExtra指定图片的输出地址,这边为刚刚得到的Uri(即imgUri)对象
intent.putExtra(MediaStore.EXTRA_OUTPUT, imgUri);
startActivityForResult(intent, CROP_PHOTO);//启动裁剪程序
}
break;
case CROP_PHOTO:
if (resultCode == RESULT_OK) {
try {
Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imgUri));
imgPhoto.setImageBitmap(bitmap);//将裁剪后的图片显示出来
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
break;
}
}
}
AndroidManifest.xml文件中声明权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
例子:在上一个例子的基础上加一下内容,
布局文件:
……
通知(Notification)是Android系统中比较有特色的一个功能,当某个应用程序希望向用户发出一些提示信息,而该应用程序又不在前台运行时,就可以借助通知来实现。发出一条通知后,手机最上方的状态栏中会显示一个通知的图标,下拉状态栏后可以看到通知的详细内容。
通知的用法还是比较灵活的,既可以在活动里创建,也可以在广播接收器里创建,当然还可以在服务里创建。相比于广播接收器和服务,在活动里创建通知的场景还是比较少的,因为一般只有当程序进入到后台的时候我们才需要使用通知。
不过,无论是在哪里创建通知,整体的步骤都是相同的。
例子:
//NotificationManager用于管理通知,它也是一个系统服务,调用Context的getSystemService()方法获取到,getSystemService()方法接收一个字符串参数用于确定获取系统的哪个服务,这里我们传入 Context.NOTIFICATION_SERVICE即可。
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
//点击通知后,就不显示通知了。这里传入一个参数是id,就是我们创建通知的时候指定的id
manager.cancel(1);
//Notification对象用于存储通知所需的各种信息,我们可以使用它的有参构造函数来进行创建。Notification的有参构造函数接收三个参数,第一个参数用于指定通知的图标,第二个参数用于指定通知的ticker内容,当通知刚被创建的时候,它会在系统的状态栏一闪而过,属于一种瞬时的提示信息。第三个参数用于指定通知被创建的时间,以毫秒为单位,当下拉系统状态栏时,这里指定的时间会显示在相应的通知上。
Notification notification = new Notification(R.mipmap.ic_launcher,"This is ticker text",System.currentTimeMillis());
//创建一个Intent意图,指明这个通知要做的事情
Intent intent = new Intent(this, NotificationActivity.class);
//PendingIntent从名字上看起来就和Intent有些类似,它们之间也确实存在着不少共同点。比如它们都可以去指明某一个“意图”,都可以用于启动活动、启动服务以及发送广播等。不同的是,Intent更加倾向于去立即执行某个动作,而PendingIntent更加倾向于在某个合适的时机去执行某个动作。所以,也可以把PendingIntent简单地理解为延迟执行的Intent。
//PendingIntent的用法同样很简单,它主要提供了几个静态方法用于获取PendingIntent的实例,可以根据需求来选择是使用getActivity()方法、getBroadcast()方法、还是getService()方法。这几个方法所接收的参数都是相同的,
//第一个参数依旧是Context,
//第二个参数一般用不到,通常都是传入0即可。
//第三个参数是一个Intent对象,我们可以通过这个对象构建出PendingIntent的“意图”。
//第四个参数用于确定PendingIntent的行为,有FLAG_ONE_SHOT、FLAG_NO_CREATE、FLAG_CANCEL_CURRENT和FLAG_UPDATE_ CURRENT这四种值可选,每种值的含义你可以查看文档,我就不一一进行解释了。
PendingIntent pi = PendingIntent.getActivity(this, 0, intent,PendingIntent.FLAG_CANCEL_CURRENT);
//调用Notification的setLatestEventInfo()方法就可以给通知设置一个标准的布局。这个方法接收四个参数,第一个参数是Context,第二个参数用于指定通知的标题内容,下拉系统状态栏就可以看到这部分内容。第三个参数用于指定通知的正文内容,同样下拉系统状态栏就可以看到这部分内容。第四个参数就是我们创建好的PendingIntent。
notification.setLatestEventInfo(this, "This is content title", "This is content text", pi);
//调用NotificationManager的notify()方法就可以让通知显示出来了。notify()方法接收两个参数,第一个参数是id,要保证为每个通知所指定的id都是不同的。第二个参数则是Notification对象,这里直接将我们刚刚创建好的Notification对象传入即可。
manager.notify(1,notification);
1、在通知发出的时候播放一段音频:
//在指定音频文件的时候还需要先获取到音频文件对应的URI
Uri soundUri = Uri.fromFile(new File("/system/media/audio/ringtones/Basic_tone.ogg"));
notification.sound = soundUri;
2、在通知到来的时候让手机进行振动:
//vibrate是一个长整型的数组,用于设置手机静止和振动的时长,以毫秒为单位。下标为0的值表示手机静止的时长,下标为1的值表示手机振动的时长,下标为2的值又表示手机静止的时长,以此类推。所以,如果想要让手机在通知到来的时候立刻振动1秒,然后静止1秒,再振动1秒。
long[] vibrates = {0, 1000, 1000, 1000};
notification.vibrate = vibrates;
不过,想要控制手机振动还需要声明权限的。因此,我们还得编辑AndroidManifest.xml文件,加入如下声明:
<uses-permission android:name="android.permission.VIBRATE" />
3、在通知到来时控制手机LED灯的显示:
//ledARGB用于控制LED灯的颜色,一般有红绿蓝三种颜色可选。
notification.ledARGB = Color.GREEN;
//ledOnMS用于指定LED灯亮起的时长,以毫秒为单位。
notification.ledOnMS = 1000;
//ledOffMS用于指定LED灯暗去的时长,也是以毫秒为单位。
notification.ledOffMS = 1000;
//flags可用于指定通知的一些行为,其中就包括显示LED灯这一选项。
notification.flags = Notification.FLAG_SHOW_LIGHTS;
当然,如果你不想进行那么多繁杂的设置,也可以直接使用通知的默认效果,它会根据当前手机的环境来决定播放什么铃声,以及如何振动,写法如下:notification.defaults = Notification.DEFAULT_ALL;
注意,以上所涉及的这些高级技巧都要在手机上运行才能看得到效果,模拟器是无法表现出振动、以及LED灯闪烁等功能的。
接收短信
当手机接收到一条短信的时候,系统会发出一条值为 android.provider.Telephony.SMS_RECEIVED 的广播,这条广播里携带着与短信相关的所有数据。每个应用程序都可以在广播接收器里对它进行监听,收到广播时再从中解析出短信的内容即可。
class MessageReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//从Intent参数中取出了一个Bundle对象
Bundle bundle = intent.getExtras();
//使用pdu密钥来提取一个SMS pdus数组,其中每一个pdu都表示一条短信消息。
Object[] pdus = (Object[]) bundle.get("pdus"); // 提取短信消息
//使用SmsMessage的createFromPdu()方法将每一个pdu字节数组转换为SmsMessage对象
SmsMessage[] messages = new SmsMessage[pdus.length];
for (int i = 0; i < messages.length; i++) {
messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
}
//调用这个对象的getOriginatingAddress()方法就可以获取到短信的发送方号码
String address = messages[0].getOriginatingAddress(); // 获取发送方号码
String fullMessage = "";
//调用getMessageBody() 方法就可以获取到短信的内容,然后将每一个 SmsMessage对象中的短信内容拼接起来,就组成了一条完整的短信。
for (SmsMessage message : messages) {
fullMessage += message.getMessageBody(); // 获取短信内容
}
sender.setText(address);
content.setText(fullMessage);
}
}
我们还需要对它进行注册才能让它接收到短信广播。
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);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(messageReceiver);
}
不过最后我们还需要给程序声明一个接收短信的权限才行,修改 AndroidManifest.xml中的代码:
"android.permission.RECEIVE_SMS" />
拦截短信
public class MainActivity extends Activity {
……
@Override
protected void onCreate(Bundle savedInstanceState) {
……
receiveFilter = new IntentFilter();
receiveFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
receiveFilter.setPriority(100);//设置优先级
messageReceiver = new MessageReceiver();
registerReceiver(messageReceiver, receiveFilter);
}
……
class MessageReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
……
abortBroadcast();//阻止广播的传递
}
}
}
发送短信
权限:
"android.permission. SEND_SMS" />
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);
在Android中播放音频文件一般都是使用MediaPlayer类来实现的,它对多种格式的音频文件提供了非常全面的控制方法,从而使得播放音乐的工作变得十分简单。下表列出了MediaPlayer类中一些较为常用的控制方法。
下面是一个例子:
布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btn_play"
style="@style/audio_btn"
android:text="Play" />
<Button
android:id="@+id/btn_pause"
style="@style/audio_btn"
android:text="Pause" />
<Button
android:id="@+id/btn_stop"
style="@style/audio_btn"
android:text="Stop" />
LinearLayout>
Java代码:
代码运行有错,一直播放不了音乐,待解决~
播放视频文件其实并不比播放音频文件复杂,主要是使用VideoView类来实现的。这个类将视频的显示和控制集于一身,使得我们仅仅借助它就可以完成一个简易的视频播放器。VideoView的用法和MediaPlayer也比较类似,主要有以下常用方法: