面试题答案
一键面试Flutter 端
- 定义方法通道:在Flutter项目的
lib
目录下,创建一个用于与原生代码交互的方法通道。
import 'package:flutter/services.dart';
const MethodChannel _channel = MethodChannel('com.example.notification_plugin');
- 定义通知相关方法:提供在Flutter中调用原生通知功能的方法。
Future<void> showNotification(String title, String body) async {
try {
await _channel.invokeMethod('showNotification', {
'title': title,
'body': body
});
} on PlatformException catch (e) {
print('Failed to show notification: ${e.message}');
}
}
iOS 端
- 创建Flutter插件项目:在终端中运行
flutter create --template=plugin -i swift -a kotlin notification_plugin
创建一个Flutter插件项目。 - 配置
Info.plist
:在ios/Runner/Info.plist
文件中添加通知权限配置。
<key>NSUserNotificationUsageDescription</key>
<string>$(PRODUCT_NAME) would like to send you notifications.</string>
- 实现原生通知功能:在
ios/Classes/NotificationPlugin.swift
文件中实现与Flutter交互及通知展示逻辑。
import Flutter
import UIKit
import UserNotifications
public class NotificationPlugin: NSObject, FlutterPlugin {
public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: "com.example.notification_plugin", binaryMessenger: registrar.messenger())
let instance = NotificationPlugin()
registrar.addMethodCallDelegate(instance, channel: channel)
}
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
if call.method == "showNotification" {
guard let args = call.arguments as? [String: Any],
let title = args["title"] as? String,
let body = args["body"] as? String else {
result(FlutterMethodNotImplemented)
return
}
showLocalNotification(title: title, body: body)
result(nil)
} else {
result(FlutterMethodNotImplemented)
}
}
func showLocalNotification(title: String, body: String) {
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .sound, .badge]) { (granted, error) in
if granted {
let content = UNMutableNotificationContent()
content.title = title
content.body = body
content.sound = UNNotificationSound.default
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false)
let request = UNNotificationRequest(identifier: "localNotification", content: content, trigger: trigger)
center.add(request, withCompletionHandler: nil)
}
}
}
}
Android 端
- 配置权限:在
android/app/src/main/AndroidManifest.xml
文件中添加通知权限。
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
- 实现原生通知功能:在
android/src/main/kotlin/com/example/notification_plugin/NotificationPlugin.kt
文件中实现与Flutter交互及通知展示逻辑。
package com.example.notification_plugin
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.Build
import androidx.core.app.NotificationCompat
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.embedding.engine.plugins.activity.ActivityAware
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
class NotificationPlugin: FlutterPlugin, MethodCallHandler, ActivityAware {
private lateinit var channel : MethodChannel
private var context: Context? = null
private var activity: android.app.Activity? = null
override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
channel = MethodChannel(flutterPluginBinding.binaryMessenger, "com.example.notification_plugin")
channel.setMethodCallHandler(this)
context = flutterPluginBinding.applicationContext
}
override fun onMethodCall(call: MethodCall, result: Result) {
if (call.method == "showNotification") {
val title = call.argument<String>("title")
val body = call.argument<String>("body")
showNotification(title, body)
result.success(null)
} else {
result.notImplemented()
}
}
private fun showNotification(title: String?, body: String?) {
val notificationManager = context?.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val channelId = "my_channel_01"
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val name = "My Channel"
val descriptionText = "This is my channel"
val importance = NotificationManager.IMPORTANCE_DEFAULT
val channel = NotificationChannel(channelId, name, importance).apply {
description = descriptionText
}
notificationManager.createNotificationChannel(channel)
}
val intent = Intent(context, activity?.javaClass).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
val pendingIntent: PendingIntent? = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
val builder = NotificationCompat.Builder(context!!, channelId)
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentTitle(title)
.setContentText(body)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
notificationManager.notify(1, builder.build())
}
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
channel.setMethodCallHandler(null)
}
override fun onAttachedToActivity(binding: ActivityPluginBinding) {
activity = binding.activity
}
override fun onDetachedFromActivityForConfigChanges() {
activity = null
}
override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {
activity = binding.activity
}
override fun onDetachedFromActivity() {
activity = null
}
}
通过上述步骤,即可在Flutter插件开发中为iOS和Android分别定制简单的本地通知功能插件,并实现Flutter与原生代码的交互。