├── settings.gradle ├── art ├── ic_launcher_icon.png ├── ic_launcher_icon.pptx ├── ic_preference_wifi.pptx ├── ic_status_bac_icon.png ├── ic_status_bac_icon.pptx ├── ic_launcher_icon_114.png ├── ic_launcher_icon_512.png ├── ic_launcher_icon_512.pptx ├── ic_launcher_icon_web.png ├── ic_menu_toggle_wifi.pptx ├── ic_preference_wifi_grey.png └── ic_preference_wifi_white.png ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── app ├── src │ └── main │ │ ├── res │ │ ├── drawable-hdpi │ │ │ ├── ic_menu_edit.png │ │ │ ├── ic_menu_help.png │ │ │ ├── ic_dialog_info.png │ │ │ ├── ic_menu_delete.png │ │ │ ├── ic_menu_enable.png │ │ │ ├── ic_launcher_icon.png │ │ │ ├── ic_settings_wifi.png │ │ │ ├── ic_dialog_time_grey.png │ │ │ ├── ic_menu_agenda_grey.png │ │ │ ├── ic_menu_manage_grey.png │ │ │ ├── ic_menu_toggle_wifi.png │ │ │ ├── ic_status_bac_icon.png │ │ │ ├── ic_dialog_time_white.png │ │ │ ├── ic_menu_agenda_white.png │ │ │ ├── ic_menu_manage_white.png │ │ │ ├── ic_status_bac_icon_big.png │ │ │ ├── ic_preference_wifi_grey.png │ │ │ └── ic_preference_wifi_white.png │ │ ├── drawable-ldpi │ │ │ ├── ic_menu_edit.png │ │ │ ├── ic_menu_help.png │ │ │ ├── ic_dialog_info.png │ │ │ ├── ic_menu_delete.png │ │ │ ├── ic_menu_enable.png │ │ │ ├── ic_launcher_icon.png │ │ │ ├── ic_settings_wifi.png │ │ │ ├── ic_dialog_time_grey.png │ │ │ ├── ic_menu_agenda_grey.png │ │ │ ├── ic_menu_manage_grey.png │ │ │ ├── ic_menu_toggle_wifi.png │ │ │ ├── ic_status_bac_icon.png │ │ │ ├── ic_dialog_time_white.png │ │ │ ├── ic_menu_agenda_white.png │ │ │ ├── ic_menu_manage_white.png │ │ │ ├── ic_preference_wifi_grey.png │ │ │ └── ic_preference_wifi_white.png │ │ ├── drawable-mdpi │ │ │ ├── ic_menu_edit.png │ │ │ ├── ic_menu_help.png │ │ │ ├── ic_dialog_info.png │ │ │ ├── ic_menu_delete.png │ │ │ ├── ic_menu_enable.png │ │ │ ├── ic_launcher_icon.png │ │ │ ├── ic_settings_wifi.png │ │ │ ├── ic_dialog_time_grey.png │ │ │ ├── ic_menu_agenda_grey.png │ │ │ ├── ic_menu_manage_grey.png │ │ │ ├── ic_menu_toggle_wifi.png │ │ │ ├── ic_status_bac_icon.png │ │ │ ├── ic_dialog_time_white.png │ │ │ ├── ic_menu_agenda_white.png │ │ │ ├── ic_menu_manage_white.png │ │ │ ├── ic_preference_wifi_grey.png │ │ │ └── ic_preference_wifi_white.png │ │ ├── drawable-xhdpi │ │ │ ├── ic_menu_edit.png │ │ │ ├── ic_menu_help.png │ │ │ ├── ic_dialog_info.png │ │ │ ├── ic_launcher_icon.png │ │ │ ├── ic_menu_delete.png │ │ │ ├── ic_menu_enable.png │ │ │ ├── ic_settings_wifi.png │ │ │ ├── ic_status_bac_icon.png │ │ │ ├── ic_dialog_time_grey.png │ │ │ ├── ic_dialog_time_white.png │ │ │ ├── ic_menu_agenda_grey.png │ │ │ ├── ic_menu_agenda_white.png │ │ │ ├── ic_menu_manage_grey.png │ │ │ ├── ic_menu_manage_white.png │ │ │ ├── ic_menu_toggle_wifi.png │ │ │ ├── ic_preference_wifi_grey.png │ │ │ └── ic_preference_wifi_white.png │ │ ├── drawable-hdpi-v11 │ │ │ └── ic_status_bac_icon.png │ │ ├── drawable-ldpi-v11 │ │ │ └── ic_status_bac_icon.png │ │ ├── drawable-mdpi-v11 │ │ │ └── ic_status_bac_icon.png │ │ ├── drawable-xhdpi-v11 │ │ │ └── ic_status_bac_icon.png │ │ ├── drawable │ │ │ ├── ic_tab_general.xml │ │ │ ├── ic_tab_audit.xml │ │ │ ├── ic_tab_time.xml │ │ │ └── ic_tab_wifi_list.xml │ │ ├── values │ │ │ ├── colors.xml │ │ │ ├── attrs.xml │ │ │ └── arrays.xml │ │ ├── xml │ │ │ ├── wifi_list_preferences.xml │ │ │ ├── donate_preferences.xml │ │ │ ├── wifi_preferences.xml │ │ │ ├── time_interval_preferences.xml │ │ │ ├── general_preferences.xml │ │ │ └── advanced_preferences.xml │ │ ├── menu │ │ │ ├── menu_wifi_prefereces.xml │ │ │ └── menu_preferences.xml │ │ ├── layout │ │ │ ├── dialog_custom_layout.xml │ │ │ ├── wifi_list_edit_bar_layout.xml │ │ │ ├── activity_list.xml │ │ │ ├── dialog_welcome_extra_layout.xml │ │ │ └── preference.xml │ │ ├── values-ja │ │ │ ├── arrays.xml │ │ │ └── strings.xml │ │ ├── xml-v11 │ │ │ ├── donate_preferences.xml │ │ │ ├── wifi_preferences.xml │ │ │ ├── time_interval_preferences.xml │ │ │ ├── general_preferences.xml │ │ │ └── advanced_preferences.xml │ │ ├── values-hu │ │ │ └── arrays.xml │ │ ├── values-it │ │ │ └── arrays.xml │ │ ├── values-es │ │ │ └── arrays.xml │ │ ├── values-pt │ │ │ └── arrays.xml │ │ ├── values-ru │ │ │ └── arrays.xml │ │ ├── values-nl │ │ │ └── arrays.xml │ │ ├── values-fr │ │ │ └── arrays.xml │ │ ├── values-da │ │ │ └── arrays.xml │ │ └── values-de │ │ │ └── arrays.xml │ │ ├── java │ │ └── org │ │ │ └── cprados │ │ │ └── wificellmanager │ │ │ ├── ui │ │ │ ├── DescribeableElement.java │ │ │ ├── MyListItemView.java │ │ │ ├── TimeIntervalPreferences.java │ │ │ ├── IconPreference.java │ │ │ ├── MyCheckBoxPreference.java │ │ │ ├── AdvancedPreferences.java │ │ │ ├── GeneralPreferences.java │ │ │ └── TimePreference.java │ │ │ ├── sys │ │ │ ├── WakeLockManager.java │ │ │ ├── NotificationManager.java │ │ │ ├── CellStateListener.java │ │ │ ├── MobileDataManager.java │ │ │ └── CellStateManager.java │ │ │ ├── RequestedActionManager.java │ │ │ └── EventReceiver.java │ │ ├── AndroidManifest.xml │ │ └── aidl │ │ └── com │ │ └── android │ │ └── vending │ │ └── billing │ │ └── IInAppBillingService.aidl ├── build.gradle ├── app.iml └── Wi-Fi Matic.iml ├── .gitignore ├── WifiCellManager.iml ├── README.md ├── doc ├── ChangeLog.txt ├── Wi-Fi Matic Google Play.txt └── LICENSE-2.0.txt ├── gradlew.bat └── gradlew /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | -------------------------------------------------------------------------------- /art/ic_launcher_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/art/ic_launcher_icon.png -------------------------------------------------------------------------------- /art/ic_launcher_icon.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/art/ic_launcher_icon.pptx -------------------------------------------------------------------------------- /art/ic_preference_wifi.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/art/ic_preference_wifi.pptx -------------------------------------------------------------------------------- /art/ic_status_bac_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/art/ic_status_bac_icon.png -------------------------------------------------------------------------------- /art/ic_status_bac_icon.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/art/ic_status_bac_icon.pptx -------------------------------------------------------------------------------- /art/ic_launcher_icon_114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/art/ic_launcher_icon_114.png -------------------------------------------------------------------------------- /art/ic_launcher_icon_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/art/ic_launcher_icon_512.png -------------------------------------------------------------------------------- /art/ic_launcher_icon_512.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/art/ic_launcher_icon_512.pptx -------------------------------------------------------------------------------- /art/ic_launcher_icon_web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/art/ic_launcher_icon_web.png -------------------------------------------------------------------------------- /art/ic_menu_toggle_wifi.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/art/ic_menu_toggle_wifi.pptx -------------------------------------------------------------------------------- /art/ic_preference_wifi_grey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/art/ic_preference_wifi_grey.png -------------------------------------------------------------------------------- /art/ic_preference_wifi_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/art/ic_preference_wifi_white.png -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_menu_edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-hdpi/ic_menu_edit.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_menu_help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-hdpi/ic_menu_help.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-ldpi/ic_menu_edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-ldpi/ic_menu_edit.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-ldpi/ic_menu_help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-ldpi/ic_menu_help.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_menu_edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-mdpi/ic_menu_edit.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_menu_help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-mdpi/ic_menu_help.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_dialog_info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-hdpi/ic_dialog_info.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_menu_delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-hdpi/ic_menu_delete.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_menu_enable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-hdpi/ic_menu_enable.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-ldpi/ic_dialog_info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-ldpi/ic_dialog_info.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-ldpi/ic_menu_delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-ldpi/ic_menu_delete.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-ldpi/ic_menu_enable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-ldpi/ic_menu_enable.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_dialog_info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-mdpi/ic_dialog_info.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_menu_delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-mdpi/ic_menu_delete.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_menu_enable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-mdpi/ic_menu_enable.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_menu_edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-xhdpi/ic_menu_edit.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_menu_help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-xhdpi/ic_menu_help.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_launcher_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-hdpi/ic_launcher_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_settings_wifi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-hdpi/ic_settings_wifi.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-ldpi/ic_launcher_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-ldpi/ic_launcher_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-ldpi/ic_settings_wifi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-ldpi/ic_settings_wifi.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_launcher_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-mdpi/ic_launcher_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_settings_wifi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-mdpi/ic_settings_wifi.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_dialog_info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-xhdpi/ic_dialog_info.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_launcher_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-xhdpi/ic_launcher_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_menu_delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-xhdpi/ic_menu_delete.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_menu_enable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-xhdpi/ic_menu_enable.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_settings_wifi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-xhdpi/ic_settings_wifi.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_dialog_time_grey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-hdpi/ic_dialog_time_grey.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_menu_agenda_grey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-hdpi/ic_menu_agenda_grey.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_menu_manage_grey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-hdpi/ic_menu_manage_grey.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_menu_toggle_wifi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-hdpi/ic_menu_toggle_wifi.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_status_bac_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-hdpi/ic_status_bac_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-ldpi/ic_dialog_time_grey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-ldpi/ic_dialog_time_grey.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-ldpi/ic_menu_agenda_grey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-ldpi/ic_menu_agenda_grey.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-ldpi/ic_menu_manage_grey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-ldpi/ic_menu_manage_grey.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-ldpi/ic_menu_toggle_wifi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-ldpi/ic_menu_toggle_wifi.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-ldpi/ic_status_bac_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-ldpi/ic_status_bac_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_dialog_time_grey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-mdpi/ic_dialog_time_grey.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_menu_agenda_grey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-mdpi/ic_menu_agenda_grey.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_menu_manage_grey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-mdpi/ic_menu_manage_grey.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_menu_toggle_wifi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-mdpi/ic_menu_toggle_wifi.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_status_bac_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-mdpi/ic_status_bac_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_status_bac_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-xhdpi/ic_status_bac_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi-v11/ic_status_bac_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-hdpi-v11/ic_status_bac_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_dialog_time_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-hdpi/ic_dialog_time_white.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_menu_agenda_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-hdpi/ic_menu_agenda_white.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_menu_manage_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-hdpi/ic_menu_manage_white.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_status_bac_icon_big.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-hdpi/ic_status_bac_icon_big.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-ldpi-v11/ic_status_bac_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-ldpi-v11/ic_status_bac_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-ldpi/ic_dialog_time_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-ldpi/ic_dialog_time_white.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-ldpi/ic_menu_agenda_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-ldpi/ic_menu_agenda_white.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-ldpi/ic_menu_manage_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-ldpi/ic_menu_manage_white.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi-v11/ic_status_bac_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-mdpi-v11/ic_status_bac_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_dialog_time_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-mdpi/ic_dialog_time_white.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_menu_agenda_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-mdpi/ic_menu_agenda_white.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_menu_manage_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-mdpi/ic_menu_manage_white.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_dialog_time_grey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-xhdpi/ic_dialog_time_grey.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_dialog_time_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-xhdpi/ic_dialog_time_white.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_menu_agenda_grey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-xhdpi/ic_menu_agenda_grey.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_menu_agenda_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-xhdpi/ic_menu_agenda_white.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_menu_manage_grey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-xhdpi/ic_menu_manage_grey.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_menu_manage_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-xhdpi/ic_menu_manage_white.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_menu_toggle_wifi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-xhdpi/ic_menu_toggle_wifi.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_preference_wifi_grey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-hdpi/ic_preference_wifi_grey.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_preference_wifi_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-hdpi/ic_preference_wifi_white.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-ldpi/ic_preference_wifi_grey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-ldpi/ic_preference_wifi_grey.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-ldpi/ic_preference_wifi_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-ldpi/ic_preference_wifi_white.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_preference_wifi_grey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-mdpi/ic_preference_wifi_grey.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_preference_wifi_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-mdpi/ic_preference_wifi_white.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi-v11/ic_status_bac_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-xhdpi-v11/ic_status_bac_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_preference_wifi_grey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-xhdpi/ic_preference_wifi_grey.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_preference_wifi_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arqam/wifimatic-android/HEAD/app/src/main/res/drawable-xhdpi/ic_preference_wifi_white.png -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Apr 10 15:27:10 PDT 2013 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_tab_general.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_tab_audit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_tab_time.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_tab_wifi_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ff444444 4 | #D39622 5 | #417A00 6 | #B22900 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/xml/wifi_list_preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_wifi_prefereces.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # files for the dex VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # generated files 12 | bin/ 13 | gen/ 14 | build/ 15 | app/build 16 | .gradle/ 17 | .idea/ 18 | 19 | # Local configuration file (sdk path, etc) 20 | local.properties 21 | 22 | .settings/ 23 | 24 | # Non public classes 25 | EncodedPublicKey.java 26 | AuditTrailActivity.java 27 | DonatePreferences.java 28 | app/src/main/java/org/cprados/wificellmanager/billingv3/ 29 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 8 5 | buildToolsVersion "21.1.2" 6 | 7 | defaultConfig { 8 | applicationId "org.cprados.wificellmanager" 9 | minSdkVersion 8 10 | targetSdkVersion 18 11 | } 12 | 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/res/layout/dialog_custom_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 16 | 17 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /app/src/main/res/xml/donate_preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 13 | 14 | 15 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 8 | 9 | 13 | 14 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /WifiCellManager.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/values-ja/arrays.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1分 5 | 5分 6 | 15分 7 | 30分 8 | 1時間 9 | 10 | 11 | 1 12 | 5 13 | 15 14 | 30 15 | 60 16 | 17 | 18 | 無効 19 | 30秒 20 | 1分 21 | 2分 22 | 5分 23 | 24 | 25 | 0 26 | 30 27 | 60 28 | 120 29 | 300 30 | 31 | 32 | -------------------------------------------------------------------------------- /app/src/main/res/xml-v11/donate_preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 13 | 14 | 15 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/res/values-hu/arrays.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1 perc 5 | 5 perc 6 | 15 perc 7 | 30 perc 8 | 1 óra 9 | 10 | 11 | 1 12 | 5 13 | 15 14 | 30 15 | 60 16 | 17 | 18 | Soha 19 | 30 másodperc 20 | 1 perc 21 | 2 perc 22 | 5 perc 23 | 24 | 25 | 0 26 | 30 27 | 60 28 | 120 29 | 300 30 | 31 | 32 | -------------------------------------------------------------------------------- /app/src/main/res/values-it/arrays.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1 minuto 5 | 5 minuti 6 | 15 minuti 7 | 30 minuti 8 | 1 ora 9 | 10 | 11 | 1 12 | 5 13 | 15 14 | 30 15 | 60 16 | 17 | 18 | Spento 19 | 30 secondi 20 | 1 minuto 21 | 2 minuti 22 | 5 minuti 23 | 24 | 25 | 0 26 | 30 27 | 60 28 | 120 29 | 300 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/res/values-es/arrays.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1 minuto 5 | 5 minutos 6 | 15 minutos 7 | 30 minutos 8 | 1 hora 9 | 10 | 11 | 1 12 | 5 13 | 15 14 | 30 15 | 60 16 | 17 | 18 | Deshabilitado 19 | 30 segundos 20 | 1 minuto 21 | 2 minutos 22 | 5 minutos 23 | 24 | 25 | 0 26 | 30 27 | 60 28 | 120 29 | 300 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/res/values-pt/arrays.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1 minuto 5 | 5 minutos 6 | 15 minutos 7 | 30 minutos 8 | 1 hora 9 | 10 | 11 | 1 12 | 5 13 | 15 14 | 30 15 | 60 16 | 17 | 18 | Desabilitado 19 | 30 segundos 20 | 1 minuto 21 | 2 minutos 22 | 5 minutos 23 | 24 | 25 | 0 26 | 30 27 | 60 28 | 120 29 | 300 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/res/values-ru/arrays.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1 минута 5 | 5 минут 6 | 15 минут 7 | 30 минут 8 | 1 час 9 | 10 | 11 | 1 12 | 5 13 | 15 14 | 30 15 | 60 16 | 17 | 18 | Отключено 19 | 30 секунд 20 | 1 минута 21 | 2 минуты 22 | 5 минут 23 | 24 | 25 | 0 26 | 30 27 | 60 28 | 120 29 | 300 30 | 31 | 32 | -------------------------------------------------------------------------------- /app/src/main/res/values-nl/arrays.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1 minuut 5 | 5 minuten 6 | 15 minuten 7 | 30 minuten 8 | 1 uur 9 | 10 | 11 | 1 12 | 5 13 | 15 14 | 30 15 | 60 16 | 17 | 18 | Uitgeschakeld 19 | 30 seconden 20 | 1 minuut 21 | 2 minuten 22 | 5 minuten 23 | 24 | 25 | 0 26 | 30 27 | 60 28 | 120 29 | 300 30 | 31 | 32 | -------------------------------------------------------------------------------- /app/src/main/res/values/arrays.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1 minute 5 | 5 minutes 6 | 15 minutes 7 | 30 minutes 8 | 1 hour 9 | 10 | 11 | 1 12 | 5 13 | 15 14 | 30 15 | 60 16 | 17 | 18 | Disabled 19 | 30 seconds 20 | 1 minute 21 | 2 minutes 22 | 5 minutes 23 | 24 | 25 | 0 26 | 30 27 | 60 28 | 120 29 | 300 30 | 31 | 32 | -------------------------------------------------------------------------------- /app/src/main/res/values-fr/arrays.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1 minute 5 | 5 minutes 6 | 15 minutes 7 | 30 minutes 8 | 1 heure 9 | 10 | 11 | 1 12 | 5 13 | 15 14 | 30 15 | 60 16 | 17 | 18 | Désactivé 19 | 30 secondes 20 | 1 minute 21 | 2 minutes 22 | 5 minutes 23 | 24 | 25 | 0 26 | 30 27 | 60 28 | 120 29 | 300 30 | 31 | 32 | -------------------------------------------------------------------------------- /app/src/main/res/values-da/arrays.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1 minut 5 | 5 minutter 6 | 15 minutter 7 | 30 minutter 8 | 1 time 9 | 10 | 11 | 1 12 | 5 13 | 15 14 | 30 15 | 60 16 | 17 | 18 | Deaktiveret 19 | 30 sekunder 20 | 1 minut 21 | 2 minutter 22 | 5 minutter 23 | 24 | 25 | 0 26 | 30 27 | 60 28 | 120 29 | 300 30 | 31 | 32 | -------------------------------------------------------------------------------- /app/src/main/res/values-de/arrays.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1 Minute 5 | 5 Minuten 6 | 15 Minuten 7 | 30 Minuten 8 | 1 Stunde 9 | 10 | 11 | 1 12 | 5 13 | 15 14 | 30 15 | 60 16 | 17 | 18 | Deaktiviert 19 | 30 Sekunden 20 | 1 Minuten 21 | 2 Minuten 22 | 5 Minuten 23 | 24 | 25 | 0 26 | 30 27 | 60 28 | 120 29 | 300 30 | 31 | 32 | -------------------------------------------------------------------------------- /app/src/main/java/org/cprados/wificellmanager/ui/DescribeableElement.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DescribeableElement.java 3 | * This file is part of WifiCellManager. 4 | * Copyright (C) 2012 Carlos Prados 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package org.cprados.wificellmanager.ui; 20 | 21 | import android.content.res.Resources; 22 | 23 | /** Interface to be implemented by enumerated that identify events, states, actions, etc, 24 | * that can have a text description to be shown in the UI*/ 25 | public abstract interface DescribeableElement { 26 | public String getDescription(Resources res, Object...args); 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/res/layout/wifi_list_edit_bar_layout.xml: -------------------------------------------------------------------------------- 1 | 12 | 13 | 21 | 22 | 30 | 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Wi-Fi Matic Android App 2 | ======================= 3 | 4 | - What is Wi-Fi Matic? 5 | 6 | Wi-Fi Matic is and Android app that activates and deactivates Wi-Fi of your device automatically depending on your location, helping you to save battery and consumption of data through your operator network. 7 | 8 | It detects automatically the location of known Wi-Fi networks (f.i: home, office, etc.), turns on W-Fi when you arrive a place where there is Wi-Fi, and turns it off when you leave. 9 | 10 | You will simply notice that your device automatically uses Wi-Fi in the usual places where you have Wi-Fi access, while it keeps Wi-Fi off where you don't have it. 11 | 12 | - How does it work? 13 | 14 | It DOES NOT USE GPS neither requires to have Android network location services enabled, as it uses your operator network cell identifiers (cell tower identifiers) as the relative location where you are, and where your Wi-Fi networks are. It is designed to minimize usage of resources and battery. 15 | 16 | Wi-Fi Matic detects and learns automatically locations where you are connected to a Wi-Fi, and doesn't need configuration. Besides, it allows you to manage manually your Wi-Fi when needed not interfering with you or with your device data connections. 17 | 18 | Check: https://sites.google.com/site/wifimaticapp 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 21 | 22 | 27 | 28 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /app/src/main/res/layout/dialog_welcome_extra_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 14 | 15 | 24 | 25 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/xml/wifi_preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 15 | 16 | 17 | 24 | 25 | 26 | 33 | 34 | 35 | 36 | 37 | 40 | 41 | -------------------------------------------------------------------------------- /app/src/main/res/xml-v11/wifi_preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 15 | 16 | 17 | 24 | 25 | 26 | 33 | 34 | 35 | 36 | 37 | 40 | 41 | -------------------------------------------------------------------------------- /app/src/main/java/org/cprados/wificellmanager/ui/MyListItemView.java: -------------------------------------------------------------------------------- 1 | /* 2 | * AuditTrailManager.java 3 | * This file is part of WifiCellManager. 4 | * Copyright (C) 2012 Carlos Prados 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package org.cprados.wificellmanager.ui; 20 | 21 | import android.content.Context; 22 | import android.graphics.Canvas; 23 | import android.graphics.Paint; 24 | import android.util.AttributeSet; 25 | import android.widget.LinearLayout; 26 | 27 | /** 28 | * A custom layout for each item in the Audit Trail list view. 29 | */ 30 | public class MyListItemView extends LinearLayout { 31 | 32 | private Paint mPaint = new Paint(); 33 | private int mColorStripe; 34 | private boolean mDrawColorStripe = false; 35 | 36 | public MyListItemView(Context context) { 37 | super(context); 38 | } 39 | 40 | public MyListItemView(Context context, AttributeSet attrs) { 41 | super(context, attrs); 42 | } 43 | 44 | public void setColorStripe (boolean draw, int color) { 45 | mDrawColorStripe = draw; 46 | mColorStripe = color; 47 | } 48 | 49 | @Override 50 | protected void dispatchDraw(Canvas canvas) { 51 | super.dispatchDraw(canvas); 52 | 53 | /* Draw vertical color stripe */ 54 | if (mPaint != null && mDrawColorStripe) { 55 | mPaint.setColor(mColorStripe); 56 | canvas.drawRect(0, 0, 8, getHeight(), mPaint); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /app/src/main/res/xml/time_interval_preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 13 | 14 | 15 | 25 | 26 | 27 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /app/src/main/res/xml-v11/time_interval_preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 13 | 14 | 15 | 25 | 26 | 27 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /doc/ChangeLog.txt: -------------------------------------------------------------------------------- 1 | 1.2.1 2 | - Added a schedule to turn off Wi-Fi during an interval of the day (f.i. during the nights). 3 | - Added advanced preferences for specific devices where cell location is not made available by Android until the screen is turned on. Only needed if in your device Wi-Fi is never turned on/off untill you turn on screen. 4 | - Added preference to autoturn off Wi-Fi after a certain time of being disconnected. 5 | - Fixed issue that caused cell -1--1 to be added to the list. 6 | - Donations via Google Play. 7 | 8 | 1.2.2 9 | - Updated to solve problem under Android 4.2 that caused screen to be turned on 10 | 11 | 1.3.1: 12 | - Amazon Marketplace support. 13 | 14 | 1.3.2: 15 | - UI improvement under Android 3.X & 4.X. 16 | - Ability to manage delete & dissable individual cells tower ids. 17 | - Color codes to signal current and nearby cells and wifis. 18 | - German translation (Thanks Bj�rn!). 19 | - Misc functional fixes. 20 | 21 | 1.3.3: 22 | - Top 1 requested feature: Added option to turn off mobile data while connected to a known Wi-Fi. See advanced preferences. Use this option it at your risk as it could cause data charges. 23 | - Fixed missbehaviour in History tab if Wi-Fi name had a pipe ("|") character. 24 | - French translation (Thanks to Robin Getta). 25 | - Portuguese translation (Thanks to Paulo Barqueira) 26 | - Danish translation (Thanks to Jimmy Jorjensen) 27 | - Dutch translation (Thanks to Eelco Dijkstra, dedicated to his wife Sandra). 28 | 29 | 1.3.4: 30 | - Wi-Fi Matic is now opensource! Check http://github.com/cprados/wifimatic-android 31 | - Option to decide what to do when mobile coverage is lost (location is unknown). 32 | - Russian Translation (thanks to Alexander Krasnobelov). 33 | - Fixed problem with scheduled Wi-Fi on/off. 34 | - Fixed problem of not detecting coverage loss correctly under Android 4.2 with LTE. 35 | - Explicitly require a SIM enabled phone/tablet to be eligible in Google Play. 36 | - Fixed problem when cancelling Access Point mode activation. 37 | 38 | 1.3.5: 39 | - Removed telephony enabled device as compatibility requirement. 40 | - Corrected typo in German Translation. 41 | 42 | 1.3.6: 43 | - Google APIs update. 44 | - Added Japanese language. Thanks whim0321. 45 | - Minor corrections. 46 | -------------------------------------------------------------------------------- /app/src/main/res/xml/general_preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 14 | 15 | 16 | 23 | 24 | 25 | 34 | 35 | 36 | 43 | 44 | 45 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /app/src/main/res/xml-v11/general_preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 14 | 15 | 16 | 23 | 24 | 25 | 34 | 35 | 36 | 43 | 44 | 45 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /app/src/main/res/xml/advanced_preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | 14 | 15 | 16 | 22 | 23 | 24 | 30 | 31 | 32 | 33 | 34 | 37 | 38 | 46 | 47 | 48 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /doc/Wi-Fi Matic Google Play.txt: -------------------------------------------------------------------------------- 1 | Important: this app is not designed to reveal Wi-Fi passwords, neither to help you to set up your phone to connect to a Wi-Fi for the first time. Please, read carefully the description and if it is not what you are looking for, do not download it. 2 | 3 | Wi-Fi Matic activates and deactivates Wi-Fi of your device automatically depending on your location, helping you to save battery and consumption of data through your operator network. 4 | 5 | It detects automatically the location of known Wi-Fi networks (f.i: home, office, etc.), turns on W-Fi when you arrive a place where there is Wi-Fi, and turns it off when you leave. 6 | 7 | You will simply notice that your device automatically uses Wi-Fi in the usual places where you have Wi-Fi access, while it keeps Wi-Fi off where you don't have it. 8 | 9 | - How does it work? 10 | 11 | It DOES NOT USE GPS neither requires to have Android network location services enabled, as it uses your operator network cell identifiers (cell tower identifiers) as the relative location where you are, and where your Wi-Fi networks are. It is designed to minimize usage of resources and battery. 12 | 13 | Wi-Fi Matic detects and learns automatically locations where you are connected to a Wi-Fi, and doesn't need configuration. Besides, it allows you to manage manually your Wi-Fi when needed not interfering with you or with your device data connections. 14 | 15 | - How is it used? 16 | 17 | 1.- Once it is installed, click on "Enable Wi-Fi Matic" and leave the app in the background. 18 | 19 | 2.- Whenever you want to connect to a Wi-Fi for the first time, do it manually in the Android Wireless networks settings menu, or just let Android connect to any of the networks already known by your device. 20 | 21 | 3.- And that's it: Wi-Fi Matic will learn your Wi-Fi location when you get connected. Whenever you leave that place, Wi-Fi will be automatically turned off and whenever you get back, Wi-Fi will be automatically turned on. 22 | 23 | See: https://sites.google.com/site/wifimaticapp/ 24 | 25 | Articles: 26 | 27 | http://www.emezeta.com/articulos/como-reducir-el-consumo-de-datos-en-android#axzz2CZMHWknK 28 | 29 | http://www.dragonazul.es/review/las-10-mejores-aplicaciones-gratuitas-para-android/2/ 30 | 31 | http://justinbee.tumblr.com/post/24618702269/common-sense-android-app-wi-fi-matic 32 | 33 | http://www.mundoandroides.com/como-ahorrar-internet-en-tu-android 34 | 35 | http://www.eleconomista.es/CanalPDA/2012/36403/10-trucos-para-reducir-el-consumo-de-datos-en-android/ 36 | 37 | keywords: wi-fi wifi wireless automatic turn on off location positioning detection scheduler -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /app/src/main/res/xml-v11/advanced_preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | 14 | 15 | 16 | 22 | 23 | 24 | 30 | 31 | 32 | 33 | 34 | 37 | 38 | 46 | 47 | 48 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /app/src/main/res/layout/preference.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 20 | 28 | 29 | 37 | 38 | 45 | 46 | 53 | 54 | 55 | 56 | 57 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /app/src/main/java/org/cprados/wificellmanager/sys/WakeLockManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * WakeLockManager.java 3 | * This file is part of WifiCellManager. 4 | * Copyright (C) 2012 Carlos Prados 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package org.cprados.wificellmanager.sys; 20 | 21 | import org.cprados.wificellmanager.DataManager; 22 | 23 | import android.content.Context; 24 | import android.os.PowerManager; 25 | 26 | /** 27 | * Manager class for the application CPU Wake Lock. Wake Lock is acquired from the broadcast receivers and listeners 28 | * before invoking manager service and is released when the service has finished processing 29 | */ 30 | public class WakeLockManager { 31 | 32 | /** The wake lock tag */ 33 | private static final String WAKELOCK_TAG = WakeLockManager.class.getName() + ".wake_lock"; 34 | 35 | /** The WakeLockManager instance */ 36 | private static WakeLockManager mInstance = null; 37 | 38 | /** Wake lock to be acquired before running the manager service*/ 39 | private PowerManager.WakeLock mCpuWakeLock = null; 40 | 41 | /** Returns the WakeLockManager instance */ 42 | public static WakeLockManager getWakeLockManager() { 43 | if (mInstance == null) 44 | mInstance = new WakeLockManager(); 45 | return mInstance; 46 | } 47 | 48 | /** Acquires the wake lock */ 49 | public void acquireWakeLock(Context context) { 50 | 51 | PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); 52 | 53 | if (mCpuWakeLock == null) { 54 | 55 | if (!DataManager.getTurnOnScreen(context)) { 56 | mCpuWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK , WAKELOCK_TAG); 57 | //mCpuWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, WAKELOCK_TAG); 58 | } 59 | 60 | // Turn on screen fix 61 | else { 62 | //mCpuWakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, WAKELOCK_TAG); 63 | mCpuWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE , WAKELOCK_TAG); 64 | } 65 | 66 | mCpuWakeLock.acquire(); 67 | } 68 | } 69 | 70 | /** Release the wake lock */ 71 | public void releaseWakeLock() { 72 | if (mCpuWakeLock != null) { 73 | mCpuWakeLock.release(); 74 | mCpuWakeLock = null; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 23 | 24 | 25 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /app/src/main/java/org/cprados/wificellmanager/sys/NotificationManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * NotificationManager.java 3 | * This file is part of WifiCellManager. 4 | * Copyright (C) 2012 Carlos Prados 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package org.cprados.wificellmanager.sys; 20 | 21 | import java.util.Date; 22 | 23 | import org.cprados.wificellmanager.DataManager; 24 | import org.cprados.wificellmanager.R; 25 | import org.cprados.wificellmanager.StateMachine.StateAction; 26 | import org.cprados.wificellmanager.ui.DescribeableElement; 27 | import org.cprados.wificellmanager.ui.Preferences; 28 | 29 | import android.app.Notification; 30 | import android.app.PendingIntent; 31 | import android.content.Context; 32 | import android.content.Intent; 33 | import android.content.res.Resources; 34 | import android.os.Bundle; 35 | 36 | /** Class to manage Status bar notifications */ 37 | public class NotificationManager { 38 | 39 | /** Id of the notification in the notifications bar */ 40 | private static final int sNid = 0; 41 | 42 | /** Adds or updates a notification in the system status bar appropriate for an action */ 43 | public static void notifyAction(Context context, StateAction action, DescribeableElement cause, Date date, Bundle stateData) { 44 | 45 | if (context != null) { 46 | Resources res = context.getResources(); 47 | 48 | // Notification title is the action description 49 | String title = (action != null) ? action.getDescription(res) : null; 50 | 51 | String text; 52 | if (action != StateAction.ADD) { 53 | Object[] args = {CellStateManager.getNearbyWifis(stateData), 54 | WifiStateManager.getCurrentWifi(stateData), 55 | DataManager.getOffAfterDiscTimeout(context)}; 56 | 57 | // Notification text is the action cause description 58 | text = (cause != null) ? cause.getDescription(res, args) : null; 59 | } 60 | else { 61 | // Notification text is the wifi name 62 | text = WifiStateManager.getCurrentWifi(stateData); 63 | } 64 | 65 | // Puts a notification in the notifications bar 66 | if (text != null && title != null) { 67 | putNotification(context, title, text, date); 68 | } 69 | } 70 | } 71 | 72 | /** Adds or updates a notification in the system status bar */ 73 | public static void putNotification(Context context, String title, String text, Date date) { 74 | 75 | if (DataManager.getNotifications(context)) { 76 | int icon = R.drawable.ic_status_bac_icon; 77 | long when = date.getTime(); 78 | context = context.getApplicationContext(); 79 | 80 | Intent notificationIntent = new Intent(context, Preferences.class); 81 | notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 82 | notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); 83 | PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); 84 | Notification notification = new Notification(icon, text, when); 85 | notification.setLatestEventInfo(context, title, text, contentIntent); 86 | 87 | android.app.NotificationManager nm = (android.app.NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 88 | nm.notify(sNid, notification); 89 | } 90 | } 91 | 92 | /** Removes the notification from the system status bar */ 93 | public static void removeNotification(Context context) { 94 | 95 | context = context.getApplicationContext(); 96 | android.app.NotificationManager nm = (android.app.NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 97 | nm.cancel(sNid); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /app/src/main/java/org/cprados/wificellmanager/sys/CellStateListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * CellStateListener.java 3 | * This file is part of WifiCellManager. 4 | * Copyright (C) 2012 Carlos Prados 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package org.cprados.wificellmanager.sys; 20 | 21 | import org.cprados.wificellmanager.BuildConfig; 22 | import org.cprados.wificellmanager.ManagerService; 23 | 24 | import android.content.Context; 25 | import android.content.Intent; 26 | import android.telephony.CellLocation; 27 | import android.telephony.PhoneStateListener; 28 | import android.telephony.TelephonyManager; 29 | import android.telephony.cdma.CdmaCellLocation; 30 | import android.telephony.gsm.GsmCellLocation; 31 | import android.util.Log; 32 | 33 | /** 34 | * Phone state listener singleton class, whose instance listens cell location 35 | * change events and forwards them to the manager service. 36 | */ 37 | public class CellStateListener extends PhoneStateListener { 38 | 39 | /** Tag for logging this class messages */ 40 | private static final String LOGTAG = CellStateListener.class.getPackage().getName(); 41 | 42 | /** Application context to invoke the manager service */ 43 | private Context mContext; 44 | 45 | /** Action this listener sends events to */ 46 | private String mAction; 47 | 48 | /** CellStateListener singleton instance variable */ 49 | private static CellStateListener sInstance = null; 50 | 51 | /** Returns the unique instance of this class */ 52 | public static CellStateListener getCellChangeListener(Context appContext,String action) { 53 | if (sInstance == null) 54 | sInstance = new CellStateListener(appContext, action); 55 | return sInstance; 56 | } 57 | 58 | /** 59 | * Creates the listener with a given application context to invoke the 60 | * manager service from it 61 | */ 62 | private CellStateListener(Context applicationContext, String action) { 63 | super(); 64 | this.mContext = applicationContext; 65 | this.mAction = action; 66 | } 67 | 68 | /** Configures the listener to be launched periodically on each cell change */ 69 | public static void requestCellChangeEvents(Context appContext, String action, boolean enable) { 70 | 71 | // Gets TelephonyManager service 72 | TelephonyManager tm = (TelephonyManager) appContext 73 | .getSystemService(Context.TELEPHONY_SERVICE); 74 | 75 | // Subscribes a CellChageListener to TelepphonyManager cell change events 76 | if (enable) { 77 | tm.listen(getCellChangeListener(appContext, action), LISTEN_CELL_LOCATION); 78 | } 79 | 80 | // Cancels CellChageListener subscription the TelephonyManager events 81 | else { 82 | tm.listen(CellStateListener.getCellChangeListener(appContext, action),LISTEN_NONE); 83 | delete(); 84 | } 85 | } 86 | 87 | /** Handles cell change events */ 88 | @Override 89 | public void onCellLocationChanged(CellLocation location) { 90 | 91 | if (BuildConfig.DEBUG) { 92 | Log.d(LOGTAG, "CellStateListener: Location change event: " + location); 93 | } 94 | 95 | // Creates the intent with location data 96 | Intent intent = new Intent(); 97 | 98 | if (location != null) { 99 | // GSM or UMTS cell location received 100 | if (location instanceof GsmCellLocation) { 101 | intent.putExtra(CellStateManager.EXTRA_CID,((GsmCellLocation) location).getCid()); 102 | intent.putExtra(CellStateManager.EXTRA_LAC,((GsmCellLocation) location).getLac()); 103 | TelephonyManager tm = (TelephonyManager) (mContext.getSystemService(Context.TELEPHONY_SERVICE)); 104 | if (tm != null) { 105 | intent.putExtra(CellStateManager.EXTRA_OP, tm.getNetworkOperator()); 106 | } 107 | } 108 | // CDMA cell location received 109 | else if (location instanceof CdmaCellLocation) { 110 | intent.putExtra(CellStateManager.EXTRA_CID,((CdmaCellLocation) location).getBaseStationId()); 111 | intent.putExtra(CellStateManager.EXTRA_LAC,((CdmaCellLocation) location).getSystemId()); 112 | int networkId = ((CdmaCellLocation) location).getNetworkId(); 113 | if (networkId != -1) { 114 | intent.putExtra(CellStateManager.EXTRA_OP, String.valueOf(networkId)); 115 | } 116 | } 117 | } 118 | 119 | // Forwards intent to the manager service 120 | if (mContext != null && mAction != null) { 121 | ManagerService.forwardEvent(mContext, mAction, intent); 122 | } 123 | } 124 | 125 | /** 126 | * Sets the CellStateListener instance variable to null so it can be garbage 127 | * collected 128 | */ 129 | public static void delete() { 130 | sInstance.mAction = null; 131 | sInstance.mContext = null; 132 | sInstance = null; 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /app/src/main/java/org/cprados/wificellmanager/ui/TimeIntervalPreferences.java: -------------------------------------------------------------------------------- 1 | /* 2 | * TimeIntervalPreferences.java 3 | * This file is part of WifiCellManager. 4 | * Copyright (C) 2012 Carlos Prados 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package org.cprados.wificellmanager.ui; 20 | 21 | import org.cprados.wificellmanager.DataManager; 22 | import org.cprados.wificellmanager.ManagerService; 23 | import org.cprados.wificellmanager.R; 24 | 25 | import android.content.Intent; 26 | import android.os.Bundle; 27 | import android.preference.Preference; 28 | import android.preference.Preference.OnPreferenceChangeListener; 29 | import android.preference.PreferenceActivity; 30 | import android.preference.PreferenceScreen; 31 | import android.util.Log; 32 | 33 | /** 34 | * Preferences Activity to handle configuration of disable wifi time interval 35 | */ 36 | public class TimeIntervalPreferences extends PreferenceActivity implements OnPreferenceChangeListener { 37 | 38 | /** Tag for logging this class messages */ 39 | private static final String LOGTAG = TimeIntervalPreferences.class.getPackage().getName(); 40 | 41 | /** Activity creation callback */ 42 | @Override 43 | protected void onCreate(Bundle savedInstanceState) { 44 | super.onCreate(savedInstanceState); 45 | addPreferencesFromResource(R.xml.time_interval_preferences); 46 | //setContentView(R.layout.preferences_layout); 47 | } 48 | 49 | /** Activity resume callback */ 50 | @Override 51 | protected void onResume() { 52 | super.onResume(); 53 | 54 | // Dynamically sets this activity preferences enabled or dissabled 55 | setEnabled(DataManager.getActivate(this)); 56 | 57 | // Registers preferences change callbacks 58 | PreferenceScreen screen = getPreferenceScreen(); 59 | 60 | Preference timeIntervalEnabled = screen.findPreference(DataManager.PREFERENCE_TIME_INTERVAL); 61 | if (timeIntervalEnabled != null) { 62 | timeIntervalEnabled.setOnPreferenceChangeListener(this); 63 | } 64 | 65 | Preference timeIntervalBegin = screen.findPreference(DataManager.PREFERENCE_TIME_INTERVAL_BEGIN); 66 | if (timeIntervalBegin != null) { 67 | timeIntervalBegin.setOnPreferenceChangeListener(this); 68 | } 69 | 70 | Preference timeIntervalEnd = screen.findPreference(DataManager.PREFERENCE_TIME_INTERVAL_END); 71 | if (timeIntervalEnd != null) { 72 | timeIntervalEnd.setOnPreferenceChangeListener(this); 73 | } 74 | } 75 | 76 | /** Handler for preferences change event */ 77 | public boolean onPreferenceChange(Preference pref, Object newValue) { 78 | 79 | boolean restart = false; 80 | 81 | // Time interval preference changed 82 | if (pref.getKey().equals(DataManager.PREFERENCE_TIME_INTERVAL) 83 | && Boolean.parseBoolean(newValue.toString()) != DataManager.getTimeIntervalEnabled(this)) { 84 | restart = true; 85 | } 86 | 87 | else if (pref.getKey().equals(DataManager.PREFERENCE_TIME_INTERVAL_BEGIN) && 88 | !compareTime(newValue.toString(), DataManager.getTimeIntervalBegin(this))) { 89 | restart = true; 90 | } 91 | 92 | else if (pref.getKey().equals(DataManager.PREFERENCE_TIME_INTERVAL_END) && 93 | !compareTime(newValue.toString(), DataManager.getTimeIntervalEnd(this))) { 94 | restart = true; 95 | } 96 | 97 | if (restart) { 98 | // Restarts the service 99 | Intent intent = new Intent(this.getApplicationContext(), ManagerService.class); 100 | stopService(intent); 101 | startService(intent); 102 | } 103 | 104 | return true; 105 | } 106 | 107 | private boolean compareTime (String timeString, int[] time) { 108 | 109 | boolean result = false; 110 | int [] values = new int[2]; 111 | try { 112 | String[] timeParts=timeString.split(DataManager.TIME_SEPARATOR); 113 | values[0] = Integer.parseInt(timeParts[0]); 114 | values[1] = Integer.parseInt(timeParts[1]); 115 | result = (values[0] == time[0]) && (values[1] == time[1]); 116 | } 117 | catch (Exception e) { 118 | Log.e(LOGTAG, Log.getStackTraceString(e)); 119 | } 120 | 121 | return result; 122 | } 123 | 124 | /** Enables or disables options depending on the app status */ 125 | private void setEnabled (boolean enable) { 126 | 127 | PreferenceScreen screen = getPreferenceScreen(); 128 | if (screen != null) { 129 | 130 | // Enables or disables main scheduler activation checkbox preference 131 | Preference timeIntervalPref = screen.findPreference(DataManager.PREFERENCE_TIME_INTERVAL); 132 | if (timeIntervalPref != null) { 133 | timeIntervalPref.setEnabled(enable); 134 | } 135 | } 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /app/src/main/java/org/cprados/wificellmanager/RequestedActionManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RequestedActionManager.java 3 | * This file is part of WifiCellManager. 4 | * Copyright (C) 2012 Carlos Prados 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package org.cprados.wificellmanager; 20 | 21 | 22 | import org.cprados.wificellmanager.StateMachine.State; 23 | import org.cprados.wificellmanager.StateMachine.StateAction; 24 | import org.cprados.wificellmanager.StateMachine.StateEvent; 25 | import org.cprados.wificellmanager.ui.DescribeableElement; 26 | 27 | import android.content.Context; 28 | import android.content.Intent; 29 | import android.content.res.Resources; 30 | import android.util.Log; 31 | 32 | /** Handler of intents sent to the Manager Service to request it explicitly to an action */ 33 | public class RequestedActionManager { 34 | 35 | /** Extra name for the action requested in and event */ 36 | private static final String EXTRA_ACTION = RequestedActionManager.class.getName() + ".action"; 37 | 38 | /** Initiator of actions of the intents sent to the service for explicit action requests*/ 39 | public static final String EXPLICIT_ACTION_REQ = ManagerService.class.getName() + ".explicit_action_req_"; 40 | 41 | /** Action requests handled by the Manager Service */ 42 | public enum RequestedAction implements DescribeableElement { 43 | SCHEDULED_OFF, SCHEDULED_ON, DEFERRED_OFF; 44 | 45 | /** Returns the requested action description */ 46 | @Override 47 | public String getDescription (Resources res, Object...args) { 48 | 49 | String description = null; 50 | 51 | switch (this) { 52 | case SCHEDULED_OFF: 53 | description = res.getString(R.string.requested_action_scheduled_off); 54 | break; 55 | case SCHEDULED_ON: 56 | description = res.getString(R.string.requested_action_scheduled_on); 57 | break; 58 | case DEFERRED_OFF: 59 | description = res.getString(R.string.requested_action_deferred_off,args[2]); 60 | break; 61 | } 62 | 63 | return description; 64 | } 65 | }; 66 | 67 | /** Tag for logging this class messages */ 68 | private static final String LOGTAG = RequestedActionManager.class.getPackage().getName(); 69 | 70 | /** 71 | * Determines requested state action in the intent 72 | */ 73 | public static StateAction getStateAction (Context context, Intent intent, State currentState) { 74 | 75 | StateAction result = StateAction.NONE; 76 | 77 | if (intent != null) { 78 | 79 | String extraAction = intent.getStringExtra(EXTRA_ACTION); 80 | 81 | if (extraAction != null) { 82 | 83 | // Scheduled or deferred disable wifi event received 84 | if (extraAction.equals(RequestedAction.SCHEDULED_OFF.toString()) || 85 | extraAction.equals(RequestedAction.DEFERRED_OFF.toString())) { 86 | 87 | // Action is turn off wifi if state is not off 88 | StateEvent wifiState = currentState.getWifiState(); 89 | if (wifiState != StateEvent.OFF) { 90 | result = StateAction.OFF; 91 | } 92 | } 93 | 94 | // Scheduled enable wifi event received 95 | else if (extraAction.equals(RequestedAction.SCHEDULED_ON.toString())) { 96 | 97 | // Action is turn wifi on if there are nearby wifis and it is off 98 | StateEvent cellState = currentState.getCellState(); 99 | StateEvent wifiState = currentState.getWifiState(); 100 | if (cellState == StateEvent.IN && wifiState == StateEvent.OFF) { 101 | result = StateAction.ON; 102 | } 103 | } 104 | } 105 | } 106 | 107 | Log.d(LOGTAG, "RequestedActionManager: Action Requested: " + result); 108 | 109 | return (result); 110 | } 111 | 112 | /** Builds an explicit requested event intent */ 113 | public static Intent createRequestedAction (RequestedAction requestedAction) { 114 | 115 | Intent result = new Intent(); 116 | 117 | if (result != null) { 118 | result.putExtra(EXTRA_ACTION, requestedAction.toString()); 119 | } 120 | 121 | return (result); 122 | } 123 | 124 | /** Return the explicit requested action from an intent */ 125 | public static RequestedAction getRequestedAction(Intent intent) { 126 | 127 | RequestedAction result = null; 128 | 129 | if (intent != null) { 130 | String extraAction = intent.getStringExtra(EXTRA_ACTION); 131 | if (extraAction != null) { 132 | try { 133 | result = RequestedAction.valueOf(extraAction); 134 | } 135 | catch (Exception e) { 136 | Log.e(LOGTAG, Log.getStackTraceString(e)); 137 | } 138 | } 139 | } 140 | 141 | return result; 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /app/src/main/java/org/cprados/wificellmanager/ui/IconPreference.java: -------------------------------------------------------------------------------- 1 | /* 2 | * IconPreference.java 3 | * This file is part of WifiCellManager. 4 | * Copyright (C) 2012 Carlos Prados 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package org.cprados.wificellmanager.ui; 20 | 21 | import org.cprados.wificellmanager.R; 22 | 23 | import android.content.Context; 24 | import android.content.res.TypedArray; 25 | import android.graphics.Typeface; 26 | import android.graphics.drawable.Drawable; 27 | import android.preference.Preference; 28 | import android.util.AttributeSet; 29 | import android.view.View; 30 | import android.view.ViewGroup; 31 | import android.widget.ImageView; 32 | import android.widget.TextView; 33 | 34 | /** Extension to Preference that allows to place an Icon at the right of the preference title */ 35 | public class IconPreference extends Preference { 36 | 37 | /** The icon of the preference */ 38 | private Drawable mIcon; 39 | 40 | /** Whether the preference is to be highlighted in bold */ 41 | private boolean mBold = false; 42 | 43 | private int mColorStripe = 0; 44 | 45 | /** Constructor to create an IconPreference */ 46 | public IconPreference (Context context) { 47 | super(context); 48 | setLayoutResource(R.layout.preference); 49 | } 50 | 51 | /** Constructor to create an IconPreference */ 52 | public IconPreference(Context context, AttributeSet attrs) { 53 | super(context, attrs); 54 | setLayoutResource(R.layout.preference); 55 | TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.IconPreference); 56 | mIcon = a.getDrawable(R.styleable.IconPreference_icon); 57 | mBold = a.getBoolean(R.styleable.IconPreference_bold, false); 58 | mColorStripe= a.getColor(R.styleable.IconPreference_color_stripe, 0); 59 | } 60 | 61 | /** Constructor to create an IconPreference */ 62 | public IconPreference(Context context, AttributeSet attrs, int defStyle) { 63 | super(context, attrs, defStyle); 64 | setLayoutResource(R.layout.preference); 65 | TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.IconPreference, defStyle, 0); 66 | mIcon = a.getDrawable(R.styleable.IconPreference_icon); 67 | mBold = a.getBoolean(R.styleable.IconPreference_bold, false); 68 | mColorStripe= a.getColor(R.styleable.IconPreference_color_stripe, 0); 69 | } 70 | 71 | /** 72 | * Binds the created View to the data for this IconPreference. 73 | * Draws the icon and the title in bold if defined for this preference. 74 | * Summary and Bold title text mimics the color of the CheckBoxPreferences. 75 | */ 76 | @Override 77 | public void onBindView(View view) { 78 | super.onBindView(view); 79 | 80 | View widgetLayout = view.findViewById(android.R.id.widget_frame); 81 | if (widgetLayout != null && widgetLayout instanceof ViewGroup) { 82 | ((ViewGroup) widgetLayout).removeAllViews(); 83 | if (mIcon != null) { 84 | ImageView imageView = new ImageView(widgetLayout.getContext()); 85 | imageView.setImageDrawable(mIcon); 86 | ((ViewGroup) widgetLayout).addView(imageView); 87 | widgetLayout.setVisibility(View.VISIBLE); 88 | } 89 | } 90 | 91 | TextView titleView = (TextView) view.findViewById(android.R.id.title); 92 | if (titleView != null) { 93 | if (mBold) { 94 | if (isEnabled()) { 95 | titleView.setTextColor(MyCheckBoxPreference.getSummaryColor()); 96 | } 97 | titleView.setTypeface(Typeface.DEFAULT_BOLD, Typeface.BOLD); 98 | } 99 | } 100 | 101 | TextView summaryView = (TextView) view.findViewById(android.R.id.summary); 102 | if (summaryView != null && isEnabled()) { 103 | summaryView.setTextColor(MyCheckBoxPreference.getSummaryColor()); 104 | } 105 | 106 | // Set the color stripe 107 | if (view instanceof MyListItemView) { 108 | ((MyListItemView) view).setColorStripe((this.mColorStripe != 0), this.mColorStripe); 109 | } 110 | } 111 | 112 | /** Set an Icon for this preference */ 113 | public void setMyIcon(Drawable icon) { 114 | if ((icon == null && mIcon != null) || (icon != null && !icon.equals(mIcon))) { 115 | mIcon = icon; 116 | notifyChanged(); 117 | } 118 | } 119 | 120 | /** Returns the Icon of this preference or null if it has not been set */ 121 | public Drawable getIcon() { 122 | return mIcon; 123 | } 124 | 125 | /** Set this preference to be highlighted in bold letters */ 126 | public void setBold (boolean bold) { 127 | mBold = bold; 128 | notifyChanged(); 129 | } 130 | 131 | /** Returns if this preference has been set to be highlighted in bold letters */ 132 | public boolean getBold() { 133 | return mBold; 134 | } 135 | 136 | /** Set color stripe of this preference */ 137 | public void setColorStripe (int color) { 138 | mColorStripe = color; 139 | notifyChanged(); 140 | } 141 | 142 | /** Returns color stripe of this preference */ 143 | public int getColorStripe() { 144 | return mColorStripe; 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /app/src/main/java/org/cprados/wificellmanager/sys/MobileDataManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MobileDataManager.java 3 | * This file is part of WifiCellManager. 4 | * Copyright (C) 2012 Carlos Prados 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package org.cprados.wificellmanager.sys; 20 | 21 | import java.lang.reflect.Field; 22 | import java.lang.reflect.Method; 23 | 24 | import org.cprados.wificellmanager.StateMachine.StateAction; 25 | 26 | import android.content.Context; 27 | import android.net.ConnectivityManager; 28 | import android.os.Bundle; 29 | import android.util.Log; 30 | 31 | /** Manages changes in mobile data connectivity state of the system */ 32 | public class MobileDataManager { 33 | 34 | /** Tag for logging this class messages */ 35 | private static final String LOGTAG = MobileDataManager.class.getPackage().getName(); 36 | 37 | /** Extra name for flag that indicates if any action on mobile data was made */ 38 | private static final String EXTRA_PENDING_MOBILE_DATA_ACTION = WifiStateManager.class.getName() + ".pending_mobile_data_action"; 39 | 40 | /** 41 | * Turns off or restores mobile data. Sets pending mobile data action flag to true if it actually turned mobile data off. Clears 42 | * pending mobile data action flag if it restored mobile data to original state 43 | */ 44 | public static void setMobileDataState(Context context, StateAction targetState, Bundle stateData) { 45 | 46 | if (stateData != null && (targetState == StateAction.DATA_OFF || targetState == StateAction.DATA_RESTORE)) { 47 | 48 | if (targetState == StateAction.DATA_RESTORE && getPendingMobileDataAction(stateData)) { 49 | 50 | // Turns on mobile data if it is off 51 | if (!getMobileDataState(context)) { 52 | setMobileDataState (context, true); 53 | } 54 | 55 | // Clears pending mobile data action flag. 56 | setPendingMobileDataAction(stateData, false); 57 | } 58 | 59 | else if (targetState == StateAction.DATA_OFF) { 60 | 61 | // Turns off mobile data if it is on 62 | if (getMobileDataState(context)) { 63 | if (setMobileDataState (context, false)) { 64 | 65 | // Only if it was Wi-Fi Matic who turned mobile data off, set mobile data action flag to true 66 | // so it will remind to turn it back on later 67 | setPendingMobileDataAction(stateData, true); 68 | } 69 | } 70 | } 71 | } 72 | } 73 | 74 | /** 75 | * Checks if mobile data is on or off. Returns true if it is on, false if it is off. 76 | */ 77 | private static boolean getMobileDataState(Context context) { 78 | boolean status = false; 79 | 80 | try { 81 | ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 82 | Method method = connectivityManager.getClass().getMethod("getMobileDataEnabled"); 83 | status = (Boolean) method.invoke(connectivityManager); 84 | } catch (Exception e) { 85 | Log.e(LOGTAG, Log.getStackTraceString(e)); 86 | } 87 | 88 | return status; 89 | } 90 | 91 | /** 92 | * Sets Mobile data on or off. Status true turns on, false turns off. Returns true if action succeeded, false otherwise 93 | */ 94 | private static boolean setMobileDataState(Context context, boolean status) { 95 | boolean result = false; 96 | try { 97 | // Uses reflection to get access to setMobileDataEnabled method 98 | final ConnectivityManager conman = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 99 | final Class conmanClass = Class.forName(conman.getClass().getName()); 100 | final Field iConnectivityManagerField = conmanClass.getDeclaredField("mService"); 101 | iConnectivityManagerField.setAccessible(true); 102 | final Object iConnectivityManager = iConnectivityManagerField.get(conman); 103 | final Class iConnectivityManagerClass = Class.forName(iConnectivityManager.getClass().getName()); 104 | final Method setMobileDataEnabledMethod = iConnectivityManagerClass.getDeclaredMethod("setMobileDataEnabled", 105 | Boolean.TYPE); 106 | setMobileDataEnabledMethod.setAccessible(true); 107 | 108 | // Sets mobile data enabed to target state 109 | setMobileDataEnabledMethod.invoke(iConnectivityManager, status); 110 | result = true; 111 | } 112 | catch (Exception e) { 113 | Log.e(LOGTAG, Log.getStackTraceString(e)); 114 | } 115 | return result; 116 | } 117 | 118 | /** Returns if there is a pending mobile data action stored in state data bundle */ 119 | public static boolean getPendingMobileDataAction (Bundle stateData) { 120 | boolean result = false; 121 | result = (stateData != null) ? stateData.getBoolean(EXTRA_PENDING_MOBILE_DATA_ACTION) : false; 122 | return result; 123 | } 124 | 125 | /** Sets or clears a pending mobile data action to state data bundle */ 126 | public static void setPendingMobileDataAction (Bundle stateData, boolean status) { 127 | if (stateData != null) { 128 | if (status) { 129 | stateData.putBoolean(EXTRA_PENDING_MOBILE_DATA_ACTION, true); 130 | } 131 | else { 132 | stateData.remove(EXTRA_PENDING_MOBILE_DATA_ACTION); 133 | } 134 | } 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /app/src/main/java/org/cprados/wificellmanager/ui/MyCheckBoxPreference.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MyCheckBoxPreference.java 3 | * This file is part of WifiCellManager. 4 | * Copyright (C) 2012 Carlos Prados 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package org.cprados.wificellmanager.ui; 20 | 21 | import org.cprados.wificellmanager.R; 22 | 23 | import android.content.Context; 24 | import android.content.res.ColorStateList; 25 | import android.content.res.TypedArray; 26 | import android.graphics.Color; 27 | import android.util.AttributeSet; 28 | import android.view.View; 29 | import android.widget.TextView; 30 | 31 | /** 32 | * Trivial extension to standard CheckBoxPreference that retrieves the color 33 | * Android gives to the text of the summary of the preferences. This normally depends on the 34 | * flavor of Android the application runs under. The color can be later retrieved 35 | * from other preferences to mimic the standard colors. 36 | */ 37 | public class MyCheckBoxPreference extends android.preference.CheckBoxPreference { 38 | 39 | /** Color of the text of the summary of the preferences */ 40 | private static int sSummaryColor = Color.WHITE; 41 | 42 | /** Whether the color has been retrieved or not */ 43 | private static boolean sInitialized = false; 44 | 45 | /** Whether this preference should be drawn in grey color */ 46 | private boolean mGrey = false; 47 | 48 | private int mColorStripe = 0; 49 | 50 | /** Constructor from a Context */ 51 | public MyCheckBoxPreference(Context context) { 52 | super(context); 53 | } 54 | 55 | /** Constructor from a Context and AttributeSet */ 56 | public MyCheckBoxPreference(Context context, AttributeSet attrs) { 57 | super(context, attrs); 58 | TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.IconPreference); 59 | mColorStripe= a.getColor(R.styleable.IconPreference_color_stripe, 0); 60 | if (mColorStripe != 0) { 61 | setLayoutResource(R.layout.preference); 62 | } 63 | } 64 | 65 | /** Constructor from a Context, AttributeSet and def style */ 66 | public MyCheckBoxPreference(Context context, AttributeSet attrs, int defStyle) { 67 | super(context, attrs, defStyle); 68 | TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.IconPreference, defStyle, 0); 69 | mColorStripe= a.getColor(R.styleable.IconPreference_color_stripe, 0); 70 | if (mColorStripe != 0) { 71 | setLayoutResource(R.layout.preference); 72 | } 73 | } 74 | 75 | public void setGrey (boolean grey) { 76 | mGrey = grey; 77 | notifyChanged(); 78 | } 79 | 80 | /** 81 | * Binds the created View to the data for this Preference. Extended from 82 | * CheckBoxPreference to retrieve summary color first time its invoked 83 | */ 84 | @Override 85 | public void onBindView(View view) { 86 | super.onBindView(view); 87 | if (isEnabled()) { 88 | 89 | // Preference is being used to detect sSummaryColor for other preferences 90 | // Retrieves current summary color 91 | if (!sInitialized && !mGrey && mColorStripe == 0) { 92 | sSummaryColor = getSummaryColor(view); 93 | sInitialized = true; 94 | } 95 | 96 | // Sets texts color to grey of this preference as required 97 | else if (mGrey) { 98 | 99 | TextView titleView = (TextView) view.findViewById(android.R.id.title); 100 | if (titleView != null) { 101 | titleView.setTextColor(Color.GRAY); 102 | } 103 | 104 | TextView summaryView = (TextView) view.findViewById(android.R.id.summary); 105 | if (summaryView != null) { 106 | summaryView.setTextColor(Color.GRAY); 107 | } 108 | } 109 | 110 | // Preference is being used as a normal check box preference with color stripe. 111 | // Sets summary color 112 | else if (mColorStripe != 0) { 113 | TextView summaryView = (TextView) view.findViewById(android.R.id.summary); 114 | if (summaryView != null) { 115 | summaryView.setTextColor(MyCheckBoxPreference.getSummaryColor()); 116 | } 117 | } 118 | } 119 | 120 | // Set the color stripe if configured 121 | if (view instanceof MyListItemView) { 122 | ((MyListItemView) view).setColorStripe((this.mColorStripe != 0), this.mColorStripe); 123 | } 124 | } 125 | 126 | /** Retrieves summary text color given the view a preference is being drawn into */ 127 | private int getSummaryColor(View view) { 128 | 129 | int color = Color.WHITE; 130 | 131 | // Gets the color android gave to the summary by default 132 | TextView summaryView = (TextView) view.findViewById(android.R.id.summary); 133 | if (summaryView != null) { 134 | ColorStateList list = summaryView.getTextColors(); 135 | if (list != null) { 136 | color = list.getDefaultColor(); 137 | } 138 | } 139 | return color; 140 | } 141 | 142 | /** Retrieves the color of the text of the summary of the check box preferences*/ 143 | public static int getSummaryColor() { 144 | return sSummaryColor; 145 | } 146 | 147 | /** Set color stripe of this preference */ 148 | public void setColorStripe (int color) { 149 | if (color != 0) { 150 | setLayoutResource(R.layout.preference); 151 | } 152 | mColorStripe = color; 153 | notifyChanged(); 154 | } 155 | 156 | /** Returns color stripe of this preference */ 157 | public int getColorStripe() { 158 | return mColorStripe; 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /app/app.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /app/Wi-Fi Matic.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /app/src/main/java/org/cprados/wificellmanager/ui/AdvancedPreferences.java: -------------------------------------------------------------------------------- 1 | /* 2 | * AdvancedPreferences.java 3 | * This file is part of WifiCellManager. 4 | * Copyright (C) 2012 Carlos Prados 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package org.cprados.wificellmanager.ui; 20 | 21 | import org.cprados.wificellmanager.DataManager; 22 | import org.cprados.wificellmanager.R; 23 | 24 | import android.app.Dialog; 25 | import android.os.Bundle; 26 | import android.preference.Preference; 27 | import android.preference.Preference.OnPreferenceChangeListener; 28 | import android.preference.PreferenceActivity; 29 | import android.preference.PreferenceScreen; 30 | 31 | /** 32 | * Preferences Activity to handle advanced configuration options 33 | */ 34 | public class AdvancedPreferences extends PreferenceActivity implements OnPreferenceChangeListener { 35 | 36 | /** Id of the dialog to confirm screen on preference */ 37 | private static final int DIALOG_CONFIRM_SCREEN_ON = 0; 38 | 39 | /** Id of the dialog to confirm force update preference */ 40 | private static final int DIALOG_CONFIRM_FORCE_UPDATE = 1; 41 | 42 | /** Id of the dialog to confirm disconnection timeout preference */ 43 | private static final int DIALOG_CONFIRM_DISC_TIMEOUT = 2; 44 | 45 | /** Id of the dialog to confirm mobile data management */ 46 | private static final int DIALOG_CONFIRM_MOBILE_DATA_MANAGED = 3; 47 | 48 | /** Id of the dialog to confirm mobile data management */ 49 | private static final int DIALOG_UNK_LOCATION_ACTIVATES_WIFI = 4; 50 | 51 | /** Activity creation callback */ 52 | @Override 53 | protected void onCreate(Bundle savedInstanceState) { 54 | super.onCreate(savedInstanceState); 55 | addPreferencesFromResource(org.cprados.wificellmanager.R.xml.advanced_preferences); 56 | } 57 | 58 | /** Activity resume callback */ 59 | @Override 60 | protected void onResume() { 61 | super.onResume(); 62 | 63 | // Registers preferences click and change callbacks 64 | PreferenceScreen screen = getPreferenceScreen(); 65 | screen.findPreference(DataManager.PREFERENCE_TURN_ON_SCREEN).setOnPreferenceChangeListener(this); 66 | screen.findPreference(DataManager.PREFERENCE_FORCE_UPDATE_LOCATION).setOnPreferenceChangeListener(this); 67 | screen.findPreference(DataManager.PREFERENCE_OFF_AFTER_DISC_TIMEOUT).setOnPreferenceChangeListener(this); 68 | screen.findPreference(DataManager.PREFERENCE_MOBILE_DATA_MANAGED).setOnPreferenceChangeListener(this); 69 | screen.findPreference(DataManager.PREFERENCE_UNK_LOCATION_ACTIVATES_WIFI).setOnPreferenceChangeListener(this); 70 | } 71 | 72 | /** 73 | * Handler for this Activity dialogs creation 74 | */ 75 | protected Dialog onCreateDialog(int id) { 76 | 77 | Dialog result = null; 78 | 79 | switch (id) { 80 | case DIALOG_CONFIRM_SCREEN_ON: 81 | 82 | result = (new Dialogs.ConfirmPreferenceDialogBuilder(this, 83 | R.string.dialog_text_turn_on_screen, 84 | findPreference(DataManager.PREFERENCE_TURN_ON_SCREEN), 85 | Boolean.valueOf(false))).create(); 86 | break; 87 | 88 | case DIALOG_CONFIRM_FORCE_UPDATE: 89 | 90 | result = (new Dialogs.ConfirmPreferenceDialogBuilder(this, 91 | R.string.dialog_text_force_update_location, 92 | findPreference(DataManager.PREFERENCE_FORCE_UPDATE_LOCATION), 93 | Boolean.valueOf(false))).create(); 94 | break; 95 | 96 | case DIALOG_CONFIRM_DISC_TIMEOUT: 97 | result = (new Dialogs.ConfirmPreferenceDialogBuilder(this, 98 | R.string.dialog_text_off_after_disc_timeout, 99 | findPreference(DataManager.PREFERENCE_OFF_AFTER_DISC_TIMEOUT), 100 | String.valueOf(DataManager.PREFERENCE_DEFAULT_OFF_AFTER_DISC_TIMEOUT))).create(); 101 | break; 102 | 103 | case DIALOG_CONFIRM_MOBILE_DATA_MANAGED: 104 | 105 | result = (new Dialogs.ConfirmPreferenceDialogBuilder(this, 106 | R.string.dialog_text_mobile_data_managed, 107 | findPreference(DataManager.PREFERENCE_MOBILE_DATA_MANAGED), 108 | Boolean.valueOf(false))).create(); 109 | break; 110 | 111 | case DIALOG_UNK_LOCATION_ACTIVATES_WIFI: 112 | 113 | result = (new Dialogs.ConfirmPreferenceDialogBuilder(this, 114 | R.string.dialog_text_unk_location_activates_wifi, 115 | findPreference(DataManager.PREFERENCE_UNK_LOCATION_ACTIVATES_WIFI), 116 | Boolean.valueOf(false))).create(); 117 | break; 118 | } 119 | 120 | return result; 121 | } 122 | 123 | public boolean onPreferenceChange(Preference preference, Object newValue) { 124 | 125 | // Turn on screen preference changed 126 | if (preference.getKey().equals(DataManager.PREFERENCE_TURN_ON_SCREEN)) { 127 | if (newValue != null && Boolean.parseBoolean(newValue.toString())) { 128 | showDialog(DIALOG_CONFIRM_SCREEN_ON); 129 | } 130 | } 131 | 132 | // Force update location preference changed 133 | else if (preference.getKey().equals(DataManager.PREFERENCE_FORCE_UPDATE_LOCATION)) { 134 | if (newValue != null && Boolean.parseBoolean(newValue.toString())) { 135 | showDialog(DIALOG_CONFIRM_FORCE_UPDATE); 136 | } 137 | } 138 | 139 | else if (preference.getKey().equals(DataManager.PREFERENCE_OFF_AFTER_DISC_TIMEOUT)) { 140 | if (newValue != null && !newValue.toString().equals(String.valueOf(DataManager.PREFERENCE_DEFAULT_OFF_AFTER_DISC_TIMEOUT))) { 141 | showDialog(DIALOG_CONFIRM_DISC_TIMEOUT); 142 | } 143 | } 144 | 145 | else if (preference.getKey().equals(DataManager.PREFERENCE_MOBILE_DATA_MANAGED)) { 146 | if (newValue != null && Boolean.parseBoolean(newValue.toString())) { 147 | showDialog(DIALOG_CONFIRM_MOBILE_DATA_MANAGED); 148 | } 149 | } 150 | 151 | else if (preference.getKey().equals(DataManager.PREFERENCE_UNK_LOCATION_ACTIVATES_WIFI)) { 152 | if (newValue != null && Boolean.parseBoolean(newValue.toString())) { 153 | showDialog(DIALOG_UNK_LOCATION_ACTIVATES_WIFI); 154 | } 155 | } 156 | 157 | return true; 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /app/src/main/java/org/cprados/wificellmanager/ui/GeneralPreferences.java: -------------------------------------------------------------------------------- 1 | /* 2 | * GeneralPreferences.java 3 | * This file is part of WifiCellManager. 4 | * Copyright (C) 2012 Carlos Prados 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package org.cprados.wificellmanager.ui; 20 | 21 | import org.cprados.wificellmanager.DataManager; 22 | import org.cprados.wificellmanager.ManagerService; 23 | import org.cprados.wificellmanager.R; 24 | import org.cprados.wificellmanager.StateMachine; 25 | 26 | import android.content.BroadcastReceiver; 27 | import android.content.Context; 28 | import android.content.Intent; 29 | import android.content.IntentFilter; 30 | import android.content.res.Resources; 31 | import android.os.Bundle; 32 | import android.preference.CheckBoxPreference; 33 | import android.preference.Preference; 34 | import android.preference.Preference.OnPreferenceChangeListener; 35 | import android.preference.Preference.OnPreferenceClickListener; 36 | import android.preference.PreferenceActivity; 37 | import android.preference.PreferenceScreen; 38 | 39 | /** 40 | * Preferences activity to handle program management options, 41 | * start and stop, and permits to monitor program status 42 | */ 43 | public class GeneralPreferences extends PreferenceActivity implements OnPreferenceChangeListener, OnPreferenceClickListener { 44 | 45 | /** Action to be sent in a broadcast to ask this activity to refresh */ 46 | private static final String REFRESH_UI_ACTION = GeneralPreferences.class.getPackage().getName() + ".refresh_ui"; 47 | 48 | /** Broadcast receiver that receives refresh requests for this activity */ 49 | private BroadcastReceiver mRefreshReceiver = null; 50 | 51 | /** Activity creation callback */ 52 | @Override 53 | protected void onCreate(Bundle savedInstanceState) { 54 | super.onCreate(savedInstanceState); 55 | addPreferencesFromResource(R.xml.general_preferences); 56 | } 57 | 58 | /** Activity resume callback */ 59 | @Override 60 | protected void onResume() { 61 | super.onResume(); 62 | 63 | // Registers preferences click and change callbacks 64 | PreferenceScreen screen = getPreferenceScreen(); 65 | screen.findPreference(DataManager.PREFERENCE_ACTIVATE).setOnPreferenceClickListener(this); 66 | screen.findPreference(DataManager.PREFERENCE_FREQ).setOnPreferenceChangeListener(this); 67 | screen.findPreference(DataManager.PREFERENCE_ADVANCED).setOnPreferenceClickListener(this); 68 | 69 | // Registers refresh receiver callback 70 | registerReceiver(mRefreshReceiver = new BroadcastReceiver() { 71 | public void onReceive(Context context, Intent intent) { 72 | refreshUI(); 73 | } 74 | }, new IntentFilter(REFRESH_UI_ACTION)); 75 | 76 | // Refreshes UI preferences that may have changed 77 | refreshUI(); 78 | } 79 | 80 | /** Activity pause callback */ 81 | @Override 82 | protected void onPause() { 83 | super.onPause(); 84 | 85 | // Unregister refresh receiver callback 86 | if (mRefreshReceiver != null) { 87 | unregisterReceiver(mRefreshReceiver); 88 | mRefreshReceiver = null; 89 | } 90 | } 91 | 92 | /** Handler for preferences click event */ 93 | public boolean onPreferenceClick(Preference pref) { 94 | 95 | // Activate preference clicked 96 | if (pref.getKey().equals(DataManager.PREFERENCE_ACTIVATE)) { 97 | Intent intent = new Intent(this.getApplicationContext(), ManagerService.class); 98 | 99 | // Activate the service requesting init actions 100 | if (DataManager.getActivate(this)) { 101 | startService(intent.setAction(ManagerService.INIT_ACTION)); 102 | 103 | // Disable welcome dialog 104 | DataManager.setWizardStep(this, Dialogs.WelcomeDialogBuilder.FINISHED_STEP); 105 | } 106 | else { 107 | // Deactivate the service 108 | stopService(intent); 109 | 110 | // Refreshes the UI 111 | refreshUI(); 112 | } 113 | } 114 | 115 | else if (pref.getKey().equals(DataManager.PREFERENCE_ADVANCED)) { 116 | 117 | // Start advanced preferences activity 118 | Intent intent = new Intent(this, AdvancedPreferences.class); 119 | startActivity(intent); 120 | } 121 | 122 | return true; 123 | } 124 | 125 | /** Handler for preferences change event */ 126 | public boolean onPreferenceChange(Preference pref, Object newValue) { 127 | 128 | // Check frequency preference changed 129 | if (pref.getKey().equals(DataManager.PREFERENCE_FREQ)) { 130 | 131 | // Service was running and frequency preference actually changed 132 | if (DataManager.getActivate(this) && (Integer.parseInt((String) newValue) != DataManager.getFrequency(this))) { 133 | 134 | // Restarts the service 135 | Intent intent = new Intent(this.getApplicationContext(), ManagerService.class); 136 | stopService(intent); 137 | startService(intent); 138 | } 139 | } 140 | 141 | return true; 142 | } 143 | 144 | /** Refresh Preferences activity UI */ 145 | private void refreshUI() { 146 | 147 | // Refresh activate preference value and status message 148 | PreferenceScreen screen = getPreferenceScreen(); 149 | CheckBoxPreference prefActivate = (CheckBoxPreference) screen.findPreference(DataManager.PREFERENCE_ACTIVATE); 150 | prefActivate.setSummary(getStatusMessage()); 151 | prefActivate.setChecked(DataManager.getActivate(this)); 152 | } 153 | 154 | /** Determines the status message of the application shown in UI */ 155 | private String getStatusMessage() { 156 | 157 | String statusMessage = null; 158 | Resources res = getResources(); 159 | StateMachine.State currentState = DataManager.getState(this); 160 | 161 | // State machine has not been initialized jet 162 | if (currentState == null) { 163 | // System is not initialized jet 164 | statusMessage = res.getString(R.string.preference_summary_activate); 165 | } 166 | // Get current state description 167 | else { 168 | statusMessage = currentState.getDescription(res,DataManager.getNumWifisOfCurrentCell(this),DataManager.getCurrentWifi(this)); 169 | } 170 | 171 | return statusMessage; 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /app/src/main/java/org/cprados/wificellmanager/EventReceiver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * EventReceiver.java 3 | * This file is part of WifiCellManager. 4 | * Copyright (C) 2012 Carlos Prados 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package org.cprados.wificellmanager; 20 | 21 | import java.util.Calendar; 22 | import java.util.Date; 23 | 24 | import org.cprados.wificellmanager.sys.WakeLockManager; 25 | 26 | import android.app.AlarmManager; 27 | import android.app.PendingIntent; 28 | import android.content.BroadcastReceiver; 29 | import android.content.ComponentName; 30 | import android.content.Context; 31 | import android.content.Intent; 32 | import android.content.pm.PackageManager; 33 | import android.util.Log; 34 | 35 | /** 36 | * Broadcast receiver that handles events fired by the system and forwards them to the manager service: 37 | * Handles boot completion, alarm manager periodic events, wifi and connection state changes. 38 | */ 39 | public class EventReceiver extends BroadcastReceiver { 40 | 41 | /** Tag for logging this class messages */ 42 | private static final String LOGTAG = EventReceiver.class.getPackage().getName(); 43 | 44 | /** Enables or disables event entry */ 45 | public static void activateReceiver(Context context, boolean enableReceiver) { 46 | 47 | // Gets boot receiver component name 48 | ComponentName componentName = new ComponentName(context, EventReceiver.class); 49 | 50 | // Gets package manager reference 51 | PackageManager packageManager = context.getPackageManager(); 52 | 53 | if (packageManager != null) { 54 | 55 | // Checks current setting 56 | int currentlyEnabled = packageManager.getComponentEnabledSetting(componentName); 57 | 58 | // Checks how setting should be 59 | int targetEnabled = enableReceiver ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED 60 | : PackageManager.COMPONENT_ENABLED_STATE_DISABLED; 61 | 62 | // Set component enabled setting 63 | if (currentlyEnabled != targetEnabled) 64 | packageManager.setComponentEnabledSetting(componentName, targetEnabled, PackageManager.DONT_KILL_APP); 65 | } 66 | } 67 | 68 | /** Configures alarm manager to send broadcasts to this receiver periodically at a given frequency (given in milliseconds)*/ 69 | public static void requestPeriodicEvents (Context context, int[] timeOfDay, long frequency, String action, Intent intent, boolean enable) { 70 | 71 | // Gets alarm manager 72 | AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 73 | 74 | // Creates intent message to wrap it within a pending intent 75 | // object to be given to alarm manager service 76 | if (intent == null) { 77 | intent = new Intent(context, EventReceiver.class); 78 | } 79 | else { 80 | intent.setClass(context, EventReceiver.class); 81 | } 82 | 83 | // Sets the action 84 | if (action != null) { 85 | intent.setAction(action); 86 | } 87 | PendingIntent pIntent = PendingIntent.getBroadcast(context, 0, intent, 0); 88 | 89 | // Schedules or cancels the alarm 90 | if (enable) { 91 | long time = 0; 92 | if ((timeOfDay!=null) && (timeOfDay.length > 1)) { 93 | am.setRepeating(AlarmManager.RTC_WAKEUP, time = getNextTimeMillis(timeOfDay[0],timeOfDay[1]), frequency, pIntent); 94 | if (BuildConfig.DEBUG) { 95 | Log.d(LOGTAG, "EventReceiver: Repeating Alarm set: " + (new Date(time)) + "), frequency(ms)=" + frequency + ", action=" + action); 96 | } 97 | } 98 | else { 99 | am.setInexactRepeating(AlarmManager.RTC_WAKEUP, time = System.currentTimeMillis(), frequency, pIntent); 100 | if (BuildConfig.DEBUG) { 101 | Log.d(LOGTAG, "EventReceiver: Inexact Repeating Alarm set: " + (new Date(time)) + "), frequency(ms)=" + frequency + ", action=" + action); 102 | } 103 | } 104 | } 105 | else { 106 | am.cancel(pIntent); 107 | if (BuildConfig.DEBUG) { 108 | Log.d(LOGTAG, "EventReceiver: Alarm canceled: action=" + action); 109 | } 110 | } 111 | } 112 | 113 | /** Configures alarm manager to send a broadcast to this receiver at a given time */ 114 | public static void requestEvent(Context context, Date date, String action, Intent intent, boolean enable) { 115 | 116 | // Gets alarm manager 117 | AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 118 | 119 | // Creates intent message to wrap it within a pending intent 120 | // object to be given to alarm manager service 121 | if (intent == null) { 122 | intent = new Intent(context, EventReceiver.class); 123 | } 124 | else { 125 | intent.setClass(context, EventReceiver.class); 126 | } 127 | 128 | // Sets the action 129 | if (action != null) { 130 | intent.setAction(action); 131 | } 132 | 133 | PendingIntent pIntent = PendingIntent.getBroadcast(context, 0, intent, 0); 134 | 135 | // Schedules or cancels the alarm 136 | if (enable) { 137 | if (date != null) { 138 | am.set(AlarmManager.RTC_WAKEUP, date.getTime(), pIntent); 139 | } 140 | } 141 | else { 142 | am.cancel(pIntent); 143 | } 144 | } 145 | 146 | /** Given an hour and minute, returns the time in ms since 1/1/1970 of the next occurrence */ 147 | private static long getNextTimeMillis(int hour, int minute) { 148 | 149 | Calendar now = Calendar.getInstance(); 150 | Calendar result = (Calendar) now.clone(); 151 | 152 | result.set(Calendar.HOUR_OF_DAY,hour); 153 | result.set(Calendar.MINUTE,minute); 154 | result.set(Calendar.SECOND,0); 155 | 156 | if(result.before(now)) { 157 | result.add(Calendar.DATE,1); 158 | } 159 | 160 | return result.getTimeInMillis(); 161 | } 162 | 163 | /** Event reception handler */ 164 | @Override 165 | public void onReceive(Context context, Intent intent) { 166 | 167 | if (BuildConfig.DEBUG) { 168 | Log.d(LOGTAG, "EventReceiver: " + intent); 169 | } 170 | 171 | // Acquires wake lock 172 | WakeLockManager.getWakeLockManager().acquireWakeLock(context.getApplicationContext()); 173 | 174 | // Forwards the intent to the manager service 175 | ManagerService.forwardEvent(context, null, intent); 176 | } 177 | } -------------------------------------------------------------------------------- /app/src/main/aidl/com/android/vending/billing/IInAppBillingService.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.vending.billing; 18 | 19 | import android.os.Bundle; 20 | 21 | /** 22 | * InAppBillingService is the service that provides in-app billing version 3 and beyond. 23 | * This service provides the following features: 24 | * 1. Provides a new API to get details of in-app items published for the app including 25 | * price, type, title and description. 26 | * 2. The purchase flow is synchronous and purchase information is available immediately 27 | * after it completes. 28 | * 3. Purchase information of in-app purchases is maintained within the Google Play system 29 | * till the purchase is consumed. 30 | * 4. An API to consume a purchase of an inapp item. All purchases of one-time 31 | * in-app items are consumable and thereafter can be purchased again. 32 | * 5. An API to get current purchases of the user immediately. This will not contain any 33 | * consumed purchases. 34 | * 35 | * All calls will give a response code with the following possible values 36 | * RESULT_OK = 0 - success 37 | * RESULT_USER_CANCELED = 1 - user pressed back or canceled a dialog 38 | * RESULT_BILLING_UNAVAILABLE = 3 - this billing API version is not supported for the type requested 39 | * RESULT_ITEM_UNAVAILABLE = 4 - requested SKU is not available for purchase 40 | * RESULT_DEVELOPER_ERROR = 5 - invalid arguments provided to the API 41 | * RESULT_ERROR = 6 - Fatal error during the API action 42 | * RESULT_ITEM_ALREADY_OWNED = 7 - Failure to purchase since item is already owned 43 | * RESULT_ITEM_NOT_OWNED = 8 - Failure to consume since item is not owned 44 | */ 45 | interface IInAppBillingService { 46 | /** 47 | * Checks support for the requested billing API version, package and in-app type. 48 | * Minimum API version supported by this interface is 3. 49 | * @param apiVersion the billing version which the app is using 50 | * @param packageName the package name of the calling app 51 | * @param type type of the in-app item being purchased "inapp" for one-time purchases 52 | * and "subs" for subscription. 53 | * @return RESULT_OK(0) on success, corresponding result code on failures 54 | */ 55 | int isBillingSupported(int apiVersion, String packageName, String type); 56 | 57 | /** 58 | * Provides details of a list of SKUs 59 | * Given a list of SKUs of a valid type in the skusBundle, this returns a bundle 60 | * with a list JSON strings containing the productId, price, title and description. 61 | * This API can be called with a maximum of 20 SKUs. 62 | * @param apiVersion billing API version that the Third-party is using 63 | * @param packageName the package name of the calling app 64 | * @param skusBundle bundle containing a StringArrayList of SKUs with key "ITEM_ID_LIST" 65 | * @return Bundle containing the following key-value pairs 66 | * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on 67 | * failure as listed above. 68 | * "DETAILS_LIST" with a StringArrayList containing purchase information 69 | * in JSON format similar to: 70 | * '{ "productId" : "exampleSku", "type" : "inapp", "price" : "$5.00", 71 | * "title : "Example Title", "description" : "This is an example description" }' 72 | */ 73 | Bundle getSkuDetails(int apiVersion, String packageName, String type, in Bundle skusBundle); 74 | 75 | /** 76 | * Returns a pending intent to launch the purchase flow for an in-app item by providing a SKU, 77 | * the type, a unique purchase token and an optional developer payload. 78 | * @param apiVersion billing API version that the app is using 79 | * @param packageName package name of the calling app 80 | * @param sku the SKU of the in-app item as published in the developer console 81 | * @param type the type of the in-app item ("inapp" for one-time purchases 82 | * and "subs" for subscription). 83 | * @param developerPayload optional argument to be sent back with the purchase information 84 | * @return Bundle containing the following key-value pairs 85 | * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on 86 | * failure as listed above. 87 | * "BUY_INTENT" - PendingIntent to start the purchase flow 88 | * 89 | * The Pending intent should be launched with startIntentSenderForResult. When purchase flow 90 | * has completed, the onActivityResult() will give a resultCode of OK or CANCELED. 91 | * If the purchase is successful, the result data will contain the following key-value pairs 92 | * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on 93 | * failure as listed above. 94 | * "INAPP_PURCHASE_DATA" - String in JSON format similar to 95 | * '{"orderId":"12999763169054705758.1371079406387615", 96 | * "packageName":"com.example.app", 97 | * "productId":"exampleSku", 98 | * "purchaseTime":1345678900000, 99 | * "purchaseToken" : "122333444455555", 100 | * "developerPayload":"example developer payload" }' 101 | * "INAPP_DATA_SIGNATURE" - String containing the signature of the purchase data that 102 | * was signed with the private key of the developer 103 | * TODO: change this to app-specific keys. 104 | */ 105 | Bundle getBuyIntent(int apiVersion, String packageName, String sku, String type, 106 | String developerPayload); 107 | 108 | /** 109 | * Returns the current SKUs owned by the user of the type and package name specified along with 110 | * purchase information and a signature of the data to be validated. 111 | * This will return all SKUs that have been purchased in V3 and managed items purchased using 112 | * V1 and V2 that have not been consumed. 113 | * @param apiVersion billing API version that the app is using 114 | * @param packageName package name of the calling app 115 | * @param type the type of the in-app items being requested 116 | * ("inapp" for one-time purchases and "subs" for subscription). 117 | * @param continuationToken to be set as null for the first call, if the number of owned 118 | * skus are too many, a continuationToken is returned in the response bundle. 119 | * This method can be called again with the continuation token to get the next set of 120 | * owned skus. 121 | * @return Bundle containing the following key-value pairs 122 | * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on 123 | * failure as listed above. 124 | * "INAPP_PURCHASE_ITEM_LIST" - StringArrayList containing the list of SKUs 125 | * "INAPP_PURCHASE_DATA_LIST" - StringArrayList containing the purchase information 126 | * "INAPP_DATA_SIGNATURE_LIST"- StringArrayList containing the signatures 127 | * of the purchase information 128 | * "INAPP_CONTINUATION_TOKEN" - String containing a continuation token for the 129 | * next set of in-app purchases. Only set if the 130 | * user has more owned skus than the current list. 131 | */ 132 | Bundle getPurchases(int apiVersion, String packageName, String type, String continuationToken); 133 | 134 | /** 135 | * Consume the last purchase of the given SKU. This will result in this item being removed 136 | * from all subsequent responses to getPurchases() and allow re-purchase of this item. 137 | * @param apiVersion billing API version that the app is using 138 | * @param packageName package name of the calling app 139 | * @param purchaseToken token in the purchase information JSON that identifies the purchase 140 | * to be consumed 141 | * @return 0 if consumption succeeded. Appropriate error values for failures. 142 | */ 143 | int consumePurchase(int apiVersion, String packageName, String purchaseToken); 144 | } 145 | -------------------------------------------------------------------------------- /app/src/main/java/org/cprados/wificellmanager/ui/TimePreference.java: -------------------------------------------------------------------------------- 1 | /* 2 | * TimePreference.java 3 | * This file is part of WifiCellManager. 4 | * Copyright (C) 2012 Carlos Prados 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package org.cprados.wificellmanager.ui; 20 | 21 | import android.app.Dialog; 22 | import android.content.Context; 23 | import android.content.res.TypedArray; 24 | import android.os.Bundle; 25 | import android.os.Parcel; 26 | import android.os.Parcelable; 27 | import android.preference.DialogPreference; 28 | import android.text.format.DateFormat; 29 | import android.util.AttributeSet; 30 | import android.view.View; 31 | import android.view.ViewGroup; 32 | import android.widget.TextView; 33 | import android.widget.TimePicker; 34 | 35 | /** 36 | * Preference to select time of date. Saves selected the value in HH:MM date, but displays the selected value 37 | * in 24h or 12h format depending on system wide setting 38 | */ 39 | public class TimePreference extends DialogPreference { 40 | 41 | /** Current hour loaded or saved by this preference */ 42 | protected int mHour=0; 43 | 44 | /** Current minute loaded or saved by this preference */ 45 | protected int mMinute=0; 46 | 47 | /** Whether time format of the system was set to 24h when this preference was instantiated */ 48 | protected boolean m24HourFormat; 49 | 50 | /** Time Picker View of the alert dialog shown by this preference */ 51 | protected TimePicker mTimePicker; 52 | 53 | /** Time displayed Text View of this preference that is shown in the Preferences Activity */ 54 | protected TextView mTimeDisplay; 55 | 56 | public TimePreference(Context ctxt, AttributeSet attrs) { 57 | super(ctxt, attrs); 58 | m24HourFormat = DateFormat.is24HourFormat(ctxt); 59 | } 60 | 61 | public TimePreference(Context ctxt, AttributeSet attrs, int defStyle) { 62 | super(ctxt, attrs, defStyle); 63 | m24HourFormat = DateFormat.is24HourFormat(ctxt); 64 | } 65 | 66 | /** Creates the String representation of this preference internal state */ 67 | @Override 68 | public String toString() { 69 | if(m24HourFormat) { 70 | return ((mHour < 10) ? "0" : "") 71 | + Integer.toString(mHour) 72 | + ":" + ((mMinute < 10) ? "0" : "") 73 | + Integer.toString(mMinute); 74 | } else { 75 | int myHour = mHour % 12; 76 | return ((myHour == 0) ? "12" : ((myHour < 10) ? "0" : "") + Integer.toString(myHour)) 77 | + ":" + ((mMinute < 10) ? "0" : "") 78 | + Integer.toString(mMinute) 79 | + ((mHour >= 12) ? " PM" : " AM"); 80 | } 81 | } 82 | 83 | 84 | /** Creates the time picker view of the dialog */ 85 | @Override 86 | protected View onCreateDialogView() { 87 | mTimePicker=new TimePicker(getContext().getApplicationContext()); 88 | return(mTimePicker); 89 | } 90 | 91 | /** Initializes time picker dialog view with this preference internal state data */ 92 | @Override 93 | protected void onBindDialogView(View v) { 94 | super.onBindDialogView(v); 95 | initializeDialogView(null); 96 | } 97 | 98 | /** Initializes time picker dialog view with initial values or state data that is passed */ 99 | private void initializeDialogView (TimeSavedState state) { 100 | if (mTimePicker != null) { 101 | mTimePicker.setIs24HourView(m24HourFormat); 102 | if(state == null) { 103 | mTimePicker.setCurrentHour(mHour); 104 | mTimePicker.setCurrentMinute(mMinute); 105 | } 106 | else { 107 | mTimePicker.setCurrentHour(state.currentHour); 108 | mTimePicker.setCurrentMinute(state.currentMinute); 109 | } 110 | } 111 | } 112 | 113 | /** Loads the currently selected time in this preferences widget frame, as a text */ 114 | @Override 115 | public void onBindView(View view) { 116 | View widgetLayout; 117 | //int childCounter = 0; 118 | widgetLayout = view.findViewById(android.R.id.widget_frame); 119 | 120 | //do { 121 | // widgetLayout = ((ViewGroup) view).getChildAt(childCounter); 122 | // childCounter++; 123 | //} while (widgetLayout.getId() != android.R.id.widget_frame); 124 | 125 | if (widgetLayout != null && widgetLayout instanceof ViewGroup) { 126 | ((ViewGroup) widgetLayout).removeAllViews(); 127 | // Creates the text view with the selected hour 128 | mTimeDisplay = new TextView(widgetLayout.getContext()); 129 | mTimeDisplay.setText(toString()); 130 | 131 | // Sets the color 132 | mTimeDisplay.setTextColor(MyCheckBoxPreference.getSummaryColor()); 133 | 134 | // Adds the Text View to the widget frame 135 | ((ViewGroup) widgetLayout).addView(mTimeDisplay); 136 | 137 | // This line fixed the visibility issue 138 | widgetLayout.setVisibility(View.VISIBLE); 139 | } 140 | super.onBindView(view); 141 | } 142 | 143 | /** Saves the data to the Shared Preference as a String in h:m format */ 144 | @Override 145 | protected void onDialogClosed(boolean positiveResult) { 146 | super.onDialogClosed(positiveResult); 147 | 148 | if (positiveResult) { 149 | mTimePicker.clearFocus(); 150 | mHour=mTimePicker.getCurrentHour(); 151 | mMinute=mTimePicker.getCurrentMinute(); 152 | 153 | String time=String.valueOf(mHour)+":"+String.valueOf(mMinute); 154 | 155 | if (callChangeListener(time)) { 156 | persistString(time); 157 | mTimeDisplay.setText(toString()); 158 | } 159 | } 160 | } 161 | 162 | @Override 163 | protected Object onGetDefaultValue(TypedArray a, int index) { 164 | return(a.getString(index)); 165 | } 166 | 167 | /** Obtains initial state for this preference */ 168 | @Override 169 | protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { 170 | String time=null; 171 | 172 | if (restoreValue) { 173 | if (defaultValue==null) { 174 | time=getPersistedString("00:00"); 175 | } 176 | else { 177 | time=getPersistedString(defaultValue.toString()); 178 | } 179 | } 180 | else { 181 | if (defaultValue==null) { 182 | time="00:00"; 183 | } 184 | else { 185 | time=defaultValue.toString(); 186 | } 187 | if (shouldPersist()) { 188 | persistString(time); 189 | } 190 | } 191 | 192 | String[] timeParts=time.split(":"); 193 | mHour=Integer.parseInt(timeParts[0]); 194 | mMinute=Integer.parseInt(timeParts[1]);; 195 | } 196 | 197 | /** Returns current state of this preference and the time picker dialog if shown */ 198 | @Override 199 | protected Parcelable onSaveInstanceState() { 200 | final Parcelable superState = super.onSaveInstanceState(); 201 | Dialog dialog = getDialog(); 202 | if (dialog == null || !dialog.isShowing()) { 203 | return superState; 204 | } 205 | 206 | final TimeSavedState myState = new TimeSavedState(superState); 207 | myState.isDialogShowing = true; 208 | myState.currentHour = mTimePicker.getCurrentHour(); 209 | myState.currentMinute = mTimePicker.getCurrentMinute(); 210 | return myState; 211 | } 212 | 213 | /** Restores current state of this preference and the time picker dialog if shown */ 214 | @Override 215 | protected void onRestoreInstanceState(Parcelable state) { 216 | if (state == null || !state.getClass().equals(TimeSavedState.class)) { 217 | // Didn't save state for us in onSaveInstanceState 218 | super.onRestoreInstanceState(state); 219 | return; 220 | } 221 | 222 | TimeSavedState myState = (TimeSavedState) state; 223 | super.onRestoreInstanceState(null); 224 | if (myState.isDialogShowing) { 225 | showDialog(null); 226 | initializeDialogView(myState); 227 | } 228 | } 229 | 230 | /** Class to represent saved internal state of these preferences */ 231 | private static class TimeSavedState extends BaseSavedState { 232 | boolean isDialogShowing; 233 | int currentHour; 234 | int currentMinute; 235 | Bundle dialogBundle; 236 | 237 | public TimeSavedState(Parcel source) { 238 | super(source); 239 | isDialogShowing = source.readInt() == 1; 240 | currentHour = source.readInt(); 241 | currentMinute = source.readInt(); 242 | dialogBundle = source.readBundle(); 243 | } 244 | 245 | @Override 246 | public void writeToParcel(Parcel dest, int flags) { 247 | super.writeToParcel(dest, flags); 248 | dest.writeInt(isDialogShowing ? 1 : 0); 249 | dest.writeInt(currentHour); 250 | dest.writeInt(currentMinute); 251 | dest.writeBundle(dialogBundle); 252 | } 253 | 254 | public TimeSavedState(Parcelable superState) { 255 | super(superState); 256 | } 257 | } 258 | } 259 | 260 | 261 | 262 | -------------------------------------------------------------------------------- /app/src/main/res/values-ja/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | オプション 6 | Wi-Fi 7 | スケジュール 8 | 履歴 9 | 10 | 11 | Wi-Fi Matic 12 | Wi-Fi Matic 1.3.6 13 | Wi-Fiを記憶する 14 | 新しいく接続されたWi-Fiを記憶する 15 | チェック間隔 16 | 所在地をチェックする頻度 17 | 通知を表示する 18 | 各アクションの通知 19 | Wi-Fi Maticの有効化 20 | 自動Wi-Fi管理の有効化 21 | 高度な設定 22 | 高度な使用方法に関する設定 23 | 24 | 25 | %sに接続済み 26 | 27 | Wi-Fi on, 付近に1個のネットワーク 28 | Wi-Fi on, 付近に%d個のネットワーク 29 | 30 | 31 | Wi-Fi off, 付近に1個のネットワーク 32 | Wi-Fi off, 付近に%d個のネットワーク 33 | 34 | Wi-Fi on, エリア外 35 | Wi-Fi off, エリア外 36 | %sに接続済み, エリア外 37 | Wi-Fi on, 圏外 38 | Wi-Fi off, 圏外 39 | %sに接続済み, 圏外 40 | 41 | 42 | 初期化中 43 | 44 | Wi-Fiネットワーク付近 45 | %d個のWi-Fiネットワーク付近 46 | 47 | Wi-Fiエリア外 48 | 圏外 49 | %sに接続済み 50 | Wi-Fi on 51 | Wi-Fi off 52 | 53 | 54 | Wi-Fi所在地を記憶しました 55 | Wi-Fi有効化中 56 | Wi-Fi無効化中 57 | スケジュールによるWi-Fi有効化 58 | スケジュールによるWi-Fi無効化 59 | 切断後%d秒経過 60 | 61 | 62 | 記憶したWi-Fiネットワーク 63 | 64 | このWi-Fiネットワーク周辺のセル数: %d 65 | このWi-Fiネットワーク周辺のセル数: %d 66 | 67 | 無効化したWi-Fiネットワーク 68 | 69 | 70 | 有効化 71 | 無効化 72 | 削除 73 | 74 | 75 | Wi-Fiの編集 76 | セルIDの編集 77 | e 78 | Wi-Fiの有効化 79 | Wi-Fiの無効化 80 | w 81 | 情報 82 | h 83 | Wi-Fi無効化中 84 | Wi-Fi有効化中 85 | 86 | 87 | あなたのいる場所に応じて自動的にWi-Fiを有効化/無効化します。\ 88 | バッテリー消費と事業者ネットワーク経由のデータ通信量を抑えます。\n\n 89 | 私の妻Ericaに捧ぐ :-)\n\n\ 90 | Copyright © 2012 - 2015 Carlos Prados\n\ 91 | <wifimatic.app@gmail.com> 92 | ヘルプ 93 | 評価 94 | http://sites.google.com/site/wifimaticapp/ 95 | http://play.google.com/store/apps/details?id=org.cprados.wificellmanager 96 | http://www.amazon.com/gp/mas/dl/android?p=org.cprados.wificellmanager 97 | 98 | 99 | 当Wi-Fiの動作 100 | 自動有効化 101 | エリア内に入ったらWi-Fiを有効化する 102 | 自動無効化 103 | エリア外に出たらWi-Fiを無効化する 104 | 新しい所在地の追加 105 | 新しい所在地を記録する 106 | 記憶所在地 107 | セル: %1$d-%2$d 108 | GSM/WCDMA/CDMAセルID 109 | 無効化したセルID 110 | 111 | 112 | 無効化スケジュール 113 | Wi-Fi無効化のスケジュール 114 | 無効化する時間 115 | 設定時間にWi-Fiを無効化する 116 | 有効化する時間 117 | 設定時間にエリア内なら、Wi-Fiを有効化する 118 | OK 119 | Cancel 120 | 121 | 122 | 所在地チェック 123 | スクリーンON 124 | 所在地チェック中にスクリーンをON 125 | 所在地情報を強制更新 126 | 最新の所在地情報の取得 127 | スクリーンがOFFの場合、所在地情報の更新ができないデバイスがあります。\n\n 128 | このオプションは、所在地チェック時に瞬時にスクリーンをONにします。\n\n 129 | チェック間隔の間に同一場所に滞在しても、スクリーンを手動でONした時だけ、\ 130 | Wi-Fiが自動的に有効化/無効化される場合、このオプションを試してください。 131 | スクリーンがOFFの場合、所在地情報をアップデートできないデバイスがあります。\n\n 132 | このオプションは、スクリーンOFF中に強制的に所在地情報を更新させます。\n\n 133 | チェック間隔の間に同一場所に滞在しても、スクリーンを手動でONした時だけ、\ 134 | Wi-Fiが自動的に有効化/無効化される場合、このオプションを試してください。 135 | OK 136 | Cancel 137 | 高度な動作設定 138 | 切断タイムアウト 139 | 切断後にWi-Fiを無効化 140 | 実験的機能\nこの設定では、設定した時間の間切断されているとWi-FiをOFFにします。\ 141 | Wi-Fi範囲から離れた際に、Wi-FiをOFFにする時間を短縮します。\n\n 142 | しかし、これは思ったほどよいアイデアではないかもしれません。設定済みWi-Fi所在地にいる際に、Wi-Fi範囲内から出てから再度範囲内に戻ると、Wi-Fiは自動的にONになりません。 143 | モバイルデータ通信の無効化 144 | 設定済みWi-Fi接続時 145 | 重要な警告\nこのオプションでは、モバイルデータ設定を最初に有効にした場合、設定済みWi-Fiネットワーク接続中はモバイルデータ設定を無効化し、Wi-Fi切断後にモバイルデータ通信を有効化します。\n\n 146 | モバイルデータ通信有効化は、追加料金が必要かもしれません。このオプションは自己責任でお使いください。 147 | 圏外でWi-Fi有効化 148 | モバイル通信圏外の場所でWi-Fiを有効化 149 | Wi-Fi Maticはデバイスの場所を認識するためにモバイル通信圏内にいることが必要です。このオプションは、モバイル通信圏外の場所でWi-Fiを有効化します。\n\n\ 150 | バッテリ消費が増えるかもしれませんが、あなたのWi-Fiネットワークが圏外にあるのであれば、このオプションが最適です。 151 | 152 | 153 | Wi-Fi Maticへようこそ!\n\n\ 154 | Wi-Fi Maticはあなたのいる場所に応じて自動的にデバイスのWi-Fiを有効化/無効化し、バッテリー消費と事業者ネットワーク経由のデータ通信量を抑えます。\n\n\ 155 | このウィザードは簡単な3ステップでWi-Fi Maticの設定を行います。 156 | Step 1:\n\n「Wi-Fi Maticの有効化」を選択してください。Wi-Fiの自動有効化/無効化機能をONにします。 157 | Step 2:\n\n現在Wi-Fiネットワークに接続していません。Wi-Fiネットワークに接続して、Wi-Fi Maticに所在地を記憶させるために、「Wi-Fi設定」を選択してください。操作が完了したら、「戻る」ボタンを押してください。\n\n\ 158 | この操作は、後からAndoridのメニューの「設定」→「無線とネットワーク」からも実施できます。 159 | <b>Step 2:</b><br><br>現在Wi-Fiネットワークに接続済みです: <b>%s</b>.<br><br>Wi-Fi Maticが所在地を記憶します。 160 | Step 3:\n\n設定完了!「完了」を選択してウィザードを終了し、Wi-Fi Maticへ戻ってください\n\n\ 161 | アプリケーションメニューの「情報」から、より詳しい情報を参照できます。 162 | 次へ >> 163 | << 戻る 164 | 完了 165 | Wi-Fi Maticの有効化: 166 | Wi-Fi設定: 167 | 再度表示しない: 168 | 169 | 170 | Tap to look for more 171 | Showing events until %s 172 | 履歴はありません 173 | 174 | 175 | 寄付する 176 | 履歴機能を有効化するためにGoogle Playで寄付をしてください 177 | org.cprados.wificellmanager.donation 178 | 例を見る 179 | 履歴機能がどのようなものか見る 180 | https://sites.google.com/site/wifimaticapp/#History 181 | 182 | -------------------------------------------------------------------------------- /app/src/main/java/org/cprados/wificellmanager/sys/CellStateManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * CellStateManager.java 3 | * This file is part of WifiCellManager. 4 | * Copyright (C) 2012 Carlos Prados 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package org.cprados.wificellmanager.sys; 20 | 21 | import java.util.Set; 22 | 23 | import org.cprados.wificellmanager.BuildConfig; 24 | import org.cprados.wificellmanager.DataManager; 25 | import org.cprados.wificellmanager.StateMachine; 26 | import org.cprados.wificellmanager.StateMachine.StateAction; 27 | import org.cprados.wificellmanager.StateMachine.StateEvent; 28 | 29 | import android.app.PendingIntent; 30 | import android.content.Context; 31 | import android.content.Intent; 32 | import android.location.LocationManager; 33 | import android.os.Bundle; 34 | import android.telephony.CellLocation; 35 | import android.telephony.TelephonyManager; 36 | import android.telephony.cdma.CdmaCellLocation; 37 | import android.telephony.gsm.GsmCellLocation; 38 | import android.util.Log; 39 | 40 | /** Manages changes in cell location state of the system */ 41 | public class CellStateManager { 42 | 43 | /** Tag for logging this class messages */ 44 | private static final String LOGTAG = CellStateManager.class.getPackage().getName(); 45 | 46 | /** Extra name for Location Area Code that may be included as extra data in intents to launch this service */ 47 | public static final String EXTRA_LAC = CellStateManager.class.getName() + ".lac"; 48 | 49 | /** Extra name for Cell Id that may be included in intents to launch this service */ 50 | public static final String EXTRA_CID = CellStateManager.class.getName() + ".cid"; 51 | 52 | /** Extra name for operator code that may be included in intents to launch this service */ 53 | public static final String EXTRA_OP = CellStateManager.class.getName() + ".op"; 54 | 55 | /** Extra name for number of nearby wifis discovered when a wifi state change event is received by this service */ 56 | private static final String EXTRA_NEARBY_WIFIS = CellStateManager.class.getName() + ".nearby_wifis"; 57 | 58 | /** Extra name initiator for flag indicating if any nearby wifi requires an automatic action */ 59 | private static final String EXTRA_WIFIS_ACTION = CellStateManager.class.getName() + ".wifis_action_"; 60 | 61 | /** Action of the intents sent to the service to refresh cell location */ 62 | public static final String CELL_CHANGE_ACTION = CellStateManager.class.getName() + ".cell_refresh"; 63 | 64 | /** Extra value that denotes an unknown Cell Id or Lac */ 65 | public static final int CELL_UNKNOWN = 0; 66 | 67 | /** 68 | * Determines if current cell location is inside or outside a known area and updates cid, lac, and nearby wifis 69 | * state data extras 70 | */ 71 | public static StateEvent getCellState (Context context, Intent intent, Bundle stateData) { 72 | StateEvent result = null; 73 | int cid = CELL_UNKNOWN; 74 | int lac = CELL_UNKNOWN; 75 | String op = null; 76 | 77 | // Retrieves Cell Id, Lac and Operator code from Telephony Manager 78 | if (intent == null || !intent.hasExtra(EXTRA_CID) || !intent.hasExtra(EXTRA_LAC) || !intent.hasExtra(EXTRA_OP)) { 79 | 80 | // Force update location fix if configured 81 | forceLocationUpdate(context); 82 | 83 | TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); 84 | CellLocation location = tm.getCellLocation(); 85 | 86 | if (location != null) { 87 | // GSM or UMTS cell location received 88 | if (location instanceof GsmCellLocation) { 89 | cid = ((GsmCellLocation) location).getCid(); 90 | lac = ((GsmCellLocation) location).getLac(); 91 | op = tm.getNetworkOperator(); 92 | } 93 | // CDMA cell location received 94 | else if (location instanceof CdmaCellLocation) { 95 | cid = ((CdmaCellLocation) location).getBaseStationId(); 96 | lac = ((CdmaCellLocation) location).getSystemId(); 97 | int networkId = ((CdmaCellLocation) location).getNetworkId(); 98 | op = (networkId != -1) ? String.valueOf(networkId) : null; 99 | } 100 | if (BuildConfig.DEBUG) { 101 | Log.d(LOGTAG, "CellStateManager: Location obtained: [" + lac + ", " + cid + ", " + op + "]"); 102 | } 103 | } 104 | } 105 | 106 | // Retrieves Cell Id, Lac and Operator code from intent 107 | else { 108 | cid = intent.getIntExtra(EXTRA_CID, CELL_UNKNOWN); 109 | lac = intent.getIntExtra(EXTRA_LAC, CELL_UNKNOWN); 110 | op = intent.getStringExtra(EXTRA_OP); 111 | } 112 | 113 | // Calculates number of nearby wifis and determines cell state 114 | Set wifis = null; 115 | int numWifis = 0; 116 | if ((cid > CELL_UNKNOWN) && (lac > CELL_UNKNOWN)) { 117 | 118 | // Cell state is IN 119 | if ((DataManager.getCellEnabled(context, cid, lac) && 120 | (wifis = DataManager.getWifisByCell(context, cid, lac))!= null) && 121 | (numWifis = DataManager.getCountWifisEnabled(context, wifis)) > 0) { 122 | result = StateEvent.IN; 123 | // Saves the flags that indicate if auto on and off actions are enabled in this cell (for any wifi in this cell) 124 | stateData.putBoolean(EXTRA_WIFIS_ACTION + StateAction.ON, DataManager.getWifiAction(context, StateAction.ON, wifis)); 125 | stateData.putBoolean(EXTRA_WIFIS_ACTION + StateAction.OFF, DataManager.getWifiAction(context, StateAction.OFF, wifis)); 126 | } 127 | 128 | // Cell state is OUT 129 | else { 130 | // Clear the flag that indicate if auto on action is enabled in this cell 131 | stateData.putBoolean(EXTRA_WIFIS_ACTION + StateAction.ON, true); 132 | result = StateEvent.OUT; 133 | } 134 | } 135 | 136 | // Cell state is UNK (no coverage) 137 | else if (op == null || op.equals("")) { 138 | result = StateEvent.UNK; 139 | } 140 | 141 | // Saves state data information: Cell Id, Lac, Operator and number of nearby wifis in this cell 142 | if (result != null) { 143 | stateData.putInt(EXTRA_CID, cid); 144 | stateData.putInt(EXTRA_LAC, lac); 145 | stateData.putString(EXTRA_OP, op); 146 | stateData.putInt(EXTRA_NEARBY_WIFIS, numWifis); 147 | } 148 | 149 | // Discards location change 150 | else { 151 | if (BuildConfig.DEBUG) { 152 | Log.d(LOGTAG, "CellStateManager: Operator: " + op + ".Fake -1 location discarded"); 153 | } 154 | } 155 | 156 | return result; 157 | } 158 | 159 | /** Returns Cid extra information from stateData bundle */ 160 | public static int getCid (Bundle stateData) { 161 | int cid = (stateData != null) ? stateData.getInt(EXTRA_CID, CELL_UNKNOWN) : CELL_UNKNOWN; 162 | return cid; 163 | } 164 | 165 | /** Returns Lac extra information from stateData bundle */ 166 | public static int getLac (Bundle stateData) { 167 | int lac = (stateData != null) ? stateData.getInt(EXTRA_LAC, CELL_UNKNOWN) : CELL_UNKNOWN; 168 | return lac; 169 | } 170 | 171 | /** Sets Lac and Cid extra information to the stateData bundle */ 172 | public static void setCurrentCell (Bundle stateData, int[] currentCell) { 173 | if (stateData != null && currentCell != null && currentCell.length > 1) { 174 | stateData.putInt(EXTRA_CID, currentCell[0]); 175 | stateData.putInt(EXTRA_LAC, currentCell[1]); 176 | } 177 | } 178 | 179 | /** Returns Operator extra information from stateData bundle */ 180 | public static String getOperator (Bundle stateData) { 181 | String op = (stateData != null) ? stateData.getString(EXTRA_OP) : null; 182 | return op; 183 | } 184 | 185 | /** Sets Operator extra information to the stateData bundle */ 186 | public static void setOperator (Bundle stateData, String op) { 187 | if (stateData != null && op != null && op.length() > 1) { 188 | stateData.putString(EXTRA_OP, op); 189 | } 190 | } 191 | 192 | /** Returns number of nearby wifis extra information from stateData bundle */ 193 | public static int getNearbyWifis (Bundle stateData) { 194 | int numWifis = (stateData != null) ? stateData.getInt(EXTRA_NEARBY_WIFIS, 0) : 0; 195 | return numWifis; 196 | } 197 | 198 | /** Sets number of nearby wifis extra information to the stateData bundle*/ 199 | public static void setNearbyWifis (Bundle stateData, int numWifis) { 200 | if (stateData != null ) { 201 | stateData.putInt(EXTRA_NEARBY_WIFIS, numWifis); 202 | } 203 | } 204 | 205 | /** Returns whether action ON or OFF enabled extra information from stateData bundle */ 206 | public static boolean getActionEnabled (Bundle stateData, StateMachine.StateAction action) { 207 | boolean wifiAction = true; 208 | if (action !=null && stateData != null) { 209 | String key = EXTRA_WIFIS_ACTION + action.name(); 210 | wifiAction = (stateData != null && stateData.containsKey(key))? stateData.getBoolean(key) : true; 211 | } 212 | return wifiAction; 213 | } 214 | 215 | /** Sets whether action ON or OFF are enabled extra information to the stateData bundle */ 216 | public static void setActionEnabled (Bundle stateData, StateMachine.StateAction action, boolean value) { 217 | if (stateData != null && action !=null) { 218 | stateData.putBoolean(EXTRA_WIFIS_ACTION + action.name(), value); 219 | } 220 | } 221 | 222 | /** Fix to force android to refresh cell id and lac before getting it via Telephony Manager API */ 223 | private static void forceLocationUpdate(Context context) { 224 | 225 | if (DataManager.getForceUpdateLocation(context)) { 226 | LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); 227 | 228 | if (lm != null) { 229 | 230 | double latitude = 40.189326; 231 | double longitude = -2.732304; 232 | 233 | Intent intent = new Intent("forceLocationUpdate"); 234 | PendingIntent proximityIntent = PendingIntent.getBroadcast(context, 0, intent, 0); 235 | lm.addProximityAlert(latitude, longitude, 100000, 1000, proximityIntent); 236 | } 237 | } 238 | } 239 | } 240 | -------------------------------------------------------------------------------- /doc/LICENSE-2.0.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | --------------------------------------------------------------------------------