使用通知
什么是通知,通知就是下拉手机看到的那些提示信息。
通知的简单用法
在Android 8.0(API26) 后对通知更改了一些内容,以前是通过Notification.Builder(Context context).set…来设置通知的震动、灯光、音效的设置,新内容加了NotificationChannel(通知渠道),通过NotificationChannel来进行震动、灯光、音效的设置,且通知必须添加通知渠道,同样需进行版本判断,否则通知不会被发送。
1.首先创建NotificationManager对象
2.创建NotificationChannel对象,指定id,name,importance(根据这个播放对应的效果),也可以设置相应的震动、音效、如果没设置按默认的importance,调用NotificationManager的createNotificationChannel(NotificationChannel channel)方法
3.通过NotificationCompat.Builder(Context,Notification)对象指定channel并设置通知的各项信息,调用build()方法创建Notification对象,调用NotificationManager的notify(id,Notification)方法
首先创建NotificationManager对象:
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
创建NotificationChannel对象:
String channel_id="voice_channel";
NotificationChannel channel = new NotificationChannel(channel_id,"voice",
NotificationManager.IMPORTANCE_HIGH);
channel.enableVibration(true);
channel.setVibrationPattern(new long[]{0,1000,1000,1000});
channel.enableLights(true);
channel.setLightColor(Color.GREEN);
第一个参数是id,第二个是name,第三个是Importance,其对应的播放效果如下,其中IMPORTANCE_HIGH会弹出横幅(像qq来消息那样)
public static final int IMPORTANCE_NONE = 0;
/**
* Min notification importance: only shows in the shade, below the fold. This should
* not be used with {@link Service#startForeground(int, Notification) Service.startForeground}
* since a foreground service is supposed to be something the user cares about so it does
* not make semantic sense to mark its notification as minimum importance. If you do this
* as of Android version {@link android.os.Build.VERSION_CODES#O}, the system will show
* a higher-priority notification about your app running in the background.
*/
public static final int IMPORTANCE_MIN = 1;
/**
* Low notification importance: shows everywhere, but is not intrusive.
*/
public static final int IMPORTANCE_LOW = 2;
/**
* Default notification importance: shows everywhere, makes noise, but does not visually
* intrude.
*/
public static final int IMPORTANCE_DEFAULT = 3;
/**
* Higher notification importance: shows everywhere, makes noise and peeks. May use full screen
* intents.
*/
public static final int IMPORTANCE_HIGH = 4;
/**
* Unused.
*/
调用NotificationManager的createNotificationChannel(NotificationChannel channel)方法:
manager.createNotificationChannel(channel);
通过NotificationCompat.Builder(Context,Notification)对象指定channel并设置通知的各项信息,调用build()方法创建Notification对象:
Notification notification = new NotificationCompat.Builder(MainActivity.this,channel_id)
.setContentTitle("First notification")
.setContentText("nothing aha fdasfdsafdsafdsafdsfdsfdsfdsfdsfdsfdsfds")
//.setStyle(new NotificationCompat.BigTextStyle().bigText("nothing aha fdasfdsafdsafdsafdsfdsfdsfdsfds fdsf fds fdsf sf sffsdsfdsfdsfds"))
/*.setStyle(new NotificationCompat.BigPictureStyle().bigPicture
(BitmapFactory.decodeResource(getResources(),R.drawable.watermelon)))*/
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))
.setContentIntent(pendingIntent)
//.setPriority(NotificationCompat.PRIORITY_MAX)
//.setAutoCancel(true)
.build();
manager.notify(1,notification); //第一个是id
Builder第一个参数是Context,第二个参数是指定NotificationChannel对象设置震动、音效;
setContentTitle():设置通知栏标题
setContentText():设置通知栏文本
setWhen():指定通知被创建的时间
setSmallIcon():设置小图标
setLargeIcon():设置大图标
要实现通知点击跳转一个活动需要PendingIntent,通过Intent对象创建
Intent intent = new Intent(MainActivity.this,TestActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(MainActivity.this,0,intent,0);
setContentIntent():接收PendingIntent对象执行相应逻辑
setAutoCancel():点击取消通知
也可以显示取消通知:
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.cancel(1); //这里的id就是前面notify()中的id
setStyle():实现长文本、显示大图片
如果是8.0以前的版本只需要创建NotificationManager对象,震动、音效、和其他标题内容都通过NotificationCompat.Builder()的set方法实现,build()创建Notification对象,调用notify()方法。
例子:
package com.example.hankzz.notificationproject;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.support.v4.app.NotificationCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import java.io.File;
public class MainActivity extends AppCompatActivity {
private Button send_notification;
private String channel_id = "voice_channel";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
send_notification = (Button) findViewById(R.id.notification_button);
send_notification.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,TestActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(MainActivity.this,0,intent,0);
if(Build.VERSION.SDK_INT >= 26){
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel channel = new NotificationChannel(channel_id,"voice",
NotificationManager.IMPORTANCE_HIGH);
channel.enableVibration(true);
channel.setVibrationPattern(new long[]{0,1000,1000,1000});
channel.enableLights(true);
channel.setLightColor(Color.GREEN);
manager.createNotificationChannel(channel);
Notification notification = new NotificationCompat.Builder(MainActivity.this,channel_id)
.setContentTitle("First notification")
.setContentText("nothing aha fdasfdsafdsafdsafdsfdsfdsfdsfdsfdsfdsfds")
//.setStyle(new NotificationCompat.BigTextStyle().bigText("nothing aha fdasfdsafdsafdsafdsfdsfdsfdsfds fdsf fds fdsf sf sffsdsfdsfdsfds"))
/*.setStyle(new NotificationCompat.BigPictureStyle().bigPicture
(BitmapFactory.decodeResource(getResources(),R.drawable.watermelon)))*/
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))
.setContentIntent(pendingIntent)
//.setPriority(NotificationCompat.PRIORITY_MAX)
//.setAutoCancel(true)
.build();
manager.notify(1,notification);
}else{
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new NotificationCompat.Builder(MainActivity.this)
.setContentTitle("First notification")
.setContentText("nothing aha")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.build();
}
}
});
}
}
调用摄像头和相册
调用摄像头拍照
1.先创建图片文件放在缓冲目录下并指定名字。
2.通过版本判断,如果版本>7.0,通过FileProvider.getUriForFile()方法将File对象转换成Uri对象;<7.0,直接Uri.fromFile()获取Uri对象。
3.创建Intent对象将action指定为android.media.action.IMAGE_CPATURE,通过putExtra()方法将图片输出到指定uri,调用startActivityForResult()方法启动活动,打开摄像机,后会返回到onActivityResult()方法中可通过requestCode来把图片显示到ImageView中。
同样在AndroidManifest.xml中注册FileProvider
<provider
android:authorities="com.example.hankzz.camereaalbumproject.fileprovider"
android:name="android.support.v4.content.FileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"/>
</provider>
其他详细代码:
private Button photograph_button;
private ImageView photoimage;
private static final int TAKE_PHOTO = 1; //requestCode,根据这个在onActivityResult()中switch case执行显示照片
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
photograph_button = (Button) findViewById(R.id.photograph_button);
photoimage = (ImageView) findViewById(R.id.photo_image);
photograph_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
File outputimage = new File(getExternalCacheDir(),"output_image.jpg");
try {
if(outputimage.exists()){
outputimage.delete();
}
outputimage.createNewFile();
} catch (IOException e) {
e.printStackTrace();
} //创建图片文件
if(Build.VERSION.SDK_INT >= 24){
imageuri = FileProvider.getUriForFile(MainActivity.this,
"com.example.hankzz.camereaalbumproject.fileprovider",outputimage);
}else {
imageuri = Uri.fromFile(outputimage);
} /通过版本判断进行不同的Uri获取
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
intent.putExtra(MediaStore.EXTRA_OUTPUT,imageuri);
startActivityForResult(intent,TAKE_PHOTO); //开启活动,打开照相机
}
});
}
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode){
case TAKE_PHOTO:
try {
Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageuri)); //获取图片
photoimage.setImageBitmap(bitmap); //在ImageView中显示
} catch (FileNotFoundException e) {
e.printStackTrace();
}
break;
default:
break;
}
}
获取相册中照片
1.向用户申请权限,先判断是否有权限,没有申请,在onRequestPermissionsResult()对申请结果进行执行相应事件。
2.创建Intent对象将action指定为android.intent.action.GET_CONTENT,通过putType()设置参数,调用startActivityForResult()方法启动活动,打开相册,后会返回到onActivityResult()方法中可通过requestcode来进行处理图片。
3.获取通过Intent对象的getData()方法获取Uri对象,对不同类型的Uri进行处理通过getCotentResolver().query()方法获取路径,通过路径获取图片给ImageView设置图片。
详细代码:
private Button choose_button;
private ImageView photoimage;
private static final int CHOOSE_PIC = 2;
private Uri imageuri;
protected void onCreate(Bundle savedInstanceState) {
....
choose_button = (Button) findViewById(R.id.choose_button);
choose_button.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
//判断是否有权限
if(ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(MainActivity.this,new
String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1); //申请权限
}else{
openAlbum(); //打开相册
}
}
});
}
private void openAlbum(){
Intent intent = new Intent("android.intent.action.GET_CONTENT");
intent.setType("images/*");
startActivityForResult(intent,CHOOSE_PIC); //启动活动打开相册
}
private String getImagepath(Uri uri,String selection){
String path = null;
Cursor cursor = getContentResolver().query(uri,null,selection,null,null); //通过内容提供器获取图片路径
if(cursor!=null){
while(cursor.moveToNext()){
path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
}
cursor.close();
}
return path;
}
private void displayImage(String imagePath){
if(imagePath!=null){
Bitmap bitmap = BitmapFactory.decodeFile(imagePath); //根据路径获取图片
photoimage.setImageBitmap(bitmap); //在ImageView中显示图片
}else{
Toast.makeText(this,"failed",Toast.LENGTH_SHORT).show();
}
}
private void handleImageOnKitKat(Intent data){
String imagePath = null;
Uri uri = data.getData(); 获取Uri对象
//根据不同类型Uri获取路径
if(DocumentsContract.isDocumentUri(this,uri)){
String docId = DocumentsContract.getDocumentId(uri);
if("com.android.providers.media.documents".equals(uri.getAuthority())){
String id = docId.split(":")[1];
String selection = MediaStore.Images.Media._ID + "=" + id;
imagePath = getImagepath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,selection);
}else if("com.android.providers.downloads.documents".equals(uri.getAuthority())){
Uri contentUri = ContentUris.withAppendedId(Uri.parse("content:" +
"//downloads/public_downloads"),Long.valueOf(docId));
imagePath = getImagepath(contentUri,null); //获取路径
}
}else if("content".equalsIgnoreCase(uri.getScheme())){
imagePath = getImagepath(uri,null); //获取路径
}else if("file".equalsIgnoreCase(uri.getScheme())){
imagePath = uri.getPath(); //获取路径
}
displayImage(imagePath); //在ImageView中显示图片
}
@Override
//根据授权结果执行相应事件
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case 1:
if(grantResults.length>0 && grantResults[0]==PackageManager.PERMISSION_GRANTED){
openAlbum();
}else{
Toast.makeText(this,"you denied the permission",Toast.LENGTH_SHORT).show();
}
break;
default:
break;
}
}
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode){
case TAKE_PHOTO:
...
break;
case CHOOSE_PIC: //如果是打开相册执行以下
handleImageOnKitKat(data);
default:
break;
}
}
播放多媒体文件
播放音频
简单的播放音频文件通过MediaPlayer类实现
1.首先创建MediaPlayer类对象
2.调用MediaPlayer.setDataSource(String path)方法指定音频文件路径,调用Prepare()方法完成准备工作
3.调用start()、pause()、reset()、seekTo()等方法实现相应功能
4.stop()、release()将相关资源释放掉
各方法作用如下:
例子:
package com.example.hankzz.playaudioproject;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.media.MediaPlayer;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.io.File;
import java.io.IOException;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private Button play_button;
private Button pause_button;
private Button reset_button;
private MediaPlayer player = new MediaPlayer();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
play_button = (Button) findViewById(R.id.play_button);
pause_button = (Button) findViewById(R.id.pause_button);
reset_button = (Button) findViewById(R.id.reset_button);
//判断是否向用户申请权限
if(ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)!=
PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this,new String[]
{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
}else{
initPlayer(); //初始化player,就是设置音频路径调用prepare()方法
}
//各个按钮事件
play_button.setOnClickListener(this);
pause_button.setOnClickListener(this);
reset_button.setOnClickListener(this);
}
private void initPlayer(){
/*File file = new File(Environment.getExternalStorageDirectory()+"/netease/cloudmusic/Music",
"dadandme.mp3");*/ //通过路径获取音频文件,Environment.getExternalStorageDirectory()为sd卡根目录
File file = new File("/storage/emulated/0/netease/cloudmusic/Music","dadandme.mp3");
try {
//player.setDataSource(file.getPath()); //通过文件的getPath()方法获取路径,设置路径
player.setDataSource("/storage/emulated/0/netease/cloudmusic/Music/Ghoat.mp3"); //可以直接设置音频路径
player.prepare(); //准备工作
} catch (IOException e) {
e.printStackTrace();
}
}
public void onClick(View v){
switch(v.getId()){
case R.id.play_button: //播放点击事件
if(!player.isPlaying()){
player.start(); //播放音频
}
break;
case R.id.pause_button: //暂停点击事件
if(player.isPlaying()){
player.pause(); //暂停
}
break;
case R.id.reset_button: //重置点击事件
if(player.isPlaying()){
player.reset(); //将player对象重置
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case 1:
if(grantResults.length>0 && grantResults[0]==PackageManager.PERMISSION_GRANTED){
initPlayer();
}else{
Toast.makeText(this,"you denied the permission",Toast.LENGTH_SHORT).show();
}
break;
default:
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if(player!=null){
player.stop();
player.release();
}
}
}
1.要访问手机sd卡中数据需要先向用户申明权限,并做权限处理,别忘了在在AndroidManifest.xml声明权限
2.给MediaPlayer对象player设置音频路径,准备
3.通过按钮点击事件执行播放、暂停、重播的功能
4.销毁player对象
播放视频
只能是简单播放视频,对视频格式和播放效率方面存在较大不足,通过VideoView类实现,VideoView也是一个控件,用于播放视频,因为背后仍然是MediaPlayer对视频文件进行控制,所以各方法类似播放音频。
1.首先创建VideoView类对象,获取布局中的VideoView控件
2.调用VideoView.setVideoPaht(String path)方法指定视频文件路径
3.调用start()、pause()、resume()、seekTo()等方法实现相应功能
4.suspend()将相关资源释放掉
各方法作用如下:
例子:
package com.example.hankzz.playvideoproject;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import android.widget.VideoView;
import java.io.File;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button play_button;
private Button pause_button;
private Button replay_button;
private VideoView myvideoview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
play_button = (Button) findViewById(R.id.play_button);
pause_button = (Button) findViewById(R.id.pause_button);
replay_button = (Button) findViewById(R.id.replay_button);
myvideoview = (VideoView) findViewById(R.id.myvideoview);
//判断是否有权限
if(ContextCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE)!=
PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this,new String[]
{Manifest.permission.WRITE_EXTERNAL_STORAGE},1); //向用户申请权限
}else{
initMyvideoview(); //初始化,设置视频路径
}
//设置按钮事件
play_button.setOnClickListener(this);
pause_button.setOnClickListener(this);
replay_button.setOnClickListener(this);
}
//初始化ViewVideo对象,设置路径
private void initMyvideoview(){
File file = new File(Environment.getExternalStorageDirectory(),"Test.mp4"); //获取文件
myvideoview.setVideoPath(file.getPath()); //通过文件获取路径,设置视频路径
}
public void onClick(View v){
switch(v.getId()){
case R.id.play_button: //播放事件
if(!myvideoview.isPlaying()){
myvideoview.start(); //播放
}
break;
case R.id.pause_button: //暂停事件
if(myvideoview.isPlaying()){
myvideoview.pause(); //暂停
}
break;
case R.id.replay_button: //重新播放
if(myvideoview.isPlaying()){
myvideoview.resume(); //重播
}
break;
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch(requestCode){
case 1:
if(grantResults.length>0 && grantResults[0]==PackageManager.PERMISSION_GRANTED){
initMyvideoview();
}else{
Toast.makeText(this,"you denied the permission",Toast.LENGTH_SHORT).show();
}
break;
default:
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (myvideoview != null) {
myvideoview.suspend(); //销毁ViewVideo对象
}
}
在AndroidManifest.xml声明权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
1.要访问手机sd卡中数据需要先向用户申明权限,并做权限处理,别忘了在在AndroidManifest.xml声明权限
2.给VideoView对象myvideoview设置音频路径
3.通过按钮点击事件执行播放、暂停、重播的功能
4.销毁myvideoview对象