Skip to content
Snippets Groups Projects
Commit 71bf2321 authored by Andrej Rasevic's avatar Andrej Rasevic
Browse files

adding Lab6_NotificatonsLab

parent 7d2090d1
No related branches found
No related tags found
No related merge requests found
Showing
with 1089 additions and 0 deletions
# built application files
*.apk
*.ap_
# files for the dex VM
*.dex
# Java class files
*.class
# generated files
bin/
gen/
# Local configuration file (sdk path, etc)
local.properties
# Eclipse project files
.classpath
.settings
# Proguard folder generated by Eclipse
proguard/
# Intellij project files
*.iml
*.ipr
*.iws
.idea
.idea/workspace.xml
.gradle
build/
captures/
# Mac files
.DS_Store
# Windows thumbnail db
Thumbs.db
File added
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
android {
compileSdkVersion 26
buildToolsVersion '29.0.3'
defaultConfig {
applicationId "course.labs.notificationslab"
minSdkVersion 21
//noinspection OldTargetApi
targetSdkVersion 26
testApplicationId "course.labs.notificationslab.tests"
testInstrumentationRunner "android.test.InstrumentationTestRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
}
dependencies {
androidTestImplementation 'com.jayway.android.robotium:robotium-solo:5.6.3'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
//noinspection GradleCompatible
implementation 'com.android.support:support-v4:26.1.0'
}
repositories {
mavenCentral()
}
<?xml version="1.0" encoding="utf-8"?>
<lint>
<issue id="NewApi">
<ignore path="src/course/labs/notificationslab/DownloaderTask.java" />
</issue>
</lint>
\ No newline at end of file
package course.labs.notificationslab.tests
import android.test.ActivityInstrumentationTestCase2
import android.view.View
import com.robotium.solo.Solo
import course.labs.notificationslab.MainActivity
import course.labs.notificationslab.R
import course.labs.notificationslab.TestFrontEndActivity
class OldFeedNoNotificationTest : ActivityInstrumentationTestCase2<TestFrontEndActivity>(TestFrontEndActivity::class.java) {
private var solo: Solo? = null
@Throws(Exception::class)
public override fun setUp() {
solo = Solo(instrumentation, activity)
}
@Throws(Exception::class)
public override fun tearDown() {
solo!!.finishOpenedActivities()
}
fun testRun() {
val shortDelay = 2000
val longDelay = 10000
// Wait for activity:
// 'course.labs.notificationslab.TestFrontEndActivity'
solo!!.waitForActivity(
TestFrontEndActivity::class.java, shortDelay)
// Click on Make Tweets Old
solo!!.clickOnView(solo!!
.getView(R.id.age_tweets_button))
// Click on Start Main Activty
solo!!.clickOnView(solo!!
.getView(R.id.start_main_button))
// Wait for activity: 'course.labs.notificationslab.MainActivity'
assertTrue("course.labs.notificationslab.MainActivity is not found!",
solo!!.waitForActivity(
MainActivity::class.java, shortDelay))
// Assert that: Toast message is shown
val msg = activity.getString(R.string.download_in_progress_string)
assertTrue("'$msg ' is not shown!",
solo!!.searchText(msg))
solo!!.waitForView(android.R.id.list)
val listView = solo!!.getView(android.R.id.list)
solo!!.waitForCondition({ listView.isEnabled }, longDelay)
val failMsg = activity.getString(R.string.download_failed_string)
val successMsg = activity.getString(R.string.download_succes_string)
assertTrue("Toast message did not appear", solo!!.searchText("($failMsg|$successMsg)"))
// Click on ladygaga
solo!!.clickOnView(solo!!.getView(android.R.id.text1))
// Assert that: 'feed_view' is shown
assertTrue("feed_view' is not shown!", solo!!.waitForView<View?>(solo!!
.getView(R.id.feed_view)))
}
}
\ No newline at end of file
package course.labs.notificationslab.tests
import android.test.ActivityInstrumentationTestCase2
import com.robotium.solo.Solo
import course.labs.notificationslab.MainActivity
import course.labs.notificationslab.R
import course.labs.notificationslab.TestFrontEndActivity
class OldFeedWithNotificationTest : ActivityInstrumentationTestCase2<TestFrontEndActivity>(TestFrontEndActivity::class.java) {
private var solo: Solo? = null
@Throws(Exception::class)
public override fun setUp() {
solo = Solo(instrumentation)
activity
}
@Throws(Exception::class)
public override fun tearDown() {
solo!!.finishOpenedActivities()
}
fun testRun() {
val shortDelay = 2000
// Clear the log
solo!!.clearLog()
// Wait for activity:
// 'course.labs.notificationslab.TestFrontEndActivity'
solo!!.waitForActivity(
TestFrontEndActivity::class.java,
shortDelay)
// Click on Make Tweets Old
solo!!.clickOnView(solo!!
.getView(R.id.age_tweets_button))
// Click on Start Main Activity
solo!!.clickOnView(solo!!
.getView(R.id.start_main_button))
// Wait for activity: 'course.labs.notificationslab.MainActivity'
assertTrue(
"course.labs.notificationslab.MainActivity is not found!",
solo!!.waitForActivity(MainActivity::class.java))
// Press menu back key
solo!!.goBackToActivity("TestFrontEndActivity")
/*
// Wait for activity:
// 'course.labs.notificationslab.TestFrontEndActivity'
// assertTrue(
// "course.labs.notificationslab.TestFrontEndActivity is not found!",
// solo.waitForActivity(course.labs.notificationslab.TestFrontEndActivity.class));
*/
// Wait for activity: 'course.labs.notificationslab.TestFrontEndActivity'
assertTrue(
"course.labs.notificationslab.TestFrontEndActivity is not found!",
solo!!.waitForActivity(TestFrontEndActivity::class.java))
// Robotium can't check notification area directly
val msg = activity.getString(R.string.notification_sent_string)
assertTrue("Notification was not sent", solo!!.waitForText(msg))
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="course.labs.notificationslab"
android:versionCode="1"
android:versionName="1.0" >
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:fullBackupContent="@xml/backup_descriptor">
<activity
android:name="course.labs.notificationslab.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="course.labs.notificationslab.TestFrontEndActivity"
android:label="@string/title_activity_test_front_end" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
\ No newline at end of file
package course.labs.notificationslab
internal interface DownloadFinishedListener {
open fun notifyDataRefreshed(feeds: Array<String?>?)
}
\ No newline at end of file
@file:Suppress("unused")
package course.labs.notificationslab
import android.annotation.SuppressLint
import android.app.*
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.AsyncTask
import android.os.Build
import android.os.Bundle
import android.support.v4.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.RemoteViews
import android.widget.Toast
import java.io.*
class DownloaderTaskFragment : Fragment() {
private var mDownloaderTask: DownloaderTask? = null
private var mCallback: DownloadFinishedListener? = null
private lateinit var mContext: Context
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
super.onCreate(savedInstanceState)
mDownloaderTask = DownloaderTask()
val tmp = arguments.getIntegerArrayList(
MainActivity.TAG_FRIEND_RES_IDS)
var feeds = arrayOfNulls<Int>(tmp!!.size)
feeds = tmp.toArray(feeds)
mDownloaderTask!!.execute(*feeds)
return inflater.inflate(R.layout.feed, container, false)
}
// Assign current hosting Activity to mCallback
// Store application context for use by downloadTweets()
override fun onAttach(context: Context) {
super.onAttach(context)
mContext = context
// Make sure that the hosting activity has implemented
// the correct callback interface.
try {
mCallback = context as DownloadFinishedListener
} catch (e: ClassCastException) {
throw ClassCastException("$context must implement DownloadFinishedListener")
}
}
// Null out mCallback
override fun onDetach() {
super.onDetach()
mCallback = null
}
// This class is an AsyncTask, Async has been deprecated by API 30, therefore
// you will not have to implement doInBackground and onPostExecute
@SuppressLint("StaticFieldLeak")
inner class DownloaderTask : AsyncTask<Int?, Void?, Array<String?>>() {
override fun doInBackground(vararg resourceIDs: Int?): Array<String?> {
return downloadTweets(resourceIDs as Array<Int>)
}
// Simulates downloading Twitter data from the network
private fun downloadTweets(resourceIDS: Array<Int>): Array<String?> {
val simulatedDelay = 2000
val feeds = arrayOfNulls<String>(resourceIDS.size)
var downLoadCompleted = false
try {
for (idx in resourceIDS.indices) {
var `in`: BufferedReader
try {
// Pretend downloading takes a long time
Thread.sleep(simulatedDelay.toLong())
} catch (e: InterruptedException) {
e.printStackTrace()
}
val inputStream: InputStream? = mContext.resources.openRawResource(
resourceIDS[idx])
`in` = BufferedReader(InputStreamReader(inputStream))
var readLine: String?
val buf = StringBuffer()
while (`in`.readLine().also { readLine = it } != null) {
buf.append(readLine)
}
feeds[idx] = buf.toString()
`in`.close()
}
downLoadCompleted = true
saveTweetsToFile(feeds)
} catch (e: IOException) {
e.printStackTrace()
}
// Notify user that downloading has finished
notify(downLoadCompleted)
return feeds
}
// If necessary, notifies the user that the tweet downloads are
// complete. Sends an ordered broadcast back to the BroadcastReceiver in
// MainActivity to determine whether the notification is necessary.
private fun notify(success: Boolean) {
val restartMainActivityIntent = Intent(mContext,
MainActivity::class.java)
restartMainActivityIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
// Sends an ordered broadcast to determine whether MainActivity is
// active and in the foreground. Creates a new BroadcastReceiver
// to receive a result indicating the state of MainActivity
// TODO: The Action for this broadcast Intent is MainActivity.DATA_REFRESHED_ACTION
// The result, MainActivity.IS_ALIVE, indicates that MainActivity is
// active and in the foreground.
mContext.sendOrderedBroadcast(Intent(
MainActivity.DATA_REFRESHED_ACTION), null,
object : BroadcastReceiver() {
val failMsg = mContext
.getString(R.string.download_failed_string)
val successMsg = mContext
.getString(R.string.download_succes_string)
val notificationSentMsg = mContext
.getString(R.string.notification_sent_string)
override fun onReceive(context: Context, intent: Intent) {
// TODO: Check whether or not the MainActivity
// received the broadcast
if (true) {
// TODO: If not, create a PendingIntent using the
// restartMainActivityIntent and set its flags
// to FLAG_UPDATE_CURRENT
// Uses R.layout.custom_notification for the
// layout of the notification View. The xml
// file is in res/layout/custom_notification.xml
val mContentView = RemoteViews(
mContext.packageName,
R.layout.custom_notification)
// TODO: Set the notification View's text to
// reflect whether the download completed
// successfully
// TODO: Use the Notification.Builder class to
// create the Notification. You will have to set
// several pieces of information. You can use
// android.R.drawable.stat_sys_warning
// for the small icon. You should also
// setAutoCancel(true).
// TODO: Send the notification
} else {
Toast.makeText(mContext,
if (success) successMsg else failMsg,
Toast.LENGTH_LONG).show()
}
}
}, null, 0, null, null)
}
private val channelID = "my_channel_01"
private fun createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// TODO: Create Notification Channel with id channelID,
// name R.string.channel_name
// and description R.string.channel_description of high importance
}
}
// Saves the tweets to a file
private fun saveTweetsToFile(result: Array<String?>) {
var writer: PrintWriter? = null
try {
val fos = mContext.openFileOutput(
MainActivity.TWEET_FILENAME, Context.MODE_PRIVATE)
writer = PrintWriter(BufferedWriter(
OutputStreamWriter(fos)))
for (s in result) {
writer.println(s)
}
} catch (e: IOException) {
e.printStackTrace()
} finally {
writer?.close()
}
}
// Pass newly available data back to hosting Activity
// using the DownloadFinishedListener interface
override fun onPostExecute(result: Array<String?>) {
super.onPostExecute(result)
if (null != mCallback) {
mCallback!!.notifyDataRefreshed(result)
}
}
}
companion object {
private const val TAG = "Lab-Notifications"
private const val MY_NOTIFICATION_ID = 11151990
}
}
\ No newline at end of file
package course.labs.notificationslab
import android.os.Bundle
import android.support.v4.app.Fragment
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
class FeedFragment : Fragment() {
private var mTextView: TextView? = null
private var feedFragmentData: FeedFragmentData? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.feed, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
// Read in all Twitter feeds
if (null == feedFragmentData) {
feedFragmentData = FeedFragmentData(activity)
}
}
// Display Twitter feed for selected feed
fun updateFeedDisplay(position: Int) {
Log.i(TAG, "Entered updateFeedDisplay()")
mTextView = view!!.findViewById<View>(R.id.feed_view) as TextView
mTextView!!.text = feedFragmentData!!.getFeed(position)
}
companion object {
private const val TAG = "Lab-Notifications"
}
}
\ No newline at end of file
package course.labs.notificationslab
import android.content.Context
import android.util.Log
import android.util.SparseArray
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader
// Utility class that provides stored Twitter feed data
class FeedFragmentData(private val mContext: Context) {
private val mFeeds = SparseArray<String>()
init {
loadFeeds()
}
// Load all stored Twitter feeds into the mFeeds SparseArray.
private fun loadFeeds() {
for (id in IDS) {
val inputStream = mContext.resources.openRawResource(
id)
val reader = BufferedReader(InputStreamReader(
inputStream))
val buffer = StringBuffer("")
// Read raw data from resource file
try {
var line = reader.readLine()
while (line != null) {
buffer.append(line)
line = reader.readLine()
}
} catch (e: IOException) {
Log.i(TAG, "IOException")
}
// Convert raw data into a String
var feed: JSONArray? = null
try {
feed = JSONArray(buffer.toString())
} catch (e: JSONException) {
Log.i(TAG, "JSONException")
}
mFeeds.put(id, procFeed(feed!!))
}
}
// Convert JSON formatted data to a String
private fun procFeed(feed: JSONArray): String {
var name = ""
var tweet = ""
// string buffer for twitter feeds
val textFeed = StringBuffer("")
for (j in 0 until feed.length()) {
try {
tweet = feed.getJSONObject(j).getString("text")
val user = feed.getJSONObject(j)
.get("user") as JSONObject
name = user.getString("name")
} catch (e: JSONException) {
Log.i(TAG, "JSONException while processing feed")
}
textFeed.append("$name - $tweet\n\n")
}
return textFeed.toString()
}
// Return the Twitter feed data for the specified position as a single String
internal fun getFeed(position: Int): String {
return mFeeds.get(IDS[position])
}
companion object {
private const val TAG = "FeedFragmentData"
private val IDS = intArrayOf(R.raw.ladygaga, R.raw.rebeccablack, R.raw.taylorswift)
}
}
package course.labs.notificationslab
import android.content.Context
import android.os.Bundle
import android.support.v4.app.ListFragment
import android.util.Log
import android.view.View
import android.widget.ArrayAdapter
import android.widget.ListView
class FriendsFragment : ListFragment() {
private lateinit var mCallback: SelectionListener
interface SelectionListener {
fun onItemSelected(position: Int)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Set the list adapter for this ListFragment
listAdapter = ArrayAdapter(activity, android.R.layout.simple_list_item_activated_1, FRIENDS)
}
override fun onAttach(context: Context) {
super.onAttach(context)
// Make sure that the hosting Activity has implemented
// the SelectionListener callback interface. We need this
// because when an item in this ListFragment is selected,
// the hosting Activity's onItemSelected() method will be called.
try {
mCallback = context as SelectionListener
} catch (e: ClassCastException) {
throw ClassCastException("$context must implement SelectionListener")
}
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
Log.i(TAG, "Entered onActivityCreated()")
}
override fun onListItemClick(l: ListView, view: View, position: Int, id: Long) {
// Notify the hosting Activity that a selection has been made.
mCallback.onItemSelected(position)
}
companion object {
private val FRIENDS = arrayOf("ladygaga", "msrebeccablack", "taylorswift13")
private const val TAG = "Lab-Notifications"
}
}
\ No newline at end of file
package course.labs.notificationslab
import android.content.BroadcastReceiver
import android.content.Intent
import android.content.Context
import android.content.IntentFilter
import android.support.v4.app.FragmentActivity
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
import java.io.BufferedReader
import java.io.FileNotFoundException
import java.io.IOException
import java.io.InputStreamReader
class MainActivity : FragmentActivity(), FriendsFragment.SelectionListener, DownloadFinishedListener {
private lateinit var mFriendsFragment: FriendsFragment
private lateinit var mFeedFragment: FeedFragment
private lateinit var mDownloaderFragment: DownloaderTaskFragment
private var mIsInteractionEnabled = false
private var mFormattedFeeds: Array<String?>? = arrayOfNulls<String?>(sRawTextFeedIds.size)
private var mIsFresh = false
private var mRefreshReceiver: BroadcastReceiver? = null
override fun onCreate(savedInstanceState: Bundle?) {
Log.d(TAG, "Starting MainActivity")
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mFeedFragment = FeedFragment()
// Reset instance state on reconfiguration
if (null != savedInstanceState) {
restoreState(savedInstanceState)
} else {
setupFragments()
}
}
// One time setup of UI and retained (headless) Fragment
private fun setupFragments() {
installFriendsFragment()
// The feed is fresh if it was downloaded less than 2 minutes ago
mIsFresh = System.currentTimeMillis() - getFileStreamPath(
TWEET_FILENAME).lastModified() < TWO_MIN
if (!mIsFresh) {
installDownloaderTaskFragment()
// TODO: Show a Toast message displaying
// R.string.download_in_progress string
// Set up a BroadcastReceiver to receive an Intent when download
// finishes.
mRefreshReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
// TODO: Check to make sure this is an ordered broadcast
// Let sender know that the Intent was received
// by setting result code to MainActivity.IS_ALIVE
}
}
} else {
// Process Twitter data taken from stored file
parseJSON(loadTweetsFromFile())
// Enable user interaction
mIsInteractionEnabled = true
}
}
// Add Friends Fragment to Activity
private fun installFriendsFragment() {
// Make new Fragment
mFriendsFragment = FriendsFragment()
// Give Fragment to the FragmentManager
val transaction = supportFragmentManager.beginTransaction()
transaction.replace(R.id.fragment_container, mFriendsFragment,
TAG_FRIENDS_FRAGMENT)
transaction.commit()
}
// Add DownloaderTaskFragment to Activity
private fun installDownloaderTaskFragment() {
// Make new Fragment
mDownloaderFragment = DownloaderTaskFragment()
// Set DownloaderTaskFragment arguments
val args = Bundle()
args.putIntegerArrayList(TAG_FRIEND_RES_IDS, sRawTextFeedIds)
mDownloaderFragment.arguments = args
// Give Fragment to the FragmentManager
supportFragmentManager.beginTransaction()
.add(mDownloaderFragment, TAG_DOWNLOADER_FRAGMENT).commit()
}
// Register the BroadcastReceiver
override fun onResume() {
super.onResume()
// TODO: Register the BroadcastReceiver to receive a
// DATA_REFRESHED_ACTION broadcast
}
override fun onPause() {
// TODO: Unregister the BroadcastReceiver if it has been registered
// Note: check that mRefreshReceiver is not null before attempting to
// unregister in order to work around an Instrumentation issue
super.onPause()
}
/*
* DownloadFinishedListener method
*/
// Called back by DownloaderTask after data has been loaded
override fun notifyDataRefreshed(feeds: Array<String?>?) {
// Process downloaded data
parseJSON(feeds)
// Enable user interaction
mIsInteractionEnabled = true
}
// Installs the FeedFragment when a Friend name is
// selected in the FriendsFragment
override fun onItemSelected(position: Int) {
if (mFeedFragment == null) {
mFeedFragment = FeedFragment()
}
val transaction = supportFragmentManager.beginTransaction()
transaction.replace(R.id.fragment_container, mFeedFragment)
transaction.addToBackStack(null)
transaction.commit()
supportFragmentManager.executePendingTransactions()
mFeedFragment.updateFeedDisplay(position)
}
// Restore saved instance state
private fun restoreState(savedInstanceState: Bundle?) {
// Fragments tags were saved in onSavedInstanceState
mFriendsFragment = supportFragmentManager
.findFragmentByTag(savedInstanceState!!
.getString(TAG_FRIENDS_FRAGMENT)) as FriendsFragment
mFeedFragment = supportFragmentManager
.findFragmentByTag(savedInstanceState
.getString(TAG_FEED_FRAGMENT)) as FeedFragment
mDownloaderFragment = supportFragmentManager
.findFragmentByTag(savedInstanceState
.getString(TAG_DOWNLOADER_FRAGMENT)) as DownloaderTaskFragment
mIsInteractionEnabled = savedInstanceState
.getBoolean(TAG_IS_DATA_AVAILABLE)
if (mIsInteractionEnabled) {
mFormattedFeeds = savedInstanceState
.getStringArray(TAG_PROCESSED_FEEDS)
}
}
// Convert raw data (in JSON format) into text for display
private fun parseJSON(feeds: Array<String?>?) {
val jsonFeeds = arrayOfNulls<JSONArray?>(feeds!!.size)
for (i in jsonFeeds.indices) {
try {
jsonFeeds[i] = JSONArray(feeds[i])
} catch (e: JSONException) {
e.printStackTrace()
}
var name = ""
var tweet = ""
val tmp = jsonFeeds[i]
// string buffer for feeds
val tweetRec = StringBuffer("")
for (j in 0 until tmp!!.length()) {
try {
tweet = tmp.getJSONObject(j).getString(TAG_TEXT)
val user = tmp.getJSONObject(j)[TAG_USER] as JSONObject
name = user.getString(TAG_NAME)
} catch (e: JSONException) {
e.printStackTrace()
}
tweetRec.append("$name - $tweet\n\n")
}
}
}
// Retrieve feeds text from a file
// Store them in mRawTextFeed[]
private fun loadTweetsFromFile(): Array<String?>? {
var reader: BufferedReader? = null
val rawFeeds = ArrayList<String?>()
try {
val fis = openFileInput(TWEET_FILENAME)
reader = BufferedReader(InputStreamReader(fis))
var s: String?
var i = 0
while (null != reader.readLine().also { s = it }) {
rawFeeds.add(i, s)
i++
}
} catch (e: FileNotFoundException) {
e.printStackTrace()
} catch (e: IOException) {
e.printStackTrace()
} finally {
if (null != reader) {
try {
reader.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
}
return rawFeeds.toTypedArray()
}
companion object {
private const val TAG_NAME: String = "name"
private const val TAG_USER: String = "user"
private const val TAG_TEXT: String = "text"
private const val TAG_FRIENDS_FRAGMENT: String = "friends_fragment"
private const val TAG_FEED_FRAGMENT: String = "feed_fragment"
private const val TAG_DOWNLOADER_FRAGMENT: String = "downloader_fragment"
private const val TAG_IS_DATA_AVAILABLE: String = "is_data_available"
private const val TAG_PROCESSED_FEEDS: String = "processed_feeds"
const val TAG_FRIEND_RES_IDS: String = "friends"
const val TWEET_FILENAME: String = "tweets.txt"
const val IS_ALIVE = RESULT_FIRST_USER
const val DATA_REFRESHED_ACTION: String = "course.labs.notificationslabnew.DATA_REFRESHED"
private const val TAG: String = "Lab-Notifications"
// Raw feed file IDs used to reference stored tweet data
val sRawTextFeedIds: ArrayList<Int> = arrayListOf(R.raw.ladygaga, R.raw.rebeccablack, R.raw.taylorswift)
private const val TWO_MIN = 2 * 60 * 1000.toLong()
}
}
\ No newline at end of file
package course.labs.notificationslab
import android.app.Activity
import android.content.Intent
import android.content.res.Resources.NotFoundException
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.Button
import java.io.*
class TestFrontEndActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
Log.d(TAG, "Starting FrontEndActivity...")
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_test_front_end)
sFileName = filesDir.toString() + "/" + MainActivity.TWEET_FILENAME
val ageTweetsButton = findViewById<View?>(R.id.age_tweets_button) as Button
ageTweetsButton.setOnClickListener { setFileAge(DAWN_OF_TIME) }
val rejuvTweetsButton = findViewById<View?>(R.id.rejuv_tweets_button) as Button
rejuvTweetsButton.setOnClickListener { setFileAge(System.currentTimeMillis()) }
val startMainActivityButton = findViewById<View?>(R.id.start_main_button) as Button
startMainActivityButton.setOnClickListener {
startActivity(Intent(this@TestFrontEndActivity,
MainActivity::class.java))
}
createTweetFileIfMissing()
}
private fun createTweetFileIfMissing() {
val file = File(sFileName)
if (!file.exists()) {
var out: PrintWriter? = null
var `in`: BufferedReader? = null
try {
out = PrintWriter(BufferedWriter(
OutputStreamWriter(openFileOutput(
MainActivity.TWEET_FILENAME,
MODE_PRIVATE))))
for (resId in MainActivity.sRawTextFeedIds) {
`in` = BufferedReader(InputStreamReader(
resources.openRawResource(resId)))
var line: String?
val buffer = StringBuffer()
while (`in`.readLine().also { line = it } != null) {
buffer.append(line)
}
out.println(buffer)
}
} catch (e: FileNotFoundException) {
e.printStackTrace()
} catch (e: NotFoundException) {
e.printStackTrace()
} catch (e: IOException) {
e.printStackTrace()
} finally {
try {
`in`?.close()
out?.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
}
}
private fun setFileAge(timestamp: Long) {
val file = File(sFileName)
if (file.exists()) {
file.setLastModified(timestamp)
}
}
companion object {
private const val DAWN_OF_TIME: Long = 0
private val TAG: String? = "TestFrontEndActivity"
private var sFileName: String? = null
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:ignore="MergeRootFrame" />
\ No newline at end of file
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".TestFrontEndActivity" >
<Button
android:id="@+id/rejuv_tweets_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_margin="@dimen/base_margin"
android:text="@string/make_tweets_new" />
<Button
android:id="@+id/age_tweets_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_margin="@dimen/base_margin"
android:text="@string/make_tweets_old" />
<Button
android:id="@+id/start_main_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_margin="@dimen/base_margin"
android:text="@string/start_main_activity" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/toast_layout_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#7777"
android:padding="3dp"
tools:ignore="Overdraw">
<ImageView
android:id="@+id/image"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_marginEnd="10dp"
android:contentDescription="@string/alert_string"
android:src="@android:drawable/ic_dialog_info" />
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFF"
android:textSize="24sp" />
</LinearLayout>
\ No newline at end of file
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".FeedFragment" >
<TextView
android:id="@+id/feed_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"/>
</ScrollView>
\ No newline at end of file
labs/Lab6_NotificationsLab/app/src/main/res/mipmap-hdpi/ic_launcher.png

8.02 KiB

0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment