Populating Cards from Firebase to Kotlin App - javascript

Afternoon! For starters, I'm using Kotlin to build a tinder-like app with cards and a swiping function inside Android Studio.
I'm trying to populate these cards with an image and 2 text-fields with data from Firebase.. And I can't seem to do it. My difficulty with it seems trivial but it's tripping me up pretty bad.
It looks to me like the app is correctly reading the only 2 datasets currently in the database, evident by only showing 2 cards - but I can't get it to read and display the name, location and image of each of the datasets.
I've attached the CardAdapter.kt file where the values aren't getting read / updated here:
package com.sit708.coupledApp.adapters
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import com.bumptech.glide.Glide
import com.sit708.coupledApp.R
import com.sit708.coupledApp.util.Dates
import com.sit708.coupledApp.activities.UserInfoActivity
class CardsAdapter(context: Context?, resourceId: Int, dates: List<Dates>): ArrayAdapter<Dates>(
context!!, resourceId, dates) {
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val date = getItem(position)
val finalView = convertView ?: LayoutInflater.from(context).inflate(R.layout.item, parent, false)
val name = finalView.findViewById<TextView>(R.id.nameTV)
val userInfo = finalView.findViewById<LinearLayout>(R.id.userInfoLayout)
val image = finalView.findViewById<ImageView>(R.id.photoIV)
/*THESE VALUES AREN'T GETTING READ, UPDATED OR DISPLAYED*/
name.text = "${date?.dateName}, ${date?.dateLocation}"
Glide.with(context)
.load(date?.dateImg)
.into(image)
userInfo.setOnClickListener {
finalView.context.startActivity(UserInfoActivity.newIntent(finalView.context, date?.dateID))
}
return finalView
}
}
Here you can see that the comma is being displayed but not the name or location
Here is my SwipeFragment.kt just in case this proves useful:
package com.sit708.coupledApp.fragments
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.Toast
import androidx.fragment.app.Fragment
import com.google.firebase.database.DataSnapshot
import com.google.firebase.database.DatabaseError
import com.google.firebase.database.DatabaseReference
import com.google.firebase.database.ValueEventListener
import com.lorentzos.flingswipe.SwipeFlingAdapterView
import com.sit708.coupledApp.R
import com.sit708.coupledApp.util.Dates
import com.sit708.coupledApp.activities.TinderCallback
import com.sit708.coupledApp.adapters.CardsAdapter
import com.sit708.coupledApp.databinding.FragmentSwipeBinding
import com.sit708.coupledApp.util.*
class SwipeFragment : Fragment() {
private var _binding: FragmentSwipeBinding? = null
private val binding get() = _binding!!
private var callback: TinderCallback? = null
private lateinit var dateId: String
private lateinit var dateDatabase: DatabaseReference
private lateinit var chatDatabase: DatabaseReference
private lateinit var userDatabase: DatabaseReference
private var cardsAdapter: ArrayAdapter<Dates>? = null
private var rowItems = ArrayList<Dates>()
private var dateName: String? = null
private var dateImg: String? = null
private var dateLocation: String? = null
fun setCallback(callback: TinderCallback) {
this.callback = callback
dateId = callback.onGetUserId()
userDatabase = callback.getUserDatabase()
chatDatabase = callback.getChatDatabase()
dateDatabase = callback.getDateDatabase()
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentSwipeBinding.inflate(layoutInflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
dateDatabase.child(dateId).addListenerForSingleValueEvent(object : ValueEventListener {
override fun onCancelled(p0: DatabaseError) {
}
override fun onDataChange(p0: DataSnapshot) {
val date = p0.getValue(Dates::class.java)
dateName = date?.dateName
dateImg = date?.dateImg
dateLocation = date?.dateLocation
populateItems()
}
})
cardsAdapter = CardsAdapter(context, R.layout.item, rowItems)
binding.frame.adapter = cardsAdapter
binding.frame.setFlingListener(object : SwipeFlingAdapterView.onFlingListener {
override fun removeFirstObjectInAdapter() {
rowItems.removeAt(0)
cardsAdapter?.notifyDataSetChanged()
}
override fun onLeftCardExit(p0: Any?) {
var date = p0 as Dates
dateDatabase.child(date.dateID.toString()).child(DATA_SWIPES_LEFT).child(dateId).setValue(true)
}
override fun onRightCardExit(p0: Any?) {
val selectedDates = p0 as Dates
val selectedDateId = selectedDates.dateID
if (!selectedDateId.isNullOrEmpty()) {
dateDatabase.child(dateId).child(DATA_SWIPES_RIGHT)
.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onCancelled(p0: DatabaseError) {
}
override fun onDataChange(p0: DataSnapshot) {
if (p0.hasChild(selectedDateId)) {
Toast.makeText(context, "Match!", Toast.LENGTH_SHORT).show()
val chatKey = chatDatabase.push().key
if (chatKey != null) {
dateDatabase.child(dateId).child(DATA_SWIPES_RIGHT).child(selectedDateId)
.removeValue()
dateDatabase.child(dateId).child(DATA_MATCHES).child(selectedDateId)
.setValue(chatKey)
dateDatabase.child(selectedDateId).child(DATA_MATCHES).child(dateId)
.setValue(chatKey)
chatDatabase.child(chatKey).child(dateId).child(DATA_DATE_NAME).setValue(dateName)
chatDatabase.child(chatKey).child(dateId).child(DATA_DATE_IMAGE)
.setValue(dateImg)
chatDatabase.child(chatKey).child(selectedDateId).child(DATA_NAME)
.setValue(selectedDates.dateName)
}
} else {
dateDatabase.child(selectedDateId).child(DATA_SWIPES_RIGHT).child(dateId)
.setValue(true)
}
}
})
}
}
override fun onAdapterAboutToEmpty(p0: Int) {
}
override fun onScroll(p0: Float) {
}
})
binding.likeButton.setOnClickListener {
if (rowItems.isNotEmpty()) {
binding.frame.topCardListener.selectRight()
}
}
binding.dislikeButton.setOnClickListener {
if (rowItems.isNotEmpty()) {
binding.frame.topCardListener.selectLeft()
}
}
}
fun populateItems() {
binding.noUsersLayout.visibility = View.GONE
binding.progressLayout.visibility = View.VISIBLE
val cardsQuery = dateDatabase
cardsQuery.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onCancelled(p0: DatabaseError) {
}
override fun onDataChange(p0: DataSnapshot) {
p0.children.forEach { child ->
val date = child.getValue(Dates::class.java)
if (date != null) {
var showDate = true
if (child.child(DATA_SWIPES_LEFT).hasChild(dateId) ||
child.child(DATA_SWIPES_RIGHT).hasChild(dateId) ||
child.child(DATA_MATCHES).hasChild(dateId)
) {
showDate = false
}
if (showDate) {
rowItems.add(Dates())
cardsAdapter?.notifyDataSetChanged()
}
}
}
binding.progressLayout.visibility = View.GONE
if (rowItems.isEmpty()) {
binding.noUsersLayout.visibility = View.VISIBLE
}
}
})
}
}
Here is a screenshot of my database with only 2 sets of data that I'd like it to read from
If you need anymore info let me know and but any guidance would be greatly appreciated!
Small screenshot of my Data.kt file

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.

