diff options
22 files changed, 793 insertions, 73 deletions
diff --git a/app/build.gradle b/app/build.gradle index 3663e88..9aa7285 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -22,4 +22,5 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:22.0.0' + compile 'com.android.support:support-v4:22.0.0' } diff --git a/app/src/androidTest/java/org/rssin/neurons/FeedSorterTest.java b/app/src/androidTest/java/org/rssin/neurons/FeedSorterTest.java new file mode 100755 index 0000000..a2d59ee --- /dev/null +++ b/app/src/androidTest/java/org/rssin/neurons/FeedSorterTest.java @@ -0,0 +1,66 @@ +package org.rssin.neurons;
+
+import android.util.Log;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.rssin.rss.FeedItem;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+
+public class FeedSorterTest extends TestCase {
+
+ public void testFeedback() throws Exception {
+ Log.d("FeedSorterTest", "Dit is een test");
+ Assert.assertTrue(true);
+ }
+
+ public void testSortItems() throws Exception {
+ List<String> gameList = new ArrayList<>();
+ gameList.add("Games");
+ List<String> sportList = new ArrayList<>();
+ sportList.add("Sport");
+
+ FeedItem[] likedItems = new FeedItem[]
+ {
+ new FeedItem("", new Date(), "TITEL", "DESCRIPTION", "", "Randy", gameList, "", "", ""),
+ };
+
+ FeedItem[] dislikedItems = new FeedItem[]
+ {
+ new FeedItem("", new Date(), "TITEL", "DESCRIPTION", "", "Randy", sportList, "", "", ""),
+ };
+
+ FeedSorter s = new FeedSorter();
+
+ //I like games & I hate sports
+ for(int i = 0; i < 100; i++)
+ {
+ for(FeedItem item : likedItems)
+ {
+ s.feedback(item, Feedback.Like);
+ }
+
+ for(FeedItem item : dislikedItems)
+ {
+ s.feedback(item, Feedback.Dislike);
+ }
+ }
+
+ FeedItem sportsItem = new FeedItem("", new Date(2014, 1, 1, 1, 2, 1), "SPORT ARTICLE", "DESCRIPTION", "", "Randy", sportList, "", "", "");
+ FeedItem gamesItem = new FeedItem("", new Date(2014, 1, 1, 1, 1, 1), "GAME ARTICLE", "DESCRIPTION", "", "Randy", gameList, "", "", "");
+
+ List<FeedItem> testItems = new LinkedList<>();
+ testItems.add(sportsItem);
+ testItems.add(gamesItem);
+
+ List<FeedItem> sortedItems = s.sortItems(testItems);
+ Assert.assertEquals(sortedItems.get(0), gamesItem);
+ Assert.assertEquals(sortedItems.get(1), sportsItem);
+ }
+}
\ No newline at end of file diff --git a/app/src/androidTest/java/org/rssin/neurons/NeuralNetworkTest.java b/app/src/androidTest/java/org/rssin/neurons/NeuralNetworkTest.java new file mode 100755 index 0000000..b0f6eea --- /dev/null +++ b/app/src/androidTest/java/org/rssin/neurons/NeuralNetworkTest.java @@ -0,0 +1,133 @@ +package org.rssin.neurons;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+public class NeuralNetworkTest extends TestCase {
+
+ public void testAnd() throws Exception {
+ MultiNeuralNetwork nn = new MultiNeuralNetwork(10, 2);
+ nn.addInput();
+ nn.addInput();
+ nn.addInput();
+
+ //Simple AND
+ for (int i = 0; i < 100; i++)
+ {
+ PredictionInterface p1 = nn.computeOutput(new double[] {
+ 1,
+ -1,
+ -1,
+ });
+ p1.learn(-1);
+
+ PredictionInterface p2 = nn.computeOutput(new double[] {
+ 1,
+ -1,
+ 1,
+ });
+ p2.learn(-1);
+
+ PredictionInterface p3 = nn.computeOutput(new double[] {
+ 1,
+ 1,
+ -1,
+ });
+ p3.learn(-1);
+
+ PredictionInterface p4 = nn.computeOutput(new double[] {
+ 1,
+ 1,
+ 1,
+ });
+ p4.learn(1);
+ }
+
+ Assert.assertTrue(nn.computeOutput(new double[] {
+ 1,
+ -1,
+ -1,
+ }).getOutput() < 0);
+
+ Assert.assertTrue(nn.computeOutput(new double[] {
+ 1,
+ 1,
+ -1,
+ }).getOutput() < 0);
+
+ Assert.assertTrue(nn.computeOutput(new double[] {
+ 1,
+ -1,
+ 1,
+ }).getOutput() < 0);
+
+ Assert.assertTrue(nn.computeOutput(new double[] {
+ 1,
+ 1,
+ 1,
+ }).getOutput() > 0);
+ }
+
+ public void testXor() throws Exception {
+ MultiNeuralNetwork nn = new MultiNeuralNetwork(10, 2);
+ nn.addInput();
+ nn.addInput();
+ nn.addInput();
+
+ //Simple AND
+ for (int i = 0; i < 100; i++)
+ {
+ PredictionInterface p1 = nn.computeOutput(new double[] {
+ 1,
+ -1,
+ -1,
+ });
+ p1.learn(-1);
+
+ PredictionInterface p2 = nn.computeOutput(new double[] {
+ 1,
+ -1,
+ 1,
+ });
+ p2.learn(1);
+
+ PredictionInterface p3 = nn.computeOutput(new double[] {
+ 1,
+ 1,
+ -1,
+ });
+ p3.learn(1);
+
+ PredictionInterface p4 = nn.computeOutput(new double[] {
+ 1,
+ 1,
+ 1,
+ });
+ p4.learn(-1);
+ }
+
+ Assert.assertTrue(nn.computeOutput(new double[] {
+ 1,
+ -1,
+ -1,
+ }).getOutput() < 0);
+
+ Assert.assertTrue(nn.computeOutput(new double[] {
+ 1,
+ 1,
+ -1,
+ }).getOutput() > 0);
+
+ Assert.assertTrue(nn.computeOutput(new double[] {
+ 1,
+ -1,
+ 1,
+ }).getOutput() > 0);
+
+ Assert.assertTrue(nn.computeOutput(new double[] {
+ 1,
+ 1,
+ 1,
+ }).getOutput() < 0);
+ }
+}
\ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 497f27d..912bd7b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,7 +8,7 @@ android:label="@string/app_name" android:theme="@style/AppTheme" > <activity - android:name=".UnifiedInboxActivity" + android:name="org.rssin.android.UnifiedInboxActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> @@ -16,6 +16,18 @@ <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> + <activity + android:name="org.rssin.android.SettingsActivity" + android:label="@string/title_activity_settings" > + </activity> + <activity + android:name="org.rssin.android.FiltersActivity" + android:label="@string/title_activity_filters" + android:parentActivityName="org.rssin.android.UnifiedInboxActivity" > + <meta-data + android:name="android.support.PARENT_ACTIVITY" + android:value="org.rssin.android.UnifiedInboxActivity" /> + </activity> </application> </manifest> diff --git a/app/src/main/java/org/rssin/android/FiltersActivity.java b/app/src/main/java/org/rssin/android/FiltersActivity.java new file mode 100644 index 0000000..254020f --- /dev/null +++ b/app/src/main/java/org/rssin/android/FiltersActivity.java @@ -0,0 +1,126 @@ +package org.rssin.android; + +import android.app.Activity; +import android.content.Context; +import android.support.v7.app.ActionBarActivity; +import android.os.Bundle; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.ListView; +import android.widget.TextView; +import android.widget.Toast; + +import org.rssin.rssin.Filter; +import org.rssin.rssin.Keyword; +import org.rssin.rssin.R; + +import java.io.IOException; +import java.util.List; + +public class FiltersActivity extends ActionBarActivity { + + private FiltersList filters; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_filters); + + try { + filters = new FiltersList(this); + } catch (IOException ex) { + Toast.makeText(this, "Couldn't load filters.", Toast.LENGTH_SHORT).show(); + Log.e("FILTER", "IOException", ex); + + filters = new FiltersList(); + } + + Filter filter = new Filter("Hello world"); + filter.getKeywords().add(new Keyword("Keyword test")); + filter.getKeywords().add(new Keyword("Keyword test 2")); + filters.getFilters().add(filter); + + FilterAdapter adapter = new FilterAdapter(this, R.layout.activity_filters_item, filters.getFilters()); + ((ListView) findViewById(R.id.filters_list)).setAdapter(adapter); + + try { + filters.save(this); + } catch (IOException ex) { + Toast.makeText(this, "Couldn't save filters.", Toast.LENGTH_SHORT).show(); + Log.e("FILTER", "IOException", ex); + } + } + + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.menu_filters, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + int id = item.getItemId(); + + //noinspection SimplifiableIfStatement + if (id == R.id.action_settings) { + return true; + } + + return super.onOptionsItemSelected(item); + } + + private static class FilterAdapter extends ArrayAdapter<Filter> { + + Context context; + int layoutResourceId; + List<Filter> filters; + + public FilterAdapter(Context context, int resource, List<Filter> objects) { + super(context, resource, objects); + this.context = context; + layoutResourceId = resource; + filters = objects; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + View row = convertView; + FilterHolder holder = null; + + if (row == null) { + LayoutInflater inflater = ((Activity) context).getLayoutInflater(); + row = inflater.inflate(layoutResourceId, parent, false); + + holder = new FilterHolder(); + holder.title = (TextView) row.findViewById(R.id.filter_item_title); + holder.keywords = (TextView) row.findViewById(R.id.filter_item_keywords); + + row.setTag(holder); + } else { + holder = (FilterHolder) row.getTag(); + } + + Filter filter = filters.get(position); + holder.title.setText(filter.getTitle()); + holder.keywords.setText(filter.getKeywordsAsString()); + + return row; + } + + private static class FilterHolder { + TextView title; + TextView keywords; + } + } + +} diff --git a/app/src/main/java/org/rssin/android/FiltersList.java b/app/src/main/java/org/rssin/android/FiltersList.java new file mode 100644 index 0000000..99810a0 --- /dev/null +++ b/app/src/main/java/org/rssin/android/FiltersList.java @@ -0,0 +1,63 @@ +package org.rssin.android; + +import android.content.Context; +import android.preference.PreferenceManager; +import android.util.Base64; + +import org.rssin.rssin.Filter; + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by camilstaps on 19-5-15. + */ +public class FiltersList { + + private static final String PREF_KEY = "filters_list"; + private final List<Filter> filters; + + public FiltersList(Context context) throws IOException { + String filters = PreferenceManager.getDefaultSharedPreferences(context).getString(PREF_KEY, null); + if (filters == null) { + this.filters = new ArrayList<>(); + } else { + List<Filter> filters_list; + try { + ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(Base64.decode(filters, Base64.DEFAULT))); + filters_list = (List) ois.readObject(); + } catch (ClassNotFoundException ex) { + filters_list = new ArrayList<>(); + } + this.filters = filters_list; + } + } + + public FiltersList(List<Filter> filters) { + this.filters = filters; + } + + public FiltersList() { + this.filters = new ArrayList<>(); + } + + public List<Filter> getFilters() { + return filters; + } + + public void save(Context context) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(filters); + oos.close(); + String string = Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT); + PreferenceManager.getDefaultSharedPreferences(context).edit().putString(PREF_KEY, string).apply(); + } + +} diff --git a/app/src/main/java/org/rssin/android/SettingsActivity.java b/app/src/main/java/org/rssin/android/SettingsActivity.java new file mode 100644 index 0000000..99ccdfa --- /dev/null +++ b/app/src/main/java/org/rssin/android/SettingsActivity.java @@ -0,0 +1,153 @@ +package org.rssin.android; + +import android.annotation.TargetApi; +import android.content.Context; +import android.content.res.Configuration; +import android.media.Ringtone; +import android.media.RingtoneManager; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.preference.ListPreference; +import android.preference.Preference; +import android.preference.PreferenceActivity; +import android.preference.PreferenceCategory; +import android.preference.PreferenceFragment; +import android.preference.PreferenceManager; +import android.preference.RingtonePreference; +import android.text.TextUtils; + +import org.rssin.rssin.R; + +import java.util.List; + +public class SettingsActivity extends PreferenceActivity { + /** + * Determines whether to always show the simplified settings UI, where + * settings are presented in a single list. When false, settings are shown + * as a master/detail two-pane view on tablets. When true, a single pane is + * shown on tablets. + * + * For now, this is true, so that we don't have to think about tablets. + */ + private static final boolean ALWAYS_SIMPLE_PREFS = true; + + @Override + protected void onPostCreate(Bundle savedInstanceState) { + super.onPostCreate(savedInstanceState); + setupSimplePreferencesScreen(); + } + + /** + * Shows the simplified settings UI if the device configuration if the + * device configuration dictates that a simplified, single-pane UI should be + * shown. + */ + private void setupSimplePreferencesScreen() { + if (!isSimplePreferences(this)) { + return; + } + + // Add 'general' preferences. + addPreferencesFromResource(R.xml.pref_main); + + // Add 'data and sync' preferences, and a corresponding header. + PreferenceCategory fakeHeader = new PreferenceCategory(this); + fakeHeader.setTitle(R.string.pref_header_data_sync); + getPreferenceScreen().addPreference(fakeHeader); + addPreferencesFromResource(R.xml.pref_data_sync); + + // Bind the summaries of EditText/List/Dialog/Ringtone preferences to + // their values. When their values change, their summaries are updated + // to reflect the new value, per the Android Design guidelines. + bindPreferenceSummaryToValue(findPreference("sync_frequency")); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean onIsMultiPane() { + return isXLargeTablet(this) && !isSimplePreferences(this); + } + + /** + * Helper method to determine if the device has an extra-large screen. For + * example, 10" tablets are extra-large. + */ + private static boolean isXLargeTablet(Context context) { + return (context.getResources().getConfiguration().screenLayout + & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_XLARGE; + } + + /** + * Determines whether the simplified settings UI should be shown. This is + * true if this is forced via {@link #ALWAYS_SIMPLE_PREFS}, or the device + * doesn't have newer APIs like {@link PreferenceFragment}, or the device + * doesn't have an extra-large screen. In these cases, a single-pane + * "simplified" settings UI should be shown. + */ + private static boolean isSimplePreferences(Context context) { + return ALWAYS_SIMPLE_PREFS + || Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB + || !isXLargeTablet(context); + } + + /** + * A preference value change listener that updates the preference's summary + * to reflect its new value. + */ + private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object value) { + String stringValue = value.toString(); + + if (preference instanceof ListPreference) { + ListPreference listPreference = (ListPreference) preference; + int index = listPreference.findIndexOfValue(stringValue); + + preference.setSummary(index >= 0 + ? listPreference.getEntries()[index] + : null); + } else { + preference.setSummary(stringValue); + } + return true; + } + }; + + /** + * Binds a preference's summary to its value. More specifically, when the + * preference's value is changed, its summary (line of text below the + * preference title) is updated to reflect the value. The summary is also + * immediately updated upon calling this method. The exact display format is + * dependent on the type of preference. + * + * @see #sBindPreferenceSummaryToValueListener + */ + private static void bindPreferenceSummaryToValue(Preference preference) { + // Set the listener to watch for value changes. + preference.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener); + + // Trigger the listener immediately with the preference's + // current value. + sBindPreferenceSummaryToValueListener.onPreferenceChange(preference, + PreferenceManager + .getDefaultSharedPreferences(preference.getContext()) + .getString(preference.getKey(), "")); + } + + /** + * This fragment shows data and sync preferences only. It is used when the + * activity is showing a two-pane settings UI. + */ + @TargetApi(Build.VERSION_CODES.HONEYCOMB) + public static class DataSyncPreferenceFragment extends PreferenceFragment { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + addPreferencesFromResource(R.xml.pref_data_sync); + bindPreferenceSummaryToValue(findPreference("sync_frequency")); + } + } +} diff --git a/app/src/main/java/org/rssin/rssin/UnifiedInboxActivity.java b/app/src/main/java/org/rssin/android/UnifiedInboxActivity.java index b1bf0dc..dbe1c89 100644 --- a/app/src/main/java/org/rssin/rssin/UnifiedInboxActivity.java +++ b/app/src/main/java/org/rssin/android/UnifiedInboxActivity.java @@ -1,10 +1,13 @@ -package org.rssin.rssin; +package org.rssin.android; +import android.content.Intent; import android.support.v7.app.ActionBarActivity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; +import org.rssin.rssin.R; + public class UnifiedInboxActivity extends ActionBarActivity { @@ -12,6 +15,9 @@ public class UnifiedInboxActivity extends ActionBarActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_unified_inbox); + + Intent intent = new Intent(this, FiltersActivity.class); + startActivity(intent); } diff --git a/app/src/main/java/org/rssin/neurons/FeedSorter.java b/app/src/main/java/org/rssin/neurons/FeedSorter.java index 5f24ac1..550d9e5 100755 --- a/app/src/main/java/org/rssin/neurons/FeedSorter.java +++ b/app/src/main/java/org/rssin/neurons/FeedSorter.java @@ -25,7 +25,7 @@ public class FeedSorter { private int[] isNthMonthInput = new int[12];
private int[] isNthWeekDayInput = new int[7];
- private int isMorning, isAfternoon, isEvening, isNight;
+ private int isMorning, isAfternoon, isEvening, isNight, biasInput;
private Hashtable<String, Integer> categoryInputs = new Hashtable<String, Integer>();
private Hashtable<String, Integer> wordInputs = new Hashtable<String, Integer>();
private Hashtable<String, Integer> feedSourceInputs = new Hashtable<String, Integer>();
@@ -36,20 +36,21 @@ public class FeedSorter { }
private void createNewNetwork() {
- for(int i = 0; i < 12; i++)
- {
- isNthMonthInput[i] = nn.addInput();
- }
-
- for(int i = 0; i < 7; i++)
- {
- isNthWeekDayInput[i] = nn.addInput();
- }
-
- isMorning = nn.addInput();
- isAfternoon = nn.addInput();
- isEvening = nn.addInput();
- isNight = nn.addInput();
+ biasInput = nn.addInput();
+// for(int i = 0; i < 12; i++)
+// {
+// isNthMonthInput[i] = nn.addInput();
+// }
+//
+// for(int i = 0; i < 7; i++)
+// {
+// isNthWeekDayInput[i] = nn.addInput();
+// }
+//
+// isMorning = nn.addInput();
+// isAfternoon = nn.addInput();
+// isEvening = nn.addInput();
+// isNight = nn.addInput();
}
private PredictionInterface getPrediction(FeedItem item) {
@@ -65,6 +66,8 @@ public class FeedSorter { double[] inputs = new double[nn.getInputCount()];
+ inputs[biasInput] = 1;
+
//Initialize all inputs to -1 / false
for(int i = 0; i < inputs.length; i++)
{
@@ -72,39 +75,39 @@ public class FeedSorter { }
//Set month
- Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
- for(int i = 0; i < isNthMonthInput.length; i++)
- {
- if(cal.get(Calendar.MONTH) - cal.getMinimum(Calendar.MONTH) == i)
- {
- inputs[isNthMonthInput[i]] = 1;
- }
- }
+// Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
+// for(int i = 0; i < isNthMonthInput.length; i++)
+// {
+// if(cal.get(Calendar.MONTH) - cal.getMinimum(Calendar.MONTH) == i)
+// {
+// inputs[isNthMonthInput[i]] = 1;
+// }
+// }
//Set weekday
- for(int i = 0; i < isNthWeekDayInput.length; i++)
- {
- if(cal.get(Calendar.DAY_OF_WEEK) - cal.getMinimum(Calendar.DAY_OF_WEEK) == i)
- {
- inputs[isNthMonthInput[i]] = 1;
- }
- }
+// for(int i = 0; i < isNthWeekDayInput.length; i++)
+// {
+// if(cal.get(Calendar.DAY_OF_WEEK) - cal.getMinimum(Calendar.DAY_OF_WEEK) == i)
+// {
+// inputs[isNthMonthInput[i]] = 1;
+// }
+// }
//Set day
- int hourOfDay = cal.get(Calendar.HOUR_OF_DAY);
- if(hourOfDay > 6 && hourOfDay < 12)
- {
- inputs[isMorning] = 1;
- }else if(hourOfDay >= 12 && hourOfDay <= 6)
- {
- inputs[isAfternoon] = 1;
- }else if(hourOfDay >= 6 && hourOfDay < 23)
- {
- inputs[isEvening] = 1;
- }else if(hourOfDay >= 23 || hourOfDay <= 6)
- {
- inputs[isNight] = 1;
- }
+// int hourOfDay = cal.get(Calendar.HOUR_OF_DAY);
+// if(hourOfDay > 6 && hourOfDay < 12)
+// {
+// inputs[isMorning] = 1;
+// }else if(hourOfDay >= 12 && hourOfDay <= 6)
+// {
+// inputs[isAfternoon] = 1;
+// }else if(hourOfDay >= 6 && hourOfDay < 23)
+// {
+// inputs[isEvening] = 1;
+// }else if(hourOfDay >= 23 || hourOfDay <= 6)
+// {
+// inputs[isNight] = 1;
+// }
for(String category : item.getCategory())
{
@@ -120,7 +123,7 @@ public class FeedSorter { * @param feedback The feedback. Like will move these types of items up in the list,
* dislike will move them down.
*/
- public void Feedback(FeedItem item, Feedback feedback)
+ public void feedback(FeedItem item, Feedback feedback)
{
PredictionInterface prediction = getPrediction(item);
switch(feedback)
@@ -160,7 +163,7 @@ public class FeedSorter { long lhsSeconds = (long)(lhs.getPubDate().getTime() / 1000 + lPrediction.getOutput() * SECONDS_IN_DAY);
long rhsSeconds = (long)(rhs.getPubDate().getTime() / 1000 + rPrediction.getOutput() * SECONDS_IN_DAY);
- return (int)Math.signum(lhsSeconds - rhsSeconds);
+ return (int)Math.signum(rhsSeconds - lhsSeconds);
}
});
diff --git a/app/src/main/java/org/rssin/neurons/NeuralNetwork.java b/app/src/main/java/org/rssin/neurons/NeuralNetwork.java index 7c2e447..f5ee569 100755 --- a/app/src/main/java/org/rssin/neurons/NeuralNetwork.java +++ b/app/src/main/java/org/rssin/neurons/NeuralNetwork.java @@ -25,7 +25,11 @@ class NeuralNetwork { public int addInput() {
int result = 0;
for (int i = 0; i < hiddenNodes.length; i++) {
+<<<<<<< HEAD result = hiddenNodes[i].addWeight();
+======= + //result = hiddenNodes[i].AddWeight();
+>>>>>>> 7336ef600f6bd472b9aa1d59ad6418ff5c543044 }
return result;
diff --git a/app/src/main/java/org/rssin/rss/Feed.java b/app/src/main/java/org/rssin/rss/Feed.java index 2de9629..b48f036 100644 --- a/app/src/main/java/org/rssin/rss/Feed.java +++ b/app/src/main/java/org/rssin/rss/Feed.java @@ -1,17 +1,17 @@ package org.rssin.rss; -import android.widget.EditText; +import java.io.Serializable; import java.util.ArrayList; import java.util.Date; import java.util.LinkedList; import java.util.List; - /** * Created by Randy on 19-5-2015. */ -public class Feed { +public class Feed implements Serializable { + private static final long serialVersionUID = 2; private String guid; private Date pubDate; @@ -41,6 +41,9 @@ public class Feed { this.source = source; } + public void addPost(FeedItem post) { + posts.add(post); + } public List<FeedItem> getPosts() { return posts; @@ -83,5 +86,5 @@ public class Feed { public String getSource() { return source; } - + } diff --git a/app/src/main/java/org/rssin/rss/FeedLoader.java b/app/src/main/java/org/rssin/rss/FeedLoader.java index f1ab72e..db0f1db 100644 --- a/app/src/main/java/org/rssin/rss/FeedLoader.java +++ b/app/src/main/java/org/rssin/rss/FeedLoader.java @@ -9,19 +9,20 @@ import java.util.LinkedList; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserFactory; -import android.util.Log; - /** * Created by Randy on 19-5-2015. */ public class FeedLoader { + private Feed feed; + private String urlString = null; private XmlPullParserFactory xmlFactoryObject; public volatile boolean parsingComplete = true; - public FeedLoader(String url){ + public FeedLoader(Feed feed, String url){ + this.setFeed(feed); this.urlString = url; } @@ -35,8 +36,11 @@ public class FeedLoader { String name=myParser.getName(); switch (event) { case XmlPullParser.START_TAG: - post = new FeedItem(null, null, null, null, null, - null, new LinkedList<String>(), null, null, null); + if(name.equals("item")) + { + post = new FeedItem(null, null, null, null, null, + null, new LinkedList<String>(), null, null, null); + } break; case XmlPullParser.TEXT: text = myParser.getText(); @@ -74,6 +78,9 @@ public class FeedLoader { else if(name.equals("source")) { post.setSource(text); } + else if(name.equals("item")) { + feed.addPost(post); + } break; } event = myParser.next(); @@ -109,4 +116,8 @@ public class FeedLoader { }); thread.start(); } + + public void setFeed(Feed feed) { + this.feed = feed; + } } diff --git a/app/src/main/java/org/rssin/rssin/Filter.java b/app/src/main/java/org/rssin/rssin/Filter.java index 6bb191f..1cffe1a 100644 --- a/app/src/main/java/org/rssin/rssin/Filter.java +++ b/app/src/main/java/org/rssin/rssin/Filter.java @@ -1,45 +1,70 @@ package org.rssin.rssin; +import android.text.TextUtils; + import org.rssin.rss.Feed; import java.io.Serializable; -import java.util.HashSet; -import java.util.Set; +import java.util.ArrayList; +import java.util.List; /** * Created by camilstaps on 19-5-15. */ public class Filter implements Serializable { - private final Set<Feed> feeds; - private final Set<Keyword> keywords; + private static final long serialVersionUID = 0; + + private final List<Feed> feeds; + private final List<Keyword> keywords; + private String title = new String(""); public Filter() { - feeds = new HashSet<>(); - keywords = new HashSet<>(); + feeds = new ArrayList<>(); + keywords = new ArrayList<>(); } - public Filter(Set<Keyword> keywords) { - this.feeds = new HashSet<>(); - this.keywords = keywords; + public Filter(String title) { + this.title = title; + feeds = new ArrayList<>(); + keywords = new ArrayList<>(); } - public Filter(HashSet<Feed> feeds) { - this.feeds = feeds; - this.keywords = new HashSet<>(); + public Filter(String title, List<Keyword> keywords) { + this.feeds = new ArrayList<>(); + this.keywords = keywords; + this.title = title; } - public Filter(HashSet<Keyword> keywords, HashSet<Feed> feeds) { + public Filter(String title, List<Keyword> keywords, List<Feed> feeds) { this.feeds = feeds; this.keywords = keywords; + this.title = title; } - public Set<Feed> getFeeds() { + public List<Feed> getFeeds() { return feeds; } - public Set<Keyword> getKeywords() { + public List<Keyword> getKeywords() { return keywords; } + public String getKeywordsAsString() { + Keyword[] keywords = new Keyword[this.keywords.size()]; + int i = 0; + for (Keyword keyword : this.keywords) { + keywords[i++] = keyword; + } + return TextUtils.join(", ", keywords); + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + } diff --git a/app/src/main/java/org/rssin/rssin/Keyword.java b/app/src/main/java/org/rssin/rssin/Keyword.java index 690d627..8555e1a 100644 --- a/app/src/main/java/org/rssin/rssin/Keyword.java +++ b/app/src/main/java/org/rssin/rssin/Keyword.java @@ -1,9 +1,13 @@ package org.rssin.rssin; +import java.io.Serializable; + /** * Created by camilstaps on 19-5-15. */ -public class Keyword { +public class Keyword implements Serializable { + + private static final long serialVersionUID = 1; private final String keyword; @@ -15,4 +19,9 @@ public class Keyword { return keyword; } + @Override + public String toString() { + return keyword; + } + } diff --git a/app/src/main/res/layout/activity_filters.xml b/app/src/main/res/layout/activity_filters.xml new file mode 100644 index 0000000..521a319 --- /dev/null +++ b/app/src/main/res/layout/activity_filters.xml @@ -0,0 +1,14 @@ +<RelativeLayout 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:paddingLeft="@dimen/activity_horizontal_margin" + android:paddingRight="@dimen/activity_horizontal_margin" + android:paddingTop="@dimen/activity_vertical_margin" + android:paddingBottom="@dimen/activity_vertical_margin" + tools:context="org.rssin.android.FiltersActivity"> + + <ListView + android:id="@+id/filters_list" + android:layout_width="match_parent" + android:layout_height="match_parent"></ListView> + +</RelativeLayout> diff --git a/app/src/main/res/layout/activity_filters_item.xml b/app/src/main/res/layout/activity_filters_item.xml new file mode 100644 index 0000000..99fbb19 --- /dev/null +++ b/app/src/main/res/layout/activity_filters_item.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="fill_parent" + android:layout_height="fill_parent"> + + <TextView android:id="@+id/filter_item_title" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:textSize="22sp" + android:padding="10dp"/> + + <TextView android:id="@+id/filter_item_keywords" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:padding="10dp"/> + +</LinearLayout>
\ No newline at end of file diff --git a/app/src/main/res/menu/menu_filters.xml b/app/src/main/res/menu/menu_filters.xml new file mode 100644 index 0000000..0f6a87f --- /dev/null +++ b/app/src/main/res/menu/menu_filters.xml @@ -0,0 +1,7 @@ +<menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + tools:context="org.rssin.android.FiltersActivity"> + <item android:id="@+id/action_settings" android:title="@string/action_settings" + android:orderInCategory="100" app:showAsAction="never" /> +</menu> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index bbe8b60..e3e9d33 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -3,4 +3,5 @@ <string name="hello_world">Hello world!</string> <string name="action_settings">Settings</string> + <string name="title_activity_filters">Filters</string> </resources> diff --git a/app/src/main/res/values/strings_activity_settings.xml b/app/src/main/res/values/strings_activity_settings.xml new file mode 100644 index 0000000..73fa482 --- /dev/null +++ b/app/src/main/res/values/strings_activity_settings.xml @@ -0,0 +1,34 @@ +<resources> + <string name="title_activity_settings">Settings</string> + + <!-- Example General settings --> + <string name="pref_header_general">General</string> + + <!-- Example settings for Data & Sync --> + <string name="pref_header_data_sync">Data & sync</string> + + <string name="pref_title_sync_frequency">Sync frequency</string> + <string-array name="pref_sync_frequency_titles"> + <item>1 minute</item> + <item>2 minutes</item> + <item>5 minutes</item> + <item>10 minutes</item> + <item>15 minutes</item> + <item>30 minutes</item> + <item>1 hour</item> + <item>Never</item> + </string-array> + <string-array name="pref_sync_frequency_values"> + <item>1</item> + <item>2</item> + <item>5</item> + <item>10</item> + <item>15</item> + <item>30</item> + <item>60</item> + <item>-1</item> + </string-array> + + <string name="pref_title_system_sync_settings">System sync settings</string> + +</resources> diff --git a/app/src/main/res/xml/pref_data_sync.xml b/app/src/main/res/xml/pref_data_sync.xml new file mode 100644 index 0000000..ffda831 --- /dev/null +++ b/app/src/main/res/xml/pref_data_sync.xml @@ -0,0 +1,21 @@ +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> + + <!-- NOTE: Hide buttons to simplify the UI. Users can touch outside the dialog to + dismiss it. --> + <!-- NOTE: ListPreference's summary should be set to its value by the activity code. --> + <ListPreference + android:key="sync_frequency" + android:title="@string/pref_title_sync_frequency" + android:entries="@array/pref_sync_frequency_titles" + android:entryValues="@array/pref_sync_frequency_values" + android:defaultValue="180" + android:negativeButtonText="@null" + android:positiveButtonText="@null" /> + + <!-- This preference simply launches an intent when selected. Use this UI sparingly, per + design guidelines. --> + <Preference android:title="@string/pref_title_system_sync_settings"> + <intent android:action="android.settings.SYNC_SETTINGS" /> + </Preference> + +</PreferenceScreen> diff --git a/app/src/main/res/xml/pref_headers.xml b/app/src/main/res/xml/pref_headers.xml new file mode 100644 index 0000000..1c58203 --- /dev/null +++ b/app/src/main/res/xml/pref_headers.xml @@ -0,0 +1,6 @@ +<preference-headers xmlns:android="http://schemas.android.com/apk/res/android"> + + <header android:fragment="org.rssin.android.SettingsActivity$DataSyncPreferenceFragment" + android:title="@string/pref_header_data_sync" /> + +</preference-headers> diff --git a/app/src/main/res/xml/pref_main.xml b/app/src/main/res/xml/pref_main.xml new file mode 100644 index 0000000..dfc2102 --- /dev/null +++ b/app/src/main/res/xml/pref_main.xml @@ -0,0 +1,3 @@ +<?xml version="1.0" encoding="utf-8"?> +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> +</PreferenceScreen>
\ No newline at end of file |