13、通知
在活动里创建通知的场景还是比较少的,因为一般只有当程序进入到后台的时候我们才需要使用通知
getSystemService()方法接收一个字符串参数用于确定获取系统的 哪个 服务
Notification 的有参构造函数接收三个参数,
第一个参数用于指定通知的图标
第二个参数用于指定通知的 ticker 内容,当通知刚被创建的时候,它会在系统的状态栏一闪而过,属于一种瞬时的提示信息。
第三个参数用于指定通知被创建的时间,以毫秒为单位,当下拉系统状态栏时,这里指定的时间会显示在相应的通知上。
Notification 的 setLatestEventInfo()方法就可以给通知设置一个标准的布局。
这个方法接收四个参数,第一个参数是 Context。
第二个参数用于指定通知的标题内容,下拉系统状态栏就可以看到这部分内容。
第三个参数用于指定通知的正文内容,同样下拉系统状态栏就可以看到这部分内容。
第四个参数我们暂时还用不到,可以先传入 null
notify()方法接收两个参数,第一个参数是 id,要保证为每个通知所指定的 id 都是不同的。
老写法:
NotificationManager manager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); Notification notification = new Notification(R.drawable.ic_launcher, "This is ticker text", System.currentTimeMillis()); notification.setLatestEventInfo(this, "This is content title","This is content text", null); manager.notify(1, notification);
新写法:
Notification.Builder builder1 = new Notification.Builder(MainActivity.this); builder1.setSmallIcon(R.drawable.advise2); //设置图标 builder1.setTicker("显示第二个通知"); builder1.setContentTitle("通知"); //设置标题 builder1.setContentText("点击查看详细内容"); //消息内容 builder1.setWhen(System.currentTimeMillis()); //发送时间 builder1.setDefaults(Notification.DEFAULT_ALL); //设置默认的提示音,振动方式,灯光 builder1.setAutoCancel(true);//打开程序后图标消失 //跳转 Intent intent =new Intent (MainActivity.this,NotificationActivity.class); PendingIntent pendingIntent =PendingIntent.getActivity(MainActivity.this, 0, intent, 0); builder1.setContentIntent(pendingIntent); Notification notification1 = builder1.build(); notificationManager.notify(124, notification1); // 通过通知管理器发送通知
Intent 更加倾向于去立即执行某个动作,而 PendingIntent 更加倾向于在某个合适的时机去执行某个动作。所以,也可以把 PendingIntent 简单地理解为延迟执行的 Intent。
可以根据需求来选择是使用 getActivity()方法、getBroadcast()方法、还是 getService()方法。
第一个参数依旧是 Context。第二个参数一般用不到,通常都是传入 0 即可。第三个参数是一个 Intent 对象,我们可以通过这个对象构建出 PendingIntent 的“意图”。第四个参数用于确定 PendingIntent 的行为,有FLAG_ONE_SHOT、FLAG_NO_CREATE、FLAG_CANCEL_CURRENT 和 FLAG_UPDATE_CURRENT 这四种值可选
取消通知:
接收通知活动NotificationActivity onCreate()中:
NotificationManager manager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); manager.cancel(124);
setLatestEventInfo方法不存在:
低于API Level 11版本,也就是Android 2.3.3以下的系统中,setLatestEventInfo()函数是唯一的实现方法。
notification.setLatestEventInfo(context, title, message, pendingIntent);
高于API Level 11,低于API Level 16 (Android 4.1.2)版本的系统中,可使用Notification.Builder来构造函数。但要使用getNotification()来使notification实现。此时,前面版本在notification中设置的Flags,icon等属性都已经无效,要在builder里面设置。
Notification.Builder builder = new Notification.Builder(context) .setAutoCancel(true) .setContentTitle("title") .setContentText("describe") .setContentIntent(pendingIntent) .setSmallIcon(R.drawable.ic_launcher) .setWhen(System.currentTimeMillis()) .setOngoing(true); notification=builder.getNotification();
高于API Level 16的版本,就可以用Builder和build()函数来配套的方便使用notification了。
Notification notification = new Notification.Builder(context) .setAutoCancel(true) .setContentTitle("title") .setContentText("describe") .setContentIntent(pendingIntent) .setSmallIcon(R.drawable.ic_launcher) .setWhen(System.currentTimeMillis()) .build();
【接收短信】
声明权限:
<uses-permission android:name="android.permission.RECEIVE_SMS" />
当手机接收到一条短信的时候,系统会发出一条值为
android.provider.Telephony.SMS_RECEIVED 的广播,这条广播里携带着与短信相关的所有
数据。每个应用程序都可以在广播接收器里对它进行监听,收到广播时再从中解析出短信的内容即可
class MessageReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Bundle bundle = intent.getExtras(); 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 += message.getMessageBody(); 、 } sender.setText(address); content.setText(fullMessage); } } //MainActivity中动态注册接收器广播: receiveFilter = new IntentFilter(); receiveFilter.addAction("android.provider.Telephony.SMS_RECEIVED"); messageReceiver = new MessageReceiver(); registerReceiver(messageReceiver, receiveFilter); protected void onDestroy() { super.onDestroy(); unregisterReceiver(messageReceiver); }
拦截短信:
你会发现在系统状态栏出现了一个通知图标,这个通知图标是由 Android自带的短信程序产生的。也就是说当短信到来时,不仅我们的程序会接收到这条短信,系统的短信程序同样也会收到。同样一条短信被重复接收两遍就会造成比较差的用户体验
系统发出的短信广播正是一条有序广播,所以可以拦截。
步骤:
一是提高 MessageReceiver 的优先级,让它能够先于系统短信程序接收到短信广播。
二是在 onReceive()方法中调用 abortBroadcast()方法
发送短信:
发送短信也是需要声明权限的
<uses-permission android:name="android.permission. SEND_SMS" />
法1:
万能的intent能够帮我们做很多事,只要你有“意图”它就会满足你。
private void sendMessageViaSystem() { Uri uri = Uri.parse("smsto:"+etNumber.getText()); Intent intent = new Intent(Intent.ACTION_VIEW,uri); intent.putExtra("sms_body",etMessage.getText().toString()); //intent.setType("rnd"); startActivity(intent); }
法2:
SmsManager smsManager = SmsManager.getDefault(); smsManager.sendTextMessage(to.getText().toString(), null, msgInput.getText().toString(), null, null); //sendTextMessage()方法接收五个参数, public void sendTextMessage( String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent)
其中第一个参数用于指定接收人的手机号码,
第三个参数用于指定短信的内容
第四个参数来对短信的发送状态进行监控
后两个参数是PendingIntent,我们要监听发送状态就要用到这两个参数。与这个两个PendingIntent联系的是两个Broadcast Receiver
发送后提示发送成功:
1、动态注册 sendFilter = new IntentFilter(); sendFilter.addAction("SENT_SMS_ACTION"); sendStatusReceiver = new SendStatusReceiver(); registerReceiver(sendStatusReceiver, sendFilter); 2、发送短信 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); 3、广播接收器 class SendStatusReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (getResultCode() == RESULT_OK) { // 短信发送成功 Toast.makeText(context, "Send succeeded",Toast.LENGTH_LONG).show(); } else { // 短信发送失败 Toast.makeText(context, "Send failed",Toast.LENGTH_LONG).show(); } } }
发送接收短信示例:
https://blog.csdn.net/lincyang/article/details/47686693
http://www.androidchina.net/3316.html
调用摄像头拍照
点击按钮后拍照,然后拍完后调用剪裁,剪裁完成后放入按钮下图片控件中。
调 用 Environment 的getExternalStorageDirectory()方法获取到的就是手机 SD 卡的根目录
涉及到了向 SD卡中写数据的操作,需要声明权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); takePhoto = (Button) findViewById(R.id.take_photo); picture = (ImageView) findViewById(R.id.picture); takePhoto.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // 创建File对象,用于存储拍照后的图片 File outputImage = new File(Environment.getExternalStorageDirectory(), "tempImage.jpg"); try { if (outputImage.exists()) { outputImage.delete(); } outputImage.createNewFile(); } catch (IOException e) { e.printStackTrace(); } //调用摄像头拍照 //将 File 对象转换成 Uri 对象,这个 Uri 对象标识着 output_image.jpg 这张图片的唯一地址 imageUri = Uri.fromFile(outputImage); Intent intent = new Intent("android.media.action. IMAGE_CAPTURE"); //指定图片的输出地址 intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); 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 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; } }
从相册选取照片剪裁:
chooseFromAlbum.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // 创建File对象,用于存储选择的照片 File outputImage = new File(Environment.getExternalStorageDirectory(), "output_image.jpg"); try { if (outputImage.exists()) { outputImage.delete(); } 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); } });
播放音频、视频