JS interface doesn't work with Android Kotlin

I am trying to implement JS interface in my WebView. I created a separate class with a method which calls listener, subsequently the string caught by listener should be put in the intent (in MainActivity) and intent finishes.
MainActivity.kt:
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.webkit.JavascriptInterface
import android.webkit.WebChromeClient
import android.webkit.WebSettings
import android.webkit.WebViewClient
import androidx.appcompat.app.AppCompatActivity
import sbs.pros.app.databinding.ActivityMainBinding
typealias IDListener = (qr: String) -> Unit
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private val answerIntent = Intent()
#SuppressLint("SetJavaScriptEnabled")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityPayBinding.inflate(layoutInflater)
val WebView = binding.webView
val webSettings: WebSettings = WebView.settings
WebView.settings.javaScriptEnabled = true
WebView.settings.javaScriptCanOpenWindowsAutomatically = true
webSettings.builtInZoomControls = false
WebView.webViewClient = WebViewClient()
WebView.webChromeClient = WebChromeClient()
WebView.addJavascriptInterface(WebAppInterface(this
) { id ->
answerIntent.putExtra("pay", id)
setResult(RESULT_OK)
finish()
}, "AndroidInterface")
WebView.setInitialScale(160)
WebView.loadUrl("https://pros.sbs/payment/create_payment.php?apicall=one_address")
setContentView(binding.root)
}
}
class WebAppInterface internal constructor(c: Context, listener: IDListener) {
var mContext: Context = c
fun WebAppInterface(context: Context) {
this.mContext = context
}
#JavascriptInterface
#SuppressWarnings("unused")
fun getID(id: String?, listener: IDListener) {
if (id != null) {
listener(id)
}
}
}
create_payment.php:
<script src="javascript.js">
function giveID(id) {
AndroidInterface.getID(id);
}
</script>
<?php
if(null !==filter_input(INPUT_GET, 'apicall')){
switch(filter_input(INPUT_GET, 'apicall')){
case 'one_address':
?>
<script src="javascript.js">
giveID('some_id');
</script>
<?php
break;
}
}
The intent then should finish, showing a result (String) in a separate TextView. Unfortunately, that does not happen and the result returned is null. Please help me to find the problem with the interface.

