├── .gitignore ├── .gitlab-ci.yml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── build.gradle ├── importFromCrowdin.sh └── src └── main ├── AndroidManifest.xml ├── java └── de │ └── nico │ └── ha_manager │ ├── HWManager.java │ ├── activities │ ├── About.java │ ├── AddHomework.java │ ├── Main.java │ ├── Preferences.java │ ├── SubjectOffers.java │ └── Subjects.java │ ├── database │ ├── Helper.java │ └── Source.java │ └── helper │ ├── ActionBarWrapper.java │ ├── Constants.java │ ├── Converter.java │ ├── CustomAdapter.java │ ├── CustomToast.java │ ├── FilenameUtils.java │ ├── Homework.java │ ├── Subject.java │ ├── Theme.java │ └── Utils.java └── res ├── drawable-hdpi └── ic_launcher.png ├── drawable-mdpi └── ic_launcher.png ├── drawable-xhdpi └── ic_launcher.png ├── drawable-xxhdpi └── ic_launcher.png ├── layout-v11 ├── activity_add.xml └── button_bar.xml ├── layout ├── activity_about.xml ├── activity_add.xml ├── activity_expandable_list.xml ├── activity_list.xml ├── button_bar.xml ├── listview_entry.xml ├── listview_expanded_entry1.xml └── listview_expanded_entry2.xml ├── menu-v11 └── main.xml ├── menu └── main.xml ├── values-ar └── strings.xml ├── values-cs └── strings.xml ├── values-de └── strings.xml ├── values-en └── strings.xml ├── values-es └── strings.xml ├── values-fa └── strings.xml ├── values-fr └── strings.xml ├── values-hu └── strings.xml ├── values-ja └── strings.xml ├── values-large-v11 └── styles.xml ├── values-large-v21 └── styles.xml ├── values-pl └── strings.xml ├── values-pt-rBR └── strings.xml ├── values-tr └── strings.xml ├── values-v11 └── styles.xml ├── values-v14 └── styles.xml ├── values-v21 └── styles.xml ├── values ├── constants.xml ├── strings.xml └── styles.xml └── xml └── preferences.xml /.gitignore: -------------------------------------------------------------------------------- 1 | # https://gist.github.com/AltNico/c581f370b3f88715876b 2 | 3 | *.apk 4 | *.ap_ 5 | *.dex 6 | *.class 7 | bin/ 8 | build/ 9 | build.xml 10 | .DS_Store 11 | gen/ 12 | .gradle/ 13 | gradlew 14 | gradlew.bat 15 | gradle-wrapper.jar 16 | gradle-wrapper.properties 17 | .idea/ 18 | *.iml 19 | local.properties 20 | *.log 21 | proguard/ 22 | out 23 | .settings/ 24 | *.swp 25 | *~ 26 | 27 | # Source: 28 | # https://raw.githubusercontent.com/github/gitignore/master/Android.gitignore 29 | # https://gitlab.com/fdroid/fdroidclient/raw/master/.gitignore 30 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | before_script: 2 | - apt-get --quiet update --yes 3 | - apt-get --quiet install --yes wget tar unzip openjdk-7-jdk lib32stdc++6 lib32z1 4 | - wget --quiet --output-document=android-sdk.tgz https://dl.google.com/android/android-sdk_r24.4.1-linux.tgz 5 | - tar --extract --gzip --file=android-sdk.tgz 6 | - echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter platform-tools,tools,build-tools-23.0.3,android-23,extra-android-m2repository 7 | - wget --quiet --output-document=gradle.zip https://services.gradle.org/distributions/gradle-3.1-bin.zip 8 | - unzip -q gradle.zip 9 | - export ANDROID_HOME=$PWD/android-sdk-linux 10 | 11 | test: 12 | script: 13 | - gradle-3.1/bin/gradle build 14 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog of HW-Manager 2 | 3 | ### 0.94.3 (02.10.2016) 4 | 5 | * Translation into Polish 6 | 7 | ### 0.94.2 (13.03.2016) 8 | 9 | * Translation into Portuguese, Brazilian 10 | * Minor improvements 11 | 12 | ### 0.94.1 (20.02.2016) 13 | 14 | * Translations into Turkish and Japanese 15 | * Make APK smaller 16 | * Bump dependencies 17 | 18 | ### 0.94 (03.09.2015) 19 | 20 | * Install on external SD 21 | * Continuous integration with Travis 22 | * Cleaner project 23 | * JavaDoc comments 24 | 25 | ### 0.93 (03.09.2015) 26 | 27 | * now able to sort homework (#2) 28 | * add additional information to a homework (#16) 29 | * added a dark/light switch 30 | * french and arabic translations 31 | * now changes in-app language at run time 32 | 33 | ### 0.92 (03.09.2015) 34 | 35 | * Switched from Eclipse to Android Studio 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HW-Manager - UNMAINTAINED 2 | 3 | *This project is no longer maintained. Feel free to fork it!* 4 | 5 | [![Build Status](https://gitlab.com/hw-manager/android/badges/master/build.svg)](https://gitlab.com/hw-manager/android/commits/master) 6 | [![Translation status](https://d322cqt584bo4o.cloudfront.net/hw-manager/localized.png)](https://crowdin.com/project/hw-manager) 7 | 8 | ## Download 9 | 10 | * [F-Droid](https://f-droid.org/repository/browse/?fdid=de.nico.ha_manager) 11 | * [GitLab](https://gitlab.com/hw-manager/android/tags) 12 | * [GitHub](https://github.com/hw-manager/android/releases) 13 | * [Google Play Store](https://play.google.com/store/apps/details?id=de.nico.ha_manager) 14 | 15 | ## What is this project for? 16 | 17 | With HW-Manager you are able to save your homework for school. This 18 | repository contains its source code. 19 | 20 | ## How do I get set up? 21 | 22 | A: 23 | - *Import* the project in Android Studio. 24 | 25 | B: 26 | 27 | gradle build 28 | 29 | ## Repositories 30 | 31 | Official repository: 32 | [GitLab](https://gitlab.com/hw-manager/android) 33 | 34 | Official mirror (Pull Request are welcome): 35 | [GitHub](https://github.com/hw-manager/android) 36 | 37 | ## TODO 38 | 39 | Take a look at 40 | [GitLab Issues](https://gitlab.com/hw-manager/android/issues). 41 | 42 | If you want to report an issue but not to sign up on GitLab, you can 43 | also send it to me by [mail](mailto:nicoalt@posteo.org). 44 | 45 | ## LICENSE 46 | 47 | See 48 | [LICENSE](./LICENSE). 49 | 50 | [`FilenameUtils.java`](src/main/java/de/nico/ha_manager/helper/FilenameUtils.java) 51 | is a trimmed version of `FilenameUtils` from the Apache Commons IO library, 52 | only using required methods. It is licensed under Apache License Version 53 | 2.0. 54 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Author: Nico Alt 2 | // See the file "LICENSE" for the full license governing this code. 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:2.2.0' 9 | } 10 | } 11 | 12 | allprojects { 13 | repositories { 14 | jcenter() 15 | } 16 | } 17 | 18 | apply plugin: 'com.android.application' 19 | 20 | android { 21 | compileSdkVersion 23 22 | buildToolsVersion "23.0.3" 23 | 24 | defaultConfig { 25 | applicationId "de.nico.ha_manager" 26 | minSdkVersion 4 27 | targetSdkVersion 22 28 | versionCode 26 29 | versionName "0.94.3" 30 | } 31 | 32 | buildTypes { 33 | release { 34 | minifyEnabled true 35 | shrinkResources true 36 | } 37 | } 38 | 39 | lintOptions { 40 | abortOnError false 41 | } 42 | } 43 | 44 | dependencies { 45 | compile 'com.android.support:support-v4:23.2.1' 46 | } 47 | -------------------------------------------------------------------------------- /importFromCrowdin.sh: -------------------------------------------------------------------------------- 1 | # !/bin/bash 2 | # By Nico Alt 3 | # See "LICENSE" for license information 4 | 5 | # Download and unzip files 6 | mkdir tmp 7 | cd tmp 8 | wget https://crowdin.com/download/project/hw-manager.zip 9 | unzip hw-manager.zip 10 | 11 | # Delete files in app directory 12 | rm -R ../src/main/res/values-ar 13 | rm -R ../src/main/res/values-cs 14 | rm -R ../src/main/res/values-de 15 | rm -R ../src/main/res/values-en 16 | rm -R ../src/main/res/values-es 17 | rm -R ../src/main/res/values-fa 18 | rm -R ../src/main/res/values-fr 19 | rm -R ../src/main/res/values-hu 20 | rm -R ../src/main/res/values-ja 21 | rm -R ../src/main/res/values-pl 22 | rm -R ../src/main/res/values-pt-rBR 23 | rm -R ../src/main/res/values-tr 24 | 25 | # Copy downloaded files to res directory 26 | cp -R values-ar-rSA ../src/main/res/values-ar 27 | cp -R values-cs-rCZ ../src/main/res/values-cs 28 | cp -R values-de-rDE ../src/main/res/values-de 29 | cp -R values-en-rUS ../src/main/res/values-en 30 | cp -R values-es-rES ../src/main/res/values-es 31 | cp -R values-fa-rIR ../src/main/res/values-fa 32 | cp -R values-fr-rFR ../src/main/res/values-fr 33 | cp -R values-hu-rHU ../src/main/res/values-hu 34 | cp -R values-ja-rJP ../src/main/res/values-ja 35 | cp -R values-pl-rPL ../src/main/res/values-pl 36 | cp -R values-pt-rBR ../src/main/res/values-pt-rBR 37 | cp -R values-tr-rTR ../src/main/res/values-tr 38 | 39 | # Delete temporary directory 40 | cd .. 41 | rm -R tmp 42 | 43 | # Show changes 44 | git status 45 | -------------------------------------------------------------------------------- /src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 5 | 8 | 9 | 10 | 11 | 12 | 18 | 19 | 20 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 35 | 38 | 39 | 40 | 41 | 44 | 47 | 48 | 49 | 50 | 53 | 56 | 57 | 58 | 59 | 62 | 65 | 66 | 67 | 68 | 71 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /src/main/java/de/nico/ha_manager/HWManager.java: -------------------------------------------------------------------------------- 1 | package de.nico.ha_manager; 2 | 3 | /* 4 | * @author Nico Alt 5 | * See the file "LICENSE" for the full license governing this code. 6 | */ 7 | 8 | import android.app.Application; 9 | import android.content.Context; 10 | import android.content.SharedPreferences; 11 | import android.content.res.Configuration; 12 | import android.preference.PreferenceManager; 13 | import android.text.TextUtils; 14 | 15 | import java.util.Locale; 16 | 17 | public final class HWManager extends Application { 18 | 19 | /** 20 | * Update the language used in the app. 21 | * 22 | * @param c Needed by {@link android.preference.PreferenceManager}. 23 | */ 24 | public static void updateLanguage(final Context c) { 25 | final SharedPreferences prefs = PreferenceManager 26 | .getDefaultSharedPreferences(c); 27 | final String lang = prefs.getString("locale_override", ""); 28 | updateLanguage(c, lang); 29 | } 30 | 31 | /** 32 | * Update the language used in the app. 33 | * 34 | * @param c Needed to get the resources. 35 | * @param lang Language to be used in the app, 36 | */ 37 | private static void updateLanguage(final Context c, final String lang) { 38 | final Configuration cfg = new Configuration(); 39 | if (!TextUtils.isEmpty(lang)) 40 | cfg.locale = new Locale(lang); 41 | else 42 | cfg.locale = Locale.getDefault(); 43 | 44 | c.getResources().updateConfiguration(cfg, null); 45 | } 46 | 47 | @Override 48 | public final void onCreate() { 49 | updateLanguage(this); 50 | super.onCreate(); 51 | } 52 | } -------------------------------------------------------------------------------- /src/main/java/de/nico/ha_manager/activities/About.java: -------------------------------------------------------------------------------- 1 | package de.nico.ha_manager.activities; 2 | 3 | /* 4 | * @author Nico Alt 5 | * @author Devin 6 | * See the file "LICENSE" for the full license governing this code. 7 | */ 8 | 9 | import android.os.Bundle; 10 | import android.support.v4.app.FragmentActivity; 11 | import android.support.v4.app.NavUtils; 12 | import android.text.Html; 13 | import android.view.MenuItem; 14 | import android.widget.TextView; 15 | 16 | import de.nico.ha_manager.R; 17 | import de.nico.ha_manager.helper.Constants; 18 | import de.nico.ha_manager.helper.Theme; 19 | import de.nico.ha_manager.helper.Utils; 20 | 21 | /** 22 | * Shows an About page 23 | */ 24 | public final class About extends FragmentActivity { 25 | 26 | @Override 27 | protected final void onCreate(final Bundle savedInstanceState) { 28 | super.onCreate(savedInstanceState); 29 | Theme.set(this, false); 30 | setContentView(R.layout.activity_about); 31 | update(); 32 | Utils.setupActionBar(this, false); 33 | } 34 | 35 | @Override 36 | public final boolean onOptionsItemSelected(final MenuItem item) { 37 | switch (item.getItemId()) { 38 | // Respond to the action bar's Up/Home button 39 | case android.R.id.home: 40 | NavUtils.navigateUpFromSameTask(this); 41 | return true; 42 | } 43 | return super.onOptionsItemSelected(item); 44 | } 45 | 46 | /** 47 | * Updates the content of the about page. 48 | */ 49 | private void update() { 50 | // Get Build Info 51 | final String appName = getString(R.string.app_name); 52 | final String buildInfo = Utils.getBuildInfo(this); 53 | 54 | final TextView tv = (TextView) findViewById(R.id.about_title); 55 | tv.setText(appName + " " + buildInfo); 56 | 57 | final TextView contentView = (TextView) findViewById(R.id.about_content); 58 | contentView 59 | .setText(Html.fromHtml(Constants.about_us_content)); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/de/nico/ha_manager/activities/AddHomework.java: -------------------------------------------------------------------------------- 1 | package de.nico.ha_manager.activities; 2 | 3 | /* 4 | * @author Nico Alt 5 | * @author Devin 6 | * See the file "LICENSE" for the full license governing this code. 7 | */ 8 | 9 | import android.annotation.SuppressLint; 10 | import android.app.DatePickerDialog; 11 | import android.content.Context; 12 | import android.content.Intent; 13 | import android.content.SharedPreferences; 14 | import android.os.Bundle; 15 | import android.preference.PreferenceManager; 16 | import android.support.v4.app.FragmentActivity; 17 | import android.support.v4.app.NavUtils; 18 | import android.view.MenuItem; 19 | import android.view.View; 20 | import android.view.inputmethod.InputMethodManager; 21 | import android.widget.ArrayAdapter; 22 | import android.widget.Button; 23 | import android.widget.CheckBox; 24 | import android.widget.DatePicker; 25 | import android.widget.EditText; 26 | import android.widget.Spinner; 27 | import android.widget.TextView; 28 | 29 | import java.util.Arrays; 30 | import java.util.Calendar; 31 | 32 | import de.nico.ha_manager.R; 33 | import de.nico.ha_manager.database.Source; 34 | import de.nico.ha_manager.helper.Converter; 35 | import de.nico.ha_manager.helper.Homework; 36 | import de.nico.ha_manager.helper.Subject; 37 | import de.nico.ha_manager.helper.Theme; 38 | import de.nico.ha_manager.helper.Utils; 39 | 40 | @SuppressLint("SimpleDateFormat") 41 | /** 42 | * Shows a page to add a homework. 43 | */ 44 | public final class AddHomework extends FragmentActivity { 45 | 46 | /** 47 | * String array containing the subjects 48 | */ 49 | private static String[] subjects; 50 | 51 | /** 52 | * 0 is year, 1 is month and 2 is day 53 | */ 54 | private static int[] date; 55 | 56 | /** 57 | * Time in milliseconds 58 | */ 59 | private static long time; 60 | 61 | /** 62 | * ID of the homework entry in the database 63 | */ 64 | private static String ID = null; 65 | 66 | @Override 67 | protected final void onCreate(final Bundle savedInstanceState) { 68 | Theme.set(this, true); 69 | super.onCreate(savedInstanceState); 70 | setContentView(R.layout.activity_add); 71 | 72 | subjects = Subject.get(this); 73 | date = getDate(0); 74 | 75 | setUntilTV(date); 76 | setSpinner(); 77 | handleIntent(getIntent()); 78 | Utils.setupActionBar(this, false); 79 | } 80 | 81 | @Override 82 | public final boolean onOptionsItemSelected(final MenuItem item) { 83 | switch (item.getItemId()) { 84 | // Respond to the action bar's Up/Home button 85 | case android.R.id.home: 86 | NavUtils.navigateUpFromSameTask(this); 87 | return true; 88 | } 89 | return super.onOptionsItemSelected(item); 90 | } 91 | 92 | /** 93 | * @param time If it's 0, current time will be used. 94 | * @return Int array where 0 is year, 1 is month and 2 is day. 95 | */ 96 | private int[] getDate(final long time) { 97 | final Calendar c = Calendar.getInstance(); 98 | if (time != 0) 99 | c.setTimeInMillis(time); 100 | 101 | final int[] tmpDate = new int[3]; 102 | 103 | // E.g "1970" 104 | tmpDate[0] = c.get(Calendar.YEAR); 105 | 106 | // E.g "01" 107 | tmpDate[1] = c.get(Calendar.MONTH); 108 | 109 | // Get current day, e.g. "01", plus one day > e.g. "02" 110 | tmpDate[2] = c.get(Calendar.DAY_OF_MONTH) + 1; 111 | 112 | if (time != 0) 113 | tmpDate[2] = c.get(Calendar.DAY_OF_MONTH); 114 | 115 | return tmpDate; 116 | } 117 | 118 | /** 119 | * Sets the button with the date until the homework has to be done. 120 | * 121 | * @param date If it's 0, current time will be used. 122 | */ 123 | private void setUntilTV(final int[] date) { 124 | final String until = Converter.toDate(date); 125 | final TextView untilTV = (TextView) findViewById(R.id.button_until); 126 | untilTV.setText(until); 127 | time = Converter.toMilliseconds(date); 128 | } 129 | 130 | /** 131 | * Sets spinner with subjects. 132 | */ 133 | private void setSpinner() { 134 | final Spinner subSpin = (Spinner) findViewById(R.id.spinner_subject); 135 | final ArrayAdapter adapter = new ArrayAdapter<>(this, 136 | android.R.layout.simple_spinner_item, subjects); 137 | adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 138 | subSpin.setAdapter(adapter); 139 | } 140 | 141 | /** 142 | * Handles information from an intent. 143 | * 144 | * @param intent Intent with information 145 | */ 146 | private void handleIntent(final Intent intent) { 147 | final Bundle extras = intent.getExtras(); 148 | if (extras != null) { 149 | // Set ID 150 | ID = extras.getString(Source.allColumns[0]); 151 | 152 | // Set Title 153 | final EditText hwEdit = (EditText) findViewById(R.id.editText_homework); 154 | hwEdit.setText(extras.getString(Source.allColumns[1])); 155 | 156 | // Set Subject 157 | final String subject = extras.getString(Source.allColumns[2]); 158 | final Spinner subSpin = (Spinner) findViewById(R.id.spinner_subject); 159 | ArrayAdapter adapter = new ArrayAdapter<>(this, 160 | android.R.layout.simple_spinner_item, subjects); 161 | // Get position in subject list 162 | int spinnerPosition = adapter.getPosition(subject); 163 | // If subject is not in subject list 164 | if (spinnerPosition == -1) { 165 | final int size = subjects.length; 166 | final String[] tmp = new String[size + 1]; 167 | System.arraycopy(subjects, 0, tmp, 0, size); 168 | tmp[size] = subject; 169 | Arrays.sort(tmp); 170 | 171 | subjects = tmp; 172 | setSpinner(); 173 | adapter = new ArrayAdapter<>(this, 174 | android.R.layout.simple_spinner_item, subjects); 175 | spinnerPosition = adapter.getPosition(subject); 176 | } 177 | subSpin.setSelection(spinnerPosition); 178 | 179 | // Set Info 180 | final EditText infoEdit = (EditText) findViewById(R.id.editText_info); 181 | infoEdit.setText(extras.getString(Source.allColumns[3])); 182 | 183 | // Set Urgent 184 | if (!extras.getString(Source.allColumns[4]).equals("")) { 185 | final CheckBox checkBox = (CheckBox) findViewById(R.id.checkBox_urgent); 186 | checkBox.setChecked(true); 187 | } 188 | 189 | // Set Until 190 | time = Long.valueOf(extras.getString(Source.allColumns[5])).longValue(); 191 | date = getDate(time); 192 | setUntilTV(date); 193 | 194 | // Change the "Add" button to "Save" 195 | final Button mAdd = (Button) findViewById(R.id.button_add); 196 | mAdd.setText(R.string.hw_save); 197 | } 198 | } 199 | 200 | /** 201 | * Sets button with {@link android.app.DatePickerDialog}. 202 | * 203 | * @param v Needed because method is called from layout 204 | */ 205 | public final void setUntil(final View v) { 206 | final DatePickerDialog dpd = new DatePickerDialog(this, 207 | new DatePickerDialog.OnDateSetListener() { 208 | 209 | @Override 210 | public final void onDateSet(final DatePicker view, final int year, 211 | final int monthOfYear, final int dayOfMonth) { 212 | date[0] = year; 213 | date[1] = monthOfYear; 214 | date[2] = dayOfMonth; 215 | setUntilTV(date); 216 | 217 | } 218 | 219 | }, date[0], date[1], date[2]); 220 | 221 | dpd.show(); 222 | } 223 | 224 | /** 225 | * Adds the homework to the database and finishes the activity. 226 | * 227 | * @param v Needed because method is called from layout 228 | */ 229 | public final void addHomework(final View v) { 230 | final Spinner subSpin = (Spinner) findViewById(R.id.spinner_subject); 231 | final EditText hwEdit = (EditText) findViewById(R.id.editText_homework); 232 | final EditText infoEdit = (EditText) findViewById(R.id.editText_info); 233 | 234 | // Close keyboard 235 | final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); 236 | imm.hideSoftInputFromWindow(hwEdit.getWindowToken(), 0); 237 | 238 | // If nothing filled in -> cancel 239 | if (hwEdit.getText().toString().trim().length() == 0) { 240 | hwEdit.setError(getString(R.string.toast_have2enter)); 241 | return; 242 | } 243 | 244 | // Urgent? 245 | String urgent; 246 | final CheckBox urgentCheck = (CheckBox) findViewById(R.id.checkBox_urgent); 247 | if (urgentCheck.isChecked()) 248 | urgent = getString(R.string.action_urgent); 249 | else 250 | urgent = ""; 251 | 252 | // Get filled in data 253 | final String subject = subSpin.getSelectedItem().toString(); 254 | final String homework = hwEdit.getText().toString().trim(); 255 | final String info = infoEdit.getText().toString().trim(); 256 | 257 | // Entry in database 258 | Homework.add(this, ID, homework, subject, time, info, urgent, ""); 259 | 260 | // Auto-export 261 | final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); 262 | final boolean autoExport = prefs.getBoolean("pref_autoexport", false); 263 | if (autoExport) 264 | Homework.exportIt(this, true); 265 | 266 | finish(); 267 | } 268 | } 269 | 270 | 271 | -------------------------------------------------------------------------------- /src/main/java/de/nico/ha_manager/activities/Main.java: -------------------------------------------------------------------------------- 1 | package de.nico.ha_manager.activities; 2 | 3 | /* 4 | * @author Nico Alt 5 | * @author Devin 6 | * See the file "LICENSE" for the full license governing this code. 7 | */ 8 | 9 | import android.app.AlertDialog; 10 | import android.content.DialogInterface; 11 | import android.content.Intent; 12 | import android.os.Bundle; 13 | import android.support.v4.app.FragmentActivity; 14 | import android.util.Log; 15 | import android.view.ContextMenu; 16 | import android.view.ContextMenu.ContextMenuInfo; 17 | import android.view.Menu; 18 | import android.view.MenuItem; 19 | import android.view.View; 20 | import android.widget.ExpandableListAdapter; 21 | import android.widget.ExpandableListView; 22 | import android.widget.SimpleAdapter; 23 | 24 | import java.util.ArrayList; 25 | import java.util.HashMap; 26 | 27 | import de.nico.ha_manager.R; 28 | import de.nico.ha_manager.database.Source; 29 | import de.nico.ha_manager.helper.Converter; 30 | import de.nico.ha_manager.helper.CustomAdapter; 31 | import de.nico.ha_manager.helper.Homework; 32 | import de.nico.ha_manager.helper.Subject; 33 | import de.nico.ha_manager.helper.Theme; 34 | import de.nico.ha_manager.helper.Utils; 35 | 36 | /** 37 | * The main class of HW-Manager. 38 | */ 39 | public final class Main extends FragmentActivity { 40 | 41 | /** 42 | * {@link java.util.ArrayList} containing a {@link java.util.HashMap} with the homework. 43 | */ 44 | private static ArrayList> hwArray = new ArrayList<>(); 45 | 46 | @Override 47 | protected final void onCreate(final Bundle savedInstanceState) { 48 | Theme.set(this, false); 49 | super.onCreate(savedInstanceState); 50 | setContentView(R.layout.activity_expandable_list); 51 | setTitle(getString(R.string.title_homework)); 52 | update(); 53 | 54 | // If subject list is empty 55 | if (!(Subject.get(this).length > 0)) 56 | Subject.setDefault(this); 57 | } 58 | 59 | @Override 60 | public final void onResume() { 61 | super.onResume(); 62 | update(); 63 | } 64 | 65 | @Override 66 | public final boolean onCreateOptionsMenu(final Menu menu) { 67 | getMenuInflater().inflate(R.menu.main, menu); 68 | return true; 69 | } 70 | 71 | @Override 72 | public final boolean onOptionsItemSelected(final MenuItem item) { 73 | // Handle presses on the action bar items 74 | switch (item.getItemId()) { 75 | case R.id.action_settings: 76 | startActivity(new Intent(this, Preferences.class)); 77 | finish(); 78 | return true; 79 | 80 | case R.id.action_delete: 81 | deleteAll(); 82 | return true; 83 | 84 | case R.id.action_add: 85 | startActivity(new Intent(this, AddHomework.class)); 86 | return true; 87 | default: 88 | return super.onOptionsItemSelected(item); 89 | } 90 | } 91 | 92 | @Override 93 | public final void onCreateContextMenu(final ContextMenu menu, final View v, 94 | final ContextMenuInfo menuInfo) { 95 | super.onCreateContextMenu(menu, v, menuInfo); 96 | // menu.add(0, v.getId(), 0, getString(R.string.dialog_completed)); 97 | menu.add(0, v.getId(), 1, getString(R.string.dialog_edit)); 98 | menu.add(0, v.getId(), 2, getString(R.string.dialog_delete)); 99 | } 100 | 101 | @Override 102 | public final boolean onContextItemSelected(final MenuItem item) { 103 | final ExpandableListView.ExpandableListContextMenuInfo info = (ExpandableListView.ExpandableListContextMenuInfo) item 104 | .getMenuInfo(); 105 | if (item.getTitle() == getString(R.string.dialog_completed)) { 106 | final ExpandableListView hwList = (ExpandableListView) findViewById(R.id.expandableListView_main); 107 | if (Utils.crossOneOut(this, hwArray, ExpandableListView.getPackedPositionGroup(info.packedPosition))) 108 | update(); 109 | return true; 110 | } 111 | if (item.getTitle() == getString(R.string.dialog_edit)) { 112 | editOne(hwArray, ExpandableListView.getPackedPositionGroup(info.packedPosition)); 113 | return true; 114 | } 115 | if (item.getTitle() == getString(R.string.dialog_delete)) { 116 | deleteOne(hwArray, ExpandableListView.getPackedPositionGroup(info.packedPosition)); 117 | update(); 118 | return true; 119 | } 120 | return false; 121 | } 122 | 123 | /** 124 | * Updates homework list. 125 | */ 126 | private void update() { 127 | // Remove old content 128 | hwArray.clear(); 129 | final Source s = new Source(this); 130 | 131 | // Get content from SQLite Database 132 | try { 133 | s.open(); 134 | hwArray = s.get(this); 135 | s.close(); 136 | } catch (Exception ex) { 137 | Log.e("Update Homework List", ex.toString()); 138 | } 139 | setOnClick(); 140 | } 141 | 142 | /** 143 | * Sets fake onClickListener which creates a {@link android.view.ContextMenu}. 144 | */ 145 | private void setOnClick() { 146 | final ExpandableListView hwList = (ExpandableListView) findViewById(R.id.expandableListView_main); 147 | final ExpandableListAdapter e = CustomAdapter.expandableEntry(this, hwArray); 148 | hwList.setAdapter(e); 149 | registerForContextMenu(hwList); 150 | /* 151 | Still does not work... 152 | Utils.crossOut(e, hwArray); 153 | */ 154 | } 155 | 156 | /** 157 | * Edits a homework. 158 | * 159 | * @param ArHa {@link java.util.ArrayList} containing a {@link java.util.HashMap} with the homework. 160 | * @param pos Position where the homework is. 161 | */ 162 | private void editOne(final ArrayList> ArHa, final int pos) { 163 | final String currentID = "ID = " + ArHa.get(pos).get(Source.allColumns[0]); 164 | final Intent intent = new Intent(this, AddHomework.class); 165 | final Bundle mBundle = new Bundle(); 166 | mBundle.putString(Source.allColumns[0], currentID); 167 | for (int i = 1; i < Source.allColumns.length; i++) 168 | mBundle.putString(Source.allColumns[i], 169 | ArHa.get(pos).get(Source.allColumns[i])); 170 | intent.putExtras(mBundle); 171 | startActivity(intent); 172 | } 173 | 174 | /** 175 | * Deletes a homework. 176 | * 177 | * @param ArHa {@link java.util.ArrayList} containing a {@link java.util.HashMap} with the homework. 178 | * @param pos Position where the homework is. 179 | */ 180 | private void deleteOne(final ArrayList> ArHa, final int pos) { 181 | final ArrayList> tempArray = Converter.toTmpArray(ArHa, pos); 182 | final String currentID = "ID = " + ArHa.get(pos).get(Source.allColumns[0]); 183 | final SimpleAdapter alertAdapter = CustomAdapter.entry(this, tempArray); 184 | 185 | final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this); 186 | alertDialog 187 | .setTitle(getString(R.string.dialog_delete)) 188 | .setAdapter(alertAdapter, null) 189 | .setPositiveButton((getString(android.R.string.yes)), 190 | new DialogInterface.OnClickListener() { 191 | @Override 192 | public final void onClick(final DialogInterface d, final int i) { 193 | Homework.delete(Main.this, currentID); 194 | update(); 195 | } 196 | }) 197 | .setNegativeButton((getString(android.R.string.no)), null) 198 | .show(); 199 | } 200 | 201 | /** 202 | * Deletes all homework. 203 | */ 204 | private void deleteAll() { 205 | final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this); 206 | alertDialog 207 | .setTitle(getString(R.string.dialog_delete)) 208 | .setMessage(getString(R.string.dialog_really_delete_hw)) 209 | .setPositiveButton((getString(android.R.string.yes)), 210 | new DialogInterface.OnClickListener() { 211 | @Override 212 | public final void onClick(final DialogInterface d, final int i) { 213 | Homework.delete(Main.this, null); 214 | update(); 215 | } 216 | }) 217 | .setNegativeButton((getString(android.R.string.no)), null) 218 | .show(); 219 | } 220 | } 221 | -------------------------------------------------------------------------------- /src/main/java/de/nico/ha_manager/activities/Preferences.java: -------------------------------------------------------------------------------- 1 | package de.nico.ha_manager.activities; 2 | 3 | /* 4 | * @author Nico Alt 5 | * @author Devin 6 | * See the file "LICENSE" for the full license governing this code. 7 | */ 8 | 9 | import android.app.AlertDialog; 10 | import android.content.Context; 11 | import android.content.DialogInterface; 12 | import android.content.Intent; 13 | import android.os.Bundle; 14 | import android.os.Environment; 15 | import android.preference.CheckBoxPreference; 16 | import android.preference.Preference; 17 | import android.preference.Preference.OnPreferenceClickListener; 18 | import android.preference.PreferenceActivity; 19 | import android.preference.PreferenceScreen; 20 | import android.text.InputType; 21 | import android.view.MenuItem; 22 | import android.widget.EditText; 23 | 24 | import java.io.File; 25 | import java.util.ArrayList; 26 | import java.util.Collections; 27 | import java.util.Locale; 28 | 29 | import de.nico.ha_manager.R; 30 | import de.nico.ha_manager.helper.FilenameUtils; 31 | import de.nico.ha_manager.helper.Homework; 32 | import de.nico.ha_manager.helper.Subject; 33 | import de.nico.ha_manager.helper.Theme; 34 | import de.nico.ha_manager.helper.Utils; 35 | 36 | public final class Preferences extends PreferenceActivity { 37 | 38 | /** 39 | * {@link android.content.Context} of this class. 40 | */ 41 | private static Context c; 42 | 43 | /** 44 | * List with all homework databases. 45 | */ 46 | private String[] list; 47 | 48 | @SuppressWarnings("deprecation") 49 | @Override 50 | protected final void onCreate(final Bundle savedInstanceState) { 51 | Theme.set(this, false); 52 | super.onCreate(savedInstanceState); 53 | addPreferencesFromResource(R.xml.preferences); 54 | c = this; 55 | 56 | setImportDialog(); 57 | setBuildInfo(); 58 | setLanguage(); 59 | checkPreferences(); 60 | Utils.setupActionBar(this, true); 61 | } 62 | 63 | @Override 64 | public final void onBackPressed() { 65 | startActivity(new Intent(Preferences.this, Main.class)); 66 | finish(); 67 | } 68 | 69 | @Override 70 | public final boolean onOptionsItemSelected(final MenuItem item) { 71 | switch (item.getItemId()) { 72 | // Respond to the action bar's Up/Home button 73 | case android.R.id.home: 74 | onBackPressed(); 75 | return true; 76 | } 77 | return super.onOptionsItemSelected(item); 78 | } 79 | 80 | /** 81 | * Sets the content of the import {@link android.app.AlertDialog}. 82 | */ 83 | @SuppressWarnings("deprecation") 84 | private void setImportDialog() { 85 | final ArrayList mArray = getFiles(Environment.getExternalStorageDirectory() + "/" 86 | + getString(R.string.app_name)); 87 | if (mArray != null) 88 | list = mArray.toArray(new String[mArray.size()]); 89 | final Preference importexport_import = findPreference("pref_importexport_import"); 90 | importexport_import.setOnPreferenceClickListener(new OnPreferenceClickListener() { 91 | @Override 92 | public final boolean onPreferenceClick(final Preference preference) { 93 | final AlertDialog.Builder alertDialog = new AlertDialog.Builder(c); 94 | alertDialog.setTitle(getString(R.string.pref_homework_import)) 95 | .setNegativeButton(getString(android.R.string.cancel), 96 | new DialogInterface.OnClickListener() { 97 | @Override 98 | public final void onClick( 99 | final DialogInterface d, final int i) { 100 | d.dismiss(); 101 | } 102 | }) 103 | .setItems(list, new DialogInterface.OnClickListener() { 104 | public final void onClick(final DialogInterface dialog, final int item) { 105 | Homework.importIt(c, list[item]); 106 | } 107 | }).show(); 108 | return true; 109 | } 110 | }); 111 | } 112 | 113 | /** 114 | * Sets the information when the application was built. 115 | */ 116 | @SuppressWarnings("deprecation") 117 | private void setBuildInfo() { 118 | // Get Build Info 119 | final String buildInfo = Utils.getBuildInfo(this); 120 | 121 | // Set Build Info 122 | final PreferenceScreen prefscreen = ((PreferenceScreen) findPreference("pref_about_current_version")); 123 | prefscreen.setSummary(buildInfo); 124 | onContentChanged(); 125 | } 126 | 127 | /** 128 | * Sets the list with all available languages of the app. 129 | */ 130 | @SuppressWarnings("deprecation") 131 | private void setLanguage() { 132 | final Preference language = findPreference("pref_app_language"); 133 | 134 | // Locale of HW-Manager 135 | final Locale appLoc = getResources().getConfiguration().locale; 136 | 137 | // Locale of device 138 | final Locale devLoc = Locale.getDefault(); 139 | 140 | if (devLoc.equals(appLoc)) 141 | language.setSummary(getString(R.string.pref_language_default)); 142 | else 143 | language.setSummary(appLoc.getDisplayLanguage(appLoc)); 144 | } 145 | 146 | /** 147 | * Checks if a preference was clicked. 148 | */ 149 | @SuppressWarnings("deprecation") 150 | private void checkPreferences() { 151 | final Preference language = findPreference("pref_app_language"); 152 | language.setOnPreferenceClickListener(new OnPreferenceClickListener() { 153 | @Override 154 | public final boolean onPreferenceClick(final Preference preference) { 155 | Utils.langSpinner(c); 156 | return true; 157 | } 158 | }); 159 | 160 | final CheckBoxPreference pref_theme = (CheckBoxPreference) findPreference("theme"); 161 | pref_theme.setOnPreferenceClickListener(new OnPreferenceClickListener() { 162 | @Override 163 | public final boolean onPreferenceClick(final Preference preference) { 164 | if (android.os.Build.VERSION.SDK_INT >= 11) 165 | recreate(); 166 | return true; 167 | } 168 | }); 169 | 170 | final CheckBoxPreference pref_black = (CheckBoxPreference) findPreference("black"); 171 | pref_black.setOnPreferenceClickListener(new OnPreferenceClickListener() { 172 | @Override 173 | public final boolean onPreferenceClick(final Preference preference) { 174 | if (android.os.Build.VERSION.SDK_INT >= 11) 175 | recreate(); 176 | return true; 177 | } 178 | }); 179 | 180 | final Preference subjects_add = findPreference("subjects_add"); 181 | subjects_add 182 | .setOnPreferenceClickListener(new OnPreferenceClickListener() { 183 | @Override 184 | public final boolean onPreferenceClick(final Preference preference) { 185 | final EditText input = new EditText(c); 186 | input.setInputType(InputType.TYPE_CLASS_TEXT 187 | | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES); 188 | final AlertDialog.Builder alertDialog = new AlertDialog.Builder( 189 | c); 190 | alertDialog 191 | .setTitle(getString(R.string.dialog_addSubject)) 192 | .setMessage( 193 | getString(R.string.dialog_addSubject_message)) 194 | .setView(input) 195 | .setPositiveButton( 196 | getString(android.R.string.ok), 197 | new DialogInterface.OnClickListener() { 198 | @Override 199 | public final void onClick( 200 | final DialogInterface d, final int i) { 201 | Subject.add(c, input.getText() 202 | .toString()); 203 | } 204 | }) 205 | .setNegativeButton( 206 | (getString(android.R.string.no)), null) 207 | .show(); 208 | return true; 209 | } 210 | }); 211 | 212 | final Preference subjects_reset = findPreference("subjects_reset"); 213 | subjects_reset 214 | .setOnPreferenceClickListener(new OnPreferenceClickListener() { 215 | @Override 216 | public final boolean onPreferenceClick(final Preference preference) { 217 | final AlertDialog.Builder alertDialog = new AlertDialog.Builder( 218 | c); 219 | alertDialog 220 | .setTitle(getString(R.string.dialog_delete)) 221 | .setMessage( 222 | getString(R.string.dialog_really_delete_subs)) 223 | .setPositiveButton( 224 | (getString(android.R.string.yes)), 225 | new DialogInterface.OnClickListener() { 226 | 227 | @Override 228 | public final void onClick( 229 | final DialogInterface d, final int i) { 230 | Subject.setDefault(c); 231 | } 232 | 233 | }) 234 | .setNegativeButton( 235 | (getString(android.R.string.no)), null) 236 | .show(); 237 | return true; 238 | } 239 | }); 240 | 241 | final Preference feedback_share = findPreference("feedback_share"); 242 | feedback_share 243 | .setOnPreferenceClickListener(new OnPreferenceClickListener() { 244 | @Override 245 | public final boolean onPreferenceClick(final Preference preference) { 246 | return Utils.shareApp(c); 247 | } 248 | }); 249 | 250 | final Preference importexport_export = findPreference("pref_importexport_export"); 251 | importexport_export 252 | .setOnPreferenceClickListener(new OnPreferenceClickListener() { 253 | @Override 254 | public final boolean onPreferenceClick(final Preference preference) { 255 | final AlertDialog.Builder alertDialog = new AlertDialog.Builder( 256 | c); 257 | alertDialog 258 | .setTitle( 259 | getString(R.string.pref_homework_export)) 260 | .setMessage( 261 | getString(R.string.dialog_export_message)) 262 | .setPositiveButton( 263 | (getString(android.R.string.yes)), 264 | new DialogInterface.OnClickListener() { 265 | 266 | @Override 267 | public final void onClick( 268 | final DialogInterface d, final int i) { 269 | Homework.exportIt(c, false); 270 | // Reload the Import dialog. 271 | setImportDialog(); 272 | } 273 | 274 | }) 275 | .setNegativeButton( 276 | (getString(android.R.string.no)), null) 277 | .show(); 278 | return true; 279 | 280 | } 281 | 282 | }); 283 | } 284 | 285 | /** 286 | * Gets a list of the *.db files in /sdcard/HW-Manager/ 287 | * for the import dialog. 288 | */ 289 | private ArrayList getFiles(final String DirectoryPath) { 290 | final ArrayList myFiles = new ArrayList<>(); 291 | final File f = new File(DirectoryPath); 292 | 293 | f.mkdirs(); 294 | final File[] files = f.listFiles(); 295 | if (files.length == 0) 296 | return null; 297 | else { 298 | for (final File file : files) { 299 | // We only want .db files here. 300 | if (FilenameUtils.getExtension(file.getName()).equals("db")) { 301 | // Since the file extensions are all the same, we can just remove them. 302 | final String mTrimmedFile = FilenameUtils.removeExtension(file.getName()); 303 | myFiles.add(mTrimmedFile); 304 | } 305 | } 306 | } 307 | // Make sure the list is in alphabetical order. It already will. 308 | Collections.sort(myFiles); 309 | // Reverse the order so newest is on top. 310 | Collections.reverse(myFiles); 311 | return myFiles; 312 | } 313 | } 314 | -------------------------------------------------------------------------------- /src/main/java/de/nico/ha_manager/activities/SubjectOffers.java: -------------------------------------------------------------------------------- 1 | package de.nico.ha_manager.activities; 2 | 3 | /* 4 | * @author Nico Alt 5 | * @author Devin 6 | * See the file "LICENSE" for the full license governing this code. 7 | */ 8 | 9 | import android.app.AlertDialog; 10 | import android.content.DialogInterface; 11 | import android.os.Bundle; 12 | import android.support.v4.app.FragmentActivity; 13 | import android.support.v4.app.NavUtils; 14 | import android.view.MenuItem; 15 | import android.view.View; 16 | import android.widget.AdapterView; 17 | import android.widget.AdapterView.OnItemClickListener; 18 | import android.widget.ArrayAdapter; 19 | import android.widget.ListView; 20 | import android.widget.TextView; 21 | 22 | import java.util.Arrays; 23 | 24 | import de.nico.ha_manager.R; 25 | import de.nico.ha_manager.helper.Subject; 26 | import de.nico.ha_manager.helper.Theme; 27 | import de.nico.ha_manager.helper.Utils; 28 | 29 | /** 30 | * Shows a list with subject offers. 31 | */ 32 | public final class SubjectOffers extends FragmentActivity { 33 | 34 | @Override 35 | protected final void onCreate(final Bundle savedInstanceState) { 36 | Theme.set(this, false); 37 | super.onCreate(savedInstanceState); 38 | setContentView(R.layout.activity_list); 39 | update(); 40 | Utils.setupActionBar(this, false); 41 | } 42 | 43 | @Override 44 | public final boolean onOptionsItemSelected(final MenuItem item) { 45 | switch (item.getItemId()) { 46 | // Respond to the action bar's Up/Home button 47 | case android.R.id.home: 48 | NavUtils.navigateUpFromSameTask(this); 49 | return true; 50 | } 51 | return super.onOptionsItemSelected(item); 52 | } 53 | 54 | /** 55 | * Updates list with subject offers. 56 | */ 57 | private void update() { 58 | final String[] subOffers = getResources().getStringArray( 59 | R.array.subject_offers); 60 | Arrays.sort(subOffers); 61 | 62 | // Make simple list containing subjects 63 | final ArrayAdapter subAdapter = new ArrayAdapter<>(this, 64 | android.R.layout.simple_list_item_1, subOffers); 65 | 66 | final ListView subList = (ListView) findViewById(R.id.listView_main); 67 | subList.setAdapter(subAdapter); 68 | 69 | subList.setOnItemClickListener(new OnItemClickListener() { 70 | @Override 71 | public final void onItemClick(final AdapterView parent, final View v, final int pos, 72 | final long id) { 73 | // Selected item 74 | final String item = ((TextView) v).getText().toString(); 75 | 76 | final AlertDialog.Builder deleteDialog = new AlertDialog.Builder( 77 | SubjectOffers.this); 78 | deleteDialog 79 | .setTitle(getString(R.string.action_add) + ": " + item) 80 | .setPositiveButton((getString(android.R.string.yes)), 81 | new DialogInterface.OnClickListener() { 82 | 83 | @Override 84 | public final void onClick(final DialogInterface d, final int i) { 85 | Subject.add(SubjectOffers.this, item); 86 | } 87 | }) 88 | .setNegativeButton((getString(android.R.string.no)), 89 | null).show(); 90 | } 91 | 92 | }); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/de/nico/ha_manager/activities/Subjects.java: -------------------------------------------------------------------------------- 1 | package de.nico.ha_manager.activities; 2 | 3 | /* 4 | * @author Nico Alt 5 | * @author Devin 6 | * See the file "LICENSE" for the full license governing this code. 7 | */ 8 | 9 | import android.app.AlertDialog; 10 | import android.content.DialogInterface; 11 | import android.os.Bundle; 12 | import android.support.v4.app.FragmentActivity; 13 | import android.support.v4.app.NavUtils; 14 | import android.view.MenuItem; 15 | import android.view.View; 16 | import android.widget.AdapterView; 17 | import android.widget.AdapterView.OnItemClickListener; 18 | import android.widget.ArrayAdapter; 19 | import android.widget.ListView; 20 | import android.widget.TextView; 21 | 22 | import de.nico.ha_manager.R; 23 | import de.nico.ha_manager.helper.Subject; 24 | import de.nico.ha_manager.helper.Theme; 25 | import de.nico.ha_manager.helper.Utils; 26 | 27 | /** 28 | * Shows a list with all subjects used. 29 | */ 30 | public final class Subjects extends FragmentActivity { 31 | 32 | @Override 33 | protected final void onCreate(final Bundle savedInstanceState) { 34 | Theme.set(this, false); 35 | super.onCreate(savedInstanceState); 36 | setContentView(R.layout.activity_list); 37 | update(); 38 | Utils.setupActionBar(this, false); 39 | } 40 | 41 | @Override 42 | public final boolean onOptionsItemSelected(final MenuItem item) { 43 | switch (item.getItemId()) { 44 | // Respond to the action bar's Up/Home button 45 | case android.R.id.home: 46 | NavUtils.navigateUpFromSameTask(this); 47 | return true; 48 | } 49 | return super.onOptionsItemSelected(item); 50 | } 51 | 52 | /** 53 | * Updates list with subjects. 54 | */ 55 | private void update() { 56 | final String[] subjects = Subject.get(this); 57 | 58 | // Make simple list containing subjects 59 | final ArrayAdapter subAdapter = new ArrayAdapter<>(this, 60 | android.R.layout.simple_list_item_1, subjects); 61 | 62 | final ListView subList = (ListView) findViewById(R.id.listView_main); 63 | subList.setAdapter(subAdapter); 64 | 65 | subList.setOnItemClickListener(new OnItemClickListener() { 66 | @Override 67 | public final void onItemClick(final AdapterView parent, final View v, 68 | final int pos, final long id) { 69 | 70 | final String item = ((TextView) v).getText().toString(); 71 | 72 | final AlertDialog.Builder alertDialog = new AlertDialog.Builder( 73 | Subjects.this); 74 | alertDialog 75 | .setTitle( 76 | getString(R.string.dialog_delete) + ": " + item) 77 | .setPositiveButton((getString(android.R.string.yes)), 78 | new DialogInterface.OnClickListener() { 79 | 80 | @Override 81 | public final void onClick(final DialogInterface d, final int i) { 82 | Subject.delete(Subjects.this, pos); 83 | update(); 84 | } 85 | }) 86 | .setNegativeButton((getString(android.R.string.no)), 87 | null).show(); 88 | } 89 | 90 | }); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/de/nico/ha_manager/database/Helper.java: -------------------------------------------------------------------------------- 1 | package de.nico.ha_manager.database; 2 | 3 | /* 4 | * @author Nico Alt 5 | * See the file "LICENSE" for the full license governing this code. 6 | */ 7 | 8 | import android.content.Context; 9 | import android.database.sqlite.SQLiteDatabase; 10 | import android.database.sqlite.SQLiteOpenHelper; 11 | import android.util.Log; 12 | 13 | public final class Helper extends SQLiteOpenHelper { 14 | 15 | /** 16 | * The name of the database containing the homework. 17 | */ 18 | public static final String DATABASE_NAME = "Homework.db"; 19 | 20 | /** 21 | * The current version of the database containing the homework. 22 | */ 23 | private static final int DATABASE_VERSION = 3; 24 | 25 | /** 26 | * The command when first creating the database. 27 | */ 28 | private static final String TABLE_CREATE_HOMEWORK = "create table HOMEWORK(ID integer primary key autoincrement,HOMEWORK text,SUBJECT text,TIME text,INFO text,URGENT text,COMPLETED text)"; 29 | 30 | public Helper(final Context context) { 31 | super(context, DATABASE_NAME, null, DATABASE_VERSION); 32 | } 33 | 34 | @Override 35 | public final void onCreate(final SQLiteDatabase database) { 36 | database.execSQL(TABLE_CREATE_HOMEWORK); 37 | } 38 | 39 | @Override 40 | public final void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) { 41 | // Upgrade from first to third version 42 | if (oldVersion == 1 && newVersion == 3) { 43 | db.execSQL("ALTER TABLE HOMEWORK ADD COLUMN INFO TEXT"); 44 | db.execSQL("ALTER TABLE HOMEWORK ADD COLUMN TIME TEXT"); 45 | db.execSQL("ALTER TABLE HOMEWORK ADD COLUMN COMPLETED TEXT"); 46 | Log.w(Helper.class.getName(), 47 | "Upgrading database from version " + oldVersion + " to " 48 | + newVersion + "."); 49 | } 50 | // Upgrade from second to third version 51 | if (oldVersion == 2 && newVersion == 3) { 52 | db.execSQL("ALTER TABLE HOMEWORK ADD COLUMN COMPLETED TEXT"); 53 | Log.w(Helper.class.getName(), 54 | "Upgrading database from version " + oldVersion + " to " 55 | + newVersion + "."); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/de/nico/ha_manager/database/Source.java: -------------------------------------------------------------------------------- 1 | package de.nico.ha_manager.database; 2 | 3 | /* 4 | * @author Nico Alt 5 | * See the file "LICENSE" for the full license governing this code. 6 | */ 7 | 8 | import android.content.ContentValues; 9 | import android.content.Context; 10 | import android.content.SharedPreferences; 11 | import android.database.Cursor; 12 | import android.database.SQLException; 13 | import android.database.sqlite.SQLiteDatabase; 14 | import android.preference.PreferenceManager; 15 | 16 | import java.util.ArrayList; 17 | import java.util.Collections; 18 | import java.util.Comparator; 19 | import java.util.HashMap; 20 | 21 | import de.nico.ha_manager.helper.Converter; 22 | import de.nico.ha_manager.helper.Homework; 23 | 24 | public final class Source { 25 | 26 | /** 27 | * All columns used in the database. 28 | */ 29 | public static final String[] allColumns = {"ID", "HOMEWORK", "SUBJECT", "INFO", "URGENT", "TIME", "COMPLETED"}; 30 | 31 | /** 32 | * The {@link de.nico.ha_manager.database.Helper} used in this class. 33 | */ 34 | private final Helper dbHelper; 35 | 36 | /** 37 | * The {@link android.database.sqlite.SQLiteDatabase} used in this class. 38 | */ 39 | private SQLiteDatabase database; 40 | 41 | /** 42 | * Initializes the {@link de.nico.ha_manager.database.Helper} used in this class. 43 | * 44 | * @param context Needed by {@link de.nico.ha_manager.database.Helper}. 45 | */ 46 | public Source(final Context context) { 47 | dbHelper = new Helper(context); 48 | } 49 | 50 | /** 51 | * Opens the {@link de.nico.ha_manager.database.Helper} used in this class. 52 | */ 53 | public final void open() throws SQLException { 54 | database = dbHelper.getWritableDatabase(); 55 | } 56 | 57 | /** 58 | * Closes the {@link de.nico.ha_manager.database.Helper} used in this class. 59 | */ 60 | public final void close() { 61 | dbHelper.close(); 62 | } 63 | 64 | /** 65 | * Adds a homework. 66 | * 67 | * @param c Needed by {@link de.nico.ha_manager.database.Source}. 68 | * @param ID The ID used in the database. 69 | * @param title The title of the homework. 70 | * @param subject The subject of the homework. 71 | * @param time The time until the homework has to be done. 72 | * @param info Additional information to the homework. 73 | * @param urgent Is it urgent? 74 | * @param completed Is it completed? 75 | */ 76 | public final void createEntry(final Context c, final String ID, final String title, 77 | final String subject, final long time, final String info, 78 | final String urgent, final String completed) { 79 | final ContentValues values = new ContentValues(); 80 | values.put(allColumns[1], title); 81 | values.put(allColumns[2], subject); 82 | values.put(allColumns[3], info); 83 | values.put(allColumns[4], urgent); 84 | values.put(allColumns[5], String.valueOf(time)); 85 | values.put(allColumns[6], completed); 86 | 87 | String insertId = "ID = " + database.insert("HOMEWORK", null, values); 88 | if (ID != null) { 89 | Homework.delete(c, ID); 90 | insertId = ID; 91 | } 92 | 93 | final Cursor cursor = database.query("HOMEWORK", allColumns, insertId, null, 94 | null, null, null); 95 | cursor.close(); 96 | cursor.moveToFirst(); 97 | } 98 | 99 | /** 100 | * Deletes an item in the database. 101 | * 102 | * @param where Row to delete. 103 | */ 104 | public final void delete_item(final String where) { 105 | open(); 106 | database.delete("HOMEWORK", where, null); 107 | close(); 108 | } 109 | 110 | /** 111 | * Returns an ArrayList containing HashMaps containing the homework. 112 | * 113 | * @param c Needed by {@link android.preference.PreferenceManager}. 114 | */ 115 | public final ArrayList> get(final Context c) { 116 | final ArrayList> entriesList = new ArrayList<>(); 117 | 118 | final Cursor cursor = database.query("HOMEWORK", allColumns, null, null, 119 | null, null, null); 120 | cursor.moveToFirst(); 121 | 122 | if (cursor.getCount() == 0) 123 | return entriesList; 124 | 125 | while (!cursor.isAfterLast()) { 126 | final HashMap temp = new HashMap<>(); 127 | temp.put(allColumns[0], String.valueOf(cursor.getLong(0))); 128 | for (int i = 1; i < allColumns.length; i++) { 129 | // Support upgrades from older versions 130 | if (i == 5 && cursor.getString(i) == null) 131 | temp.put(allColumns[i], "1420066800000"); 132 | else 133 | temp.put(allColumns[i], cursor.getString(i)); 134 | if (i == 6 && cursor.getString(i) == null) 135 | temp.put(allColumns[i], ""); 136 | else 137 | temp.put(allColumns[i], cursor.getString(i)); 138 | } 139 | entriesList.add(temp); 140 | cursor.moveToNext(); 141 | } 142 | cursor.close(); 143 | 144 | // Sort by time 145 | final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c); 146 | if (prefs.getBoolean("pref_sortbytime", false)) 147 | Collections.sort(entriesList, new Comparator>() { 148 | 149 | @Override 150 | public final int compare(final HashMap lhs, final HashMap rhs) { 151 | final long a = Long.valueOf(lhs.get(allColumns[5])).longValue(); 152 | final long b = Long.valueOf(rhs.get(allColumns[5])).longValue(); 153 | return Long.valueOf(a).compareTo(Long.valueOf(b)); 154 | } 155 | }); 156 | 157 | // Sort by importance 158 | if (prefs.getBoolean("pref_sortbyimportance", false)) 159 | Collections.sort(entriesList, new Comparator>() { 160 | 161 | @Override 162 | public final int compare(final HashMap lhs, final HashMap rhs) { 163 | final String a = rhs.get(allColumns[4]); 164 | final String b = lhs.get(allColumns[4]); 165 | return a.compareTo(b); 166 | } 167 | }); 168 | 169 | // Add date, based on time in milliseconds 170 | for (int i = 0; i < entriesList.size(); i++) { 171 | final HashMap temp = entriesList.get(i); 172 | final long time = Long.valueOf(temp.get(allColumns[5])).longValue(); 173 | final String date = Converter.toDate(time); 174 | temp.put("UNTIL", date); 175 | } 176 | return entriesList; 177 | } 178 | } -------------------------------------------------------------------------------- /src/main/java/de/nico/ha_manager/helper/ActionBarWrapper.java: -------------------------------------------------------------------------------- 1 | package de.nico.ha_manager.helper; 2 | 3 | /* 4 | * @author Nico Alt 5 | * @author Devin 6 | * See the file "LICENSE" for the full license governing this code. 7 | * 8 | * Original code by Shane Tully located at: 9 | * https://shanetully.com/2011/10/android-3-0-actionbar-class-maintaining-compatibility-with-pre-android-3-0-apps/ 10 | */ 11 | 12 | import android.annotation.TargetApi; 13 | import android.app.ActionBar; 14 | import android.content.Context; 15 | import android.graphics.drawable.Drawable; 16 | import android.preference.PreferenceActivity; 17 | import android.support.v4.app.FragmentActivity; 18 | 19 | /** 20 | * Fixes a nasty VerifyError crash with getActionBar() 21 | * on Android versions lower than 3.0. 22 | */ 23 | 24 | @TargetApi(11) 25 | @SuppressWarnings("unused") 26 | public final class ActionBarWrapper { 27 | /** 28 | * Check if android.app.ActionBar exists and throw an error if not 29 | */ 30 | static { 31 | try { 32 | Class.forName("android.app.ActionBar"); 33 | } catch (final Exception e) { 34 | throw new RuntimeException(e); 35 | } 36 | } 37 | 38 | /** 39 | * Indicates if ActionBar is available. 40 | */ 41 | private ActionBar actionBar; 42 | 43 | /** 44 | * This method gets an instance on the Action Bar working. 45 | * 46 | * @param context Context from the Activity 47 | * @param prefActivity Because of the app needing the cast, we need 48 | * to change it to cast to PreferenceActivity instead 49 | * of FragmentActivity 50 | */ 51 | public ActionBarWrapper(final Context context, final boolean prefActivity) { 52 | if (prefActivity) { 53 | // PreferenceActivity 54 | actionBar = ((PreferenceActivity) context).getActionBar(); 55 | } else { 56 | // FragmentActivity 57 | actionBar = ((FragmentActivity) context).getActionBar(); 58 | } 59 | } 60 | 61 | /** 62 | * A static function that can be called to force the static 63 | * initialization of this class 64 | */ 65 | public static void isAvailable() { 66 | } 67 | 68 | /** 69 | * Basic core ActionBar functions 70 | */ 71 | 72 | public final void setBackgroundDrawable(final Drawable background) { 73 | if (actionBar != null) 74 | actionBar.setBackgroundDrawable(background); 75 | } 76 | 77 | public final void setDisplayShowTitleEnabled(final boolean showTitle) { 78 | if (actionBar != null) 79 | actionBar.setDisplayShowTitleEnabled(showTitle); 80 | } 81 | 82 | public final void setDisplayUseLogoEnabled(final boolean useLogo) { 83 | if (actionBar != null) 84 | actionBar.setDisplayUseLogoEnabled(useLogo); 85 | } 86 | 87 | public final void setDisplayHomeAsUpEnabled(final boolean homeAsUpEnabled) { 88 | if (actionBar != null) 89 | actionBar.setDisplayHomeAsUpEnabled(homeAsUpEnabled); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/main/java/de/nico/ha_manager/helper/Constants.java: -------------------------------------------------------------------------------- 1 | package de.nico.ha_manager.helper; 2 | 3 | /* 4 | * @author Nico Alt 5 | * @author Devin 6 | * See the file "LICENSE" for the full license governing this code. 7 | */ 8 | 9 | public final class Constants { 10 | 11 | /** 12 | * The HTML data shown in the about page. 13 | */ 14 | public static final String about_us_content = 15 | "Developers
" + 16 | "• Nico Alt
" + 17 | "• Devin
" + 18 | "
" + 19 | "Translators
" + 20 | "• Arya S Jr
" + 21 | "• Hevesi János
" + 22 | "• Jaroslav Lichtblau
" + 23 | "
" + 24 | "This program is free software: you can redistribute it and/or modify it under " + 25 | "the terms of the GNU General Public License version 3 as published by the Free " + 26 | "Software Foundation. See http://www.gnu.org/licenses/gpl-3.0."; 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/de/nico/ha_manager/helper/Converter.java: -------------------------------------------------------------------------------- 1 | package de.nico.ha_manager.helper; 2 | 3 | /* 4 | * @author Nico Alt 5 | * See the file "LICENSE" for the full license governing this code. 6 | */ 7 | 8 | import java.text.DateFormat; 9 | import java.text.SimpleDateFormat; 10 | import java.util.ArrayList; 11 | import java.util.GregorianCalendar; 12 | import java.util.HashMap; 13 | import java.util.Locale; 14 | 15 | import de.nico.ha_manager.database.Source; 16 | 17 | public final class Converter { 18 | 19 | /** 20 | * Converts an ArrayList with multiples HashMaps to an ArrayList with just one HashMap. 21 | * 22 | * @param ArHa An ArrayList with multiples HashMaps. 23 | * @param pos Indicates which HashMap has to be used. 24 | */ 25 | public static ArrayList> toTmpArray(final ArrayList> ArHa, final int pos) { 26 | // Temporary ArrayList containing a HashMap 27 | final ArrayList> tempArHa = new ArrayList<>(); 28 | 29 | // Temporary HashMap 30 | final HashMap tempHashMap = new HashMap<>(); 31 | 32 | // Fill temporary HashMap with one row of original HashMap 33 | for (int i = 0; i < Source.allColumns.length; i++) 34 | tempHashMap.put(Source.allColumns[i], 35 | ArHa.get(pos).get(Source.allColumns[i])); 36 | 37 | final String date = toDate(Long.valueOf(ArHa.get(pos).get(Source.allColumns[5])).longValue()); 38 | tempHashMap.put("UNTIL", date); 39 | 40 | // Add temporary HashMap to temporary ArrayList containing a HashMap 41 | tempArHa.add(tempHashMap); 42 | return tempArHa; 43 | } 44 | 45 | /** 46 | * Converts a time in milliseconds to a date. 47 | * 48 | * @param time Time in milliseconds, 49 | */ 50 | public static String toDate(final long time) { 51 | String until; 52 | // Format to 31.12.14 or local version of that 53 | final DateFormat f = DateFormat.getDateInstance(DateFormat.SHORT, 54 | Locale.getDefault()); 55 | final GregorianCalendar gc = new GregorianCalendar(); 56 | gc.setTimeInMillis(time); 57 | 58 | // Format to Week of Day, for example Mo. or local version of that 59 | final SimpleDateFormat dateFormat = new SimpleDateFormat("EEE", 60 | Locale.getDefault()); 61 | 62 | // Tab space because else the date is too far to the left 63 | until = (dateFormat.format(gc.getTime()) + ", " + f.format(gc.getTime())); 64 | return until; 65 | } 66 | 67 | /** 68 | * Converts a time in an int array to a date. 69 | * 70 | * @param time Time in an int array, 71 | */ 72 | public static String toDate(final int[] time) { 73 | String until; 74 | // Format to 31.12.14 or local version of that 75 | final DateFormat f = DateFormat.getDateInstance(DateFormat.SHORT, 76 | Locale.getDefault()); 77 | final GregorianCalendar gc = new GregorianCalendar(time[0], time[1], time[2]); 78 | 79 | // Format to Week of Day, for example Mo. or local version of that 80 | final SimpleDateFormat dateFormat = new SimpleDateFormat("EEE", 81 | Locale.getDefault()); 82 | 83 | // Tab space because else the date is too far to the left 84 | until = (dateFormat.format(gc.getTime()) + ", " + f.format(gc.getTime())); 85 | return until; 86 | } 87 | 88 | /** 89 | * Converts a time in milliseconds to the time in milliseconds. 90 | * 91 | * @param time Time in an int array to a date. 92 | */ 93 | public static long toMilliseconds(final int[] time) { 94 | final GregorianCalendar gc = new GregorianCalendar(time[0], time[1], time[2]); 95 | return gc.getTimeInMillis(); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/main/java/de/nico/ha_manager/helper/CustomAdapter.java: -------------------------------------------------------------------------------- 1 | package de.nico.ha_manager.helper; 2 | 3 | /* 4 | * @author Nico Alt 5 | * See the file "LICENSE" for the full license governing this code. 6 | */ 7 | 8 | import android.content.Context; 9 | import android.widget.SimpleAdapter; 10 | import android.widget.SimpleExpandableListAdapter; 11 | 12 | import java.util.ArrayList; 13 | import java.util.HashMap; 14 | import java.util.List; 15 | import java.util.Map; 16 | 17 | import de.nico.ha_manager.R; 18 | 19 | public final class CustomAdapter { 20 | 21 | /** 22 | * Returns a SimpleAdapter that uses the layout "listview_entry". 23 | * 24 | * @param c Needed for {@link android.widget.SimpleAdapter}. 25 | * @param a ArrayList with HashMaps to show with the adapter. 26 | */ 27 | public static SimpleAdapter entry(final Context c, final ArrayList> a) { 28 | // All TextViews in Layout "listview_entry" 29 | final int[] i = {R.id.textView_urgent, R.id.textView_subject, 30 | R.id.textView_homework, R.id.textView_until}; 31 | final String[] columns = {"URGENT", "SUBJECT", "HOMEWORK", "UNTIL"}; 32 | 33 | // Make a SimpleAdapter which is like a row in the homework list 34 | return new SimpleAdapter(c, a, R.layout.listview_entry, columns, i); 35 | } 36 | 37 | /** 38 | * Returns a SimpleExpandableListAdapter that uses the layout "listview_expanded_entry1". 39 | * 40 | * @param c Needed for {@link android.widget.SimpleExpandableListAdapter}. 41 | * @param a ArrayList with HashMaps to show with the adapter. 42 | */ 43 | public static SimpleExpandableListAdapter expandableEntry(final Context c, final ArrayList> a) { 44 | // All TextViews in Layout "listview_expanded_entry1" 45 | final int[] groupTexts = {R.id.textView_urgent, R.id.textView_subject, 46 | R.id.textView_homework, R.id.textView_until}; 47 | final String[] groupColumns = {"URGENT", "SUBJECT", "HOMEWORK", "UNTIL"}; 48 | 49 | // All TextViews in Layout "listview_expanded_entry2" 50 | final int[] childTexts = {R.id.textView_info}; 51 | final String[] childColumns = {"INFO"}; 52 | final List>> childData = covertToListListMap(a, childColumns[0]); 53 | 54 | // Make a SimpleAdapter which is like a row in the homework list 55 | return new SimpleExpandableListAdapter(c, a, R.layout.listview_expanded_entry1, groupColumns, groupTexts, childData, R.layout.listview_expanded_entry2, childColumns, childTexts); 56 | } 57 | 58 | /** 59 | * Converts an ArrayList containing HashMaps to a List containing a List Containing a Map. 60 | * 61 | * @param a ArrayList with HashMaps to convert. 62 | * @param row Row to add to the Map. 63 | */ 64 | private static List>> covertToListListMap(final ArrayList> a, final String row) { 65 | final List>> ll = new ArrayList<>(); 66 | for (int i = 0; i < a.size(); i++) { 67 | final Map tmpL = new HashMap<>(); 68 | tmpL.put(row, a.get(i).get(row)); 69 | 70 | final List> l = new ArrayList<>(); 71 | l.add(tmpL); 72 | 73 | ll.add(l); 74 | } 75 | return ll; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/de/nico/ha_manager/helper/CustomToast.java: -------------------------------------------------------------------------------- 1 | package de.nico.ha_manager.helper; 2 | 3 | /* 4 | * @author Nico Alt 5 | * See the file "LICENSE" for the full license governing this code. 6 | */ 7 | 8 | import android.content.Context; 9 | import android.widget.Toast; 10 | 11 | public final class CustomToast { 12 | 13 | /** 14 | * Shows a short Toast. 15 | * 16 | * @param c Needed for {@link android.widget.Toast}. 17 | * @param msg Message to show. 18 | */ 19 | public static void showShort(final Context c, final String msg) { 20 | Toast.makeText(c, msg, Toast.LENGTH_SHORT).show(); 21 | } 22 | 23 | /** 24 | * Shows a long Toast. 25 | * 26 | * @param c Needed for {@link android.widget.Toast}. 27 | * @param msg Message to show. 28 | */ 29 | public static void showLong(final Context c, final String msg) { 30 | Toast.makeText(c, msg, Toast.LENGTH_LONG).show(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/de/nico/ha_manager/helper/FilenameUtils.java: -------------------------------------------------------------------------------- 1 | package de.nico.ha_manager.helper; 2 | 3 | /* 4 | * @author Nico Alt 5 | * @author Devin 6 | * See the file "LICENSE" for the full license governing this code. 7 | */ 8 | 9 | /* 10 | * Licensed to the Apache Software Foundation (ASF) under one or more 11 | * contributor license agreements. See the NOTICE file distributed with 12 | * this work for additional information regarding copyright ownership. 13 | * The ASF licenses this file to You under the Apache License, Version 2.0 14 | * (the "License"); you may not use this file except in compliance with 15 | * the License. You may obtain a copy of the License at 16 | * 17 | * http://www.apache.org/licenses/LICENSE-2.0 18 | * 19 | * Unless required by applicable law or agreed to in writing, software 20 | * distributed under the License is distributed on an "AS IS" BASIS, 21 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | * See the License for the specific language governing permissions and 23 | * limitations under the License. 24 | */ 25 | 26 | public final class FilenameUtils { 27 | /** 28 | * The extension separator character. 29 | * 30 | * @since Commons IO 1.4 31 | */ 32 | private static final char EXTENSION_SEPARATOR = '.'; 33 | 34 | /** 35 | * The Unix separator character. 36 | */ 37 | private static final char UNIX_SEPARATOR = '/'; 38 | 39 | /** 40 | * The Windows separator character. 41 | */ 42 | private static final char WINDOWS_SEPARATOR = '\\'; 43 | 44 | /** 45 | * Gets the extension of a filename. 46 | *

