Window webkit failure postMessage iOS Swift - javascript

I am trying to create a library that open a web view in a class, where the objetive is opened it but does not see it in the screen. I created and try to execute a javaScript that makes a postMessage, to obtain the result for example in the method userContentController(), but I am getting and error when I execute it. Also, I am used webView.callAsyncJavaScript, cause then I want to execute some async functions that webView.evaluateJavaScript does not let. Some knows what could be the reason that can help me. Thanks.
Code:
import WebKit
class FingerprintJs : NSObject, WKScriptMessageHandler, WKNavigationDelegate{
public func tryFinger(){
getWebView()
}
public func userContentController(_ userContentController: WKUserContentController,
didReceive message: WKScriptMessage){
print("userContentController")
print(message.name)
}
private func getWebView(){
if let viewController = UIWindow.key?.rootViewController {
if Thread.isMainThread {
let webView = self.makeWebView(viewController: viewController as! ViewController)
webView.loadHTMLString(getHtml(), baseURL: nil)
if #available(iOS 14.0, *) {
print("bunea")
webView.callAsyncJavaScript(getJavaScript()!, arguments: [:], in: nil, in: .defaultClient, completionHandler:{(result) in
print("queeeeee")
print(result as Any)
})
} else {
print("Llegaste aca? porqueee ")
// Fallback on earlier versions
}
// webView.evaluateJavaScript(getJavaScript()!,completionHandler:{(result , error) in
// if error == nil {
// print("success")
// print(result as Any)
// }
// else {
// print("error in executing js ", error!)
// }
// })
} else {
print("Llegaste aca? ")
}
}else{
NSLog("The UIApplication keyWindow of the rootViewController must be loaded first", "")
}
}
private func makeWebView(viewController: ViewController) -> WKWebView {
let preferences = WKPreferences()
preferences.javaScriptEnabled = true
let config = WKWebViewConfiguration()
config.userContentController.add(self, name: "message5")
config.preferences = preferences
let webView = WKWebView(frame: .init(x: 1.0, y: 1.0, width: 0, height: 0),
configuration: config)
webView.translatesAutoresizingMaskIntoConstraints = false
viewController.view.addSubview(webView)
return webView
}
private func getJavaScript() -> String?{
var javaScript: String? = nil
if let jsSourcePath = Bundle.main.path(forResource: "ejemplo", ofType: "js") {
do {
javaScript = try String(contentsOfFile: jsSourcePath)
}
catch {
NSLog("getJavaScriptString: "+(error.localizedDescription), "")
}
}
return javaScript
}
private func getHtml() -> String {
let html: String =
"""
<html>
<body>
<script>
</script>
</body>
</html>
"""
return html
}
private var webView: WKWebView? {
didSet {
oldValue?.removeFromSuperview()
oldValue?.configuration.userContentController.removeScriptMessageHandler(forName: "message5")
}
}
}
extension UIWindow {
static var key: UIWindow? {
if #available(iOS 13, *) {
return UIApplication.shared.windows.first { $0.isKeyWindow }
} else {
return UIApplication.shared.keyWindow
}
}
}
Javascript:
testFunct();
function testFunct() {
window.webkit.messageHandlers.message5.postMessage("nice" )
}
Error:
failure(Error Domain=WKErrorDomain Code=4 "A JavaScript exception occurred" UserInfo={WKJavaScriptExceptionLineNumber=0, WKJavaScriptExceptionMessage=TypeError: undefined is not an object (evaluating 'window.webkit.messageHandlers'), WKJavaScriptExceptionColumnNumber=0, NSLocalizedDescription=A JavaScript exception occurred})
In addition for example here I have some changes of code but for example I never receive in method userContentController the message. Where I set the window.webkit.messageHandlers in the html.
import WebKit
import UIKit
class FingerprintJs : NSObject, WKScriptMessageHandler, WKNavigationDelegate{
public func tryFinger(){
getWebView()
}
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
assert(message.name == "myMessageName")
}
private func getWebView(){
if let viewController = UIWindow.key?.rootViewController {
if Thread.isMainThread {
let webView = self.makeWebView(viewController: viewController as! ViewController)
webView.loadHTMLString(getHtml(), baseURL: nil)
// webView.evaluateJavaScript(getJavaScript()!,completionHandler:{(result , error) in
// if error == nil {
// print("success")
// print(result as Any)
// }
// else {
// print("error in executing js ", error!)
// }
// })
} else {
print("Llegaste aca? ")
}
}else{
NSLog("The UIApplication keyWindow of the rootViewController must be loaded first", "")
}
}
private func makeWebView(viewController: ViewController) -> WKWebView {
let preferences = WKPreferences()
preferences.javaScriptEnabled = true
let config = WKWebViewConfiguration()
config.userContentController.add(self, name: "myMessageName")
config.preferences = preferences
let webView = WKWebView(frame: .init(x: 1.0, y: 1.0, width: 0, height: 0),
configuration: config)
webView.translatesAutoresizingMaskIntoConstraints = false
viewController.view.addSubview(webView)
webView.navigationDelegate = self
return webView
}
private func getJavaScript() -> String?{
var javaScript: String? = nil
if let jsSourcePath = Bundle.main.path(forResource: "ejemplo", ofType: "js") {
do {
javaScript = try String(contentsOfFile: jsSourcePath)
}
catch {
NSLog("getJavaScriptString: "+(error.localizedDescription), "")
}
}
return javaScript
}
private func getHtml() -> String {
let html: String =
"""
<html>
<body>
<script>
window.webkit.messageHandlers.myMessageName.postMessage("message")
</script>
</body>
</html>
"""
return html
}
private var webView: WKWebView? {
didSet {
oldValue?.removeFromSuperview()
oldValue?.configuration.userContentController.removeScriptMessageHandler(forName: "message5")
}
}
}
extension UIWindow {
static var key: UIWindow? {
if #available(iOS 13, *) {
return UIApplication.shared.windows.first { $0.isKeyWindow }
} else {
return UIApplication.shared.keyWindow
}
}
}

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
webView.evaluateJavaScript("testFunct()")
}
try calling the JS method from didFinish navigation method once the webView is loaded. It might be due to calling the JS method before the webView is properly loaded.