I have problem when i play video it's not working

Anyways Part of the tutorial makes use of a RecyclerView and I can't access it on my activity_main.xml file stating that v7 is an unresolved package. android.support.v7.widget.RecyclerView shows up with v7 onwards as red text. I know I can revert it back to older versions but I guess I am trying to make this work since moving forward its expected to know how to use androidx right?
I don't know how to add the RecyclerView to the project with my current project migrated to androidx.
What I've tried:
Adding implementation 'com.android.support:recyclerview-v7:28.0.0' based on the docs
Invalidating cache and restarting
My Dependencies:
plugins {
id 'com.android.application'
}
android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "com.kdapps.videoplayer.hdmaxplayer.video.player"
minSdkVersion 21
targetSdkVersion 30
versionCode 1
versionName "1.0.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.lifecycle:lifecycle-process:2.3.1'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
implementation 'com.github.bumptech.glide:glide:4.12.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
implementation "androidx.work:work-runtime:2.6.0"
implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.6'
implementation 'com.google.android.gms:play-services-ads:19.8.0'
implementation 'com.facebook.android:audience-network-sdk:6.3.0'
implementation 'com.wang.avi:library:2.1.3'
implementation 'org.greenrobot:eventbus:3.2.0'
implementation 'com.amitshekhar.android:android-networking:1.0.2'
implementation 'com.specyci:residemenu:1.6+'
implementation 'androidx.recyclerview:recyclerview:1.2.1'
}
package com.kdapps.videoplayer.hdmaxplayer.video.player.Fragment;
import android.annotation.SuppressLint;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ProgressBar;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.kdapps.videoplayer.hdmaxplayer.video.player.Adapter.VideoAdapter;
import com.kdapps.videoplayer.hdmaxplayer.video.player.Model.EventBus;
import com.kdapps.videoplayer.hdmaxplayer.video.player.R;
import com.kdapps.videoplayer.hdmaxplayer.video.player.Util.VideoPlayerManager;
import com.kdapps.videoplayer.hdmaxplayer.video.player.Extra.MediaData;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
public class RecentFragment extends Fragment {
#SuppressLint("StaticFieldLeak")
public static ImageView ivnodata;
public static RecyclerView recentrecycler;
ArrayList<MediaData> mediadataslist = new ArrayList<>();
private ProgressBar progress;
private View view;
#Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
org.greenrobot.eventbus.EventBus.getDefault().register(this);
}
#Override
public View onCreateView(LayoutInflater layoutInflater, ViewGroup viewGroup, Bundle bundle) {
this.view = layoutInflater.inflate(R.layout.fragment_recent, viewGroup, false);
#SuppressLint("WrongConstant")
NetworkInfo activeNetworkInfo = ((ConnectivityManager) getActivity().getSystemService("connectivity")).getActiveNetworkInfo();
if (activeNetworkInfo != null) {
activeNetworkInfo.isConnected();
}
initView();
getVideo();
return this.view;
}
#Override
public void onDestroy() {
super.onDestroy();
org.greenrobot.eventbus.EventBus.getDefault().unregister(this);
}
#SuppressLint("WrongConstant")
#Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(EventBus event_Bus) {
int type = event_Bus.getType();
if (type == 0) {
initAdapter(this.mediadataslist, event_Bus.getValue());
} else if (type == 1) {
this.progress.setVisibility(0);
recentrecycler.setVisibility(8);
new Thread(new Runnable() {
public void run() {
RecentFragment.this.getVideo();
}
}).start();
} else if (type == 2) {
int value = event_Bus.getValue();
if (value == 0) {
Collections.sort(this.mediadataslist, new Comparator<MediaData>() {
public int compare(MediaData media_Data, MediaData media_Data2) {
return (Long.compare(Long.parseLong(media_Data2.getLength()), Long.parseLong(media_Data.getLength())));
}
});
initAdapter(this.mediadataslist, VideoPlayerManager.getViewBy());
} else if (value == 1) {
Collections.sort(this.mediadataslist, new Comparator<MediaData>() {
public int compare(MediaData media_Data, MediaData media_Data2) {
return Long.compare(Integer.parseInt(media_Data2.getDuration()), Integer.parseInt(media_Data.getDuration()));
}
});
initAdapter(this.mediadataslist, VideoPlayerManager.getViewBy());
} else if (value == 2) {
Collections.sort(this.mediadataslist, new Comparator<MediaData>() {
public int compare(MediaData media_Data, MediaData media_Data2) {
return media_Data.getName().compareTo(media_Data2.getName());
}
});
initAdapter(this.mediadataslist, VideoPlayerManager.getViewBy());
} else if (value == 3) {
Collections.sort(this.mediadataslist, new Comparator<MediaData>() {
public int compare(MediaData media_Data, MediaData media_Data2) {
return media_Data2.getModifieddate().compareTo(media_Data.getModifieddate());
}
});
initAdapter(this.mediadataslist, VideoPlayerManager.getViewBy());
}
} else if (type == 3) {
this.progress.setVisibility(0);
recentrecycler.setVisibility(8);
new Thread(new Runnable() {
public void run() {
RecentFragment.this.getVideo();
}
}).start();
}
}
#SuppressLint("WrongConstant")
public void getVideo() {
this.mediadataslist.clear();
if (!TextUtils.isEmpty(VideoPlayerManager.getRecentPlay())) {
final ArrayList arrayList = (ArrayList) new Gson().fromJson(VideoPlayerManager.getRecentPlay(), new TypeToken<List<MediaData>>() {
}.getType());
Collections.reverse(arrayList);
this.mediadataslist.addAll(arrayList);
getActivity().runOnUiThread(new Runnable() {
public void run() {
RecentFragment.this.initAdapter(arrayList, VideoPlayerManager.getViewBy());
}
});
return;
}
this.progress.setVisibility(8);
recentrecycler.setVisibility(8);
ivnodata.setVisibility(0);
}
#SuppressLint("WrongConstant")
public void initAdapter(ArrayList<MediaData> arrayList, int i) {
this.progress.setVisibility(8);
if (arrayList.size() > 0) {
recentrecycler.setVisibility(0);
ivnodata.setVisibility(8);
VideoAdapter video_Adapter = new VideoAdapter(getActivity(), arrayList, i, 2);
if (i == 0) {
recentrecycler.setLayoutManager(new LinearLayoutManager(getActivity(), 1, false));
} else {
recentrecycler.setLayoutManager(new GridLayoutManager((Context) getActivity(), 3, 1, false));
}
recentrecycler.setAdapter(video_Adapter);
return;
}
recentrecycler.setVisibility(8);
ivnodata.setVisibility(0);
}
private void initView() {
recentrecycler = (RecyclerView) this.view.findViewById(R.id.hide_recycler);
progress = (ProgressBar) this.view.findViewById(R.id.progress);
ivnodata = (ImageView) this.view.findViewById(R.id.iv_nodata);
}
}
v7 RecyclerView is legacy now and you should use the androidx package instead.
to do this, add the androidx RecyclerView dependency to build.gradle(Module:app) like this
dependencies {
...
implementation "androidx.recyclerview:recyclerview:1.2.1"
...
}
and then change it's head name in xml layout to this :
<androidx.recyclerview.widget.RecyclerView
... />
and it will work as intended.
N.B : three dots (...) in my code means that I don't care the code written here and you should include your code instead.
for more information about how to deal with androidx RecyclerView check this Android Developers Tutorial