47 | * This method returns the textual part of the filename after the last dot. 48 | * There must be no directory separator after the dot. 49 | *

 50 |      * foo.txt      --> "txt"
 51 |      * a/b/c.jpg    --> "jpg"
 52 |      * a/b.txt/c    --> ""
 53 |      * a/b/c        --> ""
 54 |      * 
55 | *

56 | * The output will be the same irrespective of the machine that the code is running on. 57 | * 58 | * @param filename the filename to retrieve the extension of. 59 | * @return the extension of the file or an empty string if none exists or {@code null} 60 | * if the filename is {@code null}. 61 | */ 62 | public static String getExtension(final String filename) { 63 | if (filename == null) 64 | return null; 65 | final int index = indexOfExtension(filename); 66 | if (index == -1) 67 | return ""; 68 | else 69 | return filename.substring(index + 1); 70 | } 71 | 72 | 73 | /** 74 | * Returns the index of the last directory separator character. 75 | *

76 | * This method will handle a file in either Unix or Windows format. 77 | * The position of the last forward or backslash is returned. 78 | *

79 | * The output will be the same irrespective of the machine that the code is running on. 80 | * 81 | * @param filename the filename to find the last path separator in, null returns -1 82 | * @return the index of the last separator character, or -1 if there 83 | * is no such character 84 | */ 85 | private static int indexOfLastSeparator(final String filename) { 86 | if (filename == null) 87 | return -1; 88 | final int lastUnixPos = filename.lastIndexOf(UNIX_SEPARATOR); 89 | final int lastWindowsPos = filename.lastIndexOf(WINDOWS_SEPARATOR); 90 | return Math.max(lastUnixPos, lastWindowsPos); 91 | } 92 | 93 | /** 94 | * Returns the index of the last extension separator character, which is a dot. 95 | *

96 | * This method also checks that there is no directory separator after the last dot. 97 | * To do this it uses {@link #indexOfLastSeparator(String)} which will 98 | * handle a file in either Unix or Windows format. 99 | *

100 | * The output will be the same irrespective of the machine that the code is running on. 101 | * 102 | * @param filename the filename to find the last path separator in, null returns -1 103 | * @return the index of the last separator character, or -1 if there 104 | * is no such character 105 | */ 106 | private static int indexOfExtension(final String filename) { 107 | if (filename == null) 108 | return -1; 109 | final int extensionPos = filename.lastIndexOf(EXTENSION_SEPARATOR); 110 | final int lastSeparator = indexOfLastSeparator(filename); 111 | return (lastSeparator > extensionPos ? -1 : extensionPos); 112 | } 113 | //----------------------------------------------------------------------- 114 | 115 | /** 116 | * Removes the extension from a filename. 117 | *