Related

SwiftUI - How to evaluate javascript in webview if network is down?

I have the following webview implementation built by borrowing code (I am learning SwiftUI). I want to show a message in the webview when the networks is down. It works with a static html loaded from a string and a button but I am unable to do the same calling a web server and triggering javascript using the network status.
import SwiftUI
import WebKit
import Combine
private let urlString: String = "http://127.0.0.1"
class WebViewData: ObservableObject {
#Published var parsedText: NSAttributedString? = nil
var functionCaller = PassthroughSubject<Void,Never>()
var isInit = false
var shouldUpdateView = true
}
struct WebView: UIViewRepresentable {
#StateObject var data: WebViewData
func makeUIView(context: Context) -> WKWebView {
let wkWebview = WKWebView()
wkWebview.navigationDelegate = context.coordinator
return wkWebview
}
func updateUIView(_ uiView: WKWebView, context: Context) {
guard data.shouldUpdateView else {
data.shouldUpdateView = false
return
}
context.coordinator.tieFunctionCaller(data: data)
context.coordinator.webView = uiView
guard let url = URL(string: urlString) else { return }
let request = URLRequest(url: url)
uiView.load(request)
}
func makeCoordinator() -> WebViewCoordinator {
return WebViewCoordinator(view: self)
}
func viewWillAppear(_ uiView: WKWebView, context: UIViewRepresentableContext<WebView>){
}
}
class WebViewCoordinator : NSObject, WKNavigationDelegate {
var parent: WebView
var webView: WKWebView? = nil
private var cancellable : AnyCancellable?
init(view: WebView) {
self.parent = view
super.init()
}
func tieFunctionCaller(data: WebViewData) {
cancellable = data.functionCaller.sink(receiveValue: { _ in
self.webView?.evaluateJavaScript("message_generator(\"network_down\"")
})
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
DispatchQueue.main.async {
if !self.parent.data.isInit {
self.parent.data.isInit = true
}
}
}
}
Here the ContentView:
import SwiftUI
struct ContentView: View {
#StateObject var webViewData = WebViewData()
#ObservedObject var networkManager = NetworkManager()
var body: some View {
ZStack{
Color.white
VStack {
ExecuteCode {
print(networkManager.isConnected)
webViewData.functionCaller.send() //???
}
WebView(data: webViewData)
if (!networkManager.isConnected) {
//???
}
}
.onReceive(webViewData.$parsedText, perform: { parsedText in
if let parsedText = parsedText {
print(parsedText)
}
})
}
}
}
struct ExecuteCode : View {
init( _ codeToExec: () -> () ) {
codeToExec()
}
var body: some View {
return EmptyView()
}
}
Here the NetworkManager:
import Foundation
import Network
class NetworkManager: ObservableObject {
let monitor = NWPathMonitor()
let queue = DispatchQueue(label: "NetworkManager")
#Published var isConnected = true
var imageName: String {
return isConnected ? "wifi" : "wifi.slash"
}
var connectionDescription: String {
if isConnected {
return "Internet connection looks good!"
} else {
return "It looks like you're not connected to the internet. Make sure WiFi is enabled and try again"
}
}
init() {
monitor.pathUpdateHandler = { path in
DispatchQueue.main.async {
if path.status == .satisfied {
self.isConnected = true
} else {
self.isConnected = false
}
}
}
monitor.start(queue: queue)
}
}
Thanks for helping.
Pointers to good docs are very appreciated.