Not a Function Issue

I'm facing off a classic "Not a Function" issue on Ionic Framework, I hope that you will help me to better understand this case.
I am trying to get out an object from an array. The object has private properties that I retrieve with simple getter methods.
The problem comes out when this line of the whole class above is executed:
this.selectedWorkoutPlan = this.workoutPlanList.find(object => object.getId() === this.id);
The console returns the error mentioned before.
This is my .ts file:
import { Component } from '#angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import {WorkoutPlanService} from "../../services/workout-plan.service";
import {WorkoutPlan} from "../../models/workout-plan";
#IonicPage()
#Component({
selector: 'page-workout-plan-detail',
templateUrl: 'workout-plan-detail.html',
})
export class WorkoutPlanDetailPage {
id: number = 0;
title: string = "";
startDate: Date = new Date();
endDate: Date = new Date();
workoutPlanList: WorkoutPlan[] = [];
selectedWorkoutPlan: WorkoutPlan = new WorkoutPlan();
constructor(public navCtrl: NavController, public navParams: NavParams,
private workoutPlanService: WorkoutPlanService) {
}
ionViewDidLoad() {
this.id = this.navParams.get("id");
this.workoutPlanList = this.workoutPlanService.getWorkoutPlanList();
this.selectedWorkoutPlan = this.workoutPlanList.find(object => object.getId() === this.id);
}
}
and this is the .ts model's class.
import {WorkoutExercise} from "./workout-exercise";
export class WorkoutPlan {
private title: string;
private exercises: WorkoutExercise[];
private startDate: Date;
private endDate: Date;
private id: number;
constructor() {
this.id = new Date().getTime();
}
setTitle(newTitle: string) {
this.title = newTitle;
}
setExercises(newExercises: WorkoutExercise[]) {
this.exercises = newExercises;
}
setStartDate(newStartDate: Date) {
this.startDate = new Date(newStartDate);
}
setEndDate(newEndDate: Date) {
this.endDate = new Date(newEndDate);
}
setId(newId: number) {
this.id = newId;
}
getTitle() {
return this.title;
}
getExercises() {
return this.exercises;
}
getStartDate() {
return this.startDate;
}
getEndDate() {
return this.endDate;
}
getId() {
return this.id;
}
}
Am I missing something in the syntax?
In my mind I thought than an array's object would have properties and methods both, isn't it?
Thanks in advance for your time.
My guess is that you might be serializing your WorkOutPlan objects somewhere within WorkoutPlanService and then parsing the strings back into WorkOutPlan objects, which causes you to lose the associated methods.
Are you stringifying those objects at any time?

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