118 | * This method returns the textual part of the filename before the last dot. 119 | * There must be no directory separator after the dot. 120 | *

121 |      * foo.txt    --> foo
122 |      * a\b\c.jpg  --> a\b\c
123 |      * a\b\c      --> a\b\c
124 |      * a.b\c      --> a.b\c
125 |      * 
126 | *

127 | * The output will be the same irrespective of the machine that the code is running on. 128 | * 129 | * @param filename the filename to query, null returns null 130 | * @return the filename minus the extension 131 | */ 132 | public static String removeExtension(final String filename) { 133 | if (filename == null) 134 | return null; 135 | final int index = indexOfExtension(filename); 136 | if (index == -1) 137 | return filename; 138 | else 139 | return filename.substring(0, index); 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /src/main/java/de/nico/ha_manager/helper/Homework.java: -------------------------------------------------------------------------------- 1 | package de.nico.ha_manager.helper; 2 | 3 | /* 4 | * @author Nico Alt 5 | * @author Devin 6 | * See the file "LICENSE" for the full license governing this code. 7 | */ 8 | 9 | import android.content.Context; 10 | import android.os.Environment; 11 | import android.util.Log; 12 | 13 | import java.io.File; 14 | import java.text.SimpleDateFormat; 15 | import java.util.Date; 16 | import java.util.Locale; 17 | 18 | import de.nico.ha_manager.R; 19 | import de.nico.ha_manager.database.Helper; 20 | import de.nico.ha_manager.database.Source; 21 | 22 | public final class Homework { 23 | 24 | /** 25 | * Deletes one homework. 26 | * 27 | * @param c Needed by {@link de.nico.ha_manager.database.Source}. 28 | * @param ID ID of homework to get deleted. If set to null, all homework will get deleted. 29 | */ 30 | public static void delete(final Context c, final String ID) { 31 | final Source s = new Source(c); 32 | s.delete_item(ID); 33 | } 34 | 35 | /** 36 | * Deletes multiple homework. 37 | * 38 | * @param c Needed by {@link de.nico.ha_manager.database.Source}. 39 | * @param IDs IDs of homework to get deleted. If set to null, all homework will get deleted. 40 | */ 41 | public static void delete(final String[] IDs, final Context c) { 42 | for (String ID : IDs) { 43 | delete(c, ID); 44 | } 45 | } 46 | 47 | /** 48 | * Adds a homework. 49 | * 50 | * @param c Needed by {@link de.nico.ha_manager.database.Source}. 51 | * @param ID The ID used in the database. 52 | * @param title The title of the homework. 53 | * @param subject The subject of the homework. 54 | * @param time The time until the homework has to be done. 55 | * @param info Additional information to the homework. 56 | * @param urgent Is it urgent? 57 | * @param completed Is it completed? 58 | */ 59 | public static void add(final Context c, final String ID, final String title, 60 | final String subject, final long time, final String info, 61 | final String urgent, final String completed) { 62 | try { 63 | final Source s = new Source(c); 64 | s.open(); 65 | s.createEntry(c, ID, title, subject, time, info, urgent, completed); 66 | s.close(); 67 | } catch (final Exception ex) { 68 | Log.e("Database", ex.toString()); 69 | } 70 | } 71 | 72 | /** 73 | * Imports a homework database. 74 | * 75 | * @param c Needed by {@link de.nico.ha_manager.helper.Utils}. 76 | * @param filename The database to import. 77 | */ 78 | public static void importIt(final Context c, final String filename) { 79 | // Check if directory exists 80 | final File dir = new File(Environment.getExternalStorageDirectory() + "/" 81 | + c.getString(R.string.app_name)); 82 | if (!(dir.exists())) { 83 | CustomToast.showLong( 84 | c, 85 | c.getString(R.string.toast_nobackup) 86 | + c.getString(R.string.app_name)); 87 | return; 88 | } 89 | 90 | // Path for Database 91 | final File srcDB = new File(Environment.getExternalStorageDirectory() + "/" 92 | + c.getString(R.string.app_name) + "/" + filename + ".db"); 93 | final File dstDB = new File(c.getApplicationInfo().dataDir 94 | + "/databases/" + Helper.DATABASE_NAME); 95 | 96 | // Check if Database exists 97 | if (!(srcDB.exists())) { 98 | CustomToast.showLong( 99 | c, 100 | c.getString(R.string.toast_nobackup) 101 | + c.getString(R.string.app_name)); 102 | return; 103 | } 104 | 105 | if (Utils.transfer(srcDB, dstDB)) 106 | CustomToast.showShort(c, c.getString(R.string.toast_import_success)); 107 | else 108 | CustomToast.showShort(c, c.getString(R.string.toast_import_fail)); 109 | } 110 | 111 | /** 112 | * Exports the homework database. 113 | * 114 | * @param c Needed by {@link de.nico.ha_manager.helper.Utils}. 115 | * @param auto Indicates if it's an automatic backup. 116 | */ 117 | public static void exportIt(final Context c, final boolean auto) { 118 | // Check if directory exists 119 | final File dir = new File(Environment.getExternalStorageDirectory() + "/" 120 | + c.getString(R.string.app_name)); 121 | if (!(dir.exists())) 122 | dir.mkdir(); 123 | 124 | String stamp = new SimpleDateFormat("yyyy-MM-dd-hh-mm", Locale.US).format(new Date()); 125 | 126 | if (auto) 127 | stamp = "auto-backup"; 128 | 129 | // Path for Database 130 | final File srcDB = new File(c.getApplicationInfo().dataDir 131 | + "/databases/" + Helper.DATABASE_NAME); 132 | final File dstDB = new File(Environment.getExternalStorageDirectory() + "/" 133 | + c.getString(R.string.app_name) + "/Homework-" + stamp + ".db"); 134 | 135 | if (dstDB.exists()) 136 | dstDB.delete(); 137 | 138 | if (Utils.transfer(srcDB, dstDB) && !auto) 139 | CustomToast.showShort(c, c.getString(R.string.toast_export_success)); 140 | else if (!auto) 141 | CustomToast.showShort(c, c.getString(R.string.toast_export_fail)); 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /src/main/java/de/nico/ha_manager/helper/Subject.java: -------------------------------------------------------------------------------- 1 | package de.nico.ha_manager.helper; 2 | 3 | /* 4 | * @author Nico Alt 5 | * See the file "LICENSE" for the full license governing this code. 6 | */ 7 | 8 | import android.content.Context; 9 | import android.content.SharedPreferences; 10 | import android.preference.PreferenceManager; 11 | 12 | import java.util.Arrays; 13 | 14 | import de.nico.ha_manager.R; 15 | 16 | public final class Subject { 17 | 18 | /** 19 | * Default {@link android.content.SharedPreferences} used in this class. 20 | */ 21 | private static SharedPreferences prefs; 22 | 23 | /** 24 | * Initializes the default {@link android.content.SharedPreferences} used in this class. 25 | * 26 | * @param c Needed by {@link android.preference.PreferenceManager}. 27 | */ 28 | private static void initPrefs(final Context c) { 29 | prefs = PreferenceManager.getDefaultSharedPreferences(c); 30 | } 31 | 32 | /** 33 | * Returns a list with all subjects used by the user. 34 | * 35 | * @param c Needed by {@link android.preference.PreferenceManager}. 36 | */ 37 | public static String[] get(final Context c) { 38 | initPrefs(c); 39 | 40 | // Set size of array to amount of Strings in SharedPreferences 41 | final int size = prefs.getInt("subjects_size", 0); 42 | final String[] subjects = new String[size]; 43 | 44 | // Get parts of subject array from SharedPreferences Strings 45 | for (int i = 0; i < size; i++) 46 | subjects[i] = prefs.getString("subjects_" + i, null); 47 | 48 | return subjects; 49 | } 50 | 51 | /** 52 | * Adds a subject. 53 | * 54 | * @param c Needed by {@link android.preference.PreferenceManager}. 55 | * @param subject The subject to add. 56 | */ 57 | public static void add(final Context c, final String subject) { 58 | initPrefs(c); 59 | final int size = prefs.getInt("subjects_size", 0); 60 | final String[] subjects = new String[size + 1]; 61 | 62 | for (int i = 0; i < size; i++) 63 | subjects[i] = prefs.getString("subjects_" + i, null); 64 | 65 | subjects[size] = subject; 66 | 67 | final SharedPreferences.Editor editor = prefs.edit(); 68 | Arrays.sort(subjects); 69 | 70 | for (int i = 0; i < subjects.length; i++) 71 | editor.putString("subjects_" + i, subjects[i]); 72 | 73 | editor.putInt("subjects_size", subjects.length); 74 | editor.commit(); 75 | 76 | final String sAdded = c.getString(R.string.added); 77 | CustomToast.showShort(c, subject + " " + sAdded); 78 | } 79 | 80 | /** 81 | * Resets the list of subjects. 82 | * 83 | * @param c Needed by {@link android.preference.PreferenceManager}. 84 | */ 85 | public static void setDefault(final Context c) { 86 | // Get subjects from strings.xml 87 | final String[] subjects = c.getResources().getStringArray(R.array.subjects); 88 | 89 | // Sort subjects array alphabetically 90 | Arrays.sort(subjects); 91 | 92 | // Add subjects to SharedPreferences 93 | initPrefs(c); 94 | final SharedPreferences.Editor editor = prefs.edit(); 95 | editor.putInt("subjects_size", subjects.length); 96 | for (int i = 0; i < subjects.length; i++) 97 | editor.putString("subjects_" + i, subjects[i]); 98 | 99 | editor.commit(); 100 | } 101 | 102 | /** 103 | * Deletes a subject. 104 | * 105 | * @param c Needed by {@link android.preference.PreferenceManager}. 106 | * @param pos The subject to delete. 107 | */ 108 | public static void delete(final Context c, final int pos) { 109 | initPrefs(c); 110 | final int size = prefs.getInt("subjects_size", 0); 111 | final String[] subjects = new String[size - 1]; 112 | 113 | for (int i = 0; i < size; i++) { 114 | if (i < pos) 115 | subjects[i] = prefs.getString("subjects_" + i, null); 116 | 117 | if (i > pos) 118 | subjects[i - 1] = prefs.getString("subjects_" + i, null); 119 | } 120 | 121 | final SharedPreferences.Editor editor = prefs.edit(); 122 | 123 | for (int i = 0; i < subjects.length; i++) 124 | editor.putString("subjects_" + i, subjects[i]); 125 | 126 | editor.putInt("subjects_size", subjects.length); 127 | editor.commit(); 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /src/main/java/de/nico/ha_manager/helper/Theme.java: -------------------------------------------------------------------------------- 1 | package de.nico.ha_manager.helper; 2 | 3 | /* 4 | * @author Nico Alt 5 | * @author Devin 6 | * See the file "LICENSE" for the full license governing this code. 7 | */ 8 | 9 | import android.app.Activity; 10 | import android.content.SharedPreferences; 11 | import android.preference.PreferenceManager; 12 | 13 | import de.nico.ha_manager.R; 14 | 15 | public final class Theme { 16 | 17 | /** 18 | * Sets the theme. 19 | * 20 | * @param c {@link android.app.Activity} - It would be Context, but we need to 21 | * set the window background of the Activity, so Activity extends Context, so it 22 | * works out. 23 | * @param isAddTheme Since we use the DialogWhenLarge theme on tablets in the add 24 | * activity, we need to incorporate that. 25 | */ 26 | public static void set(final Activity c, final boolean isAddTheme) { 27 | final SharedPreferences prefs = PreferenceManager 28 | .getDefaultSharedPreferences(c); 29 | final boolean dark = prefs.getBoolean("theme", false); 30 | final boolean black = prefs.getBoolean("black", false); 31 | 32 | if (dark) { 33 | if (isAddTheme) 34 | c.setTheme(R.style.DarkAddTheme); 35 | else 36 | c.setTheme(R.style.DarkAppTheme); 37 | if (black) 38 | c.getWindow().setBackgroundDrawableResource(android.R.color.black); 39 | } else { 40 | if (isAddTheme) 41 | c.setTheme(R.style.AddTheme); 42 | else 43 | c.setTheme(R.style.AppTheme); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/de/nico/ha_manager/helper/Utils.java: -------------------------------------------------------------------------------- 1 | package de.nico.ha_manager.helper; 2 | 3 | /* 4 | * @author Nico Alt 5 | * @author Devin 6 | * See the file "LICENSE" for the full license governing this code. 7 | */ 8 | 9 | import android.app.AlertDialog; 10 | import android.app.AlertDialog.Builder; 11 | import android.content.ActivityNotFoundException; 12 | import android.content.Context; 13 | import android.content.DialogInterface; 14 | import android.content.DialogInterface.OnClickListener; 15 | import android.content.Intent; 16 | import android.content.SharedPreferences; 17 | import android.content.pm.ApplicationInfo; 18 | import android.content.pm.PackageInfo; 19 | import android.graphics.Paint; 20 | import android.os.Build; 21 | import android.preference.PreferenceManager; 22 | import android.util.Log; 23 | import android.view.View; 24 | import android.widget.ExpandableListAdapter; 25 | import android.widget.TextView; 26 | 27 | import java.io.File; 28 | import java.io.FileInputStream; 29 | import java.io.FileNotFoundException; 30 | import java.io.FileOutputStream; 31 | import java.io.IOException; 32 | import java.nio.channels.FileChannel; 33 | import java.text.DateFormat; 34 | import java.util.ArrayList; 35 | import java.util.HashMap; 36 | import java.util.Locale; 37 | import java.util.zip.ZipEntry; 38 | import java.util.zip.ZipFile; 39 | 40 | import de.nico.ha_manager.HWManager; 41 | import de.nico.ha_manager.R; 42 | import de.nico.ha_manager.database.Source; 43 | 44 | public final class Utils { 45 | 46 | private static boolean isActionBarAvailable = false; 47 | 48 | /** 49 | * A fix for a VerifyError crash on old versions 50 | * of Android 51 | */ 52 | static { 53 | try { 54 | ActionBarWrapper.isAvailable(); 55 | isActionBarAvailable = true; 56 | } catch (Throwable t) { 57 | isActionBarAvailable = false; 58 | } 59 | } 60 | 61 | public static void setupActionBar(final Context context, final boolean isPreferenceActivity) { 62 | if (Build.VERSION.SDK_INT >= 11 && isActionBarAvailable) { 63 | final ActionBarWrapper actionBarWrapper = new ActionBarWrapper(context, isPreferenceActivity); 64 | actionBarWrapper.setDisplayHomeAsUpEnabled(true); 65 | } 66 | } 67 | 68 | /** 69 | * Sends an Intent with a text to share the app. 70 | * 71 | * @param c Needed for {@link android.content.Intent}. 72 | */ 73 | @SuppressWarnings("deprecation") 74 | public static boolean shareApp(final Context c) { 75 | final String share_title = c.getString(R.string.intent_share_title); 76 | final String app_name = c.getString(R.string.app_name); 77 | 78 | final Intent intent = new Intent(android.content.Intent.ACTION_SEND); 79 | intent.setType("text/plain"); 80 | intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 81 | intent.putExtra(Intent.EXTRA_TEXT, 82 | c.getString(R.string.intent_share_text)); 83 | try { 84 | c.startActivity(Intent.createChooser(intent, share_title + " " 85 | + app_name)); 86 | return true; 87 | } catch (final ActivityNotFoundException e) { 88 | Log.e("ActivityNotFoundExcept", e.toString()); 89 | return false; 90 | } 91 | } 92 | 93 | /** 94 | * Returns some information to the build of the app. 95 | * 96 | * @param c Needed for {@link android.content.pm.PackageInfo} and 97 | * {@link android.content.pm.ApplicationInfo}. 98 | */ 99 | public static String getBuildInfo(final Context c) { 100 | String buildInfo = "Built with love."; 101 | try { 102 | // Get Version Name 103 | final PackageInfo pInfo = c.getPackageManager().getPackageInfo( 104 | c.getPackageName(), 0); 105 | final String versionName = pInfo.versionName; 106 | 107 | // Get build time 108 | final ApplicationInfo aInfo = c.getPackageManager().getApplicationInfo( 109 | c.getPackageName(), 0); 110 | final ZipFile zf = new ZipFile(aInfo.sourceDir); 111 | final ZipEntry ze = zf.getEntry("classes.dex"); 112 | zf.close(); 113 | final long time = ze.getTime(); 114 | final DateFormat f = DateFormat.getDateInstance(DateFormat.SHORT, 115 | Locale.getDefault()); 116 | final String buildDate = f.format(time); 117 | 118 | buildInfo = versionName + " (" + buildDate + ")"; 119 | 120 | } catch (final Exception e) { 121 | Log.e("Get Build Info", e.toString()); 122 | } 123 | return buildInfo; 124 | } 125 | 126 | /** 127 | * Shows a spinner with all available languages of HW-Manager. 128 | * 129 | * @param c Needed for {@link de.nico.ha_manager.HWManager} and 130 | * {@link android.content.SharedPreferences}. 131 | */ 132 | public static void langSpinner(final Context c) { 133 | final AlertDialog.Builder b = new Builder(c); 134 | // Current translations of HW-Manager 135 | final String[] languages = {"cs", "de", "en", "es", "fr", "hu", "pl", "tr", "ja", "ar", "fa"}; 136 | // Items with translation's language 137 | final String[] items = new String[languages.length + 1]; 138 | items[0] = c.getString(R.string.pref_language_default); 139 | for (int i = 1; i < languages.length + 1; i++) { 140 | final Locale appLoc = new Locale(languages[i - 1]); 141 | items[i] = appLoc.getDisplayLanguage(appLoc); 142 | } 143 | b.setTitle(c.getString(R.string.pref_language)); 144 | b.setItems(items, new OnClickListener() { 145 | 146 | @Override 147 | public final void onClick(final DialogInterface dialog, final int which) { 148 | dialog.dismiss(); 149 | final SharedPreferences prefs = PreferenceManager 150 | .getDefaultSharedPreferences(c); 151 | final SharedPreferences.Editor editor = prefs.edit(); 152 | 153 | if (which == 0) { 154 | editor.putString("locale_override", ""); 155 | editor.commit(); 156 | } else { 157 | editor.putString("locale_override", languages[which - 1]); 158 | editor.commit(); 159 | } 160 | HWManager.updateLanguage(c); 161 | } 162 | 163 | }); 164 | 165 | b.show(); 166 | } 167 | 168 | /** 169 | * Cross out solved homework. 170 | * 171 | * @param e {@link android.widget.ExpandableListAdapter} which contains the homework. 172 | * @param hwArray {@link java.util.ArrayList} which contains the homework. 173 | */ 174 | public static void crossOut(final ExpandableListAdapter e, final ArrayList> hwArray) { 175 | for (int i = 0; i < hwArray.size(); i++) { 176 | if (!hwArray.get(i).get(Source.allColumns[6]).equals("")) { 177 | final View v = e.getGroupView(i, false, null, null); 178 | 179 | final TextView tv1 = (TextView) v.findViewById(R.id.textView_subject); 180 | final TextView tv2 = (TextView) v.findViewById(R.id.textView_until); 181 | final TextView tv3 = (TextView) v.findViewById(R.id.textView_homework); 182 | final TextView tv4 = (TextView) v.findViewById(R.id.textView_urgent); 183 | tv1.setPaintFlags(tv1.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); 184 | tv2.setPaintFlags(tv2.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); 185 | tv3.setPaintFlags(tv3.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); 186 | tv4.setPaintFlags(tv4.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); 187 | } 188 | } 189 | } 190 | 191 | /** 192 | * Cross out one solved homework. 193 | * 194 | * @param hwArray {@link java.util.ArrayList} which contains the homework. 195 | * @param pos Position of solved homework. 196 | */ 197 | public static boolean crossOneOut(final Context c, final ArrayList> hwArray, final int pos) { 198 | try { 199 | final String ID = "ID = " + hwArray.get(pos).get(Source.allColumns[0]); 200 | final String title = hwArray.get(pos).get(Source.allColumns[1]); 201 | final String subject = hwArray.get(pos).get(Source.allColumns[2]); 202 | final long time = Long.valueOf(hwArray.get(pos).get(Source.allColumns[5])).longValue(); 203 | final String info = hwArray.get(pos).get(Source.allColumns[3]); 204 | final String urgent = hwArray.get(pos).get(Source.allColumns[4]); 205 | final String completed = "completed"; 206 | Homework.add(c, ID, title, subject, time, info, urgent, completed); 207 | return true; 208 | } catch (final Exception e) { 209 | Log.e("Utils.crossOneOut", e.toString()); 210 | return false; 211 | } 212 | } 213 | 214 | /** 215 | * Transfers a file. 216 | * 217 | * @param src Source from where the file has to be transferred. 218 | * @param dst Source to where the file has to be transferred. 219 | */ 220 | public static boolean transfer(final File src, final File dst) { 221 | try { 222 | final FileInputStream inStream = new FileInputStream(src); 223 | final FileOutputStream outStream = new FileOutputStream(dst); 224 | final FileChannel inChannel = inStream.getChannel(); 225 | final FileChannel outChannel = outStream.getChannel(); 226 | inChannel.transferTo(0, inChannel.size(), outChannel); 227 | inStream.close(); 228 | outStream.close(); 229 | return true; 230 | } catch (final FileNotFoundException e) { 231 | Log.e("FileNotFoundException", e.toString()); 232 | return false; 233 | } catch (final IOException e) { 234 | Log.e("IOException", e.toString()); 235 | return false; 236 | } 237 | } 238 | } 239 | 240 | 241 | 242 | -------------------------------------------------------------------------------- /src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hw-manager/android/471b28a05741f4564a55e6c2ef64b0386be75567/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hw-manager/android/471b28a05741f4564a55e6c2ef64b0386be75567/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hw-manager/android/471b28a05741f4564a55e6c2ef64b0386be75567/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/main/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hw-manager/android/471b28a05741f4564a55e6c2ef64b0386be75567/src/main/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/main/res/layout-v11/activity_add.xml: -------------------------------------------------------------------------------- 1 | 5 | 10 | 11 | 16 | 17 | 22 | 23 | 29 | 30 | 36 | 37 | 43 | 44 | 49 | 50 | 56 | 57 | 68 | 69 | 76 | 77 | 83 | 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /src/main/res/layout-v11/button_bar.xml: -------------------------------------------------------------------------------- 1 | 5 | 12 | 13 | 16 | 17 |