diff --git a/.idea/dictionaries/naresh.xml b/.idea/dictionaries/naresh.xml
new file mode 100644
index 0000000..4547fe3
--- /dev/null
+++ b/.idea/dictionaries/naresh.xml
@@ -0,0 +1,9 @@
+
+
+
+ elektro
+ hsdsans
+ weblog
+
+
+
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 6374795..20e8765 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -35,16 +35,19 @@ android {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
- implementation 'androidx.core:core-ktx:1.2.0'
- implementation 'androidx.appcompat:appcompat:1.1.0'
- implementation 'com.google.android.material:material:1.1.0'
- implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
- implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0'
- implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
- testImplementation 'junit:junit:4.+'
- androidTestImplementation 'androidx.test.ext:junit:1.1.1'
- androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
+ implementation 'androidx.core:core-ktx:1.3.2'
+ implementation 'androidx.appcompat:appcompat:1.2.0'
+ implementation 'com.google.android.material:material:1.3.0'
+ implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
+ implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.0'
+ implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.0'
+ implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
+ 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.android.volley:volley:1.2.0'
- implementation "com.squareup.okhttp3:okhttp:4.9.0"
+ implementation "androidx.work:work-runtime-ktx:2.5.0"
+
+
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 48d335b..21250d8 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,7 +1,8 @@
-
+
+
+
+
-
-
\ No newline at end of file
diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png
new file mode 100644
index 0000000..08a37e8
Binary files /dev/null and b/app/src/main/ic_launcher-playstore.png differ
diff --git a/app/src/main/java/com/nareshkumarrao/eiweblog/AboutActivity.kt b/app/src/main/java/com/nareshkumarrao/eiweblog/AboutActivity.kt
new file mode 100644
index 0000000..dec743a
--- /dev/null
+++ b/app/src/main/java/com/nareshkumarrao/eiweblog/AboutActivity.kt
@@ -0,0 +1,36 @@
+package com.nareshkumarrao.eiweblog
+
+import android.content.Intent
+import android.net.Uri
+import android.os.Bundle
+import android.view.View
+import androidx.appcompat.app.AppCompatActivity
+import androidx.appcompat.widget.AppCompatButton
+import androidx.appcompat.widget.Toolbar
+
+
+class AboutActivity : AppCompatActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_about)
+
+ val aboutToolbar = this.findViewById(R.id.about_toolbar)
+ setSupportActionBar(aboutToolbar)
+ supportActionBar?.setDisplayHomeAsUpEnabled(true)
+ supportActionBar?.setDisplayShowTitleEnabled(false)
+ }
+
+ fun sendBeer(view: View) {
+ startActivity( Intent(
+ Intent.ACTION_VIEW,
+ Uri.parse("https://paypal.me/naresh97")
+ ))
+ }
+
+ fun githubRepo(view: View){
+ startActivity( Intent(
+ Intent.ACTION_VIEW,
+ Uri.parse("https://github.com/naresh97/ei-weblog-android")
+ ))
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/nareshkumarrao/eiweblog/MainActivity.kt b/app/src/main/java/com/nareshkumarrao/eiweblog/MainActivity.kt
index 99f6fb0..cfeb7ec 100644
--- a/app/src/main/java/com/nareshkumarrao/eiweblog/MainActivity.kt
+++ b/app/src/main/java/com/nareshkumarrao/eiweblog/MainActivity.kt
@@ -1,17 +1,23 @@
package com.nareshkumarrao.eiweblog
+import android.app.NotificationChannel
+import android.app.NotificationManager
+import android.content.Context
+import android.content.Intent
+import android.os.Build
import android.os.Bundle
-import android.util.Log
import android.view.Menu
+import android.view.MenuItem
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import androidx.viewpager.widget.ViewPager
-import com.android.volley.VolleyLog
+import androidx.work.PeriodicWorkRequestBuilder
+import androidx.work.WorkManager
+import androidx.work.WorkRequest
import com.google.android.material.tabs.TabLayout
-import com.nareshkumarrao.eiweblog.ui.main.Article
import com.nareshkumarrao.eiweblog.ui.main.SectionsPagerAdapter
-import okhttp3.OkHttpClient
+import java.util.concurrent.TimeUnit
class MainActivity : AppCompatActivity() {
@@ -26,50 +32,32 @@ class MainActivity : AppCompatActivity() {
val tabs: TabLayout = findViewById(R.id.tabs)
tabs.setupWithViewPager(viewPager)
- val myToolbar = findViewById(R.id.toolbar) as Toolbar
+ val myToolbar = findViewById(R.id.about_toolbar) as Toolbar
setSupportActionBar(myToolbar)
- VolleyLog.DEBUG = true
+ Utilities.createNotificationChannel(this)
- /*val queue = Volley.newRequestQueue(this)
- val url = "https://www.reddit.com"
- val stringRequest = StringRequest(
- Request.Method.GET, url,
- { response ->
- Log.d("XMLLIST", "got response!")
- Log.d("XMLLIST", "$response")
- },
- { error -> Log.e("XMLLIST", error.toString()) })
- stringRequest.retryPolicy = DefaultRetryPolicy(
- DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 2,
- DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
- DefaultRetryPolicy.DEFAULT_BACKOFF_MULT
- )
- queue.add(stringRequest)*/
+ val uploadWorkRequest: WorkRequest =
+ PeriodicWorkRequestBuilder(1, TimeUnit.HOURS)
+ .build()
+ WorkManager.getInstance(this).enqueue(uploadWorkRequest)
- val thread = Thread {
- try {
- Log.d("XMLLIST", "Starting network request thread.")
- val client = OkHttpClient()
- val request = okhttp3.Request.Builder().url("https://google.com/").build()
- val response = client.newCall(request).execute()
- Log.d("XMLLIST", response.toString())
- } catch (e: Exception) {
- e.printStackTrace()
- }
- }
- thread.start()
}
- fun logArticles(articles: List){
- Log.i("XMLLIST", articles.toString())
- }
-
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
- //Utilities.weblogXML(baseContext, ::logArticles)
menuInflater.inflate(R.menu.toolbar_menu, menu);
return true;
}
+
+ fun showNotificationSettings(item: MenuItem){
+ val intent = Intent(this, NotificationSettingsActivity::class.java)
+ startActivity(intent)
+ }
+
+ fun showAbout(item: MenuItem){
+ val intent = Intent(this, AboutActivity::class.java)
+ startActivity(intent)
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/nareshkumarrao/eiweblog/NotificationSettingsActivity.kt b/app/src/main/java/com/nareshkumarrao/eiweblog/NotificationSettingsActivity.kt
new file mode 100644
index 0000000..4dd2d7a
--- /dev/null
+++ b/app/src/main/java/com/nareshkumarrao/eiweblog/NotificationSettingsActivity.kt
@@ -0,0 +1,17 @@
+package com.nareshkumarrao.eiweblog
+
+import androidx.appcompat.app.AppCompatActivity
+import android.os.Bundle
+import androidx.appcompat.widget.Toolbar
+
+class NotificationSettingsActivity : AppCompatActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_notification_settings)
+
+ val notificationsToolbar = this.findViewById(R.id.notification_toolbar)
+ setSupportActionBar(notificationsToolbar)
+ supportActionBar?.setDisplayHomeAsUpEnabled(true)
+ supportActionBar?.setDisplayShowTitleEnabled(false)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/nareshkumarrao/eiweblog/UpdateWorker.kt b/app/src/main/java/com/nareshkumarrao/eiweblog/UpdateWorker.kt
new file mode 100644
index 0000000..bbc3760
--- /dev/null
+++ b/app/src/main/java/com/nareshkumarrao/eiweblog/UpdateWorker.kt
@@ -0,0 +1,36 @@
+package com.nareshkumarrao.eiweblog
+
+import android.content.Context
+import androidx.work.Worker
+import androidx.work.WorkerParameters
+import java.math.BigInteger
+import java.security.MessageDigest
+
+class UpdateWorker(private val context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) {
+ override fun doWork(): Result {
+
+ Utilities.weblogList(context) { articles ->
+ val lastArticle = Utilities.getLatestRelevantArticle(articles)!!
+ val hashString = lastArticle.title + lastArticle.content + lastArticle.date
+ val oldHash = md5(hashString)
+
+ Utilities.fetchWeblogXML(applicationContext){newArticles ->
+ val lastNewArticle = Utilities.getLatestRelevantArticle(newArticles)!!
+ val newHashString = lastNewArticle.title + lastNewArticle.content + lastNewArticle.date
+ val newHash = md5(newHashString)
+
+ if(oldHash != newHash){
+ Utilities.sendNotification(context, lastNewArticle, newArticles.size)
+ }
+ }
+ }
+
+ return Result.success()
+ }
+
+ private fun md5(input:String): String {
+ val md = MessageDigest.getInstance("MD5")
+ return BigInteger(1, md.digest(input.toByteArray())).toString(16).padStart(32, '0')
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/nareshkumarrao/eiweblog/Utilities.kt b/app/src/main/java/com/nareshkumarrao/eiweblog/Utilities.kt
index 199cc08..07489f3 100644
--- a/app/src/main/java/com/nareshkumarrao/eiweblog/Utilities.kt
+++ b/app/src/main/java/com/nareshkumarrao/eiweblog/Utilities.kt
@@ -1,35 +1,74 @@
package com.nareshkumarrao.eiweblog
-import android.content.ContentValues
+import android.app.NotificationChannel
+import android.app.NotificationManager
+import android.app.PendingIntent
+import android.content.Intent
import android.content.Context
+import android.os.Build
import android.util.Log
import android.util.Xml
+import androidx.core.app.NotificationCompat
+import androidx.core.app.NotificationManagerCompat
+import androidx.core.text.HtmlCompat
import com.android.volley.Request
-import com.android.volley.Response
import com.android.volley.toolbox.StringRequest
import com.android.volley.toolbox.Volley
import com.nareshkumarrao.eiweblog.ui.main.Article
import org.xmlpull.v1.XmlPullParser
import java.io.StringReader
+
internal object Utilities {
- fun weblogXML(context: Context, function: (d: List) -> Unit) {
+
+ fun weblogList(context: Context?, function: (d: List) -> Unit){
+ val sharedPref = context?.getSharedPreferences(context?.getString(R.string.preference_file_key), Context.MODE_PRIVATE)
+ val weblogResponse = sharedPref?.getString( context?.getString(R.string.weblog_response_key), null)
+ if (weblogResponse == null){
+ fetchWeblogXML(context, function)
+ return
+ }
+
+ val parser: XmlPullParser = Xml.newPullParser()
+ parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false)
+ parser.setInput( StringReader(weblogResponse) )
+ parser.nextTag()
+ function(parseXML(parser))
+ }
+
+ fun fetchWeblogXML(context: Context?, function: (d: List) -> Unit) {
val queue = Volley.newRequestQueue(context)
- val url = "https://www.google.com"
+ val url = context?.getString(R.string.weblog_xml_url)
val stringRequest = StringRequest(Request.Method.GET, url,
{ response ->
- Log.d("XMLLIST", "got response!")
- // Display the first 500 characters of the response string.
- Log.d("XMLLIST", "$response")
+ val responseStr = String(response.toByteArray(Charsets.ISO_8859_1), Charsets.UTF_8)
+
+ val sharedPref = context?.getSharedPreferences(context?.getString(R.string.preference_file_key), Context.MODE_PRIVATE)
+ if (sharedPref != null) {
+ with (sharedPref.edit()) {
+ putString(context?.getString(R.string.weblog_response_key), responseStr)
+ apply()
+ }
+ }
+
+
+
+ val parser: XmlPullParser = Xml.newPullParser()
+ parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false)
+ //Log.d("XMLLIST", responseStr )
+ parser.setInput( StringReader(responseStr) )
+ parser.nextTag()
+
+ val articles = parseXML(parser)
+ function(articles)
+
},
{ error -> Log.e("XMLLIST", error.toString()) })
-
queue.add(stringRequest)
- Log.e("XMLLIST", "Adding request to queue from: $url")
}
private fun parseXML(parser: XmlPullParser): List {
@@ -56,7 +95,7 @@ internal object Utilities {
continue
}
if (parser.name == "z:row") {
- articles.add(parseZROW(parser))
+ parseZROW(parser)?.let { articles.add(it) }
} else {
parseSkip(parser)
}
@@ -64,16 +103,21 @@ internal object Utilities {
return articles
}
- private fun parseZROW(parser: XmlPullParser): Article {
+ private fun parseZROW(parser: XmlPullParser): Article? {
parser.require(XmlPullParser.START_TAG, null, "z:row")
val title = parser.getAttributeValue(null, "ows_Title")
val content = parser.getAttributeValue(null, "ows_Body")
val date = parser.getAttributeValue(null, "ows_Created")
val author = parser.getAttributeValue(null, "ows_Autor2")
+ val category = parser.getAttributeValue(null, "ows_Kategorie")
parser.nextTag()
- parser.require(XmlPullParser.END_TAG, null, "link")
+ parser.require(XmlPullParser.END_TAG, null, "z:row")
+
+ if(title == null || content == null || date == null || author == null || category == null){
+ return null
+ }
- return Article(title, content, date, author)
+ return Article(title, content, date, author, category)
}
private fun parseSkip(parser: XmlPullParser) {
@@ -88,4 +132,49 @@ internal object Utilities {
}
}
}
+
+ fun sendNotification(context: Context?, article: Article, id:Int) {
+ val intent = Intent(context, MainActivity::class.java).apply {
+ flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
+ }
+ val pendingIntent: PendingIntent = PendingIntent.getActivity(context, 0, intent, 0)
+
+ var builder = NotificationCompat.Builder(context!!, context.getString(R.string.channel_id))
+ .setSmallIcon(R.drawable.ic_stat_name)
+ .setContentTitle(article.title)
+ .setStyle(NotificationCompat.BigTextStyle()
+ .bigText(HtmlCompat.fromHtml(article.content, HtmlCompat.FROM_HTML_MODE_COMPACT)))
+ .setContentIntent(pendingIntent)
+ .setPriority(NotificationCompat.PRIORITY_DEFAULT)
+ .setAutoCancel(true)
+
+ with(NotificationManagerCompat.from(context)) {
+ // notificationId is a unique int for each notification that you must define
+ notify(id, builder.build())
+ }
+
+ }
+
+ fun createNotificationChannel(context: Context?){
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ val name = context?.getString(R.string.channel_name)
+ val descriptionText = context?.getString(R.string.channel_description)
+ val importance = NotificationManager.IMPORTANCE_DEFAULT
+ val channel = NotificationChannel(context?.getString(R.string.channel_id), name, importance).apply {
+ description = descriptionText
+ }
+ val notificationManager: NotificationManager = context?.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
+ notificationManager.createNotificationChannel(channel)
+ }
+ }
+
+ fun getLatestRelevantArticle(articles: List): Article? {
+ val sortedArticles = articles.sortedByDescending { it.date }
+ for (article in sortedArticles){
+ if( article.category == "Lehre" || article.category == "Prüfung" || article.category == "Sonstiges"){
+ return article
+ }
+ }
+ return null
+ }
}
diff --git a/app/src/main/java/com/nareshkumarrao/eiweblog/ui/main/ItemArticleAdapter.kt b/app/src/main/java/com/nareshkumarrao/eiweblog/ui/main/ItemArticleAdapter.kt
index ed6d1fa..8beabbf 100644
--- a/app/src/main/java/com/nareshkumarrao/eiweblog/ui/main/ItemArticleAdapter.kt
+++ b/app/src/main/java/com/nareshkumarrao/eiweblog/ui/main/ItemArticleAdapter.kt
@@ -1,26 +1,38 @@
package com.nareshkumarrao.eiweblog.ui.main
+import android.os.Build
+import android.text.Html
+import android.text.util.Linkify
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.TextView
+import androidx.core.text.HtmlCompat
import androidx.recyclerview.widget.RecyclerView
import com.nareshkumarrao.eiweblog.R
+import org.w3c.dom.Text
-data class Article(val title: String, val content: String, val date: String, val author: String)
+data class Article(val title: String, val content: String, val date: String, val author: String, val category: String)
class ItemArticleAdapter(private val articles: List) : RecyclerView.Adapter() {
inner class ViewHolder(inflater: LayoutInflater, parent: ViewGroup) : RecyclerView.ViewHolder(inflater.inflate(R.layout.item_article, parent, false)) {
private var title: TextView? = null
private var content: TextView? = null
+ private var date: TextView? = null
+ private var author: TextView? = null
init {
title = itemView.findViewById(R.id.titleText)
content = itemView.findViewById(R.id.contentText)
+ date = itemView.findViewById(R.id.dateText)
+ author = itemView.findViewById(R.id.authorText)
}
fun bind(article: Article) {
title?.text = article.title
- content?.text = article.content
+ content?.text = HtmlCompat.fromHtml(article.content, HtmlCompat.FROM_HTML_MODE_COMPACT)
+ content?.let { Linkify.addLinks(it, Linkify.WEB_URLS) };
+ author?.text = article.author
+ date?.text = article.date
}
}
diff --git a/app/src/main/java/com/nareshkumarrao/eiweblog/ui/main/SectionsFragment.kt b/app/src/main/java/com/nareshkumarrao/eiweblog/ui/main/SectionsFragment.kt
index 59c49c0..8383f51 100644
--- a/app/src/main/java/com/nareshkumarrao/eiweblog/ui/main/SectionsFragment.kt
+++ b/app/src/main/java/com/nareshkumarrao/eiweblog/ui/main/SectionsFragment.kt
@@ -7,11 +7,23 @@ import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
+import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.nareshkumarrao.eiweblog.R
+import com.nareshkumarrao.eiweblog.Utilities
+
+class SectionsFragment() : Fragment() {
+
+ private var swipeRefreshLayout: SwipeRefreshLayout? = null
-class SectionsFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
- return inflater.inflate(R.layout.fragment_sections, container, false)
+ val rootView = inflater.inflate(R.layout.fragment_sections, container, false)
+
+ this.swipeRefreshLayout = rootView.findViewById(R.id.sectionsSwipeRefresh)
+ this.swipeRefreshLayout?.setOnRefreshListener {
+ Utilities.fetchWeblogXML(this.context, ::updateView)
+ }
+
+ return rootView
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@@ -20,12 +32,36 @@ class SectionsFragment : Fragment() {
layoutManager = LinearLayoutManager(activity)
adapter = ItemArticleAdapter(listOf())
}
+ Utilities.weblogList(this.context, ::updateView)
+ }
+ companion object {
+ private const val ARG_SECTION_NAME = "section_title"
+
+ @JvmStatic
+ fun newInstance(title: String): SectionsFragment {
+ return SectionsFragment().apply {
+ arguments = Bundle().apply {
+ putString(ARG_SECTION_NAME, title)
+ }
+ }
+ }
}
- fun updateView(get_articles: List){
+
+ private fun updateView(get_articles: List){
+ this.swipeRefreshLayout?.isRefreshing=false
+ var articles: MutableList = mutableListOf()
+ val title = arguments?.getString(ARG_SECTION_NAME) ?: return
+ for (article in get_articles){
+ if(article.category == title){
+ articles.add(article)
+ }
+ }
+ articles.sortByDescending { it.date }
+
view?.findViewById(R.id.sectionsRecylerView)?.apply {
layoutManager = LinearLayoutManager(activity)
- adapter = ItemArticleAdapter(get_articles)
+ adapter = ItemArticleAdapter(articles)
}
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/nareshkumarrao/eiweblog/ui/main/SectionsPagerAdapter.kt b/app/src/main/java/com/nareshkumarrao/eiweblog/ui/main/SectionsPagerAdapter.kt
index 74bcc15..c3a230a 100644
--- a/app/src/main/java/com/nareshkumarrao/eiweblog/ui/main/SectionsPagerAdapter.kt
+++ b/app/src/main/java/com/nareshkumarrao/eiweblog/ui/main/SectionsPagerAdapter.kt
@@ -16,7 +16,7 @@ class SectionsPagerAdapter(private val context: Context, fm: FragmentManager)
: FragmentPagerAdapter(fm) {
override fun getItem(position: Int): Fragment {
- return SectionsFragment()
+ return SectionsFragment.newInstance( context.resources.getString(TAB_TITLES[position]) )
}
override fun getPageTitle(position: Int): CharSequence? {
diff --git a/app/src/main/res/drawable-hdpi/ic_stat_name.png b/app/src/main/res/drawable-hdpi/ic_stat_name.png
new file mode 100644
index 0000000..d4cbf09
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_stat_name.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_stat_name.png b/app/src/main/res/drawable-mdpi/ic_stat_name.png
new file mode 100644
index 0000000..5464f21
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_stat_name.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_stat_name.png b/app/src/main/res/drawable-xhdpi/ic_stat_name.png
new file mode 100644
index 0000000..c026274
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_stat_name.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_stat_name.png b/app/src/main/res/drawable-xxhdpi/ic_stat_name.png
new file mode 100644
index 0000000..1db9724
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_stat_name.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_stat_name.png b/app/src/main/res/drawable-xxxhdpi/ic_stat_name.png
new file mode 100644
index 0000000..ef47fb6
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_stat_name.png differ
diff --git a/app/src/main/res/drawable/toolbar_dropshadow.xml b/app/src/main/res/drawable/toolbar_dropshadow.xml
new file mode 100644
index 0000000..e7d6ab9
--- /dev/null
+++ b/app/src/main/res/drawable/toolbar_dropshadow.xml
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/app/src/main/res/layout/activity_about.xml b/app/src/main/res/layout/activity_about.xml
new file mode 100644
index 0000000..4efb1cf
--- /dev/null
+++ b/app/src/main/res/layout/activity_about.xml
@@ -0,0 +1,116 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 2bec83f..1a87dd3 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -14,7 +14,7 @@
android:theme="@style/Theme.EIWeblog.AppBarOverlay">
diff --git a/app/src/main/res/layout/activity_notification_settings.xml b/app/src/main/res/layout/activity_notification_settings.xml
new file mode 100644
index 0000000..2a70c2d
--- /dev/null
+++ b/app/src/main/res/layout/activity_notification_settings.xml
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_sections.xml b/app/src/main/res/layout/fragment_sections.xml
index c11783f..58e4ec8 100644
--- a/app/src/main/res/layout/fragment_sections.xml
+++ b/app/src/main/res/layout/fragment_sections.xml
@@ -3,8 +3,16 @@
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent">
-
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/toolbar_menu.xml b/app/src/main/res/menu/toolbar_menu.xml
index 7b29204..68fe0f8 100644
--- a/app/src/main/res/menu/toolbar_menu.xml
+++ b/app/src/main/res/menu/toolbar_menu.xml
@@ -1,6 +1,12 @@
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
index eca70cf..036d09b 100644
--- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -1,5 +1,5 @@
-
-
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
index eca70cf..036d09b 100644
--- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -1,5 +1,5 @@
-
-
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png
index a571e60..80d6c2e 100644
Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000..4c0534a
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
index 61da551..eb98ad1 100644
Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png
index c41dd28..8ff8a3a 100644
Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000..6188a57
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
index db5080a..a3069b3 100644
Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
index 6dba46d..16d6877 100644
Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000..a57c1ba
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
index da31a87..85ad7ee 100644
Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
index 15ac681..4f62e83 100644
Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000..d2b1754
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
index b216f2d..830780b 100644
Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
index f25a419..d00bcfa 100644
Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000..f4a9bf1
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
index e96783c..7bb4f14 100644
Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml
deleted file mode 100644
index dcb8506..0000000
--- a/app/src/main/res/values-night/themes.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/values/ic_launcher_background.xml b/app/src/main/res/values/ic_launcher_background.xml
new file mode 100644
index 0000000..c5d5899
--- /dev/null
+++ b/app/src/main/res/values/ic_launcher_background.xml
@@ -0,0 +1,4 @@
+
+
+ #FFFFFF
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 256f5e1..e46f1ad 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -5,8 +5,30 @@
Sonstiges
HSD
Benachrichtigungen
Information
+ com.nareshkumarrao.eiweblog.preferences
+ weblog_response
+ Veranstaltungen
+
+ My name is Naresh and I am doing my Master\'s in Automation at the HSD.\n
+ \nI wrote this app because I was unsatisfied with the EI weblog that was always silently being
+ updated. The other option would be to develop enough self-discipline to check it regulary.
+ Yeah no thanks.\n
+ \nI put too many hours of work into this app, and if you like it and found it useful, I would really
+ appreciate it if you bought me a beer, or maybe a tasty döner.
+
+ Information
+ Send me €5 for beer on PayPal
+ This project is developed open-source and is to be distributed freely
+ as contained within the terms of the GPLv3 license. More information about the license and the
+ source code of this project can be found on its GitHub repository.
+
+ EI Weblog Notifications
+ Latest updates from the EI Weblog
+ com.nareshkumarrao.eiweblog.update
+ Benachrichtigungen
+ Notify me when new updates are posted to the weblog
\ No newline at end of file
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index 8dae71f..050154c 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -1,6 +1,6 @@
-
diff --git a/images/launcher.png b/images/launcher.png
new file mode 100644
index 0000000..69758fa
Binary files /dev/null and b/images/launcher.png differ
diff --git a/images/launcher.svg b/images/launcher.svg
new file mode 100644
index 0000000..a003e91
--- /dev/null
+++ b/images/launcher.svg
@@ -0,0 +1,82 @@
+
+