Why do the XMLHttpRequest open and send not called using javascript in Android?

I am trying to intercept a POST request before opening an HTML page using webView.
I followed the tutorial on: https://medium.com/#madmuc/intercept-all-network-traffic-in-webkit-on-android-9c56c9262c85
which injects the javascript file through a .js file in the assets folder:
XMLHttpRequest.prototype.origOpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, url, async, user, password) {
// these will be the key to retrieve the payload
this.recordedMethod = method;
this.recordedUrl = url;
this.origOpen(method, url, async, user, password);
};
XMLHttpRequest.prototype.origSend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = function(body) {
// interceptor is a Kotlin interface added in WebView
if(body) recorder.recordPayload(this.recordedMethod, this.recordedUrl, body);
this.origSend(body);
};
However, the open and send are never called, I added logs to test and if I move the recorder.recordPayload(...) (which is the method in the javascript interface) out of those functions then recordPayload is called, so the problem is not with the interface or reading from the file.
webView class:
class TestWebView : WebView {
private var urlReturned = false
private var postbackUrl: String? = "https://www.xxxxx.com"
private var postbackHandled = false```
lateinit var recorder: PayloadRecorder
lateinit var payload: String
constructor(context: Context?) : super(context) {
initUI()
}
private fun initUI() {
if (!isInEditMode) {
settings.javaScriptEnabled = true
settings.builtInZoomControls = true
settings.displayZoomControls = false
settings.loadWithOverviewMode = true
settings.useWideViewPort = true
recorder = PayloadRecorder()
addJavascriptInterface(recorder, "recorder")
evaluateJavascript(
context.assets.open("override.js").reader().readText(), null
)
}
val client: WebViewClient = object : WebViewClient() {
override fun shouldInterceptRequest(
view: WebView,
request: WebResourceRequest
): WebResourceResponse? {
val payload = recorder.getPayload(request.method, request.url.toString())
// handle the request with the given payload and return the response
return super.shouldInterceptRequest(view, request)
}
override fun onPageStarted(
view: WebView,
url: String,
favicon: Bitmap?
) {
Log.i("testURL", url)
evaluateJavascript(
context.assets.open("override.js").reader().readText(),
object : ValueCallback<String> {
override fun onReceiveValue(value: String?) {
Log.i("onReceiveValue", value)
}
}
)
}
}
setWebChromeClient(object : WebChromeClient() {
override fun onConsoleMessage(consoleMessage: ConsoleMessage): Boolean {
Log.d("WebView", consoleMessage.message())
return true
}
})
}
constructor(context: Context?, attrs: AttributeSet?) : super(
context,
attrs
) {
initUI()
}
constructor(
context: Context?,
attrs: AttributeSet?,
defStyle: Int
) : super(context, attrs, defStyle) {
initUI()
}
constructor(
context: Context?,
attrs: AttributeSet?,
defStyle: Int,
privateBrowsing: Boolean
) : super(context, attrs, defStyle) {
initUI()
}
class PayloadRecorder {
private val payloadMap: MutableMap<String, String> =
mutableMapOf()
#JavascriptInterface
fun recordPayload(
method: String,
url: String,
payload: String
) {
payloadMap["$method-$url"] = payload
Log.i("payloadRecorder", "recordPayLoad")
}
fun getPayload(
method: String,
url: String
): String? =
payloadMap["$method-$url"]
}
/**
* The function that is called and starts the html progress
*/
#JvmOverloads
fun process(
acsUrl: String?,
md: String?,
paReq: String?,
postbackUrl: String? = null
) {
urlReturned = false
postbackHandled = false
if (!TextUtils.isEmpty(postbackUrl)) {
this.postbackUrl = postbackUrl
}
val postParams: String
payload = paReq?: ""
postParams = //my code
postUrl(acsUrl, postParams.toByteArray())
}
}
recordPayload is never called therefore in shouldInterceptRequest payload always comes back null.

Javascript console log in UIWebView in Swift

Is there any way to print logs that is created by "console.log" in web page in UIWebView or WKWebView in swift (like Chrome F12.)
Have a nice days.
Here's a basic implementation for the UIWebView:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Create the web view.
let webView = UIWebView()
webView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(webView)
webView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
webView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
webView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
webView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
webView.delegate = self
webView.loadRequest(URLRequest(url: URL(string: "https://www.google.com.py")!))
}
}
extension ViewController: UIWebViewDelegate {
func webViewDidFinishLoad(_ webView: UIWebView) {
let js = "console.log = function() {window.location = 'logger://webview?' + JSON.stringify(Array.prototype.slice.call(arguments))}"
webView.stringByEvaluatingJavaScript(from: js)
}
func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
if request.url?.scheme == "logger" {
guard let data = request.url?.query?.removingPercentEncoding?.data(using: .utf8) else { return true }
guard let obj = try? JSONSerialization.jsonObject(with: data, options: []) else { return true }
guard let jsonData = try? JSONSerialization.data(withJSONObject: obj, options: .prettyPrinted) else { return true }
guard let json = String(data: jsonData, encoding: .utf8) else { return true }
print(json)
}
return true
}
}
Example
console.log(4, 3.53, 'Hello', {d: {f: 4}}, function() {}, undefined, null, true)
Prints the following in Xcode log:
[
4,
3.5299999999999998,
"Hello",
{
"d" : {
"f" : 4
}
},
null,
null,
null,
true
]
Caveats
This only prints logs executed after the page has loaded.
Since we're using JSON.stringify, we can't print the following types: function, undefined
Since we're using JSON.stringify, true and false are
printed as 1 and 0, respectively

javascript does not work on iOS9+Swift 2.0

I have been using WKWebView.
I would like to work javascript on iOS9+Swift 2.0.
But It couldn't work.
console.log("hoge") couldn't even work.
My code is here
import UIKit
class CommonWebVCL: GABase,UIWebViewDelegate,UIScrollViewDelegate,WKNavigationDelegate,WKUIDelegate {
var webview: WKWebView!
var str_url:String! = ""
var url:String!
var gobackSearch:Bool! = false
var previousScrollViewYOffset:CGFloat? = 0
var toolbarheight:CGFloat = 0
var analytics_category:String!
override func viewDidLoad() {
super.viewDidLoad()
changeUserAgent()
let webViewConfiguration = WKWebViewConfiguration()
self.webview = WKWebView(frame: self.view.bounds, configuration: webViewConfiguration)
self.webview.navigationDelegate = self
self.webview.UIDelegate = self
addObserverForWKWebView()
self.view.addSubview(webview)
setBackButton()
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
navigationBarInit()
//タブの遷移でdelegateが外れるので貼り直す
self.webview.scrollView.delegate = self
}
func setBackBtnForWeb(){
let leftbtn = UIButton(frame: CGRect(x: 0, y: 0, width: 48, height: 22))
leftbtn.setImage(UIImage(named: "back_btn"), forState: .Normal)
leftbtn.addTarget(self, action: "goBackForWeb:", forControlEvents: UIControlEvents.TouchUpInside)
let backButton = UIBarButtonItem(customView: leftbtn)
self.navigationItem.setLeftBarButtonItem(backButton, animated: true)
}
func webView(webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!){
// インジケータを表示する
if let tmpstr_url = self.webview.URL?.absoluteString{
if (tmpstr_url.rangeOfString("tel") == nil){
SVProgressHUD.show()
}
}
}
func webView(webView: WKWebView, didFinishNavigation navigation: WKNavigation!){
// インジケータを表示する
if SVProgressHUD.isVisible(){
SVProgressHUD.dismiss()
}
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
navigationBarInit()
let URL = NSURL(string: url)
let urlRequest: NSURLRequest = NSURLRequest(URL: URL!)
self.webview.loadRequest(urlRequest)
}
override func viewDidLayoutSubviews() {
self.webview.frame = self.view.bounds
navigationBarInit()
}
override func viewDidDisappear(animated: Bool) {
super.viewDidDisappear(animated)
if SVProgressHUD.isVisible(){
SVProgressHUD.dismiss()
}
if (self.gobackSearch != nil){
sendEvent(analytics_category, str_action: "back")
self.navigationController?.popViewControllerAnimated(true)
}
self.webview.scrollView.delegate = nil
self.webview.navigationDelegate = nil
self.webview.stopLoading()
UIApplication.sharedApplication().networkActivityIndicatorVisible = false
}
func addObserverForWKWebView(){
self.webview.addObserver(self, forKeyPath: "canGoBack", options: NSKeyValueObservingOptions.New, context: nil) // WEBページで戻ることができるか監視のため、Observerに追加
self.webview.addObserver(self, forKeyPath: "URL", options: NSKeyValueObservingOptions.New, context: nil) // WEBページで戻ることができるか監視のため、Observerに追加
}
// Observerで監視対象のプロパティに変更があったときの処理
override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
if object!.isEqual(webview){
if keyPath == "estimatedProgress"{
self.navigationController?.setSGProgressMaskWithPercentage(Float(self.webview.estimatedProgress*100))
navigationBarInit()
}else if keyPath == "canGoBack"{
}else if keyPath == "URL"{
if let tmpstr_url = self.webview.URL?.absoluteString{
self.str_url = tmpstr_url
handleUrl()
}
}
}
}
//URLを見て何かするところ
func handleUrl(){
}
// 画面を閉じるときにObserverを削除。削除しないとアプリ落ちる
deinit{
if self.webview != nil{
//self.webview.removeObserver(self, forKeyPath: "estimatedProgress", context: nil)
self.webview.removeObserver(self, forKeyPath: "canGoBack", context: nil)
self.webview.removeObserver(self, forKeyPath: "URL", context: nil)
}
}
#IBAction func goBackForWeb(sender: AnyObject) {
if self.webview.canGoBack{
webview.goBack()
}else{
self.navigationController?.popViewControllerAnimated(true)
}
}
func webViewDidStartLoad(webView: UIWebView){
SVProgressHUD.showWithStatus("読み込み中")
navigationBarInit()
}
func webViewDidFinishLoad(webView: UIWebView){
SVProgressHUD.dismiss()
}
func webView(webView: UIWebView, didFailLoadWithError error: NSError?){
SVProgressHUD.dismiss()
}
func webView(webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: () -> Void){
let alertController = UIAlertController(title: frame.request.URL?.host, message: message, preferredStyle: .Alert)
alertController.addAction(UIAlertAction(title: "OK", style: .Default, handler: { action in
completionHandler()
}))
self.presentViewController(alertController, animated: true, completion: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
What is this problem?
By the way this problem is only iOS9 by swift2.0.
It works correctly on other platform including iOS9 by swift 1.2.
I might resolve it by myself.
This web page always use http protocol.
So I changed https protocol,javascript have worked correctly.

Clearing system notification

I am trying to implement this plugin Phonegap system notification. I am reading two Rss feeds and displaying it to the user as a Status bar notification. Once the Notifications has been displayed to the user and the user clicks on the notification, he is taken to the app but I am not able to clear the notifications from the status bar. Could you please suggest me a way to clear these notifications by looking at my code.
How can I call navigator.systemNotification.cancelNotification() when the user clicks on the statusbar notification.
notification.js
google.load("feeds", "1");
google.setOnLoadCallback(function () {
var rss1old = '',
rss1new = '',
rss2old ='',
rss2new ='',
getRss = function (url, callback) {
(url) && (function (url) {
var feed = new google.feeds.Feed(url);
feed.load(function (result) {
(!result.error && callback) && (callback(result.feed.entries[0].title));
});
}(url));
};
setInterval(function () {
getRss(
'http://yofreesamples.com/category/free-coupons/feed/?type=rss',
function (title) {
rss1new = title;
if(rss1old !== rss1new) {
rss1old = rss1new;
navigator.systemNotification.onBackground();
navigator.systemNotification.updateNotification(rss1new,1);
navigator.notification.beep(1);
navigator.notification.vibrate(2000);
}
}
);
}, 5000);
setInterval(function () {
getRss(
'http://yofreesamples.com/category/real-freebies/feed/?type=rss',
function (title) {
rss2new = title;
if(rss2old !== rss2new) {
rss2old = rss2new;
navigator.systemNotification.onBackground();
navigator.systemNotification.updateNotification(rss2new,1);
navigator.notification.beep(1);
navigator.notification.vibrate(1000);
}
}
);
}, 6000);
});
SystemNotification.js -> Included from the plugin
function SystemNotification() {
}
SystemNotification.prototype.notificationEnabled = false;
SystemNotification.prototype.newCount = 0; //to keep track of multiple notifications events
SystemNotification.prototype.enableNotification = function () {
this.notificationEnabled = true;
};
SystemNotification.prototype.disableNotification = function () {
this.notificationEnabled = false;
};
SystemNotification.prototype.onBackground = function () {
this.enableNotification();
};
SystemNotification.prototype.onForeground = function () {
this.disableNotification();
};
SystemNotification.prototype.createStatusBarNotification = function (contentTitle, contentText, tickerText) {
PhoneGap.exec(null, null, "systemNotification", "createStatusBarNotification", [contentTitle, contentText, tickerText]);
};
SystemNotification.prototype.updateNotification = function (contentText, tickerText, number) {
this.newCount++;
var contentTitle = this.newCount + "RssFeeds";
if (this.newCount === 1) {
this.createStatusBarNotification(contentTitle, contentText, tickerText);
} else {
PhoneGap.exec(null, null, "systemNotification", "updateNotification", [contentTitle, contentText, this.newCount]);
this.showTickerText(tickerText); //optional
}
};
SystemNotification.prototype.cancelNotification = function (contentText) {
this.newCount--;
if (this.newCount === 0) {
PhoneGap.exec(null, null, "systemNotification", "cancelNotification", []);
}
else {
//updating the notification
var contentTitle = "my title";
PhoneGap.exec(null, null, "systemNotification", "updateNotification", [contentTitle, contentText, this.newCount]);
}
};
SystemNotification.prototype.showTickerText = function (tickerText) {
PhoneGap.exec(null, null, "systemNotification", "showTickerText", [tickerText]);
};
SystemNotification.prototype.touch = function () {
PhoneGap.exec(null, null, "systemNotification", "touch", []);
};
PhoneGap.addConstructor(function () {
if (typeof(navigator.systemNotification) == "undefined") {
navigator.systemNotification = new SystemNotification();
navigator.systemNotification.touch(); //this ensures that the plugin is added when phonegap kicks off
}
});
Systemnotification.Java -> Included from the plugin
package com.yfs.project;
import org.json.JSONArray;
import org.json.JSONException;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import com.phonegap.api.Plugin;
import com.phonegap.api.PluginResult;
public class SystemNotification extends Plugin {
final int notif_ID = 1234;
NotificationManager notificationManager;
Notification note;
PendingIntent contentIntent;
#Override
public PluginResult execute(String action, JSONArray args, String callbackId)
{
PluginResult.Status status = PluginResult.Status.OK;
String result = "";
try {
if (action.equals("createStatusBarNotification")) {
this.createStatusBarNotification(args.getString(0), args.getString(1), args.getString(2));
}
else if (action.equals("updateNotification")) {
this.updateNotification(args.getString(0), args.getString(1), args.getInt(2));
}
else if (action.equals("cancelNotification")) {
this.cancelNotification();
}
else if (action.equals("showTickerText")) {
this.showTickerText(args.getString(0));
}
return new PluginResult(status, result);
} catch(JSONException e) {
return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
}
}
private void updateNotification(String contentTitle, String contentText, int number)
{
note.setLatestEventInfo(this.ctx, contentTitle, contentText, contentIntent);
note.number = number;
notificationManager.notify(notif_ID,note);
}
private void createStatusBarNotification(String contentTitle, String contentText, String tickerText)
{
notificationManager = (NotificationManager) this.ctx.getSystemService(Context.NOTIFICATION_SERVICE);
note = new Notification(R.drawable.rss, tickerText, System.currentTimeMillis() );
//change the icon
Intent notificationIntent = new Intent(this.ctx, Yfs.class);
notificationIntent.setAction(Intent.ACTION_MAIN);
notificationIntent = notificationIntent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
contentIntent = PendingIntent.getActivity(this.ctx, 0, notificationIntent, 0);
note.setLatestEventInfo(this.ctx, contentTitle, contentText, contentIntent);
note.number = 1; //Just created notification so number=1. Remove this line if you dont want numbers
notificationManager.notify(notif_ID,note);
}
private void cancelNotification()
{
notificationManager.cancel(notif_ID);
}
private void showTickerText(String tickerText)
{
note.tickerText = tickerText;
notificationManager.notify(notif_ID,note);
}
public void onPause()
{
super.webView.loadUrl("javascript:navigator.systemNotification.onBackground();");
}
public void onResume()
{
super.webView.loadUrl("javascript:navigator.systemNotification.onForeground();");
}
}
On android, you'll need to set the flag AUTO_CANCEL
Where you have this
note = new Notification(R.drawable.rss, tickerText, System.currentTimeMillis() );
Add this line right under
note.flags = Notification.FLAG_AUTO_CANCEL;

Categories

Resources