通知的基本用法
package com.example.notificationtest
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.graphics.BitmapFactory
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.core.app.NotificationCompat
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val manager=getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager//获得一个NotificationManager实例,用这个实例添加渠道和消息
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
val channel=NotificationChannel("normal","Normal",NotificationManager.IMPORTANCE_DEFAULT)
manager.createNotificationChannel(channel)
}//第一次执行代码时会构造渠道.
sendNotice.setOnClickListener {
val notification=NotificationCompat.Builder(this,"normal")
.setContentTitle("This is content title")
.setContentText("This is content text")
.setSmallIcon(R.drawable.small_icon)
.setLargeIcon(BitmapFactory.decodeResource(resources,R.drawable.large_icon))
.build()
manager.notify(1,notification)
}//当点击按钮后会生成消息,并且通知.
}
}
上面的通知并不能点进去,因此改进一下,添加一个响应的Activity,并修改上述代码
package com.example.notificationtest
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.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.core.app.NotificationCompat
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val manager=getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager//获得一个NotificationManager实例,用这个实例添加渠道和消息
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
val channel=NotificationChannel("normal","Normal",NotificationManager.IMPORTANCE_DEFAULT)
manager.createNotificationChannel(channel)
}//第一次执行代码时会构造渠道.
sendNotice.setOnClickListener {
val intent=Intent(this,NotificationActivity::class.java)
val pi=PendingIntent.getActivity(this,0,intent,0)
val notification=NotificationCompat.Builder(this,"normal")
.setContentTitle("This is content title")
.setContentText("This is content text")
.setSmallIcon(R.drawable.small_icon)
.setLargeIcon(BitmapFactory.decodeResource(resources,R.drawable.large_icon))
.setContentIntent(pi)
.setAutoCancel(true)
.build()
manager.notify(1,notification)
}//当点击按钮后会生成消息,并且通知.
}
}
通知中显示长文本
在消息构建的代码处加上
.setAutoCancel(true).setStyle(NotificationCompat.BigTextStyle().bigText("Learn how to build notifications, send and sync data, and use " +
"voice actions. Get the official Android IDE and developer tools to build apps for Androids."))
通知中显示大图片
.setStyle(NotificationCompat.BigPictureStyle().bigPicture(BitmapFactory.decodeResource(resources,R.drawable.big_image)))
设置成初始为高等级的通知
添加一个消息渠道
val channel2=NotificationChannel("important","Important",NotificationManager.IMPORTANCE_HIGH)
manager.createNotificationChannel(channel2)
可以发现将这个渠道设置为了高等级
然后将消息的渠道id修改成这个渠道的id
val notification=NotificationCompat.Builder(this,"important")
调用摄像头
package com.example.cameraalbumtest
import android.app.Activity
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Matrix
import android.media.ExifInterface
import android.net.Uri
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.provider.MediaStore
import androidx.core.content.FileProvider
import kotlinx.android.synthetic.main.activity_main.*
import java.io.File
class MainActivity : AppCompatActivity() {
val takePhoto=1
lateinit var imageUri: Uri
lateinit var outputImage: File
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
takePhotoBtn.setOnClickListener {
outputImage= File(externalCacheDir,"output_image.jpg")//这里创建了一个名为output_image.jpg的文件并返回了一个引用
if(outputImage.exists()){
outputImage.delete()
}//如果之前文件存在内容就清空
outputImage.createNewFile()
imageUri=if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.N){
FileProvider.getUriForFile(this,"com.example.cameraalbumtest.fileprovider",outputImage)//第二个参数要和AndroidManifest中的一样
}else{
Uri.fromFile(outputImage)
}//通过版本将File对象转成Uri对象
val intent=Intent("android.media.action.IMAGE_CAPTURE")//隐式调用摄像头的Activity
intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri)//将得到的result放在imageUri中
startActivityForResult(intent,takePhoto)//通过这样startActivity会返回一个result
}//点击take photo后触发
}
/**
* 重写onActivityResult处理intent传回来的result
*/
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when(requestCode){
takePhoto -> {
if(resultCode== Activity.RESULT_OK){
val bitmap=BitmapFactory.decodeStream(contentResolver.openInputStream(imageUri))//取出result解码成bitmap
imageView.setImageBitmap(rotateIfRequired(bitmap))
}
}
}
}
/**
* 检测图片是否旋转了,然后进行调整
*/
private fun rotateIfRequired(bitmap: Bitmap): Bitmap{
val exif=ExifInterface(outputImage.path)
val orientation=exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,ExifInterface.ORIENTATION_NORMAL)//检测偏移了多少度
return when(orientation){
ExifInterface.ORIENTATION_ROTATE_90 -> rotateBitmap(bitmap,90)
ExifInterface.ORIENTATION_ROTATE_180-> rotateBitmap(bitmap,180)
ExifInterface.ORIENTATION_ROTATE_270-> rotateBitmap(bitmap,270)
else -> bitmap
}
}
/**
* @param bitmap: 传入的图片
* @param degree: 旋转的度数
* @return: 旋转后的图片
*/
private fun rotateBitmap(bitmap: Bitmap, degree: Int): Bitmap{
val matrix=Matrix()
matrix.postRotate(degree.toFloat())
val rotatedBitmap=Bitmap.createBitmap(bitmap,0,0,bitmap.width,bitmap.height,matrix,true)
bitmap.recycle()
return rotatedBitmap
}
}
在AndroidManifest.xml中添加provider
<provider
android:authorities="com.example.cameraalbumtest.fileprovider"
android:name="androidx.core.content.FileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"/>
</provider>
res→xml→file_paths.xml(路径设为’/'将整个SD卡进行共享
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path
name="my_images"
path="/"/>
</paths>
从相册中选择图片
添加一个触发按钮
fromAlbumBtn.setOnClickListener {
val intent=Intent(Intent.ACTION_OPEN_DOCUMENT)
intent.addCategory(Intent.CATEGORY_OPENABLE)
intent.type="image/*"
startActivityForResult(intent,fromAlbum)
}
添加结果处理.
fromAlbum->{
if(resultCode==Activity.RESULT_OK&&data!=null){
data.data?.let {
uri->
val bitmap=getBitmapFromUri(uri)
imageView.setImageBitmap(bitmap)
}
}
}
新增一个方法
private fun getBitmapFromUri(uri: Uri)=contentResolver.openFileDescriptor(uri,"r")?.use{
BitmapFactory.decodeFileDescriptor(it.fileDescriptor)
}