Compare commits
29 Commits
Author | SHA1 | Date |
---|---|---|
|
06a37b019a | 5 years ago |
|
e83b2665c4 | 5 years ago |
|
5ca3b74432 | 5 years ago |
|
5c614fb5e1 | 5 years ago |
|
5ed8bab661 | 5 years ago |
|
e2d9507ce6 | 5 years ago |
|
ca8bbf4ed5 | 5 years ago |
|
675694e273 | 5 years ago |
|
83025ce7af | 5 years ago |
|
ee103156af | 5 years ago |
|
716c3bdfcc | 5 years ago |
|
55f0d5b996 | 5 years ago |
|
072adde354 | 5 years ago |
|
54848e5816 | 5 years ago |
|
f05adf9b2e | 5 years ago |
|
606b19465a | 5 years ago |
|
8b9e68d274 | 5 years ago |
|
034104681b | 5 years ago |
|
a8b359111f | 5 years ago |
|
26a3de3e77 | 5 years ago |
|
2a9e64b91d | 5 years ago |
|
d5438ffccc | 5 years ago |
|
c770d29239 | 5 years ago |
|
10b8ca87c0 | 5 years ago |
|
cd8507fb27 | 5 years ago |
|
3b22cd7b48 | 5 years ago |
|
fec5892317 | 5 years ago |
|
9bfca39764 | 5 years ago |
|
a3c8fa1f8d | 5 years ago |
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_3" default="true" />
|
||||
<component name="masterDetails">
|
||||
<states>
|
||||
<state key="ProjectJDKs.UI">
|
||||
<settings>
|
||||
<last-edited>1.8</last-edited>
|
||||
<splitter-proportions>
|
||||
<option name="proportions">
|
||||
<list>
|
||||
<option value="0.2" />
|
||||
</list>
|
||||
</option>
|
||||
</splitter-proportions>
|
||||
</settings>
|
||||
</state>
|
||||
</states>
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/AndroidApp.iml" filepath="$PROJECT_DIR$/.idea/AndroidApp.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,100 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="dfd94b2a-6d7a-49b9-9f27-735b64fff405" name="Default" comment="">
|
||||
<change afterPath="$PROJECT_DIR$/Tbot/.idea/caches/build_file_checksums.ser" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/Tbot/.idea/codeStyles/Project.xml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/Tbot/.idea/dbnavigator.xml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/Tbot/.idea/encodings.xml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/Tbot/.idea/jarRepositories.xml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/Tbot/.idea/vcs.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Tbot/.idea/gradle.xml" beforeDir="false" afterPath="$PROJECT_DIR$/Tbot/.idea/gradle.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Tbot/.idea/misc.xml" beforeDir="false" afterPath="$PROJECT_DIR$/Tbot/.idea/misc.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Tbot/.idea/modules.xml" beforeDir="false" afterPath="$PROJECT_DIR$/Tbot/.idea/modules.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Tbot/app/src/main/java/me/wshuo/tbot/AudioCall.java" beforeDir="false" afterPath="$PROJECT_DIR$/Tbot/app/src/main/java/me/wshuo/tbot/AudioCall.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Tbot/app/src/main/java/me/wshuo/tbot/Falldown.java" beforeDir="false" afterPath="$PROJECT_DIR$/Tbot/app/src/main/java/me/wshuo/tbot/Falldown.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Tbot/app/src/main/java/me/wshuo/tbot/IPConnect.java" beforeDir="false" afterPath="$PROJECT_DIR$/Tbot/app/src/main/java/me/wshuo/tbot/IPConnect.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Tbot/app/src/main/java/me/wshuo/tbot/Settings.java" beforeDir="false" afterPath="$PROJECT_DIR$/Tbot/app/src/main/java/me/wshuo/tbot/Settings.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Tbot/build.gradle" beforeDir="false" afterPath="$PROJECT_DIR$/Tbot/build.gradle" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="FavoritesManager">
|
||||
<favorites_list name="CodeIris Favorites" />
|
||||
</component>
|
||||
<component name="Git.Settings">
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/../.." />
|
||||
</component>
|
||||
<component name="ProjectId" id="1nVUrsoNQto1JIPhO4wGl4aCOcO" />
|
||||
<component name="ProjectLevelVcsManager" settingsEditedManually="true" />
|
||||
<component name="ProjectViewState">
|
||||
<option name="hideEmptyMiddlePackages" value="true" />
|
||||
<option name="showExcludedFiles" value="true" />
|
||||
<option name="showLibraryContents" value="true" />
|
||||
</component>
|
||||
<component name="PropertiesComponent">
|
||||
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
|
||||
<property name="android.sdk.path" value="D:/ANDROID/sdk" />
|
||||
<property name="last_opened_file_path" value="$PROJECT_DIR$/android_remocons" />
|
||||
<property name="settings.editor.selected.configurable" value="preferences.lookFeel" />
|
||||
<property name="settings.editor.splitter.proportion" value="0.25526074" />
|
||||
</component>
|
||||
<component name="RunManager">
|
||||
<configuration name="<template>" type="Applet" default="true" selected="false">
|
||||
<option name="MAIN_CLASS_NAME" />
|
||||
<option name="HTML_FILE_NAME" />
|
||||
<option name="HTML_USED" value="false" />
|
||||
<option name="WIDTH" value="400" />
|
||||
<option name="HEIGHT" value="300" />
|
||||
<option name="POLICY_FILE" value="$APPLICATION_HOME_DIR$/bin/appletviewer.policy" />
|
||||
<option name="VM_PARAMETERS" />
|
||||
</configuration>
|
||||
<configuration name="<template>" type="JUnit" default="true" selected="false">
|
||||
<option name="MAIN_CLASS_NAME" />
|
||||
<option name="VM_PARAMETERS" value="-ea" />
|
||||
<option name="PARAMETERS" />
|
||||
<option name="WORKING_DIRECTORY" value="$MODULE_DIR$" />
|
||||
</configuration>
|
||||
<configuration name="<template>" type="#org.jetbrains.idea.devkit.run.PluginConfigurationType" default="true" selected="false">
|
||||
<option name="VM_PARAMETERS" value="-Xmx512m -Xms256m -XX:MaxPermSize=250m -ea" />
|
||||
</configuration>
|
||||
<configuration default="true" type="Application" factoryName="Application">
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
<configuration default="true" type="TestNG">
|
||||
<option name="TEST_OBJECT" value="CLASS" />
|
||||
<option name="WORKING_DIRECTORY" value="$MODULE_DIR$" />
|
||||
<properties />
|
||||
<listeners />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
<component name="SvnConfiguration">
|
||||
<configuration />
|
||||
</component>
|
||||
<component name="TaskManager">
|
||||
<task active="true" id="Default" summary="Default task">
|
||||
<changelist id="dfd94b2a-6d7a-49b9-9f27-735b64fff405" name="Default" comment="" />
|
||||
<created>1524884716802</created>
|
||||
<option name="number" value="Default" />
|
||||
<option name="presentableId" value="Default" />
|
||||
<updated>1524884716802</updated>
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
<component name="WindowStateProjectService">
|
||||
<state x="700" y="302" key="FileChooserDialogImpl" timestamp="1612340452944">
|
||||
<screen x="0" y="0" width="1920" height="1040" />
|
||||
</state>
|
||||
<state x="700" y="302" key="FileChooserDialogImpl/0.0.1920.1040@0.0.1920.1040" timestamp="1612340452944" />
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,9 @@
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/workspace.xml
|
||||
/.idea/libraries
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
.externalNativeBuild
|
@ -0,0 +1,164 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<DBN-PSQL>
|
||||
<case-options enabled="true">
|
||||
<option name="KEYWORD_CASE" value="lower" />
|
||||
<option name="FUNCTION_CASE" value="lower" />
|
||||
<option name="PARAMETER_CASE" value="lower" />
|
||||
<option name="DATATYPE_CASE" value="lower" />
|
||||
<option name="OBJECT_CASE" value="preserve" />
|
||||
</case-options>
|
||||
<formatting-settings enabled="false" />
|
||||
</DBN-PSQL>
|
||||
<DBN-SQL>
|
||||
<case-options enabled="true">
|
||||
<option name="KEYWORD_CASE" value="lower" />
|
||||
<option name="FUNCTION_CASE" value="lower" />
|
||||
<option name="PARAMETER_CASE" value="lower" />
|
||||
<option name="DATATYPE_CASE" value="lower" />
|
||||
<option name="OBJECT_CASE" value="preserve" />
|
||||
</case-options>
|
||||
<formatting-settings enabled="false">
|
||||
<option name="STATEMENT_SPACING" value="one_line" />
|
||||
<option name="CLAUSE_CHOP_DOWN" value="chop_down_if_statement_long" />
|
||||
<option name="ITERATION_ELEMENTS_WRAPPING" value="chop_down_if_not_single" />
|
||||
</formatting-settings>
|
||||
</DBN-SQL>
|
||||
<DBN-PSQL>
|
||||
<case-options enabled="true">
|
||||
<option name="KEYWORD_CASE" value="lower" />
|
||||
<option name="FUNCTION_CASE" value="lower" />
|
||||
<option name="PARAMETER_CASE" value="lower" />
|
||||
<option name="DATATYPE_CASE" value="lower" />
|
||||
<option name="OBJECT_CASE" value="preserve" />
|
||||
</case-options>
|
||||
<formatting-settings enabled="false" />
|
||||
</DBN-PSQL>
|
||||
<DBN-SQL>
|
||||
<case-options enabled="true">
|
||||
<option name="KEYWORD_CASE" value="lower" />
|
||||
<option name="FUNCTION_CASE" value="lower" />
|
||||
<option name="PARAMETER_CASE" value="lower" />
|
||||
<option name="DATATYPE_CASE" value="lower" />
|
||||
<option name="OBJECT_CASE" value="preserve" />
|
||||
</case-options>
|
||||
<formatting-settings enabled="false">
|
||||
<option name="STATEMENT_SPACING" value="one_line" />
|
||||
<option name="CLAUSE_CHOP_DOWN" value="chop_down_if_statement_long" />
|
||||
<option name="ITERATION_ELEMENTS_WRAPPING" value="chop_down_if_not_single" />
|
||||
</formatting-settings>
|
||||
</DBN-SQL>
|
||||
<codeStyleSettings language="XML">
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
</indentOptions>
|
||||
<arrangement>
|
||||
<rules>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:android</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:id</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:name</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>name</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>style</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>ANDROID_ATTRIBUTE_ORDER</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>.*</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
</rules>
|
||||
</arrangement>
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<resourceExtensions />
|
||||
<wildcardResourcePatterns>
|
||||
<entry name="!?*.java" />
|
||||
<entry name="!?*.form" />
|
||||
<entry name="!?*.class" />
|
||||
<entry name="!?*.groovy" />
|
||||
<entry name="!?*.scala" />
|
||||
<entry name="!?*.flex" />
|
||||
<entry name="!?*.kt" />
|
||||
<entry name="!?*.clj" />
|
||||
<entry name="!?*.aj" />
|
||||
</wildcardResourcePatterns>
|
||||
<annotationProcessing>
|
||||
<profile default="true" name="Default" enabled="false">
|
||||
<processorPath useClasspath="true" />
|
||||
</profile>
|
||||
</annotationProcessing>
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,3 @@
|
||||
<component name="CopyrightManager">
|
||||
<settings default="" />
|
||||
</component>
|
@ -0,0 +1,458 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DBNavigator.Project.DataEditorManager">
|
||||
<record-view-column-sorting-type value="BY_INDEX" />
|
||||
<value-preview-text-wrapping value="true" />
|
||||
<value-preview-pinned value="false" />
|
||||
</component>
|
||||
<component name="DBNavigator.Project.DataExportManager">
|
||||
<export-instructions>
|
||||
<create-header value="true" />
|
||||
<quote-values-containing-separator value="true" />
|
||||
<quote-all-values value="false" />
|
||||
<value-separator value="" />
|
||||
<file-name value="" />
|
||||
<file-location value="" />
|
||||
<scope value="GLOBAL" />
|
||||
<destination value="FILE" />
|
||||
<format value="EXCEL" />
|
||||
<charset value="GBK" />
|
||||
</export-instructions>
|
||||
</component>
|
||||
<component name="DBNavigator.Project.DatabaseBrowserManager">
|
||||
<autoscroll-to-editor value="false" />
|
||||
<autoscroll-from-editor value="true" />
|
||||
<show-object-properties value="true" />
|
||||
<loaded-nodes />
|
||||
</component>
|
||||
<component name="DBNavigator.Project.DatabaseFileManager">
|
||||
<open-files />
|
||||
</component>
|
||||
<component name="DBNavigator.Project.EditorStateManager">
|
||||
<last-used-providers />
|
||||
</component>
|
||||
<component name="DBNavigator.Project.MethodExecutionManager">
|
||||
<method-browser />
|
||||
<execution-history>
|
||||
<group-entries value="true" />
|
||||
<execution-inputs />
|
||||
</execution-history>
|
||||
<argument-values-cache />
|
||||
</component>
|
||||
<component name="DBNavigator.Project.ObjectDependencyManager">
|
||||
<last-used-dependency-type value="INCOMING" />
|
||||
</component>
|
||||
<component name="DBNavigator.Project.ObjectQuickFilterManager">
|
||||
<last-used-operator value="EQUAL" />
|
||||
<filters />
|
||||
</component>
|
||||
<component name="DBNavigator.Project.ScriptExecutionManager" clear-outputs="true">
|
||||
<recently-used-interfaces />
|
||||
</component>
|
||||
<component name="DBNavigator.Project.Settings">
|
||||
<connections />
|
||||
<browser-settings>
|
||||
<general>
|
||||
<display-mode value="TABBED" />
|
||||
<navigation-history-size value="100" />
|
||||
<show-object-details value="false" />
|
||||
</general>
|
||||
<filters>
|
||||
<object-type-filter>
|
||||
<object-type name="SCHEMA" enabled="true" />
|
||||
<object-type name="USER" enabled="true" />
|
||||
<object-type name="ROLE" enabled="true" />
|
||||
<object-type name="PRIVILEGE" enabled="true" />
|
||||
<object-type name="CHARSET" enabled="true" />
|
||||
<object-type name="TABLE" enabled="true" />
|
||||
<object-type name="VIEW" enabled="true" />
|
||||
<object-type name="MATERIALIZED_VIEW" enabled="true" />
|
||||
<object-type name="NESTED_TABLE" enabled="true" />
|
||||
<object-type name="COLUMN" enabled="true" />
|
||||
<object-type name="INDEX" enabled="true" />
|
||||
<object-type name="CONSTRAINT" enabled="true" />
|
||||
<object-type name="DATASET_TRIGGER" enabled="true" />
|
||||
<object-type name="DATABASE_TRIGGER" enabled="true" />
|
||||
<object-type name="SYNONYM" enabled="true" />
|
||||
<object-type name="SEQUENCE" enabled="true" />
|
||||
<object-type name="PROCEDURE" enabled="true" />
|
||||
<object-type name="FUNCTION" enabled="true" />
|
||||
<object-type name="PACKAGE" enabled="true" />
|
||||
<object-type name="TYPE" enabled="true" />
|
||||
<object-type name="TYPE_ATTRIBUTE" enabled="true" />
|
||||
<object-type name="ARGUMENT" enabled="true" />
|
||||
<object-type name="DIMENSION" enabled="true" />
|
||||
<object-type name="CLUSTER" enabled="true" />
|
||||
<object-type name="DBLINK" enabled="true" />
|
||||
</object-type-filter>
|
||||
</filters>
|
||||
<sorting>
|
||||
<object-type name="COLUMN" sorting-type="NAME" />
|
||||
<object-type name="FUNCTION" sorting-type="NAME" />
|
||||
<object-type name="PROCEDURE" sorting-type="NAME" />
|
||||
<object-type name="ARGUMENT" sorting-type="POSITION" />
|
||||
</sorting>
|
||||
<default-editors>
|
||||
<object-type name="VIEW" editor-type="SELECTION" />
|
||||
<object-type name="PACKAGE" editor-type="SELECTION" />
|
||||
<object-type name="TYPE" editor-type="SELECTION" />
|
||||
</default-editors>
|
||||
</browser-settings>
|
||||
<navigation-settings>
|
||||
<lookup-filters>
|
||||
<lookup-objects>
|
||||
<object-type name="SCHEMA" enabled="true" />
|
||||
<object-type name="USER" enabled="false" />
|
||||
<object-type name="ROLE" enabled="false" />
|
||||
<object-type name="PRIVILEGE" enabled="false" />
|
||||
<object-type name="CHARSET" enabled="false" />
|
||||
<object-type name="TABLE" enabled="true" />
|
||||
<object-type name="VIEW" enabled="true" />
|
||||
<object-type name="MATERIALIZED VIEW" enabled="true" />
|
||||
<object-type name="NESTED TABLE" enabled="false" />
|
||||
<object-type name="COLUMN" enabled="false" />
|
||||
<object-type name="INDEX" enabled="true" />
|
||||
<object-type name="CONSTRAINT" enabled="true" />
|
||||
<object-type name="DATASET TRIGGER" enabled="true" />
|
||||
<object-type name="DATABASE TRIGGER" enabled="true" />
|
||||
<object-type name="SYNONYM" enabled="false" />
|
||||
<object-type name="SEQUENCE" enabled="true" />
|
||||
<object-type name="PROCEDURE" enabled="true" />
|
||||
<object-type name="FUNCTION" enabled="true" />
|
||||
<object-type name="PACKAGE" enabled="true" />
|
||||
<object-type name="TYPE" enabled="true" />
|
||||
<object-type name="TYPE ATTRIBUTE" enabled="false" />
|
||||
<object-type name="ARGUMENT" enabled="false" />
|
||||
<object-type name="DIMENSION" enabled="false" />
|
||||
<object-type name="CLUSTER" enabled="false" />
|
||||
<object-type name="DBLINK" enabled="true" />
|
||||
</lookup-objects>
|
||||
<force-database-load value="false" />
|
||||
<prompt-connection-selection value="true" />
|
||||
<prompt-schema-selection value="true" />
|
||||
</lookup-filters>
|
||||
</navigation-settings>
|
||||
<dataset-grid-settings>
|
||||
<general>
|
||||
<enable-zooming value="true" />
|
||||
<enable-column-tooltip value="true" />
|
||||
</general>
|
||||
<sorting>
|
||||
<nulls-first value="true" />
|
||||
<max-sorting-columns value="4" />
|
||||
</sorting>
|
||||
<tracking-columns>
|
||||
<columnNames value="" />
|
||||
<visible value="true" />
|
||||
<editable value="false" />
|
||||
</tracking-columns>
|
||||
</dataset-grid-settings>
|
||||
<dataset-editor-settings>
|
||||
<text-editor-popup>
|
||||
<active value="false" />
|
||||
<active-if-empty value="false" />
|
||||
<data-length-threshold value="100" />
|
||||
<popup-delay value="1000" />
|
||||
</text-editor-popup>
|
||||
<values-actions-popup>
|
||||
<show-popup-button value="true" />
|
||||
<element-count-threshold value="1000" />
|
||||
<data-length-threshold value="250" />
|
||||
</values-actions-popup>
|
||||
<general>
|
||||
<fetch-block-size value="100" />
|
||||
<fetch-timeout value="30" />
|
||||
<trim-whitespaces value="true" />
|
||||
<convert-empty-strings-to-null value="true" />
|
||||
<select-content-on-cell-edit value="true" />
|
||||
<large-value-preview-active value="true" />
|
||||
</general>
|
||||
<filters>
|
||||
<prompt-filter-dialog value="true" />
|
||||
<default-filter-type value="BASIC" />
|
||||
</filters>
|
||||
<qualified-text-editor text-length-threshold="300">
|
||||
<content-types>
|
||||
<content-type name="Text" enabled="true" />
|
||||
<content-type name="Properties" enabled="true" />
|
||||
<content-type name="XML" enabled="true" />
|
||||
<content-type name="DTD" enabled="true" />
|
||||
<content-type name="HTML" enabled="true" />
|
||||
<content-type name="XHTML" enabled="true" />
|
||||
<content-type name="Java" enabled="true" />
|
||||
<content-type name="SQL" enabled="true" />
|
||||
<content-type name="PL/SQL" enabled="true" />
|
||||
<content-type name="JSON" enabled="true" />
|
||||
<content-type name="JSON5" enabled="true" />
|
||||
<content-type name="Groovy" enabled="true" />
|
||||
<content-type name="AIDL" enabled="true" />
|
||||
<content-type name="YAML" enabled="true" />
|
||||
<content-type name="Manifest" enabled="true" />
|
||||
</content-types>
|
||||
</qualified-text-editor>
|
||||
<record-navigation>
|
||||
<navigation-target value="VIEWER" />
|
||||
</record-navigation>
|
||||
</dataset-editor-settings>
|
||||
<code-editor-settings>
|
||||
<general>
|
||||
<show-object-navigation-gutter value="false" />
|
||||
<show-spec-declaration-navigation-gutter value="true" />
|
||||
<enable-spellchecking value="true" />
|
||||
<enable-reference-spellchecking value="false" />
|
||||
</general>
|
||||
<confirmations>
|
||||
<save-changes value="false" />
|
||||
<revert-changes value="true" />
|
||||
</confirmations>
|
||||
</code-editor-settings>
|
||||
<code-completion-settings>
|
||||
<filters>
|
||||
<basic-filter>
|
||||
<filter-element type="RESERVED_WORD" id="keyword" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="function" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="parameter" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="datatype" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="exception" selected="true" />
|
||||
<filter-element type="OBJECT" id="schema" selected="true" />
|
||||
<filter-element type="OBJECT" id="role" selected="true" />
|
||||
<filter-element type="OBJECT" id="user" selected="true" />
|
||||
<filter-element type="OBJECT" id="privilege" selected="true" />
|
||||
<user-schema>
|
||||
<filter-element type="OBJECT" id="table" selected="true" />
|
||||
<filter-element type="OBJECT" id="view" selected="true" />
|
||||
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||
<filter-element type="OBJECT" id="index" selected="true" />
|
||||
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||
<filter-element type="OBJECT" id="synonym" selected="false" />
|
||||
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||
<filter-element type="OBJECT" id="function" selected="true" />
|
||||
<filter-element type="OBJECT" id="package" selected="true" />
|
||||
<filter-element type="OBJECT" id="type" selected="true" />
|
||||
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||
</user-schema>
|
||||
<public-schema>
|
||||
<filter-element type="OBJECT" id="table" selected="false" />
|
||||
<filter-element type="OBJECT" id="view" selected="false" />
|
||||
<filter-element type="OBJECT" id="materialized view" selected="false" />
|
||||
<filter-element type="OBJECT" id="index" selected="false" />
|
||||
<filter-element type="OBJECT" id="constraint" selected="false" />
|
||||
<filter-element type="OBJECT" id="trigger" selected="false" />
|
||||
<filter-element type="OBJECT" id="synonym" selected="false" />
|
||||
<filter-element type="OBJECT" id="sequence" selected="false" />
|
||||
<filter-element type="OBJECT" id="procedure" selected="false" />
|
||||
<filter-element type="OBJECT" id="function" selected="false" />
|
||||
<filter-element type="OBJECT" id="package" selected="false" />
|
||||
<filter-element type="OBJECT" id="type" selected="false" />
|
||||
<filter-element type="OBJECT" id="dimension" selected="false" />
|
||||
<filter-element type="OBJECT" id="cluster" selected="false" />
|
||||
<filter-element type="OBJECT" id="dblink" selected="false" />
|
||||
</public-schema>
|
||||
<any-schema>
|
||||
<filter-element type="OBJECT" id="table" selected="true" />
|
||||
<filter-element type="OBJECT" id="view" selected="true" />
|
||||
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||
<filter-element type="OBJECT" id="index" selected="true" />
|
||||
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||
<filter-element type="OBJECT" id="synonym" selected="true" />
|
||||
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||
<filter-element type="OBJECT" id="function" selected="true" />
|
||||
<filter-element type="OBJECT" id="package" selected="true" />
|
||||
<filter-element type="OBJECT" id="type" selected="true" />
|
||||
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||
</any-schema>
|
||||
</basic-filter>
|
||||
<extended-filter>
|
||||
<filter-element type="RESERVED_WORD" id="keyword" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="function" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="parameter" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="datatype" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="exception" selected="true" />
|
||||
<filter-element type="OBJECT" id="schema" selected="true" />
|
||||
<filter-element type="OBJECT" id="user" selected="true" />
|
||||
<filter-element type="OBJECT" id="role" selected="true" />
|
||||
<filter-element type="OBJECT" id="privilege" selected="true" />
|
||||
<user-schema>
|
||||
<filter-element type="OBJECT" id="table" selected="true" />
|
||||
<filter-element type="OBJECT" id="view" selected="true" />
|
||||
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||
<filter-element type="OBJECT" id="index" selected="true" />
|
||||
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||
<filter-element type="OBJECT" id="synonym" selected="true" />
|
||||
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||
<filter-element type="OBJECT" id="function" selected="true" />
|
||||
<filter-element type="OBJECT" id="package" selected="true" />
|
||||
<filter-element type="OBJECT" id="type" selected="true" />
|
||||
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||
</user-schema>
|
||||
<public-schema>
|
||||
<filter-element type="OBJECT" id="table" selected="true" />
|
||||
<filter-element type="OBJECT" id="view" selected="true" />
|
||||
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||
<filter-element type="OBJECT" id="index" selected="true" />
|
||||
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||
<filter-element type="OBJECT" id="synonym" selected="true" />
|
||||
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||
<filter-element type="OBJECT" id="function" selected="true" />
|
||||
<filter-element type="OBJECT" id="package" selected="true" />
|
||||
<filter-element type="OBJECT" id="type" selected="true" />
|
||||
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||
</public-schema>
|
||||
<any-schema>
|
||||
<filter-element type="OBJECT" id="table" selected="true" />
|
||||
<filter-element type="OBJECT" id="view" selected="true" />
|
||||
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||
<filter-element type="OBJECT" id="index" selected="true" />
|
||||
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||
<filter-element type="OBJECT" id="synonym" selected="true" />
|
||||
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||
<filter-element type="OBJECT" id="function" selected="true" />
|
||||
<filter-element type="OBJECT" id="package" selected="true" />
|
||||
<filter-element type="OBJECT" id="type" selected="true" />
|
||||
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||
</any-schema>
|
||||
</extended-filter>
|
||||
</filters>
|
||||
<sorting enabled="true">
|
||||
<sorting-element type="RESERVED_WORD" id="keyword" />
|
||||
<sorting-element type="RESERVED_WORD" id="datatype" />
|
||||
<sorting-element type="OBJECT" id="column" />
|
||||
<sorting-element type="OBJECT" id="table" />
|
||||
<sorting-element type="OBJECT" id="view" />
|
||||
<sorting-element type="OBJECT" id="materialized view" />
|
||||
<sorting-element type="OBJECT" id="index" />
|
||||
<sorting-element type="OBJECT" id="constraint" />
|
||||
<sorting-element type="OBJECT" id="trigger" />
|
||||
<sorting-element type="OBJECT" id="synonym" />
|
||||
<sorting-element type="OBJECT" id="sequence" />
|
||||
<sorting-element type="OBJECT" id="procedure" />
|
||||
<sorting-element type="OBJECT" id="function" />
|
||||
<sorting-element type="OBJECT" id="package" />
|
||||
<sorting-element type="OBJECT" id="type" />
|
||||
<sorting-element type="OBJECT" id="dimension" />
|
||||
<sorting-element type="OBJECT" id="cluster" />
|
||||
<sorting-element type="OBJECT" id="dblink" />
|
||||
<sorting-element type="OBJECT" id="schema" />
|
||||
<sorting-element type="OBJECT" id="role" />
|
||||
<sorting-element type="OBJECT" id="user" />
|
||||
<sorting-element type="RESERVED_WORD" id="function" />
|
||||
<sorting-element type="RESERVED_WORD" id="parameter" />
|
||||
</sorting>
|
||||
<format>
|
||||
<enforce-code-style-case value="true" />
|
||||
</format>
|
||||
</code-completion-settings>
|
||||
<execution-engine-settings>
|
||||
<statement-execution>
|
||||
<fetch-block-size value="100" />
|
||||
<execution-timeout value="20" />
|
||||
<debug-execution-timeout value="600" />
|
||||
<focus-result value="false" />
|
||||
<prompt-execution value="false" />
|
||||
</statement-execution>
|
||||
<script-execution>
|
||||
<command-line-interfaces />
|
||||
<execution-timeout value="300" />
|
||||
</script-execution>
|
||||
<method-execution>
|
||||
<execution-timeout value="30" />
|
||||
<debug-execution-timeout value="600" />
|
||||
<parameter-history-size value="10" />
|
||||
</method-execution>
|
||||
</execution-engine-settings>
|
||||
<operation-settings>
|
||||
<transactions>
|
||||
<uncommitted-changes>
|
||||
<on-project-close value="ASK" />
|
||||
<on-disconnect value="ASK" />
|
||||
<on-autocommit-toggle value="ASK" />
|
||||
</uncommitted-changes>
|
||||
<multiple-uncommitted-changes>
|
||||
<on-commit value="ASK" />
|
||||
<on-rollback value="ASK" />
|
||||
</multiple-uncommitted-changes>
|
||||
</transactions>
|
||||
<session-browser>
|
||||
<disconnect-session value="ASK" />
|
||||
<kill-session value="ASK" />
|
||||
<reload-on-filter-change value="false" />
|
||||
</session-browser>
|
||||
<compiler>
|
||||
<compile-type value="KEEP" />
|
||||
<compile-dependencies value="ASK" />
|
||||
<always-show-controls value="false" />
|
||||
</compiler>
|
||||
<debugger>
|
||||
<debugger-type value="ASK" />
|
||||
<use-generic-runners value="true" />
|
||||
</debugger>
|
||||
</operation-settings>
|
||||
<ddl-file-settings>
|
||||
<extensions>
|
||||
<mapping file-type-id="VIEW" extensions="vw" />
|
||||
<mapping file-type-id="TRIGGER" extensions="trg" />
|
||||
<mapping file-type-id="PROCEDURE" extensions="prc" />
|
||||
<mapping file-type-id="FUNCTION" extensions="fnc" />
|
||||
<mapping file-type-id="PACKAGE" extensions="pkg" />
|
||||
<mapping file-type-id="PACKAGE_SPEC" extensions="pks" />
|
||||
<mapping file-type-id="PACKAGE_BODY" extensions="pkb" />
|
||||
<mapping file-type-id="TYPE" extensions="tpe" />
|
||||
<mapping file-type-id="TYPE_SPEC" extensions="tps" />
|
||||
<mapping file-type-id="TYPE_BODY" extensions="tpb" />
|
||||
</extensions>
|
||||
<general>
|
||||
<lookup-ddl-files value="true" />
|
||||
<create-ddl-files value="false" />
|
||||
<synchronize-ddl-files value="true" />
|
||||
<use-qualified-names value="false" />
|
||||
<make-scripts-rerunnable value="true" />
|
||||
</general>
|
||||
</ddl-file-settings>
|
||||
<general-settings>
|
||||
<regional-settings>
|
||||
<date-format value="MEDIUM" />
|
||||
<number-format value="UNGROUPED" />
|
||||
<locale value="SYSTEM_DEFAULT" />
|
||||
<use-custom-formats value="false" />
|
||||
</regional-settings>
|
||||
<environment>
|
||||
<environment-types>
|
||||
<environment-type id="development" name="Development" description="Development environment" color="-2430209/-12296320" readonly-code="false" readonly-data="false" />
|
||||
<environment-type id="integration" name="Integration" description="Integration environment" color="-2621494/-12163514" readonly-code="true" readonly-data="false" />
|
||||
<environment-type id="production" name="Production" description="Productive environment" color="-11574/-10271420" readonly-code="true" readonly-data="true" />
|
||||
<environment-type id="other" name="Other" description="" color="-1576/-10724543" readonly-code="false" readonly-data="false" />
|
||||
</environment-types>
|
||||
<visibility-settings>
|
||||
<connection-tabs value="true" />
|
||||
<dialog-headers value="true" />
|
||||
<object-editor-tabs value="true" />
|
||||
<script-editor-tabs value="false" />
|
||||
<execution-result-tabs value="true" />
|
||||
</visibility-settings>
|
||||
</environment>
|
||||
</general-settings>
|
||||
</component>
|
||||
<component name="DBNavigator.Project.StatementExecutionManager">
|
||||
<execution-variables />
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding">
|
||||
<file url="file://$PROJECT_DIR$/app/build.gradle" charset="GBK" />
|
||||
<file url="file://$PROJECT_DIR$/app/src/main/java/me/wshuo/tbot/Settings.java" charset="GBK" />
|
||||
<file url="PROJECT" charset="UTF-8" />
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="testRunner" value="PLATFORM" />
|
||||
<option name="distributionType" value="LOCAL" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="gradleHome" value="D:\programs\Android\Android Studio\gradle\gradle-2.14.1" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
<option value="$PROJECT_DIR$/app" />
|
||||
</set>
|
||||
</option>
|
||||
<option name="resolveModulePerSourceSet" value="false" />
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RemoteRepositoriesConfiguration">
|
||||
<remote-repository>
|
||||
<option name="id" value="central" />
|
||||
<option name="name" value="Maven Central repository" />
|
||||
<option name="url" value="https://repo1.maven.org/maven2" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="jboss.community" />
|
||||
<option name="name" value="JBoss Community repository" />
|
||||
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="BintrayJCenter" />
|
||||
<option name="name" value="BintrayJCenter" />
|
||||
<option name="url" value="https://jcenter.bintray.com/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="Google" />
|
||||
<option name="name" value="Google" />
|
||||
<option name="url" value="https://dl.google.com/dl/android/maven2/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="D:\Program Files\Android\Sdk\extras\m2repository" />
|
||||
<option name="name" value="D:\Program Files\Android\Sdk\extras\m2repository" />
|
||||
<option name="url" value="file:/D:/Program%20Files/Android/Sdk/extras/m2repository" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="D:\Program Files\Android\Sdk\extras\android\m2repository" />
|
||||
<option name="name" value="D:\Program Files\Android\Sdk\extras\android\m2repository" />
|
||||
<option name="url" value="file:/D:/Program%20Files/Android/Sdk/extras/android/m2repository" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="D:\Program Files\Android\Sdk\extras\google\m2repository" />
|
||||
<option name="name" value="D:\Program Files\Android\Sdk\extras\google\m2repository" />
|
||||
<option name="url" value="file:/D:/Program%20Files/Android/Sdk/extras/google/m2repository" />
|
||||
</remote-repository>
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="EntryPointsManager">
|
||||
<entry_points version="2.0" />
|
||||
</component>
|
||||
<component name="NullableNotNullManager">
|
||||
<option name="myDefaultNullable" value="android.support.annotation.Nullable" />
|
||||
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
|
||||
<option name="myNullables">
|
||||
<value>
|
||||
<list size="12">
|
||||
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
|
||||
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
|
||||
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
|
||||
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
|
||||
<item index="4" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
|
||||
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.Nullable" />
|
||||
<item index="6" class="java.lang.String" itemvalue="android.annotation.Nullable" />
|
||||
<item index="7" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNullable" />
|
||||
<item index="8" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.qual.Nullable" />
|
||||
<item index="9" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableDecl" />
|
||||
<item index="10" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableType" />
|
||||
<item index="11" class="java.lang.String" itemvalue="com.android.annotations.Nullable" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
<option name="myNotNulls">
|
||||
<value>
|
||||
<list size="11">
|
||||
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
|
||||
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
|
||||
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
|
||||
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
|
||||
<item index="4" class="java.lang.String" itemvalue="androidx.annotation.NonNull" />
|
||||
<item index="5" class="java.lang.String" itemvalue="android.annotation.NonNull" />
|
||||
<item index="6" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNonNull" />
|
||||
<item index="7" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.qual.NonNull" />
|
||||
<item index="8" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullDecl" />
|
||||
<item index="9" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullType" />
|
||||
<item index="10" class="java.lang.String" itemvalue="com.android.annotations.NonNull" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
<option name="id" value="Android" />
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/modules/AndroidApp-Tbot.iml" filepath="$PROJECT_DIR$/.idea/modules/AndroidApp-Tbot.iml" group="Tbot" />
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/modules/app/AndroidApp-Tbot-app.iml" filepath="$PROJECT_DIR$/.idea/modules/app/AndroidApp-Tbot-app.iml" group="Tbot/app" />
|
||||
<module fileurl="file://C:/Users/wshuo/Documents/se15/src/AndroidApp/Tbot/Tbot.iml" filepath="C:/Users/wshuo/Documents/se15/src/AndroidApp/Tbot/Tbot.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/app/Tbot-app.iml" filepath="$PROJECT_DIR$/app/Tbot-app.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RunConfigurationProducerService">
|
||||
<option name="ignoredProducers">
|
||||
<set>
|
||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
|
||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
|
||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
|
||||
</set>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$/../../.." vcs="Git" />
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1 @@
|
||||
/build
|
@ -0,0 +1,33 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 26
|
||||
buildToolsVersion "26.0.2"
|
||||
defaultConfig {
|
||||
applicationId "me.wshuo.tbot"
|
||||
minSdkVersion 18
|
||||
targetSdkVersion 26
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
|
||||
exclude group: 'com.android.support', module: 'support-annotations'
|
||||
})
|
||||
compile 'com.android.support:appcompat-v7:26.1.0'
|
||||
compile 'com.android.support:design:26.1.0'
|
||||
compile 'com.android.support:support-v4:26.1.0'
|
||||
compile 'com.android.support:support-vector-drawable:26.1.0'
|
||||
testCompile 'junit:junit:4.12'
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in D:\programs\Android\sdk/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
@ -0,0 +1,27 @@
|
||||
package me.wshuo.tbot;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Instrumentation test, which will execute on an Android device.
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ExampleInstrumentedTest {
|
||||
@Test
|
||||
public void useAppContext(){
|
||||
throw new MyOwnRuntimeException("My Message"); //write by ljw
|
||||
// Context of the app under test.
|
||||
Context appContext = InstrumentationRegistry.getTargetContext();
|
||||
|
||||
assertEquals("me.wshuo.tbot", appContext.getPackageName());
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="me.wshuo.tbot">
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="空巢老人看护小助手"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity android:name=".Login">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".User"
|
||||
android:label="个人中心" />
|
||||
<activity
|
||||
android:name=".Register"
|
||||
android:label="用户注册" />
|
||||
<activity
|
||||
android:name=".Resetpwd"
|
||||
android:label="密码修改" />
|
||||
<activity android:name=".Welcome" />
|
||||
<activity android:name=".IPConnect" />
|
||||
<activity android:name=".Menu" />
|
||||
<activity android:name=".Falldown" />
|
||||
<activity android:name=".AudioCall" />
|
||||
<activity android:name=".MotionControl" />
|
||||
<activity android:name=".PreferenceSettings" />
|
||||
<activity android:name=".VideoObserve" />
|
||||
<activity android:name=".MedicineAlert" />
|
||||
<activity
|
||||
android:name=".Settings"
|
||||
android:label="@string/title_activity_settings"></activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
@ -0,0 +1,109 @@
|
||||
package me.wshuo.tbot;
|
||||
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceActivity;
|
||||
import android.support.annotation.LayoutRes;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.AppCompatDelegate;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
/**
|
||||
* A {@link android.preference.PreferenceActivity} which implements and proxies the necessary calls
|
||||
* to be used with AppCompat.
|
||||
*/
|
||||
public abstract class AppCompatPreferenceActivity extends PreferenceActivity {
|
||||
|
||||
private AppCompatDelegate mDelegate;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
getDelegate().installViewFactory();
|
||||
getDelegate().onCreate(savedInstanceState);
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostCreate(Bundle savedInstanceState) {
|
||||
super.onPostCreate(savedInstanceState);
|
||||
getDelegate().onPostCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
public ActionBar getSupportActionBar() {
|
||||
return getDelegate().getSupportActionBar();
|
||||
}
|
||||
|
||||
public void setSupportActionBar(@Nullable Toolbar toolbar) {
|
||||
getDelegate().setSupportActionBar(toolbar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MenuInflater getMenuInflater() {
|
||||
return getDelegate().getMenuInflater();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentView(@LayoutRes int layoutResID) {
|
||||
getDelegate().setContentView(layoutResID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentView(View view) {
|
||||
getDelegate().setContentView(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentView(View view, ViewGroup.LayoutParams params) {
|
||||
getDelegate().setContentView(view, params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addContentView(View view, ViewGroup.LayoutParams params) {
|
||||
getDelegate().addContentView(view, params);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostResume() {
|
||||
super.onPostResume();
|
||||
getDelegate().onPostResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onTitleChanged(CharSequence title, int color) {
|
||||
super.onTitleChanged(title, color);
|
||||
getDelegate().setTitle(title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
getDelegate().onConfigurationChanged(newConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
getDelegate().onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
getDelegate().onDestroy();
|
||||
}
|
||||
|
||||
public void invalidateOptionsMenu() {
|
||||
getDelegate().invalidateOptionsMenu();
|
||||
}
|
||||
|
||||
private AppCompatDelegate getDelegate() {
|
||||
if (mDelegate == null) {
|
||||
mDelegate = AppCompatDelegate.create(this, null);
|
||||
}
|
||||
return mDelegate;
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package me.wshuo.tbot;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
||||
public class AudioCall extends AppCompatActivity {
|
||||
|
||||
public Button btnAudioReturn;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_audio_call);
|
||||
btnAudioReturn = (Button) findViewById(R.id.btnAudioReturn);
|
||||
btnAudioReturn.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent_Audio_to_Menu = new Intent(AudioCall.this, Menu.class);
|
||||
startActivity(intent_Audio_to_Menu);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
|
||||
super.onBackPressed();
|
||||
Intent intent_Audio_to_Menu = new Intent(AudioCall.this, Menu.class);
|
||||
startActivity(intent_Audio_to_Menu);
|
||||
finish();
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package me.wshuo.tbot;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
||||
public class Falldown extends AppCompatActivity {
|
||||
|
||||
public Button btnFallReturn;
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_falldown);
|
||||
btnFallReturn = (Button) findViewById(R.id.btnFallReturn);
|
||||
btnFallReturn.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent_Fall_to_Menu = new Intent(Falldown.this, Menu.class);
|
||||
startActivity(intent_Fall_to_Menu);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
|
||||
super.onBackPressed();
|
||||
Intent intent_Fall_to_Menu = new Intent(Falldown.this, Menu.class);
|
||||
startActivity(intent_Fall_to_Menu);
|
||||
finish();
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package me.wshuo.tbot;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
||||
public class IPConnect extends AppCompatActivity {
|
||||
|
||||
public Button btnIPConnect;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_ipconnect);
|
||||
btnIPConnect = (Button) findViewById(R.id.btnIPConnect);
|
||||
btnIPConnect.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent_IP_to_Menu = new Intent(IPConnect.this, Menu.class);
|
||||
startActivity(intent_IP_to_Menu);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
|
||||
super.onBackPressed();
|
||||
Intent intent_IP_to_Menu = new Intent(IPConnect.this, Menu.class);
|
||||
startActivity(intent_IP_to_Menu);
|
||||
finish();
|
||||
}
|
||||
}
|
@ -0,0 +1,191 @@
|
||||
package me.wshuo.tbot;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
public class Login extends Activity { //登录界面活动
|
||||
|
||||
public int pwdresetFlag=0;
|
||||
private EditText mAccount; //用户名编辑
|
||||
private EditText mPwd; //密码编辑
|
||||
private Button mRegisterButton; //注册按钮
|
||||
private Button mLoginButton; //登录按钮
|
||||
private Button mCancleButton; //注销按钮
|
||||
private CheckBox mRememberCheck;
|
||||
|
||||
private SharedPreferences login_sp;
|
||||
private String userNameValue,passwordValue;
|
||||
|
||||
private View loginView; //登录
|
||||
private View loginSuccessView;
|
||||
private TextView loginSuccessShow;
|
||||
private TextView mChangepwdText;
|
||||
private UserDataManager mUserDataManager; //用户数据管理类
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.login);
|
||||
//通过id找到相应的控件
|
||||
mAccount = (EditText) findViewById(R.id.login_edit_account);
|
||||
mPwd = (EditText) findViewById(R.id.login_edit_pwd);
|
||||
mRegisterButton = (Button) findViewById(R.id.login_btn_register);
|
||||
mLoginButton = (Button) findViewById(R.id.login_btn_login);
|
||||
mCancleButton = (Button) findViewById(R.id.login_btn_cancle);
|
||||
loginView=findViewById(R.id.login_view);
|
||||
loginSuccessView=findViewById(R.id.login_success_view);
|
||||
loginSuccessShow=(TextView) findViewById(R.id.login_success_show);
|
||||
|
||||
mChangepwdText = (TextView) findViewById(R.id.login_text_change_pwd);
|
||||
|
||||
mRememberCheck = (CheckBox) findViewById(R.id.Login_Remember);
|
||||
|
||||
login_sp = getSharedPreferences("userInfo", 0);
|
||||
//2021/2/3 把name行代码取消注释
|
||||
String name=login_sp.getString("USER_NAME", "");
|
||||
//String pwd = getEncryptedPass();//write by ljw
|
||||
//String pwd =login_sp.getString("PASSWORD", "");
|
||||
String pwd =login_sp.getString("USER_PWD", "");
|
||||
//changed by lcp 2021/2/3
|
||||
//pwd =login_sp.getString("PASSWORD", "");
|
||||
|
||||
boolean choseRemember =login_sp.getBoolean("mRememberCheck", false);
|
||||
boolean choseAutoLogin =login_sp.getBoolean("mAutologinCheck", false);
|
||||
//如果上次选了记住密码,那进入登录页面也自动勾选记住密码,并填上用户名和密码
|
||||
if(choseRemember){
|
||||
mAccount.setText(name);
|
||||
mPwd.setText(pwd);
|
||||
mRememberCheck.setChecked(true);
|
||||
}
|
||||
|
||||
mRegisterButton.setOnClickListener(mListener); //采用OnClickListener方法设置不同按钮按下之后的监听事件
|
||||
mLoginButton.setOnClickListener(mListener);
|
||||
mCancleButton.setOnClickListener(mListener);
|
||||
mChangepwdText.setOnClickListener(mListener);
|
||||
|
||||
ImageView image = (ImageView) findViewById(R.id.logo); //使用ImageView显示logo
|
||||
image.setImageResource(R.drawable.logo);
|
||||
|
||||
if (mUserDataManager == null) {
|
||||
mUserDataManager = new UserDataManager(this);
|
||||
mUserDataManager.openDataBase(); //建立本地数据库
|
||||
}
|
||||
}
|
||||
OnClickListener mListener = new OnClickListener() { //不同按钮按下的监听事件选择
|
||||
public void onClick(View v) {
|
||||
switch (v.getId()) {
|
||||
case R.id.login_btn_register: //登录界面的注册按钮
|
||||
Intent intent_Login_to_Register = new Intent(Login.this,Register.class) ; //切换Login Activity至User Activity
|
||||
startActivity(intent_Login_to_Register);
|
||||
finish();
|
||||
break;
|
||||
case R.id.login_btn_login: //登录界面的登录按钮
|
||||
login();
|
||||
break;
|
||||
case R.id.login_btn_cancle: //登录界面的注销按钮
|
||||
cancel();
|
||||
break;
|
||||
case R.id.login_text_change_pwd: //登录界面的密码重置按钮
|
||||
Intent intent_Login_to_reset = new Intent(Login.this,Resetpwd.class) ; //切换Login Activity至User Activity
|
||||
startActivity(intent_Login_to_reset);
|
||||
finish();
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public void login() {//登录按钮监听事件
|
||||
if (isUserNameAndPwdValid()) {
|
||||
String userName = mAccount.getText().toString().trim();//获取当前输入的用户名和密码信息
|
||||
String userPwd = mPwd.getText().toString().trim();
|
||||
SharedPreferences.Editor editor =login_sp.edit();
|
||||
//int result=mUserDataManager.findUserByNameAndPwd(userName, userPwd);
|
||||
//for test
|
||||
int result = 1;
|
||||
if(result==1){//返回1说明用户名和密码均正确
|
||||
//保存用户名和密码
|
||||
editor.putString("USER_NAME", userName);
|
||||
editor.putString("PASSWORD", userPwd);
|
||||
//是否记住密码
|
||||
if(mRememberCheck.isChecked()){
|
||||
editor.putBoolean("mRememberCheck", true);
|
||||
}else{
|
||||
editor.putBoolean("mRememberCheck", false);
|
||||
}
|
||||
editor.apply();
|
||||
Intent intent = new Intent(Login.this,Welcome.class) ;//切换Login Activity至User Activity
|
||||
startActivity(intent);
|
||||
finish();
|
||||
Toast.makeText(this, getString(R.string.login_success),Toast.LENGTH_SHORT).show();//登录成功提示
|
||||
}else if(result==0){
|
||||
Toast.makeText(this, getString(R.string.login_fail),Toast.LENGTH_SHORT).show(); //登录失败提示
|
||||
}
|
||||
}
|
||||
}
|
||||
public void cancel() { //注销
|
||||
if (isUserNameAndPwdValid()) {
|
||||
String userName = mAccount.getText().toString().trim(); //获取当前输入的用户名和密码信息
|
||||
String userPwd = mPwd.getText().toString().trim();
|
||||
int result=mUserDataManager.findUserByNameAndPwd(userName, userPwd);
|
||||
if(result==1){ //返回1说明用户名和密码均正确
|
||||
// Intent intent = new Intent(Login.this,User.class) ; //切换Login Activity至User Activity
|
||||
// startActivity(intent);
|
||||
Toast.makeText(this, getString(R.string.cancel_success),Toast.LENGTH_SHORT).show();//登录成功提示
|
||||
mPwd.setText("");
|
||||
mAccount.setText("");
|
||||
mUserDataManager.deleteUserDatabyname(userName);
|
||||
}else if(result==0){
|
||||
Toast.makeText(this, getString(R.string.cancel_fail),Toast.LENGTH_SHORT).show(); //登录失败提示
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean isUserNameAndPwdValid() {
|
||||
if (mAccount.getText().toString().trim().equals("")) {
|
||||
Toast.makeText(this, getString(R.string.account_empty),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
return false;
|
||||
} else if (mPwd.getText().toString().trim().equals("")) {
|
||||
Toast.makeText(this, getString(R.string.pwd_empty),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
if (mUserDataManager == null) {
|
||||
mUserDataManager = new UserDataManager(this);
|
||||
mUserDataManager.openDataBase();
|
||||
}
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
if (mUserDataManager != null) {
|
||||
mUserDataManager.closeDataBase();
|
||||
mUserDataManager = null;
|
||||
}
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package me.wshuo.tbot;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
||||
public class MedicineAlert extends AppCompatActivity {
|
||||
|
||||
public Button btnAlertReturn;
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_medicine_alert);
|
||||
btnAlertReturn = (Button) findViewById(R.id.btnAlertReturn);
|
||||
btnAlertReturn.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent_Alert_to_Menu = new Intent(MedicineAlert.this, Menu.class);
|
||||
startActivity(intent_Alert_to_Menu);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
@Override
|
||||
public void onBackPressed() {//当点击后退键时执行该函数
|
||||
|
||||
super.onBackPressed();
|
||||
Intent intent_Alert_to_Menu = new Intent(MedicineAlert.this, Menu.class);
|
||||
startActivity(intent_Alert_to_Menu);
|
||||
finish();
|
||||
}
|
||||
}
|
@ -0,0 +1,107 @@
|
||||
package me.wshuo.tbot;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
||||
public class Menu extends AppCompatActivity {
|
||||
|
||||
//write by ljw 没必要改
|
||||
public Button btnMenuReturn;
|
||||
public Button getBtnMenuReturn(){return btnMenuReturn;}
|
||||
public void setBtnMenuReturn(Button btnMenuReturn){this.btnMenuReturn=btnMenuReturn;}
|
||||
|
||||
public Button btnFall;
|
||||
public Button getBtnFall(){return btnFall;}
|
||||
public void setBtnFall(Button btnFall){this.btnFall=btnFall;}
|
||||
|
||||
public Button btnAlert;
|
||||
public Button getBtnAlert(){return btnAlert;}
|
||||
public void setBtnAlert(Button btnAlert){this.btnAlert=btnAlert;}
|
||||
|
||||
public Button btnAudio;
|
||||
public Button getBtnAudio(){return btnAudio;}
|
||||
public void setBtnAudio(Button btnAudio){this.btnAudio=btnAudio;}
|
||||
|
||||
public Button btnVideo;
|
||||
public Button getBtnVideo(){return btnVideo;}
|
||||
public void setBtnVideo(Button btnVideo){this.btnVideo=btnVideo;}
|
||||
|
||||
public Button btnSetting;
|
||||
public Button getBtnSetting(){return btnSetting;}
|
||||
public void setBtnSetting(Button btnSetting){this.btnSetting=btnSetting;}
|
||||
|
||||
public Button btnControl;
|
||||
public Button getBtnControl(){return btnControl;}
|
||||
public void setBtnControl(Button btnControl){this.btnControl=btnControl;}
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_menu);
|
||||
btnMenuReturn = (Button) findViewById(R.id.btnMenuReturn);
|
||||
btnFall = (Button)findViewById(R.id.btnFall);
|
||||
btnAlert = (Button)findViewById(R.id.btnAlert);
|
||||
btnAudio = (Button)findViewById(R.id.btnAudio);
|
||||
btnVideo = (Button)findViewById(R.id.btnVideo);
|
||||
btnSetting = (Button)findViewById(R.id.btnSetting);
|
||||
btnControl = (Button)findViewById(R.id.btnControl);
|
||||
|
||||
btnMenuReturn.setOnClickListener(mListener);
|
||||
btnFall.setOnClickListener(mListener);
|
||||
btnAlert.setOnClickListener(mListener);
|
||||
btnAudio.setOnClickListener(mListener);
|
||||
btnVideo.setOnClickListener(mListener);
|
||||
btnSetting.setOnClickListener(mListener);
|
||||
btnControl.setOnClickListener(mListener);
|
||||
}
|
||||
|
||||
View.OnClickListener mListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
switch (v.getId()) {
|
||||
case R.id.btnMenuReturn:
|
||||
Intent intent_Return = new Intent(Menu.this, IPConnect.class);
|
||||
startActivity(intent_Return);
|
||||
finish();
|
||||
break;
|
||||
case R.id.btnFall:
|
||||
Intent intent_Falldown = new Intent(Menu.this, Falldown.class);
|
||||
startActivity(intent_Falldown);
|
||||
finish();
|
||||
break;
|
||||
case R.id.btnAlert:
|
||||
Intent intent_Alert = new Intent(Menu.this, MedicineAlert.class);
|
||||
startActivity(intent_Alert);
|
||||
finish();
|
||||
break;
|
||||
case R.id.btnAudio:
|
||||
Intent intent_Audio = new Intent(Menu.this, AudioCall.class);
|
||||
startActivity(intent_Audio);
|
||||
finish();
|
||||
break;
|
||||
case R.id.btnVideo:
|
||||
Intent intent_Video = new Intent(Menu.this, VideoObserve.class);
|
||||
startActivity(intent_Video);
|
||||
finish();
|
||||
break;
|
||||
case R.id.btnSetting:
|
||||
Intent intent_Setting = new Intent(Menu.this, Settings.class);
|
||||
startActivity(intent_Setting);
|
||||
finish();
|
||||
break;
|
||||
case R.id.btnControl:
|
||||
Intent intent_Control = new Intent(Menu.this, MotionControl.class);
|
||||
startActivity(intent_Control);
|
||||
finish();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package me.wshuo.tbot;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
||||
public class MotionControl extends AppCompatActivity {
|
||||
|
||||
public Button btnMotionReturn;
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_motion_control);
|
||||
btnMotionReturn = (Button) findViewById(R.id.btnMotionReturn);
|
||||
btnMotionReturn.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent_Motion_to_Menu = new Intent(MotionControl.this, Menu.class);
|
||||
startActivity(intent_Motion_to_Menu);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
@Override
|
||||
public void onBackPressed() {//当点击后退键时执行该函数
|
||||
|
||||
super.onBackPressed();
|
||||
Intent intent_Motion_to_Menu = new Intent(MotionControl.this, Menu.class);
|
||||
startActivity(intent_Motion_to_Menu);
|
||||
finish();
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package me.wshuo.tbot;
|
||||
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.os.Bundle;
|
||||
|
||||
public class PreferenceSettings extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_preference_settings);
|
||||
}
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
package me.wshuo.tbot;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Toast;
|
||||
|
||||
public class Register extends AppCompatActivity {
|
||||
private EditText mAccount; //用户名编辑
|
||||
private EditText mPwd; //密码编辑
|
||||
private EditText mPwdCheck; //密码编辑
|
||||
private Button mSureButton; //确定按钮
|
||||
private Button mCancelButton; //取消按钮
|
||||
private UserDataManager mUserDataManager; //用户数据管理类
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.register);
|
||||
mAccount = (EditText) findViewById(R.id.resetpwd_edit_name);
|
||||
mPwd = (EditText) findViewById(R.id.resetpwd_edit_pwd_old);
|
||||
mPwdCheck = (EditText) findViewById(R.id.resetpwd_edit_pwd_new);
|
||||
|
||||
mSureButton = (Button) findViewById(R.id.register_btn_sure);
|
||||
mCancelButton = (Button) findViewById(R.id.register_btn_cancel);
|
||||
|
||||
mSureButton.setOnClickListener(m_register_Listener); //注册界面两个按钮的监听事件
|
||||
mCancelButton.setOnClickListener(m_register_Listener);
|
||||
|
||||
if (mUserDataManager == null) {
|
||||
mUserDataManager = new UserDataManager(this);
|
||||
mUserDataManager.openDataBase(); //建立本地数据库
|
||||
}
|
||||
|
||||
}
|
||||
View.OnClickListener m_register_Listener = new View.OnClickListener() { //不同按钮按下的监听事件选择
|
||||
public void onClick(View v) {
|
||||
switch (v.getId()) {
|
||||
case R.id.register_btn_sure: //确认按钮的监听事件
|
||||
register_check();
|
||||
break;
|
||||
case R.id.register_btn_cancel: //取消按钮的监听事件,由注册界面返回登录界面
|
||||
Intent intent_Register_to_Login = new Intent(Register.this,Login.class) ; //切换User Activity至Login Activity
|
||||
startActivity(intent_Register_to_Login);
|
||||
finish();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
public void register_check() { //确认按钮的监听事件
|
||||
if (isUserNameAndPwdValid()) {
|
||||
String userName = mAccount.getText().toString().trim();
|
||||
String userPwd = mPwd.getText().toString().trim();
|
||||
String userPwdCheck = mPwdCheck.getText().toString().trim();
|
||||
//检查用户是否存在
|
||||
int count=mUserDataManager.findUserByName(userName);
|
||||
//用户已经存在时返回,给出提示文字
|
||||
if(count>0){
|
||||
Toast.makeText(this, getString(R.string.name_already_exist, userName),Toast.LENGTH_SHORT).show();
|
||||
return ;
|
||||
}
|
||||
if(userPwd.equals(userPwdCheck)==false){ //两次密码输入不一样
|
||||
Toast.makeText(this, getString(R.string.pwd_not_the_same),Toast.LENGTH_SHORT).show();
|
||||
return ;
|
||||
} else {
|
||||
UserData mUser = new UserData(userName, userPwd);
|
||||
mUserDataManager.openDataBase();
|
||||
long flag = mUserDataManager.insertUserData(mUser); //新建用户信息
|
||||
if (flag == -1) {
|
||||
Toast.makeText(this, getString(R.string.register_fail),Toast.LENGTH_SHORT).show();
|
||||
}else{
|
||||
Toast.makeText(this, getString(R.string.register_success),Toast.LENGTH_SHORT).show();
|
||||
Intent intent_Register_to_Login = new Intent(Register.this,Login.class) ; //切换User Activity至Login Activity
|
||||
startActivity(intent_Register_to_Login);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public boolean isUserNameAndPwdValid() {
|
||||
//write by ljw
|
||||
String myString = null;
|
||||
if (mAccount.getText().toString().trim().equals(myString)) {
|
||||
Toast.makeText(this, getString(R.string.account_empty),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
return false;
|
||||
} else if (mPwd.getText().toString().trim().equals(myString)) {
|
||||
Toast.makeText(this, getString(R.string.pwd_empty),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
return false;
|
||||
}else if(mPwdCheck.getText().toString().trim().equals(myString)) {
|
||||
Toast.makeText(this, getString(R.string.pwd_check_empty),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,285 @@
|
||||
package me.wshuo.tbot;
|
||||
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.media.Ringtone;
|
||||
import android.media.RingtoneManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.preference.ListPreference;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceActivity;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.preference.PreferenceFragment;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.preference.RingtonePreference;
|
||||
import android.text.TextUtils;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A {@link PreferenceActivity} that presents a set of application settings. On
|
||||
* handset devices, settings are presented as a single list. On tablets,
|
||||
* settings are split by category, with category headers shown to the left of
|
||||
* the list of settings.
|
||||
* <p>
|
||||
* See <a href="http://developer.android.com/design/patterns/settings.html">
|
||||
* Android Design: Settings</a> for design guidelines and the <a
|
||||
* href="http://developer.android.com/guide/topics/ui/settings.html">Settings
|
||||
* API Guide</a> for more information on developing a Settings UI.
|
||||
*/
|
||||
public class Settings extends AppCompatPreferenceActivity {
|
||||
/**
|
||||
* A preference value change listener that updates the preference's summary
|
||||
* to reflect its new value.
|
||||
*/
|
||||
private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object value) {
|
||||
String stringValue = value.toString();
|
||||
|
||||
if (preference instanceof ListPreference) {
|
||||
// For list preferences, look up the correct display value in
|
||||
// the preference's 'entries' list.
|
||||
ListPreference listPreference = (ListPreference) preference;
|
||||
int index = listPreference.findIndexOfValue(stringValue);
|
||||
|
||||
// Set the summary to reflect the new value.
|
||||
preference.setSummary(
|
||||
index >= 0
|
||||
? listPreference.getEntries()[index]
|
||||
: null);
|
||||
|
||||
} else if (preference instanceof RingtonePreference) {
|
||||
// For ringtone preferences, look up the correct display value
|
||||
// using RingtoneManager.
|
||||
if (TextUtils.isEmpty(stringValue)) {
|
||||
// Empty values correspond to 'silent' (no ringtone).
|
||||
preference.setSummary(R.string.pref_ringtone_silent);
|
||||
|
||||
} else {
|
||||
Ringtone ringtone = RingtoneManager.getRingtone(
|
||||
preference.getContext(), Uri.parse(stringValue));
|
||||
|
||||
if (ringtone == null) {
|
||||
// Clear the summary if there was a lookup error.
|
||||
preference.setSummary(null);
|
||||
} else {
|
||||
// Set the summary to reflect the new ringtone display
|
||||
// name.
|
||||
String name = ringtone.getTitle(preference.getContext());
|
||||
preference.setSummary(name);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// For all other preferences, set the summary to the value's
|
||||
// simple string representation.
|
||||
preference.setSummary(stringValue);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper method to determine if the device has an extra-large screen. For
|
||||
* example, 10" tablets are extra-large.
|
||||
*/
|
||||
private static boolean isXLargeTablet(Context context) {
|
||||
return (context.getResources().getConfiguration().screenLayout
|
||||
& Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_XLARGE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds a preference's summary to its value. More specifically, when the
|
||||
* preference's value is changed, its summary (line of text below the
|
||||
* preference title) is updated to reflect the value. The summary is also
|
||||
* immediately updated upon calling this method. The exact display format is
|
||||
* dependent on the type of preference.
|
||||
*
|
||||
* @see #sBindPreferenceSummaryToValueListener
|
||||
*/
|
||||
private static void bindPreferenceSummaryToValue(Preference preference) {
|
||||
// Set the listener to watch for value changes.
|
||||
preference.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener);
|
||||
|
||||
// Trigger the listener immediately with the preference's
|
||||
// current value.
|
||||
sBindPreferenceSummaryToValueListener.onPreferenceChange(preference,
|
||||
PreferenceManager
|
||||
.getDefaultSharedPreferences(preference.getContext())
|
||||
.getString(preference.getKey(), ""));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setupActionBar();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up the {@link android.app.ActionBar}, if the API is available.
|
||||
*/
|
||||
private void setupActionBar() {
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
// Show the Up button in the action bar.
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean onIsMultiPane() {
|
||||
return isXLargeTablet(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
public void onBuildHeaders(List<Header> target) {
|
||||
loadHeadersFromResource(R.xml.pref_headers, target);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method stops fragment injection in malicious applications.
|
||||
* Make sure to deny any unknown fragments here.
|
||||
*/
|
||||
protected boolean isValidFragment(String fragmentName) {
|
||||
/*
|
||||
if (PreferenceFragment.equals(fragmentName.getClass().getName()))
|
||||
return true;
|
||||
if (GeneralPreferenceFragment.equals(fragmentName.getClass().getName()))
|
||||
return true;
|
||||
if (DataSyncPreferenceFragment.equals(fragmentName.getClass().getName()))
|
||||
return true;
|
||||
if (NotificationPreferenceFragment.equals(fragmentName.getClass().getName()))
|
||||
return true;
|
||||
|
||||
*/
|
||||
|
||||
return PreferenceFragment.class.getName().equals(fragmentName)
|
||||
|| GeneralPreferenceFragment.class.getName().equals(fragmentName)
|
||||
|| DataSyncPreferenceFragment.class.getName().equals(fragmentName)
|
||||
|| NotificationPreferenceFragment.class.getName().equals(fragmentName);
|
||||
|
||||
}
|
||||
/* if (PreferenceFragment.equals(fragmentName.class().getName()))
|
||||
return true;
|
||||
if (GeneralPreferenceFragment.equals(fragmentName.class().getName()))
|
||||
return true;
|
||||
if (DataSyncPreferenceFragment.equals(fragmentName.class().getName()))
|
||||
return true;
|
||||
if (NotificationPreferenceFragment.equals(fragmentName.class().getName()))
|
||||
return true;
|
||||
write by ljw
|
||||
*/
|
||||
/**
|
||||
* This fragment shows general preferences only. It is used when the
|
||||
* activity is showing a two-pane settings UI.
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
public static class GeneralPreferenceFragment extends PreferenceFragment {
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
addPreferencesFromResource(R.xml.pref_general);
|
||||
setHasOptionsMenu(true);
|
||||
|
||||
// Bind the summaries of EditText/List/Dialog/Ringtone preferences
|
||||
// to their values. When their values change, their summaries are
|
||||
// updated to reflect the new value, per the Android Design
|
||||
// guidelines.
|
||||
bindPreferenceSummaryToValue(findPreference("example_text"));
|
||||
bindPreferenceSummaryToValue(findPreference("example_list"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
int id = item.getItemId();
|
||||
if (id == android.R.id.home) {
|
||||
startActivity(new Intent(getActivity(), Settings.class));
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This fragment shows notification preferences only. It is used when the
|
||||
* activity is showing a two-pane settings UI.
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
public static class NotificationPreferenceFragment extends PreferenceFragment {
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
addPreferencesFromResource(R.xml.pref_notification);
|
||||
setHasOptionsMenu(true);
|
||||
|
||||
// Bind the summaries of EditText/List/Dialog/Ringtone preferences
|
||||
// to their values. When their values change, their summaries are
|
||||
// updated to reflect the new value, per the Android Design
|
||||
// guidelines.
|
||||
bindPreferenceSummaryToValue(findPreference("notifications_new_message_ringtone"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
int id = item.getItemId();
|
||||
if (id == android.R.id.home) {
|
||||
startActivity(new Intent(getActivity(), Settings.class));
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This fragment shows data and sync preferences only. It is used when the
|
||||
* activity is showing a two-pane settings UI.
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
public static class DataSyncPreferenceFragment extends PreferenceFragment {
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
addPreferencesFromResource(R.xml.pref_data_sync);
|
||||
setHasOptionsMenu(true);
|
||||
|
||||
// Bind the summaries of EditText/List/Dialog/Ringtone preferences
|
||||
// to their values. When their values change, their summaries are
|
||||
// updated to reflect the new value, per the Android Design
|
||||
// guidelines.
|
||||
bindPreferenceSummaryToValue(findPreference("sync_frequency"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
int id = item.getItemId();
|
||||
if (id == android.R.id.home) {
|
||||
startActivity(new Intent(getActivity(), Settings.class));
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {//当点击后退键时执行该函数
|
||||
|
||||
super.onBackPressed();
|
||||
Intent intent_Setting_to_Menu = new Intent(Settings.this, Menu.class);
|
||||
startActivity(intent_Setting_to_Menu);
|
||||
finish();
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package me.wshuo.tbot;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
||||
public class User extends AppCompatActivity {
|
||||
private Button mReturnButton; //没有使用到
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.user);
|
||||
mReturnButton = (Button)findViewById(R.id.returnback);
|
||||
|
||||
}
|
||||
public void back_to_login(View view) {
|
||||
//setContentView(R.layout.login);
|
||||
Intent intent3 = new Intent(User.this,Login.class) ;
|
||||
startActivity(intent3);
|
||||
finish();
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package me.wshuo.tbot;
|
||||
/**
|
||||
* Created by FoolishFan on 2016/7/14.
|
||||
*/
|
||||
|
||||
public class UserData {
|
||||
private String userName; //用户名
|
||||
private String userPwd; //用户密码
|
||||
private int userId; //用户ID号
|
||||
public int pwdresetFlag=0;
|
||||
//获取用户名
|
||||
public String getUserName() { //获取用户名
|
||||
return userName;
|
||||
}
|
||||
//设置用户名
|
||||
public void setUserName(String userName) { //输入用户名
|
||||
this.userName = userName;
|
||||
}
|
||||
//获取用户密码
|
||||
public String getUserPwd() { //获取用户密码
|
||||
return userPwd;
|
||||
}
|
||||
//设置用户密码
|
||||
public void setUserPwd(String userPwd) { //输入用户密码
|
||||
this.userPwd = userPwd;
|
||||
}
|
||||
//获取用户id
|
||||
public int getUserId() { //获取用户ID号
|
||||
return userId;
|
||||
}
|
||||
//设置用户id
|
||||
public void setUserId(int userId) { //设置用户ID号
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
/* public UserData(String userName, String userPwd, int userId) { //用户信息
|
||||
super();
|
||||
this.userName = userName;
|
||||
this.userPwd = userPwd;
|
||||
this.userId = userId;
|
||||
}*/
|
||||
|
||||
public UserData(String userName, String userPwd) { //这里只采用用户名和密码
|
||||
super();
|
||||
this.userName = userName;
|
||||
this.userPwd = userPwd;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package me.wshuo.tbot;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
||||
public class VideoObserve extends AppCompatActivity {
|
||||
|
||||
public Button btnVideoReturn;
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_video_observe);
|
||||
btnVideoReturn = (Button)findViewById(R.id.btnVideoReturn);
|
||||
btnVideoReturn.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent_Video_to_Menu = new Intent(VideoObserve.this, Menu.class);
|
||||
startActivity(intent_Video_to_Menu);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {//当点击后退键时执行该函数
|
||||
|
||||
super.onBackPressed();
|
||||
Intent intent_Video_to_Menu = new Intent(VideoObserve.this, Menu.class);
|
||||
startActivity(intent_Video_to_Menu);
|
||||
finish();
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package me.wshuo.tbot;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
||||
public class Welcome extends AppCompatActivity {
|
||||
|
||||
public Button btnWelcome;
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_welcome);
|
||||
btnWelcome = (Button)findViewById(R.id.btnWelcome);
|
||||
btnWelcome.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent_Welcome_to_IPConnect = new Intent(Welcome.this, IPConnect.class);
|
||||
startActivity(intent_Welcome_to_IPConnect);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_pressed="true">
|
||||
<shape>
|
||||
<gradient android:startColor="#FFFF00" android:endColor="#C0C0C0"
|
||||
android:angle="0"/>
|
||||
<stroke android:width="4dip" android:color="#b0000000"/>
|
||||
<corners android:radius="15dp"/>
|
||||
<padding android:left="10dp" android:top="10dp" android:right="10dp"
|
||||
android:bottom="10dp"/>
|
||||
|
||||
</shape>
|
||||
|
||||
</item>
|
||||
<item android:state_focused="true">
|
||||
<shape>
|
||||
<gradient android:startColor="#FFFFFFFF" android:endColor="#00000000"
|
||||
android:angle="270"/>
|
||||
<stroke android:width="4dip" android:color="#00000000"/>
|
||||
<corners android:radius="15dp"/>
|
||||
<padding android:left="10dp" android:top="10dp" android:right="10dp"
|
||||
android:bottom="10dp"/>
|
||||
|
||||
</shape>
|
||||
|
||||
</item>
|
||||
<item>
|
||||
<shape>
|
||||
<gradient android:startColor="#FFFFFFFF" android:endColor="#00000000"
|
||||
android:angle="90"/>
|
||||
<stroke android:width="4dip" android:color="#00000000"/>
|
||||
<corners android:radius="15dp"/>
|
||||
<padding android:left="10dp" android:top="10dp" android:right="10dp"
|
||||
android:bottom="10dp"/>
|
||||
|
||||
</shape>
|
||||
|
||||
</item>
|
||||
</selector>
|
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportHeight="24.0"
|
||||
android:viewportWidth="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zm1,15h-2v-6h2v6zm0,-8h-2V7h2v2z" />
|
||||
</vector>
|
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportHeight="24.0"
|
||||
android:viewportWidth="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M11.5,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.9,2 2,2zm6.5,-6v-5.5c0,-3.07 -2.13,-5.64 -5,-6.32V3.5c0,-0.83 -0.67,-1.5 -1.5,-1.5S10,2.67 10,3.5v0.68c-2.87,0.68 -5,3.25 -5,6.32V16l-2,2v1h17v-1l-2,-2z" />
|
||||
</vector>
|
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportHeight="24.0"
|
||||
android:viewportWidth="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01,-.25 1.97,-.7 2.8l1.46 1.46C19.54 15.03 20 13.57 20 12c0,-4.42,-3.58,-8,-8,-8zm0 14c-3.31 0,-6,-2.69,-6,-6 0,-1.01.25,-1.97.7,-2.8L5.24 7.74C4.46 8.97 4 10.43 4 12c0 4.42 3.58 8 8 8v3l4,-4,-4,-4v3z" />
|
||||
</vector>
|
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 126 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.3 KiB |
@ -0,0 +1,99 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
tools:context="me.wshuo.tbot.AudioCall">
|
||||
|
||||
|
||||
|
||||
<TextView
|
||||
android:text="TextView"
|
||||
android:layout_width="75dp"
|
||||
android:layout_height="25dp"
|
||||
android:id="@+id/textView10"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_centerHorizontal="true"
|
||||
tools:text="语音通信" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="250dp"
|
||||
android:layout_height="250dp"
|
||||
android:id="@+id/imageView"
|
||||
android:layout_alignWithParentIfMissing="false"
|
||||
android:background="@android:color/background_dark"
|
||||
android:layout_marginTop="27dp"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_centerHorizontal="true" />
|
||||
|
||||
<Button
|
||||
android:text="拨打"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="18dp"
|
||||
android:layout_marginStart="18dp"
|
||||
android:layout_marginTop="34dp"
|
||||
android:id="@+id/button12"
|
||||
android:elevation="0dp"
|
||||
android:background="@android:color/holo_green_light"
|
||||
android:layout_below="@+id/imageView"
|
||||
android:layout_alignLeft="@+id/imageView"
|
||||
android:layout_alignStart="@+id/imageView" />
|
||||
|
||||
<Button
|
||||
android:text="挂断"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/button13"
|
||||
android:background="@android:color/holo_red_light"
|
||||
android:layout_alignBaseline="@+id/button12"
|
||||
android:layout_alignBottom="@+id/button12"
|
||||
android:layout_alignRight="@+id/imageView"
|
||||
android:layout_alignEnd="@+id/imageView"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginEnd="16dp" />
|
||||
|
||||
<Button
|
||||
android:text="返回"
|
||||
android:layout_width="45dp"
|
||||
android:layout_height="30dp"
|
||||
android:id="@+id/btnAudioReturn"
|
||||
android:bottomLeftRadius="20dp"
|
||||
android:background="@android:color/holo_red_dark"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true" />
|
||||
|
||||
<Switch
|
||||
android:text="扬声器"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/switch1"
|
||||
android:layout_below="@+id/button12"
|
||||
android:layout_alignLeft="@+id/textView10"
|
||||
android:layout_alignStart="@+id/textView10"
|
||||
android:layout_marginTop="30dp" />
|
||||
|
||||
<Switch
|
||||
android:text="录 音"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/switch2"
|
||||
android:layout_below="@+id/switch1"
|
||||
android:layout_alignRight="@+id/switch1"
|
||||
android:layout_alignEnd="@+id/switch1" />
|
||||
|
||||
<Switch
|
||||
android:text="静 音"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/switch3"
|
||||
android:layout_below="@+id/switch2"
|
||||
android:layout_alignRight="@+id/switch2"
|
||||
android:layout_alignEnd="@+id/switch2" />
|
||||
|
||||
</RelativeLayout>
|
@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/activity_falldown"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
android:orientation="vertical"
|
||||
tools:context="me.wshuo.tbot.Falldown">
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<Button
|
||||
android:text="返回"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/btnFallReturn"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:text="摔倒检测功能设置"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/textView4"
|
||||
android:textSize="30dp"
|
||||
/>
|
||||
</LinearLayout>
|
||||
|
||||
<Switch
|
||||
android:text="检测老人摔倒"
|
||||
android:layout_width="wrap_content"
|
||||
android:textSize="20dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/switch1"
|
||||
|
||||
android:layout_marginTop="30dp" />
|
||||
|
||||
<Switch
|
||||
android:text="通过电话报警"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/switch2"
|
||||
android:textSize="20dp"
|
||||
android:layout_below="@+id/switch1" />
|
||||
|
||||
<Switch
|
||||
android:text="通过短信报警"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/switch3"
|
||||
android:textSize="20dp"
|
||||
android:layout_below="@+id/switch2"
|
||||
/>
|
||||
</LinearLayout>
|
@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/activity_ipconnect"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context="me.wshuo.tbot.IPConnect">
|
||||
|
||||
<TextView
|
||||
android:text="连接到您的机器人:"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:textSize="30dp"
|
||||
android:id="@+id/tvIPConnect"
|
||||
/>
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ip"/>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etIPConnect"
|
||||
android:hint="请输入机器人ip"
|
||||
android:layout_alignParentLeft="true"
|
||||
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
android:layout_width="300dp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnIPConnect"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_toRightOf="@+id/etIPConnect"
|
||||
android:background="#00bbff"
|
||||
android:text="确定"
|
||||
/>
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
|
||||
</LinearLayout>
|
@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/activity_medicine_alert"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
android:orientation="vertical"
|
||||
tools:context="me.wshuo.tbot.MedicineAlert">
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<Button
|
||||
android:text="返回"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/btnAlertReturn"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<TextView
|
||||
android:text="设置服药提醒时间"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/textView3"
|
||||
android:textSize="30dp"
|
||||
android:layout_weight="1" />
|
||||
</LinearLayout>
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<DatePicker
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/datePicker3" />
|
||||
|
||||
<TimePicker
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/timePicker2" />
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
|
||||
</LinearLayout>
|
@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/activity_menu"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
android:background="#e2ebee"
|
||||
android:orientation="vertical"
|
||||
tools:context="me.wshuo.tbot.Menu">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation = "horizontal">
|
||||
|
||||
<TextView
|
||||
android:text="功能菜单"
|
||||
android:layout_width="272dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="#ff00b7"
|
||||
android:gravity="center"
|
||||
android:textSize="30dp"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toEndOf="@+id/btnMenuReturn" />
|
||||
|
||||
<Button
|
||||
android:text="返回"
|
||||
android:layout_width="121dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="#0073ff"
|
||||
android:id="@+id/btnMenuReturn"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentStart="true" />
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
<Button
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="摔倒检测"
|
||||
android:id="@+id/btnFall"/>
|
||||
<Button
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="服药提醒"
|
||||
android:id="@+id/btnAlert"/>
|
||||
<Button
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="语音通信"
|
||||
android:id="@+id/btnAudio"/>
|
||||
<Button
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="视频监控"
|
||||
android:id="@+id/btnVideo"/>
|
||||
<Button
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="个人设置"
|
||||
android:id="@+id/btnSetting"/>
|
||||
<Button
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="控制移动"
|
||||
android:id="@+id/btnControl"/>
|
||||
|
||||
|
||||
</LinearLayout>
|
@ -0,0 +1,82 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
tools:context="me.wshuo.tbot.MotionControl">
|
||||
|
||||
<TextView
|
||||
android:text="控制移动"
|
||||
android:layout_width="75dp"
|
||||
android:layout_height="25dp"
|
||||
android:id="@+id/textView2"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_centerHorizontal="true"
|
||||
/>
|
||||
|
||||
<Button
|
||||
android:text="返回"
|
||||
android:layout_width="45dp"
|
||||
android:layout_height="30dp"
|
||||
android:id="@+id/btnMotionReturn"
|
||||
android:bottomLeftRadius="20dp"
|
||||
android:background="@android:color/holo_red_dark"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="250dp"
|
||||
android:layout_height="250dp"
|
||||
android:id="@+id/logo"
|
||||
android:layout_alignWithParentIfMissing="false"
|
||||
android:background="@android:color/background_dark"
|
||||
android:layout_marginTop="27dp"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_centerHorizontal="true" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button11"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:background="#17ce33"
|
||||
android:layout_marginTop="22dp"
|
||||
android:layout_below="@+id/logo"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:text="前" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button6"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:background="#17ce33"
|
||||
android:layout_below="@+id/button2"
|
||||
android:layout_alignLeft="@+id/button11"
|
||||
android:layout_alignStart="@+id/button11"
|
||||
android:text="后" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button7"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:background="#17ce33"
|
||||
android:layout_below="@+id/button11"
|
||||
android:layout_toLeftOf="@+id/textView2"
|
||||
android:layout_toStartOf="@+id/textView2"
|
||||
android:text="左" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button2"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:background="#17ce33"
|
||||
android:layout_below="@+id/button11"
|
||||
android:layout_toRightOf="@+id/textView2"
|
||||
android:layout_toEndOf="@+id/textView2"
|
||||
android:text="右" />
|
||||
|
||||
</RelativeLayout>
|
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/activity_preference_settings"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
tools:context="me.wshuo.tbot.PreferenceSettings">
|
||||
|
||||
</RelativeLayout>
|
@ -0,0 +1,132 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
tools:context="me.wshuo.tbot.VideoObserve">
|
||||
|
||||
<SeekBar
|
||||
style="@style/Widget.AppCompat.SeekBar.Discrete"
|
||||
android:layout_width="200dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:max="100"
|
||||
android:progress="3"
|
||||
android:layout_alignTop="@+id/textView6"
|
||||
android:layout_alignLeft="@+id/button3"
|
||||
android:layout_alignStart="@+id/button3"
|
||||
android:id="@+id/seekBar3" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="250dp"
|
||||
android:layout_height="250dp"
|
||||
android:id="@+id/logo"
|
||||
android:layout_alignWithParentIfMissing="false"
|
||||
android:background="@android:color/background_dark"
|
||||
android:layout_marginTop="27dp"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_centerHorizontal="true" />
|
||||
|
||||
<Button
|
||||
android:text="开启"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/logo"
|
||||
android:layout_alignLeft="@+id/logo"
|
||||
android:layout_alignStart="@+id/logo"
|
||||
android:layout_marginLeft="37dp"
|
||||
android:layout_marginStart="37dp"
|
||||
android:layout_marginTop="31dp"
|
||||
android:id="@+id/button3"
|
||||
android:elevation="0dp"
|
||||
android:background="@android:color/holo_green_light" />
|
||||
|
||||
<TextView
|
||||
android:text="视频监控"
|
||||
android:layout_width="75dp"
|
||||
android:layout_height="25dp"
|
||||
android:id="@+id/textView5"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_centerHorizontal="true"
|
||||
/>
|
||||
|
||||
<Button
|
||||
android:text="返回"
|
||||
android:layout_width="45dp"
|
||||
android:layout_height="30dp"
|
||||
android:id="@+id/btnVideoReturn"
|
||||
android:bottomLeftRadius="20dp"
|
||||
android:background="@android:color/holo_red_dark"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true" />
|
||||
|
||||
<TextView
|
||||
android:text="亮 度"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="19dp"
|
||||
android:id="@+id/textView7"
|
||||
android:layout_below="@+id/textView6"
|
||||
android:layout_alignLeft="@+id/textView6"
|
||||
android:layout_alignStart="@+id/textView6"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:text="清晰度"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/textView8"
|
||||
android:layout_below="@+id/textView7"
|
||||
android:layout_alignLeft="@+id/textView7"
|
||||
android:layout_alignStart="@+id/textView7"
|
||||
android:layout_marginTop="18dp"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:text="音 量"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="17dp"
|
||||
android:id="@+id/textView6"
|
||||
android:layout_below="@+id/button3"
|
||||
|
||||
/>
|
||||
|
||||
<SeekBar
|
||||
style="@style/Widget.AppCompat.SeekBar.Discrete"
|
||||
android:layout_width="200dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:max="100"
|
||||
android:progress="3"
|
||||
android:id="@+id/seekBar"
|
||||
android:layout_alignBottom="@+id/textView7"
|
||||
android:layout_alignLeft="@+id/seekBar3"
|
||||
android:layout_alignStart="@+id/seekBar3" />
|
||||
|
||||
<SeekBar
|
||||
style="@style/Widget.AppCompat.SeekBar.Discrete"
|
||||
android:layout_width="200dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:max="100"
|
||||
android:progress="3"
|
||||
android:id="@+id/seekBar2"
|
||||
android:layout_alignTop="@+id/textView8"
|
||||
android:layout_alignLeft="@+id/seekBar"
|
||||
android:layout_alignStart="@+id/seekBar" />
|
||||
|
||||
<Button
|
||||
android:text="关闭"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/button4"
|
||||
android:background="@android:color/holo_red_light"
|
||||
android:layout_alignBaseline="@+id/button3"
|
||||
android:layout_alignBottom="@+id/button3"
|
||||
android:layout_toRightOf="@+id/button3"
|
||||
android:layout_toEndOf="@+id/button3" />
|
||||
|
||||
</RelativeLayout>
|
@ -0,0 +1,128 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/activity_welcome"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
android:background="#e2ebee"
|
||||
android:orientation="vertical"
|
||||
tools:context="me.wshuo.tbot.Welcome">
|
||||
|
||||
<TextView
|
||||
android:text="@string/welcome"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="#ff00b7"
|
||||
android:gravity="center"
|
||||
android:textSize="30dp"
|
||||
|
||||
android:id="@+id/tvWelcome" />
|
||||
|
||||
<TextView
|
||||
android:text="@string/introduction"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="#1a1c1b"
|
||||
android:gravity="center"
|
||||
android:textSize="25dp"
|
||||
android:id="@+id/tvIntroduction" />
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_gravity="center">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="68dp"
|
||||
android:layout_height="58dp"
|
||||
android:src="@drawable/w1" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="47dp"
|
||||
android:text="摔倒检测"
|
||||
android:textSize="40dp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_gravity="center">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="68dp"
|
||||
android:layout_height="58dp"
|
||||
android:src="@drawable/w2" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="47dp"
|
||||
android:text="服药提醒"
|
||||
android:textSize="40dp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_gravity="center">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="68dp"
|
||||
android:layout_height="58dp"
|
||||
android:src="@drawable/w3" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="47dp"
|
||||
android:text="语音通信"
|
||||
android:textSize="40dp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_gravity="center">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="68dp"
|
||||
android:layout_height="58dp"
|
||||
android:src="@drawable/w4" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="47dp"
|
||||
android:text="视频监控"
|
||||
android:textSize="40dp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_gravity="center">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="68dp"
|
||||
android:layout_height="58dp"
|
||||
android:src="@drawable/w1" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="47dp"
|
||||
android:text="移动控制"
|
||||
android:textSize="40dp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Great, let's go!"
|
||||
android:background="#00bbff"
|
||||
android:id="@+id/btnWelcome"/>
|
||||
</LinearLayout>
|
@ -0,0 +1,142 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
tools:context="me.wshuo.tbot.Login">
|
||||
<RelativeLayout
|
||||
android:id="@+id/login_view"
|
||||
android:layout_width="400dp"
|
||||
android:layout_height="800dp"
|
||||
android:layout_centerInParent="true">
|
||||
|
||||
<Button
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="注册"
|
||||
android:id="@+id/login_btn_register"
|
||||
android:onClick="resetpwd"
|
||||
android:textColor="#ffffff"
|
||||
android:background="#e52525"
|
||||
android:textSize="20dp"
|
||||
android:layout_below="@+id/login_btn_login"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_marginTop="10dp" />
|
||||
|
||||
<Button
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="登录"
|
||||
android:id="@+id/login_btn_login"
|
||||
android:onClick="finish_login"
|
||||
android:background="#545bcb"
|
||||
android:textSize="20dp"
|
||||
android:textColor="#ffffff"
|
||||
android:layout_below="@+id/login_edit_pwd"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_marginTop="52dp" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="300dp"
|
||||
android:layout_height="150dp"
|
||||
android:id="@+id/logo"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignWithParentIfMissing="false"
|
||||
android:background="#ffffff" />
|
||||
|
||||
<EditText
|
||||
android:layout_width="400dp"
|
||||
android:layout_height="60dp"
|
||||
android:inputType="textPassword"
|
||||
android:ems="10"
|
||||
android:id="@+id/login_edit_pwd"
|
||||
android:drawableLeft="@android:drawable/ic_lock_idle_lock"
|
||||
android:hint="请输入您的密码"
|
||||
android:layout_below="@+id/login_edit_account"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true" />
|
||||
|
||||
<EditText
|
||||
android:layout_width="400dp"
|
||||
android:layout_height="60dp"
|
||||
android:inputType="textPersonName"
|
||||
android:id="@+id/login_edit_account"
|
||||
android:drawableLeft="@android:drawable/ic_menu_myplaces"
|
||||
android:hint="请输入您的用户名"
|
||||
android:layout_below="@+id/logo"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_marginTop="20dp" />
|
||||
|
||||
<Button
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="注销"
|
||||
android:id="@+id/login_btn_cancle"
|
||||
android:textSize="20dp"
|
||||
android:layout_below="@+id/login_btn_register"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:textColor="#ffffff"
|
||||
android:background="#3a1313" />
|
||||
|
||||
<CheckBox
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="20dp"
|
||||
android:text="记住密码"
|
||||
android:id="@+id/Login_Remember"
|
||||
android:layout_below="@+id/login_edit_pwd"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:checked="false"
|
||||
android:textSize="15dp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="20dp"
|
||||
android:text="修改密码"
|
||||
android:id="@+id/login_text_change_pwd"
|
||||
android:layout_below="@+id/login_edit_pwd"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:textSize="15dp" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/login_success_view"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:layout_marginLeft="15.0px"
|
||||
android:layout_marginRight="15.0px"
|
||||
android:layout_marginTop="62.0px"
|
||||
android:background="#ff3f3f3f"
|
||||
android:paddingBottom="10.0px"
|
||||
android:paddingTop="21.0px"
|
||||
android:visibility="gone" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/login_success_show"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:textColor="#ff3f3f3f"
|
||||
android:textSize="20.0dip" />
|
||||
</RelativeLayout>
|
||||
|
||||
</RelativeLayout>
|
@ -0,0 +1,84 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
android:weightSum="1">
|
||||
|
||||
<EditText
|
||||
android:drawableLeft="@android:drawable/ic_menu_myplaces"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="60dp"
|
||||
android:inputType="textPersonName"
|
||||
android:ems="10"
|
||||
android:id="@+id/resetpwd_edit_name"
|
||||
android:layout_alignParentTop="true"
|
||||
android:hint="请输入您的用户名"
|
||||
android:layout_alignLeft="@+id/resetpwd_edit_pwd_new"
|
||||
android:layout_alignStart="@+id/resetpwd_edit_pwd_new"
|
||||
android:layout_alignRight="@+id/resetpwd_edit_pwd_new"
|
||||
android:layout_alignEnd="@+id/resetpwd_edit_pwd_new" />
|
||||
|
||||
<!--
|
||||
|
||||
<EditText android:id="@+id/edt_operator_name" style="@style/syncEditText"
|
||||
android:hint="@string/hint_operator_name" />
|
||||
<ImageView android:id="@+id/syncOperatorImg" style="@style/syncImageView"
|
||||
android:layout_alignLeft="@+id/edt_operator_name"
|
||||
android:layout_alignTop="@+id/edt_operator_name"
|
||||
android:layout_alignBottom="@+id/edt_operator_name" android:src="@drawable/sync_operator" />
|
||||
-->
|
||||
|
||||
<EditText
|
||||
android:drawableLeft="@android:drawable/ic_lock_idle_lock"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="60dp"
|
||||
android:inputType="textPassword"
|
||||
android:ems="10"
|
||||
android:id="@+id/resetpwd_edit_pwd_old"
|
||||
android:hint="请输入您的密码"
|
||||
android:layout_below="@+id/resetpwd_edit_name"
|
||||
android:layout_alignRight="@+id/resetpwd_edit_name"
|
||||
android:layout_alignEnd="@+id/resetpwd_edit_name"
|
||||
android:layout_alignLeft="@+id/resetpwd_edit_name"
|
||||
android:layout_alignStart="@+id/resetpwd_edit_name" />
|
||||
|
||||
<Button
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="取消"
|
||||
android:id="@+id/register_btn_cancel"
|
||||
android:textSize="20dp"
|
||||
android:background="#f71818"
|
||||
android:layout_below="@+id/register_btn_sure"
|
||||
android:layout_alignLeft="@+id/register_btn_sure"
|
||||
android:layout_alignStart="@+id/register_btn_sure"
|
||||
android:layout_marginTop="10dp" />
|
||||
|
||||
<EditText
|
||||
android:drawableLeft="@android:drawable/ic_lock_idle_lock"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="60dp"
|
||||
android:inputType="textPassword"
|
||||
android:ems="10"
|
||||
android:id="@+id/resetpwd_edit_pwd_new"
|
||||
android:layout_below="@+id/resetpwd_edit_pwd_old"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:hint="请确认您的密码" />
|
||||
|
||||
<Button
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="确定"
|
||||
android:id="@+id/register_btn_sure"
|
||||
android:textSize="20dp"
|
||||
android:background="#1cf718"
|
||||
android:layout_below="@+id/resetpwd_edit_pwd_new"
|
||||
android:layout_alignLeft="@+id/resetpwd_edit_pwd_new"
|
||||
android:layout_alignStart="@+id/resetpwd_edit_pwd_new"
|
||||
android:layout_marginTop="20dp" />
|
||||
|
||||
</RelativeLayout>
|
@ -0,0 +1,99 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
android:weightSum="1">
|
||||
|
||||
<EditText
|
||||
android:drawableLeft="@android:drawable/ic_menu_myplaces"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="60dp"
|
||||
android:inputType="textPersonName"
|
||||
android:ems="10"
|
||||
android:id="@+id/resetpwd_edit_name"
|
||||
android:layout_alignParentTop="true"
|
||||
android:hint="请输入您的用户名"
|
||||
android:layout_alignLeft="@+id/resetpwd_edit_pwd_new"
|
||||
android:layout_alignStart="@+id/resetpwd_edit_pwd_new"
|
||||
android:layout_alignRight="@+id/resetpwd_edit_pwd_new"
|
||||
android:layout_alignEnd="@+id/resetpwd_edit_pwd_new" />
|
||||
|
||||
<!--
|
||||
|
||||
<EditText android:id="@+id/edt_operator_name" style="@style/syncEditText"
|
||||
android:hint="@string/hint_operator_name" />
|
||||
<ImageView android:id="@+id/syncOperatorImg" style="@style/syncImageView"
|
||||
android:layout_alignLeft="@+id/edt_operator_name"
|
||||
android:layout_alignTop="@+id/edt_operator_name"
|
||||
android:layout_alignBottom="@+id/edt_operator_name" android:src="@drawable/sync_operator" />
|
||||
-->
|
||||
|
||||
<EditText
|
||||
android:drawableLeft="@android:drawable/ic_lock_idle_lock"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="60dp"
|
||||
android:inputType="textPassword"
|
||||
android:ems="10"
|
||||
android:id="@+id/resetpwd_edit_pwd_old"
|
||||
android:hint="请输入您的旧密码"
|
||||
android:layout_below="@+id/resetpwd_edit_name"
|
||||
android:layout_alignRight="@+id/resetpwd_edit_name"
|
||||
android:layout_alignEnd="@+id/resetpwd_edit_name"
|
||||
android:layout_alignLeft="@+id/resetpwd_edit_name"
|
||||
android:layout_alignStart="@+id/resetpwd_edit_name" />
|
||||
|
||||
<Button
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="取消"
|
||||
android:id="@+id/resetpwd_btn_cancel"
|
||||
android:textSize="20dp"
|
||||
android:onClick="not_to_reset"
|
||||
android:background="#f71818"
|
||||
android:layout_below="@+id/resetpwd_btn_sure"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_marginTop="20dp" />
|
||||
|
||||
<EditText
|
||||
android:drawableLeft="@android:drawable/ic_lock_idle_lock"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="60dp"
|
||||
android:inputType="textPassword"
|
||||
android:ems="10"
|
||||
android:id="@+id/resetpwd_edit_pwd_new"
|
||||
android:layout_below="@+id/resetpwd_edit_pwd_old"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:hint="请确认您的新密码"
|
||||
/>
|
||||
|
||||
<Button
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="确定"
|
||||
android:id="@+id/resetpwd_btn_sure"
|
||||
android:textSize="20dp"
|
||||
android:onClick="sure_to_reset"
|
||||
android:background="#1cf718"
|
||||
android:layout_marginTop="92dp"
|
||||
android:layout_below="@+id/resetpwd_edit_pwd_new"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true" />
|
||||
|
||||
<EditText
|
||||
android:drawableLeft="@android:drawable/ic_lock_idle_lock"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="60dp"
|
||||
android:inputType="textPassword"
|
||||
android:ems="10"
|
||||
android:id="@+id/resetpwd_edit_pwd_check"
|
||||
android:hint="请输入您的新密码"
|
||||
android:layout_below="@+id/resetpwd_edit_pwd_new"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true" />
|
||||
|
||||
</RelativeLayout>
|
@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:text="您好,欢迎回来!"
|
||||
android:id="@+id/textView"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginLeft="50dp"
|
||||
android:layout_marginTop="6dp"
|
||||
android:textSize="16dp" />
|
||||
|
||||
<Button
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="退出"
|
||||
android:id="@+id/returnback"
|
||||
android:layout_below="@+id/textView"
|
||||
android:layout_marginTop="36dp"
|
||||
android:onClick="back_to_login"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="20dp"
|
||||
android:background="#d95b5b"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true" />
|
||||
|
||||
</RelativeLayout>
|
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 4.7 KiB |
After Width: | Height: | Size: 7.5 KiB |
After Width: | Height: | Size: 10 KiB |
@ -0,0 +1,6 @@
|
||||
<resources>
|
||||
<!-- Example customization of dimensions originally defined in res/values/dimens.xml
|
||||
(such as screen margins) for screens with more than 820dp of available width. This
|
||||
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
|
||||
<dimen name="activity_horizontal_margin">64dp</dimen>
|
||||
</resources>
|
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="colorPrimary">#3F51B5</color>
|
||||
<color name="colorPrimaryDark">#303F9F</color>
|
||||
<color name="colorAccent">#FF4081</color>
|
||||
</resources>
|
@ -0,0 +1,5 @@
|
||||
<resources>
|
||||
<!-- Default screen margins, per the Android Design guidelines. -->
|
||||
<dimen name="activity_horizontal_margin">16dp</dimen>
|
||||
<dimen name="activity_vertical_margin">16dp</dimen>
|
||||
</resources>
|
@ -0,0 +1,103 @@
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="hint_operator_name">你好</string>
|
||||
<string name="hello">Hello World, Date!</string>
|
||||
<string name="app_name">Tbot</string>
|
||||
<string name="strInputAccHint">输入帐号</string>
|
||||
<string name="strAccInputLabel">帐号</string>
|
||||
<string name="strPswInputLabel">密码</string>
|
||||
<string name="login">登 录</string>
|
||||
<string name="register">注 册</string>
|
||||
<string name="cancel">取 消</string>
|
||||
<string name="account_empty">用户名为空,请重新输入!</string>
|
||||
<string name="pwd_empty">密码为空,请重新输入!</string>
|
||||
<string name="pwd_not_fit_user">密码不正确,请重新输入!</string>
|
||||
<string name="pwd_new_empty">新密码为空,请重新输入!</string>
|
||||
<string name="pwd_check_empty">密码确认为空,请重新输入!</string>
|
||||
<string name="pwd_not_the_same">密码确认不正确,请重新输入密码!</string>
|
||||
<string name="register_fail">注册用户失败,请重新尝试!</string>
|
||||
<string name="register_success">注册成功!</string>
|
||||
<string name="resetpwd_fail">密码修改失败,请重新尝试!</string>
|
||||
<string name="resetpwd_success">密码修改成功!</string>
|
||||
<string name="login_success">登陆成功!</string>
|
||||
<string name="cancel_success">注销成功!</string>
|
||||
<string name="login_fail">登录失败!请输入正确的用户名与密码!</string>
|
||||
<string name="cancel_fail">注销失败!请输入正确的用户名与密码!</string>
|
||||
<string name="name_already_exist">用户名【<xliff:g example="tom" id="id1">%1$s</xliff:g>】已存在,请重新输入!</string>
|
||||
<string name="name_not_exist">用户名【<xliff:g example="tom" id="id1">%1$s</xliff:g>】不存在,请重新输入!</string>
|
||||
<string name="user_login_success">用户:<xliff:g example="tom" id="id2">%1$s</xliff:g>登录,欢迎光临!</string>
|
||||
<string name="welcome">欢迎!</string>
|
||||
<string name="introduction">空巢老人看护小助手将会帮助您:</string>
|
||||
<string name="title_activity_settings">设置</string>
|
||||
|
||||
<!-- Strings related to Settings -->
|
||||
|
||||
<!-- Example General settings -->
|
||||
<string name="pref_header_general">General</string>
|
||||
|
||||
<string name="pref_title_social_recommendations">Enable social recommendations</string>
|
||||
<string name="pref_description_social_recommendations">Recommendations for people to contact
|
||||
based on your message history
|
||||
</string>
|
||||
|
||||
<string name="pref_title_display_name">Display name</string>
|
||||
<string name="pref_default_display_name">John Smith</string>
|
||||
|
||||
<string name="pref_title_add_friends_to_messages">Add friends to messages</string>
|
||||
<string-array name="pref_example_list_titles">
|
||||
<item>Always</item>
|
||||
<item>When possible</item>
|
||||
<item>Never</item>
|
||||
</string-array>
|
||||
<string-array name="pref_example_list_values">
|
||||
<item>1</item>
|
||||
<item>0</item>
|
||||
<item>-1</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Example settings for Data & Sync -->
|
||||
<string name="pref_header_data_sync">Data & sync</string>
|
||||
|
||||
<string name="pref_title_sync_frequency">Sync frequency</string>
|
||||
<string-array name="pref_sync_frequency_titles">
|
||||
<item>15 minutes</item>
|
||||
<item>30 minutes</item>
|
||||
<item>1 hour</item>
|
||||
<item>3 hours</item>
|
||||
<item>6 hours</item>
|
||||
<item>Never</item>
|
||||
</string-array>
|
||||
<string-array name="pref_sync_frequency_values">
|
||||
<item>15</item>
|
||||
<item>30</item>
|
||||
<item>60</item>
|
||||
<item>180</item>
|
||||
<item>360</item>
|
||||
<item>-1</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="list_preference_entries">
|
||||
<item>Entry 1</item>
|
||||
<item>Entry 2</item>
|
||||
<item>Entry 3</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="list_preference_entry_values">
|
||||
<item>1</item>
|
||||
<item>2</item>
|
||||
<item>3</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="multi_select_list_preference_default_value" />
|
||||
|
||||
<string name="pref_title_system_sync_settings">System sync settings</string>
|
||||
|
||||
<!-- Example settings for Notifications -->
|
||||
<string name="pref_header_notifications">Notifications</string>
|
||||
|
||||
<string name="pref_title_new_message_notifications">New message notifications</string>
|
||||
|
||||
<string name="pref_title_ringtone">Ringtone</string>
|
||||
<string name="pref_ringtone_silent">Silent</string>
|
||||
|
||||
<string name="pref_title_vibrate">Vibrate</string>
|
||||
</resources>
|
@ -0,0 +1,11 @@
|
||||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
@ -0,0 +1,21 @@
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<!-- NOTE: Hide buttons to simplify the UI. Users can touch outside the dialog to
|
||||
dismiss it. -->
|
||||
<!-- NOTE: ListPreference's summary should be set to its value by the activity code. -->
|
||||
<ListPreference
|
||||
android:defaultValue="180"
|
||||
android:entries="@array/pref_sync_frequency_titles"
|
||||
android:entryValues="@array/pref_sync_frequency_values"
|
||||
android:key="sync_frequency"
|
||||
android:negativeButtonText="@null"
|
||||
android:positiveButtonText="@null"
|
||||
android:title="@string/pref_title_sync_frequency" />
|
||||
|
||||
<!-- This preference simply launches an intent when selected. Use this UI sparingly, per
|
||||
design guidelines. -->
|
||||
<Preference android:title="@string/pref_title_system_sync_settings">
|
||||
<intent android:action="android.settings.SYNC_SETTINGS" />
|
||||
</Preference>
|
||||
|
||||
</PreferenceScreen>
|
@ -0,0 +1,33 @@
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="example_switch"
|
||||
android:summary="@string/pref_description_social_recommendations"
|
||||
android:title="@string/pref_title_social_recommendations" />
|
||||
|
||||
<!-- NOTE: EditTextPreference accepts EditText attributes. -->
|
||||
<!-- NOTE: EditTextPreference's summary should be set to its value by the activity code. -->
|
||||
<EditTextPreference
|
||||
android:capitalize="words"
|
||||
android:defaultValue="@string/pref_default_display_name"
|
||||
android:inputType="textCapWords"
|
||||
android:key="example_text"
|
||||
android:maxLines="1"
|
||||
android:selectAllOnFocus="true"
|
||||
android:singleLine="true"
|
||||
android:title="@string/pref_title_display_name" />
|
||||
|
||||
<!-- NOTE: Hide buttons to simplify the UI. Users can touch outside the dialog to
|
||||
dismiss it. -->
|
||||
<!-- NOTE: ListPreference's summary should be set to its value by the activity code. -->
|
||||
<ListPreference
|
||||
android:defaultValue="-1"
|
||||
android:entries="@array/pref_example_list_titles"
|
||||
android:entryValues="@array/pref_example_list_values"
|
||||
android:key="example_list"
|
||||
android:negativeButtonText="@null"
|
||||
android:positiveButtonText="@null"
|
||||
android:title="@string/pref_title_add_friends_to_messages" />
|
||||
|
||||
</PreferenceScreen>
|
@ -0,0 +1,20 @@
|
||||
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<!-- These settings headers are only used on tablets. -->
|
||||
|
||||
<header
|
||||
android:fragment="me.wshuo.tbot.Settings$GeneralPreferenceFragment"
|
||||
android:icon="@drawable/ic_info_black_24dp"
|
||||
android:title="@string/pref_header_general" />
|
||||
|
||||
<header
|
||||
android:fragment="me.wshuo.tbot.Settings$NotificationPreferenceFragment"
|
||||
android:icon="@drawable/ic_notifications_black_24dp"
|
||||
android:title="@string/pref_header_notifications" />
|
||||
|
||||
<header
|
||||
android:fragment="me.wshuo.tbot.Settings$DataSyncPreferenceFragment"
|
||||
android:icon="@drawable/ic_sync_black_24dp"
|
||||
android:title="@string/pref_header_data_sync" />
|
||||
|
||||
</preference-headers>
|
@ -0,0 +1,27 @@
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<!-- A 'parent' preference, which enables/disables child preferences (below)
|
||||
when checked/unchecked. -->
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="notifications_new_message"
|
||||
android:title="@string/pref_title_new_message_notifications" />
|
||||
|
||||
<!-- Allows the user to choose a ringtone in the 'notification' category. -->
|
||||
<!-- NOTE: This preference will be enabled only when the checkbox above is checked. -->
|
||||
<!-- NOTE: RingtonePreference's summary should be set to its value by the activity code. -->
|
||||
<RingtonePreference
|
||||
android:defaultValue="content://settings/system/notification_sound"
|
||||
android:dependency="notifications_new_message"
|
||||
android:key="notifications_new_message_ringtone"
|
||||
android:ringtoneType="notification"
|
||||
android:title="@string/pref_title_ringtone" />
|
||||
|
||||
<!-- NOTE: This preference will be enabled only when the checkbox above is checked. -->
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:dependency="notifications_new_message"
|
||||
android:key="notifications_new_message_vibrate"
|
||||
android:title="@string/pref_title_vibrate" />
|
||||
|
||||
</PreferenceScreen>
|
@ -0,0 +1,17 @@
|
||||
package me.wshuo.tbot;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
public class ExampleUnitTest {
|
||||
@Test
|
||||
public void addition_isCorrect() throws Exception {
|
||||
assertEquals(4, 2 + 2);
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.0.1'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
# Project-wide Gradle settings.
|
||||
|
||||
# IDE (e.g. Android Studio) users:
|
||||
# Gradle settings configured through the IDE *will override*
|
||||
# any settings specified in this file.
|
||||
|
||||
# For more details on how to configure your build environment visit
|
||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
org.gradle.jvmargs=-Xmx1536m
|
||||
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
@ -0,0 +1,6 @@
|
||||
#Mon Dec 28 10:00:20 PST 2015
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
|
@ -0,0 +1,160 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
esac
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
@ -0,0 +1,90 @@
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windowz variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
goto execute
|
||||
|
||||
:4NT_args
|
||||
@rem Get arguments from the 4NT Shell from JP Software
|
||||
set CMD_LINE_ARGS=%$
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
@ -0,0 +1 @@
|
||||
include ':app'
|
@ -0,0 +1,14 @@
|
||||
bin
|
||||
gen
|
||||
libs
|
||||
build
|
||||
build.xml
|
||||
local.properties
|
||||
proguard-project.txt
|
||||
.gradle
|
||||
|
||||
# These are Android Studio files, might be worth including these later.
|
||||
.idea
|
||||
*.iml
|
||||
*.log
|
||||
build-log.xml
|
@ -0,0 +1,74 @@
|
||||
### Documentation
|
||||
|
||||
See [rosjava_core](https://github.com/rosjava/rosjava_core) readme.
|
||||
|
||||
### Master Branch
|
||||
|
||||
The master branch is currently dependant on stable hydro branches of the other rosjava and android
|
||||
core repositories (too much movement there to depend on master). Also dependant on the master branch of
|
||||
android_apps.
|
||||
|
||||
### Rosinstaller
|
||||
|
||||
|
||||
* Master: https://raw.github.com/rosjava/rosjava/master/android_apps.rosinstall
|
||||
* Hydro: https://raw.github.com/rosjava/rosjava/hydro/android_apps.rosinstall
|
||||
=======
|
||||
Android Remocons
|
||||
================
|
||||
|
||||
Remocons for pairing and concert modes as well as some simple apps for testing.
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
This is primarily to get the rosjava build tools. If you are using precise, you don't need this step (it will get it from debs).
|
||||
|
||||
```
|
||||
> yujin_init_workspace -j5 ~/rosjava rosjava
|
||||
> cd ~/rosjava
|
||||
> yujin_init_build .
|
||||
> yujin_make --install-rosdeps
|
||||
> yujin_make
|
||||
```
|
||||
|
||||
This will use the maven repos for the core rosjava and android repos.
|
||||
|
||||
```
|
||||
> yujin_init_workspace -j5 ~/rocon_rosjava rocon-rosjava
|
||||
> cd ~/rocon_rosjava
|
||||
> yujin_init_build --underlays=~/rosjava/devel .
|
||||
> yujin_make --install-rosdeps
|
||||
> yujin_make
|
||||
```
|
||||
|
||||
Android core (only necessary on indigo):
|
||||
|
||||
```
|
||||
> yujin_init_workspace -j5 ~/android_core android-core
|
||||
> cd ~/android_core
|
||||
> yujin_init_build --underlays=~/rosjava/devel .
|
||||
> yujin_make
|
||||
```
|
||||
|
||||
The android interactions::
|
||||
|
||||
```
|
||||
> yujin_init_workspace -j5 ~/android_interactions
|
||||
> cd ~/android_interactions
|
||||
> yujin_init_build --underlays="~/android_core/devel;~/rocon_rosjava/devel;~/rosjava/devel" .
|
||||
> cd ~/android_interactions/src
|
||||
# to compile the rocon android apps as well
|
||||
> wstool set rocon_android_apps --git https://github.com/robotics-in-concert/rocon_android_apps.git --version=headless_launcher_update
|
||||
> wstool update -j5
|
||||
> yujin_make
|
||||
> . .bashrc
|
||||
```
|
||||
|
||||
Launch the android studio, compile the ```rocon_nfc_writer``` and ```headless_launcher```
|
||||
|
||||
Other README's
|
||||
==============
|
||||
|
||||
* rocon_nfc_writer/README.md
|
||||
* headless_launcher/README.md
|
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Daniel Stonier
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
gradleVersion = '4.1'
|
||||
}
|
||||
|
||||
buildscript {
|
||||
apply from: project.file("./buildscript2.gradle")
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.0.1'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
// classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
|
||||
}
|
||||
repositories {
|
||||
google()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
subprojects {
|
||||
/*
|
||||
* The android plugin configures a few things:
|
||||
*
|
||||
* - local deployment repository : where it dumps the jars and packaged artifacts)
|
||||
* - local maven repositories : where it finds your locally installed/built artifacts)
|
||||
* - external maven repositories : where it goes looking if it can't find dependencies locally
|
||||
* - android build tools version : which version we use across the board
|
||||
*
|
||||
* To modify, or add repos to the default external maven repositories list, pull request against this code:
|
||||
*
|
||||
* https://github.com/rosjava/rosjava_bootstrap/blob/indigo/gradle_plugins/src/main/groovy/org/ros/gradle_plugins/RosPlugin.groovy#L31
|
||||
*
|
||||
* To modify the build tools version, pull request against this code:
|
||||
*
|
||||
* https://github.com/rosjava/rosjava_bootstrap/blob/indigo/gradle_plugins/src/main/groovy/org/ros/gradle_plugins/RosAndroid.groovy#L14
|
||||
*/
|
||||
apply plugin: 'ros-android'
|
||||
|
||||
afterEvaluate { project ->
|
||||
android {
|
||||
// Exclude a few files that are duplicated across our dependencies and
|
||||
// prevent packaging Android applications.
|
||||
packagingOptions {
|
||||
exclude "META-INF/LICENSE.txt"
|
||||
exclude "META-INF/NOTICE.txt"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
defaultTasks 'assembleRelease', 'uploadArchives'
|
||||
|
||||
|
||||
repositories {
|
||||
google()
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
rootProject.buildscript {
|
||||
apply from: project.file("./buildscript2.gradle")
|
||||
dependencies {
|
||||
classpath "com.android.tools.build:gradle:3.0.1"
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
rootProject.buildscript {
|
||||
String rosMavenPath = System.getenv("ROS_MAVEN_PATH")
|
||||
String rosMavenRepository = System.getenv("ROS_MAVEN_REPOSITORY")
|
||||
repositories {
|
||||
if (rosMavenPath != null) {
|
||||
rosMavenPath.tokenize(":").each { path ->
|
||||
maven {
|
||||
// We can't use uri() here because we aren't running inside something
|
||||
// that implements the Script interface.
|
||||
url "file:${path}"
|
||||
}
|
||||
}
|
||||
}
|
||||
maven {
|
||||
url "http://repository.springsource.com/maven/bundles/release"
|
||||
}
|
||||
maven {
|
||||
url "http://repository.springsource.com/maven/bundles/external"
|
||||
}
|
||||
if (rosMavenRepository != null) {
|
||||
maven {
|
||||
url rosMavenRepository
|
||||
}
|
||||
}
|
||||
maven {
|
||||
url "https://github.com/rosjava/rosjava_mvn_repo/raw/master"
|
||||
}
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.ros.rosjava_bootstrap:gradle_plugins:0.3.0"
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Jorge Santos.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
//noinspection GroovyAssignabilityCheck
|
||||
dependencies {
|
||||
compile 'org.ros.android_core:android_10:0.2.1'
|
||||
compile 'org.ros.rosjava_core:rosjava:0.2.2'
|
||||
compile 'org.ros.rosjava_bootstrap:message_generation:0.3.0'
|
||||
compile 'org.ros.rosjava_messages:diagnostic_msgs:1.11.9'
|
||||
compile 'org.ros.rosjava_messages:rocon_interaction_msgs:0.7.12'
|
||||
compile 'org.ros.rosjava_messages:rocon_std_msgs:0.7.12'
|
||||
compile 'org.ros.rosjava_messages:rocon_app_manager_msgs:0.7.12'
|
||||
compile 'com.github.rosjava.android_extras:gingerbread:0.2.0'
|
||||
compile 'com.github.rosjava.android_extras:zxing:0.2.0'
|
||||
compile 'com.github.rosjava.zeroconf_jmdns_suite:jmdns:0.2.1'
|
||||
compile 'com.github.robotics_in_concert.rocon_rosjava_core:rosjava_utils:0.2.0'
|
||||
compile 'com.github.robotics_in_concert.rocon_rosjava_core:master_info:0.2.0'
|
||||
compile 'com.github.robotics_in_concert.rocon_rosjava_core:rocon_interactions:0.2.0'
|
||||
compile fileTree(include: 'snakeyaml*.jar', dir: '../external_libraries')
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
compileSdkVersion 26
|
||||
defaultConfig {
|
||||
minSdkVersion 18
|
||||
targetSdkVersion 26
|
||||
versionCode 1
|
||||
versionName "1.0.1"
|
||||
}
|
||||
buildToolsVersion '26.0.2'
|
||||
}
|
||||
|
||||
defaultTasks 'assembleRelease'
|
@ -0,0 +1,221 @@
|
||||
/*
|
||||
* Software License Agreement (BSD License)
|
||||
*
|
||||
* Copyright (c) 2011, Willow Garage, Inc.
|
||||
* Copyright (c) 2013, OSRF.
|
||||
* Copyright (c) 2013, Yujin Robot.
|
||||
*
|
||||
* All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of Willow Garage, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package com.github.rosjava.android_remocons.common_tools;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
import android.util.Patterns;
|
||||
|
||||
import com.github.rosjava.android_apps.application_management.AppManager;
|
||||
import com.github.rosjava.android_apps.application_management.ConcertDescription;
|
||||
import com.github.rosjava.android_apps.application_management.RosAppActivity;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
|
||||
/**
|
||||
* A rewrite of robot_remocon/AppLauncher that...
|
||||
* - works with concerts
|
||||
* - can start web apps
|
||||
* - headless; only reports error codes
|
||||
*
|
||||
* @author jorge@yujinrobot.com (Jorge Santos Simon)
|
||||
*/
|
||||
public class AppLauncher {
|
||||
|
||||
public enum Result {
|
||||
SUCCESS,
|
||||
NOT_INSTALLED,
|
||||
CANNOT_CONNECT,
|
||||
MALFORMED_URI,
|
||||
CONNECT_TIMEOUT,
|
||||
OTHER_ERROR;
|
||||
|
||||
public String message;
|
||||
|
||||
Result withMsg(String message) {
|
||||
this.message = message;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch a client app for the given concert app.
|
||||
*/
|
||||
static public Result launch(final Activity parent, final ConcertDescription concert,
|
||||
final concert_msgs.RemoconApp app) {
|
||||
|
||||
Log.i("AppLaunch", "launching concert app " + app.getDisplayName() + " on service " + app.getServiceName());
|
||||
|
||||
// On android apps, app name will be an intent action, while for web apps it will be its URL
|
||||
if (Patterns.WEB_URL.matcher(app.getName()).matches() == true) {
|
||||
return launchWebApp(parent, concert, app);
|
||||
}
|
||||
else {
|
||||
return launchAndroidApp(parent, concert, app);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Launch a client android app for the given concert app.
|
||||
*/
|
||||
static private Result launchAndroidApp(final Activity parent, final ConcertDescription concert,
|
||||
final concert_msgs.RemoconApp app) {
|
||||
|
||||
// Create the Intent from rapp's name, pass it parameters and remaps and start it
|
||||
String appName = app.getName();
|
||||
Intent intent = new Intent(appName);
|
||||
|
||||
// Copy all app data to "extra" data in the intent.
|
||||
intent.putExtra(AppManager.PACKAGE + "." + RosAppActivity.AppMode.CONCERT + "_app_name", appName);
|
||||
intent.putExtra(ConcertDescription.UNIQUE_KEY, concert);
|
||||
intent.putExtra("RemoconActivity", "com.github.rosjava.android_remocons.concert_remocon.ConcertRemocon"); // TODO must be a RoconConstant!
|
||||
intent.putExtra("Parameters", app.getParameters()); // YAML-formatted string
|
||||
|
||||
// Remappings come as a messages list that make YAML parser crash, so we must digest if for him
|
||||
if ((app.getRemappings() != null) && (app.getRemappings().size() > 0)) {
|
||||
String remaps = "{";
|
||||
for (rocon_std_msgs.Remapping remap: app.getRemappings())
|
||||
remaps += remap.getRemapFrom() + ": " + remap.getRemapTo() + ", ";
|
||||
remaps = remaps.substring(0, remaps.length() - 2) + "}";
|
||||
intent.putExtra("Remappings", remaps);
|
||||
}
|
||||
|
||||
// intent.putExtra("runningNodes", runningNodes);
|
||||
// intent.putExtra("PairedManagerActivity", "com.github.concertics_in_concert.rocon_android.concert_remocon.ConcertRemocon");
|
||||
|
||||
try {
|
||||
Log.i("AppLaunch", "trying to start activity (action: " + appName + " )");
|
||||
parent.startActivity(intent);
|
||||
return Result.SUCCESS;
|
||||
} catch (ActivityNotFoundException e) {
|
||||
Log.i("AppLaunch", "activity not found for action: " + appName);
|
||||
}
|
||||
return Result.NOT_INSTALLED.withMsg("Android app not installed");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Launch a client web app for the given concert app.
|
||||
*/
|
||||
static private Result launchWebApp(final Activity parent, final ConcertDescription concert,
|
||||
final concert_msgs.RemoconApp app) {
|
||||
try
|
||||
{
|
||||
// Validate the URL before starting anything
|
||||
URL appURL = new URL(app.getName());
|
||||
|
||||
AsyncTask<URL, Void, String> asyncTask = new AsyncTask<URL, Void, String>() {
|
||||
@Override
|
||||
protected String doInBackground(URL... urls) {
|
||||
try {
|
||||
HttpURLConnection urlConnection = (HttpURLConnection)urls[0].openConnection();
|
||||
int responseCode = urlConnection.getResponseCode();
|
||||
urlConnection.disconnect();
|
||||
return urlConnection.getResponseMessage();
|
||||
}
|
||||
catch (IOException e) {
|
||||
return e.getMessage();
|
||||
}
|
||||
}
|
||||
}.execute(appURL);
|
||||
String result = asyncTask.get(5, TimeUnit.SECONDS);
|
||||
if (result == null || (result.startsWith("OK") == false && result.startsWith("ok") == false)) {
|
||||
return Result.CANNOT_CONNECT.withMsg(result);
|
||||
}
|
||||
|
||||
// We pass concert URL, parameters and remaps as URL parameters
|
||||
String appUriStr = app.getName();
|
||||
appUriStr += "?" + "MasterURI=" + concert.getMasterUri();
|
||||
if ((app.getParameters() != null) && (app.getParameters().length() > 0)) {
|
||||
appUriStr += "&" + "params=" + URLEncoder.encode(app.getParameters());
|
||||
}
|
||||
|
||||
// Remappings come as a messages list that make YAML parser crash, so we must digest if for him
|
||||
// TODO Single quotes seem to be necessary, but I didn't confirm yet
|
||||
if ((app.getRemappings() != null) && (app.getRemappings().size() > 0)) {
|
||||
String remaps = "{";
|
||||
for (rocon_std_msgs.Remapping remap: app.getRemappings())
|
||||
remaps += "\'" + remap.getRemapFrom() + "\':\'" + remap.getRemapTo() + "\',";
|
||||
remaps = remaps.substring(0, remaps.length() - 1) + "}";
|
||||
appUriStr += "&" + "remaps=" + URLEncoder.encode(remaps);
|
||||
}
|
||||
|
||||
appURL = new URL(appUriStr);
|
||||
appURL.toURI(); // throws URISyntaxException if fails; probably a redundant check
|
||||
Uri appURI = Uri.parse(appUriStr);
|
||||
|
||||
// Create an action view intent and pass rapp's name + extra information as URI
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, appURI);
|
||||
|
||||
Log.i("AppLaunch", "trying to start web app (URI: " + appUriStr + ")");
|
||||
parent.startActivity(intent);
|
||||
return Result.SUCCESS;
|
||||
}
|
||||
catch (URISyntaxException e) {
|
||||
return Result.MALFORMED_URI.withMsg("Cannot convert URL into URI. " + e.getMessage());
|
||||
}
|
||||
catch (MalformedURLException e)
|
||||
{
|
||||
return Result.MALFORMED_URI.withMsg("App URL is not valid. " + e.getMessage());
|
||||
}
|
||||
catch (ActivityNotFoundException e) {
|
||||
// This cannot happen for a web site, right? must mean that I have no web browser!
|
||||
return Result.NOT_INSTALLED.withMsg("Activity not found for view action??? muoia???");
|
||||
}
|
||||
catch (TimeoutException e)
|
||||
{
|
||||
return Result.CONNECT_TIMEOUT.withMsg("Timeout waiting for app");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return Result.OTHER_ERROR.withMsg(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,371 @@
|
||||
/*
|
||||
* Copyright (C) 2013, OSRF.
|
||||
* Copyright (c) 2013, Yujin Robot.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.github.rosjava.android_remocons.common_tools;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
|
||||
import com.github.rosjava.android_apps.application_management.MasterId;
|
||||
|
||||
import org.ros.address.InetAddressFactory;
|
||||
import org.ros.android.NodeMainExecutorService;
|
||||
import org.ros.exception.RosRuntimeException;
|
||||
import org.ros.exception.ServiceNotFoundException;
|
||||
import org.ros.internal.node.client.ParameterClient;
|
||||
import org.ros.internal.node.server.NodeIdentifier;
|
||||
import org.ros.namespace.GraphName;
|
||||
import org.ros.node.AbstractNodeMain;
|
||||
import org.ros.node.ConnectedNode;
|
||||
import org.ros.node.Node;
|
||||
import org.ros.node.NodeConfiguration;
|
||||
import org.ros.node.service.ServiceClient;
|
||||
import org.ros.node.service.ServiceResponseListener;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import rocon_interaction_msgs.GetApp;
|
||||
import rocon_interaction_msgs.GetAppRequest;
|
||||
import rocon_interaction_msgs.GetAppResponse;
|
||||
import rocon_interaction_msgs.GetRolesAndApps;
|
||||
import rocon_interaction_msgs.GetRolesAndAppsRequest;
|
||||
import rocon_interaction_msgs.GetRolesAndAppsResponse;
|
||||
import rocon_interaction_msgs.RequestInteraction;
|
||||
import rocon_interaction_msgs.RequestInteractionRequest;
|
||||
import rocon_interaction_msgs.RequestInteractionResponse;
|
||||
|
||||
import static com.github.rosjava.android_remocons.common_tools.rocon.Constants.ANDROID_PLATFORM_INFO;
|
||||
|
||||
/**
|
||||
* This class has been derived from RobotAppsManager in android_apps/application_management.
|
||||
* The original is quite messy, and this is not much better, so maybe needs extra refactoring.
|
||||
* Also RobotAppsManager claims that it can be executed once, but I modified this to execute
|
||||
* arbitrary times. It looks to work, but mechanism is a bit brittle.
|
||||
* Apps manager implements the services and topics required to interact with the concert roles
|
||||
* manager. Typically to use this class its a three step process:
|
||||
*
|
||||
* 1) instantiate and provide a general failure handler
|
||||
* 2) provide a callback via one of the setupXXXservice methods
|
||||
* 3) call the service you want; there's a public method per service
|
||||
* 4) wait for service response.
|
||||
*
|
||||
* Essentially you are creating a node when creating an instance, and rosjava isolates each
|
||||
* service/topic to each 'node'.
|
||||
*
|
||||
* @author jorge@yujinrobot.com (Jorge Santos Simon)
|
||||
*/
|
||||
public class AppsManager extends AbstractNodeMain {
|
||||
public interface FailureHandler {
|
||||
/**
|
||||
* Called on failure with a short description of why it failed, like "exception" or "timeout".
|
||||
*/
|
||||
void handleFailure(String reason);
|
||||
}
|
||||
|
||||
// unique identifier to key string variables between activities.
|
||||
// TODO I make it compatible current apps; not needed if we rewrite as concert apps
|
||||
public static final String PACKAGE = com.github.rosjava.android_apps.application_management.AppManager.PACKAGE;
|
||||
|
||||
public enum Action {
|
||||
NONE, GET_APPS_FOR_ROLE, GET_APP_INFO, REQUEST_APP_USE
|
||||
};
|
||||
|
||||
private int app_hash;
|
||||
private String role;
|
||||
private Action action = Action.NONE;
|
||||
private rocon_interaction_msgs.RemoconApp app;
|
||||
private ConnectNodeThread connectThread;
|
||||
private ConnectedNode connectedNode;
|
||||
private NodeMainExecutorService nodeMainExecutorService;
|
||||
private FailureHandler failureCallback;
|
||||
private ServiceResponseListener<RequestInteractionResponse> requestServiceResponseListener;
|
||||
private ServiceResponseListener<GetRolesAndAppsResponse> getAppsServiceResponseListener;
|
||||
private ServiceResponseListener<GetAppResponse> appInfoServiceResponseListener;
|
||||
|
||||
|
||||
public AppsManager(FailureHandler failureCallback) {
|
||||
this.failureCallback = failureCallback;
|
||||
}
|
||||
|
||||
public void setupRequestService(ServiceResponseListener<RequestInteractionResponse> serviceResponseListener) {
|
||||
this.requestServiceResponseListener = serviceResponseListener;
|
||||
}
|
||||
|
||||
public void setupGetAppsService(ServiceResponseListener<GetRolesAndAppsResponse> serviceResponseListener) {
|
||||
this.getAppsServiceResponseListener = serviceResponseListener;
|
||||
}
|
||||
|
||||
public void setupAppInfoService(ServiceResponseListener<GetAppResponse> serviceResponseListener) {
|
||||
this.appInfoServiceResponseListener = serviceResponseListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
super.finalize();
|
||||
shutdown(); // TODO not warrantied to be called, so user should call shutdown; finalize works at all in Android??? I think no....
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
if (nodeMainExecutorService != null)
|
||||
nodeMainExecutorService.shutdownNodeMain(this);
|
||||
else
|
||||
Log.w("AppsMng", "Shutting down an uninitialized apps manager");
|
||||
}
|
||||
|
||||
public void getAppsForRole(final MasterId masterId, final String role) {
|
||||
this.action = Action.GET_APPS_FOR_ROLE;
|
||||
this.role = role;
|
||||
|
||||
// If this is the first action requested, we need a connected node, what must be done in a different thread
|
||||
// The requested action will be executed once we have a connected node (this object itself) in onStart method
|
||||
if (this.connectedNode == null) {
|
||||
Log.d("AppsMng", "First action requested (" + this.action + "). Starting node...");
|
||||
new ConnectNodeThread(masterId).start();
|
||||
}
|
||||
else {
|
||||
// But we don't need all this if we already executed an action, and so have a connected node. Anyway,
|
||||
// we must execute any action asynchronously to avoid the android.os.NetworkOnMainThreadException
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
getAppsForRole();
|
||||
return null;
|
||||
}
|
||||
}.execute(); // TODO: can we use this to incorporate a timeout to service calls?
|
||||
}
|
||||
}
|
||||
|
||||
public void requestAppUse(final MasterId masterId, final String role, final rocon_interaction_msgs.RemoconApp app) {
|
||||
this.action = Action.REQUEST_APP_USE;
|
||||
this.role = role;
|
||||
this.app = app;
|
||||
|
||||
// If this is the first action requested, we need a connected node, what must be done in a different thread
|
||||
// The requested action will be executed once we have a connected node (this object itself) in onStart method
|
||||
if (this.connectedNode == null) {
|
||||
Log.d("AppsMng", "First action requested (" + this.action + "). Starting node...");
|
||||
new ConnectNodeThread(masterId).start();
|
||||
}
|
||||
else {
|
||||
// But we don't need all this if we already executed an action, and so have a connected node. Anyway,
|
||||
// we must execute any action asynchronously to avoid the android.os.NetworkOnMainThreadException
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
requestAppUse();
|
||||
return null;
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
}
|
||||
|
||||
public void getAppInfo(final MasterId masterId, final int hash) {
|
||||
this.action = Action.GET_APP_INFO;
|
||||
this.app_hash = hash;
|
||||
|
||||
// If this is the first action requested, we need a connected node, what must be done in a different thread
|
||||
// The requested action will be executed once we have a connected node (this object itself) in onStart method
|
||||
if (this.connectedNode == null) {
|
||||
Log.d("AppsMng", "First action requested (" + this.action + "). Starting node...");
|
||||
new ConnectNodeThread(masterId).start();
|
||||
}
|
||||
else {
|
||||
// But we don't need all this if we already executed an action, and so have a connected node. Anyway,
|
||||
// we must execute any action asynchronously to avoid the android.os.NetworkOnMainThreadException
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
getAppInfo();
|
||||
return null;
|
||||
}
|
||||
}.execute(); // TODO: can we use this to incorporate a timeout to service calls?
|
||||
}
|
||||
}
|
||||
|
||||
private void getAppsForRole() {
|
||||
// call get_roles_and_apps concert service
|
||||
ServiceClient<GetRolesAndAppsRequest, GetRolesAndAppsResponse> srvClient;
|
||||
try {
|
||||
Log.d("AppsMng", "List apps service client created [" + GET_ROLES_AND_APPS_SRV + "]");
|
||||
srvClient = connectedNode.newServiceClient(GET_ROLES_AND_APPS_SRV, GetRolesAndApps._TYPE);
|
||||
} catch (ServiceNotFoundException e) {
|
||||
Log.w("AppsMng", "List apps service not found [" + GET_ROLES_AND_APPS_SRV + "]");
|
||||
throw new RosRuntimeException(e); // TODO we should recover from this calling onFailure on listener
|
||||
}
|
||||
final GetRolesAndAppsRequest request = srvClient.newMessage();
|
||||
|
||||
request.getRoles().add(role);
|
||||
request.setPlatformInfo(ANDROID_PLATFORM_INFO);
|
||||
|
||||
srvClient.call(request, getAppsServiceResponseListener);
|
||||
Log.d("AppsMng", "List apps service call done [" + GET_ROLES_AND_APPS_SRV + "]");
|
||||
}
|
||||
|
||||
private void requestAppUse() {
|
||||
// call request_interaction concert service
|
||||
ServiceClient<RequestInteractionRequest, RequestInteractionResponse> srvClient;
|
||||
try {
|
||||
Log.d("AppsMng", "Request app service client created [" + REQUEST_INTERACTION_SRV + "]");
|
||||
srvClient = connectedNode.newServiceClient(REQUEST_INTERACTION_SRV, RequestInteraction._TYPE);
|
||||
} catch (ServiceNotFoundException e) {
|
||||
Log.w("AppsMng", "Request app service not found [" + REQUEST_INTERACTION_SRV + "]");
|
||||
throw new RosRuntimeException(e); // TODO we should recover from this calling onFailure on listener
|
||||
}
|
||||
final RequestInteractionRequest request = srvClient.newMessage();
|
||||
|
||||
request.setRole(role);
|
||||
request.setApplication(app.getName());
|
||||
request.setServiceName(app.getServiceName());
|
||||
request.setPlatformInfo(ANDROID_PLATFORM_INFO);
|
||||
|
||||
srvClient.call(request, requestServiceResponseListener);
|
||||
Log.d("AppsMng", "Request app service call done [" + REQUEST_INTERACTION_SRV + "]");
|
||||
}
|
||||
|
||||
private void getAppInfo() {
|
||||
// call get_app concert service
|
||||
ServiceClient<GetAppRequest, GetAppResponse> srvClient;
|
||||
try {
|
||||
Log.d("AppsMng", "Get app info service client created [" + GET_APP_INFO_SRV + "]");
|
||||
srvClient = connectedNode.newServiceClient(GET_APP_INFO_SRV, GetApp._TYPE);
|
||||
} catch (ServiceNotFoundException e) {
|
||||
Log.w("AppsMng", "Get app info not found [" + GET_APP_INFO_SRV + "]");
|
||||
throw new RosRuntimeException(e); // TODO we should recover from this calling onFailure on listener
|
||||
}
|
||||
final GetAppRequest request = srvClient.newMessage();
|
||||
|
||||
request.setHash(app_hash);
|
||||
request.setPlatformInfo(ANDROID_PLATFORM_INFO);
|
||||
|
||||
srvClient.call(request, appInfoServiceResponseListener);
|
||||
Log.d("AppsMng", "Get app info service call done [" + GET_APP_INFO_SRV + "]");
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a thread to get a node connected with the given masterId. Returns immediately
|
||||
* TODO: what happens if the thread is already running??? kill it first and then start a new one?
|
||||
*/
|
||||
private class ConnectNodeThread extends Thread {
|
||||
private MasterId masterId;
|
||||
|
||||
public ConnectNodeThread(MasterId masterId) {
|
||||
this.masterId = masterId;
|
||||
setDaemon(true);
|
||||
setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
|
||||
@Override
|
||||
public void uncaughtException(Thread thread, Throwable ex) {
|
||||
failureCallback.handleFailure("exception: " + ex.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
URI concertUri = new URI(masterId.getMasterUri());
|
||||
|
||||
// Check if the concert exists by looking for concert name parameter
|
||||
// getParam throws when it can't find the parameter.
|
||||
ParameterClient paramClient = new ParameterClient(
|
||||
NodeIdentifier.forNameAndUri("/concert_checker", concertUri.toString()), concertUri);
|
||||
String name = (String) paramClient.getParam(GraphName.of(CONCERT_NAME_PARAM)).getResult();
|
||||
Log.i("ConcertRemocon", "Concert " + name + " found; retrieve additional information");
|
||||
|
||||
nodeMainExecutorService = new NodeMainExecutorService();
|
||||
NodeConfiguration nodeConfiguration = NodeConfiguration.newPublic(
|
||||
InetAddressFactory.newNonLoopback().getHostAddress(), concertUri);
|
||||
nodeMainExecutorService.execute(AppsManager.this, nodeConfiguration.setNodeName("apps_manager_node"));
|
||||
|
||||
} catch (URISyntaxException e) {
|
||||
Log.w("AppsMng", "invalid concert URI [" + masterId.getMasterUri() + "][" + e.toString() + "]");
|
||||
failureCallback.handleFailure("invalid concert URI");
|
||||
} catch (RuntimeException e) {
|
||||
// thrown if concert could not be found in the getParam call (from java.net.ConnectException)
|
||||
Log.w("AppsMng", "could not find concert [" + masterId.getMasterUri() + "][" + e.toString() + "]");
|
||||
failureCallback.handleFailure(e.toString());
|
||||
} catch (Throwable e) {
|
||||
Log.w("AppsMng", "exception while creating node in concert checker for URI " + masterId.getMasterUri(), e);
|
||||
failureCallback.handleFailure(e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphName getDefaultNodeName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Node started by NodeMainExecutor.execute(). Execute the requested action.
|
||||
*
|
||||
* @param connectedNode
|
||||
*/
|
||||
@Override
|
||||
public void onStart(final ConnectedNode connectedNode) {
|
||||
if (this.connectedNode != null) {
|
||||
Log.e("AppsMng", "App manager re-started before previous shutdown; ignoring...");
|
||||
return;
|
||||
}
|
||||
|
||||
this.connectedNode = connectedNode;
|
||||
|
||||
Log.d("AppsMng", "onStart() - " + action);
|
||||
|
||||
switch (action) {
|
||||
case NONE:
|
||||
Log.w("AppsMng", "Node started without specifying an action");
|
||||
break;
|
||||
case REQUEST_APP_USE:
|
||||
requestAppUse();
|
||||
break;
|
||||
case GET_APPS_FOR_ROLE:
|
||||
getAppsForRole();
|
||||
break;
|
||||
case GET_APP_INFO:
|
||||
getAppInfo();
|
||||
break;
|
||||
default:
|
||||
Log.w("AppsMng", "Unrecogniced action requested: " + action);
|
||||
}
|
||||
|
||||
Log.d("AppsMng", "Done");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShutdown(Node node) {
|
||||
Log.d("AppsMng", "Shutdown connected node...");
|
||||
super.onShutdown(node);
|
||||
|
||||
// Required so we get reconnected the next time
|
||||
this.connectedNode = null;
|
||||
Log.d("AppsMng", "Done; shutdown apps manager node main");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShutdownComplete(Node node) {
|
||||
super.onShutdownComplete(node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Node node, Throwable throwable) {
|
||||
super.onError(node, throwable);
|
||||
|
||||
Log.e("AppsMng", node.getName().toString() + " node error: " + throwable.getMessage());
|
||||
failureCallback.handleFailure(node.getName().toString() + " node error: " + throwable.toString());
|
||||
}
|
||||
}
|
@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Software License Agreement (BSD License)
|
||||
*
|
||||
* Copyright (c) 2011, Willow Garage, Inc.
|
||||
* Copyright (c) 2013, OSRF.
|
||||
* Copyright (c) 2013, Yujin Robot.
|
||||
*
|
||||
* All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of Willow Garage, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package com.github.rosjava.android_remocons.common_tools;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.github.rosjava.android_apps.application_management.ConcertDescription;
|
||||
import com.github.rosjava.android_apps.application_management.MasterId;
|
||||
|
||||
import org.ros.address.InetAddressFactory;
|
||||
import org.ros.android.NodeMainExecutorService;
|
||||
import org.ros.internal.node.client.ParameterClient;
|
||||
import org.ros.internal.node.server.NodeIdentifier;
|
||||
import org.ros.namespace.GraphName;
|
||||
import org.ros.node.NodeConfiguration;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Date;
|
||||
|
||||
import static com.github.rosjava.android_remocons.common_tools.RoconConstants.*;
|
||||
|
||||
/**
|
||||
* Threaded ROS-concert checker. Runs a thread which checks for a valid ROS
|
||||
* concert and sends back a {@link ConcertDescription} (with concert name and type)
|
||||
* on success or a failure reason on failure.
|
||||
*
|
||||
* @author hersh@willowgarage.com
|
||||
* @author murase@jsk.imi.i.u-tokyo.ac.jp (Kazuto Murase)
|
||||
* @author jorge@yujinrobot.com (Jorge Santos Simon)
|
||||
*/
|
||||
public class ConcertChecker {
|
||||
public interface ConcertDescriptionReceiver {
|
||||
/**
|
||||
* Called on success with a description of the concert that got checked.
|
||||
*/
|
||||
void receive(ConcertDescription concertDescription);
|
||||
}
|
||||
|
||||
public interface FailureHandler {
|
||||
/**
|
||||
* Called on failure with a short description of why it failed, like
|
||||
* "exception" or "timeout".
|
||||
*/
|
||||
void handleFailure(String reason);
|
||||
}
|
||||
|
||||
private CheckerThread checkerThread;
|
||||
private ConcertDescriptionReceiver foundConcertCallback;
|
||||
private FailureHandler failureCallback;
|
||||
|
||||
/**
|
||||
* Constructor. Should not take any time.
|
||||
*/
|
||||
public ConcertChecker(ConcertDescriptionReceiver foundConcertCallback, FailureHandler failureCallback) {
|
||||
this.foundConcertCallback = foundConcertCallback;
|
||||
this.failureCallback = failureCallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the checker thread with the given masterId. If the thread is
|
||||
* already running, kill it first and then start anew. Returns immediately.
|
||||
*/
|
||||
public void beginChecking(MasterId masterId) {
|
||||
stopChecking();
|
||||
if (masterId.getMasterUri() == null) {
|
||||
failureCallback.handleFailure("empty concert URI");
|
||||
return;
|
||||
}
|
||||
URI uri;
|
||||
try {
|
||||
uri = new URI(masterId.getMasterUri());
|
||||
} catch (URISyntaxException e) {
|
||||
failureCallback.handleFailure("invalid concert URI");
|
||||
return;
|
||||
}
|
||||
checkerThread = new CheckerThread(masterId, uri);
|
||||
checkerThread.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the checker thread.
|
||||
*/
|
||||
public void stopChecking() {
|
||||
if (checkerThread != null && checkerThread.isAlive()) {
|
||||
checkerThread.interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
private class CheckerThread extends Thread {
|
||||
private URI concertUri;
|
||||
private MasterId masterId;
|
||||
|
||||
public CheckerThread(MasterId masterId, URI concertUri) {
|
||||
this.concertUri = concertUri;
|
||||
this.masterId = masterId;
|
||||
setDaemon(true);
|
||||
// don't require callers to explicitly kill all the old checker threads.
|
||||
setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
|
||||
@Override
|
||||
public void uncaughtException(Thread thread, Throwable ex) {
|
||||
failureCallback.handleFailure("exception: " + ex.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
// Check if the concert exists by looking for concert name parameter
|
||||
// getParam throws when it can't find the parameter.
|
||||
ParameterClient paramClient = new ParameterClient(
|
||||
NodeIdentifier.forNameAndUri("/concert_checker", concertUri.toString()), concertUri);
|
||||
String name = (String) paramClient.getParam(GraphName.of(CONCERT_NAME_PARAM)).getResult();
|
||||
Log.i("ConcertRemocon", "Concert " + name + " found; retrieve additional information");
|
||||
|
||||
NodeMainExecutorService nodeMainExecutorService = new NodeMainExecutorService();
|
||||
NodeConfiguration nodeConfiguration = NodeConfiguration.newPublic(
|
||||
InetAddressFactory.newNonLoopback().getHostAddress(), concertUri);
|
||||
|
||||
// Check for the concert information topic
|
||||
ListenerNode<concert_msgs.ConcertInfo> readInfoTopic =
|
||||
new ListenerNode(CONCERT_INFO_TOPIC, concert_msgs.ConcertInfo._TYPE);
|
||||
nodeMainExecutorService.execute(readInfoTopic, nodeConfiguration.setNodeName("read_info_node"));
|
||||
readInfoTopic.waitForResponse();
|
||||
|
||||
|
||||
concert_msgs.ConcertInfo concertInfo = readInfoTopic.getLastMessage();
|
||||
|
||||
String concertName = concertInfo.getName();
|
||||
String concertDesc = concertInfo.getDescription();
|
||||
rocon_std_msgs.Icon concertIcon = concertInfo.getIcon();
|
||||
|
||||
if (name.equals(concertName) == false)
|
||||
Log.w("ConcertRemocon", "Concert names from parameter and topic differs; we use the later");
|
||||
|
||||
// Check for the concert roles topic
|
||||
ListenerNode<concert_msgs.Roles> readRolesTopic =
|
||||
new ListenerNode(CONCERT_ROLES_TOPIC, concert_msgs.Roles._TYPE);
|
||||
nodeMainExecutorService.execute(readRolesTopic, nodeConfiguration.setNodeName("concert_roles_node"));
|
||||
readRolesTopic.waitForResponse();
|
||||
|
||||
nodeMainExecutorService.shutdownNodeMain(readInfoTopic);
|
||||
nodeMainExecutorService.shutdownNodeMain(readRolesTopic);
|
||||
|
||||
// configure concert description
|
||||
Date timeLastSeen = new Date();
|
||||
ConcertDescription description = new ConcertDescription(masterId, concertName, concertDesc, concertIcon, timeLastSeen);
|
||||
Log.i("ConcertRemocon", "Concert is available");
|
||||
description.setConnectionStatus(ConcertDescription.OK);
|
||||
description.setUserRoles(readRolesTopic.getLastMessage());
|
||||
foundConcertCallback.receive(description);
|
||||
return;
|
||||
} catch (RuntimeException e) {
|
||||
// thrown if concert could not be found in the getParam call (from java.net.ConnectException)
|
||||
Log.w("ConcertRemocon", "could not find concert [" + concertUri + "][" + e.toString() + "]");
|
||||
failureCallback.handleFailure(e.toString());
|
||||
} catch (Throwable e) {
|
||||
Log.w("ConcertRemocon", "exception while creating node in concert checker for URI " + concertUri, e);
|
||||
failureCallback.handleFailure(e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
package com.github.rosjava.android_remocons.common_tools;
|
||||
|
||||
import org.ros.android.MessageCallable;
|
||||
import org.ros.exception.RosException;
|
||||
import org.ros.exception.RosRuntimeException;
|
||||
import org.ros.message.MessageListener;
|
||||
import org.ros.namespace.GraphName;
|
||||
import org.ros.node.AbstractNodeMain;
|
||||
import org.ros.node.ConnectedNode;
|
||||
import org.ros.node.topic.Subscriber;
|
||||
|
||||
|
||||
/**
|
||||
* Created by jorge on 10/30/13.
|
||||
*/
|
||||
public class ListenerNode<T> extends AbstractNodeMain
|
||||
{
|
||||
private String topicName;
|
||||
private String messageType;
|
||||
private T lastMessage;
|
||||
private MessageCallable<String, T> callable;
|
||||
|
||||
public ListenerNode(String topic, String type)
|
||||
{
|
||||
topicName = topic;
|
||||
messageType = type;
|
||||
}
|
||||
|
||||
public T getLastMessage()
|
||||
{
|
||||
return lastMessage;
|
||||
}
|
||||
|
||||
public void setTopicName(String topicName)
|
||||
{
|
||||
this.topicName = topicName;
|
||||
}
|
||||
|
||||
public void setMessageType(String messageType)
|
||||
{
|
||||
this.messageType = messageType;
|
||||
}
|
||||
|
||||
public void setMessageToStringCallable(MessageCallable<String, T> callable)
|
||||
{
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphName getDefaultNodeName() {
|
||||
return GraphName.of("get_" + topicName + "_node");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart(ConnectedNode connectedNode) {
|
||||
Subscriber<T> subscriber = connectedNode.newSubscriber(topicName, messageType);
|
||||
subscriber.addMessageListener(new MessageListener<T>() {
|
||||
@Override
|
||||
public void onNewMessage(final T message) {
|
||||
lastMessage = message;
|
||||
if (callable != null) {
|
||||
callable.call(message);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function to block until subscriber receives the first message.
|
||||
*
|
||||
* @throws org.ros.exception.RosException : when it times out waiting for the service.
|
||||
*/
|
||||
public void waitForResponse() throws RosException {
|
||||
int count = 0;
|
||||
while ( lastMessage == null ) {
|
||||
try {
|
||||
Thread.sleep(200);
|
||||
} catch (Exception e) {
|
||||
throw new RosRuntimeException(e);
|
||||
}
|
||||
if ( count == 20 ) { // timeout.
|
||||
throw new RosException("timed out waiting for topic messages");
|
||||
}
|
||||
count = count + 1;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,356 @@
|
||||
package com.github.rosjava.android_remocons.common_tools;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.IntentFilter.MalformedMimeTypeException;
|
||||
import android.nfc.FormatException;
|
||||
import android.nfc.NdefMessage;
|
||||
import android.nfc.NdefRecord;
|
||||
import android.nfc.NfcAdapter;
|
||||
import android.nfc.Tag;
|
||||
import android.nfc.TagLostException;
|
||||
import android.nfc.tech.IsoDep;
|
||||
import android.nfc.tech.MifareClassic;
|
||||
import android.nfc.tech.MifareUltralight;
|
||||
import android.nfc.tech.Ndef;
|
||||
import android.nfc.tech.NdefFormatable;
|
||||
import android.nfc.tech.NfcA;
|
||||
import android.nfc.tech.NfcB;
|
||||
import android.nfc.tech.NfcF;
|
||||
import android.nfc.tech.NfcV;
|
||||
import android.os.Parcelable;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Locale;
|
||||
|
||||
|
||||
public class NfcManager {
|
||||
|
||||
private Context mContext = null;
|
||||
private PendingIntent mPendingIntent = null;
|
||||
private IntentFilter[] mFilters;
|
||||
private String[][] mTechList;
|
||||
private Intent mPassedIntent = null;
|
||||
private NfcAdapter mNfcAdapter = null;
|
||||
private String mCurrentNdefString = "";
|
||||
|
||||
public NfcManager(Context context) {
|
||||
mContext = context;
|
||||
mNfcAdapter = NfcAdapter.getDefaultAdapter(mContext);
|
||||
|
||||
Intent targetIntent = new Intent(mContext, mContext.getClass());
|
||||
targetIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||
mPendingIntent = PendingIntent.getActivity(mContext, 0, targetIntent, 0);
|
||||
|
||||
IntentFilter filter_1 = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
|
||||
IntentFilter filter_2 = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED);
|
||||
IntentFilter filter_3 = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
|
||||
|
||||
try {
|
||||
filter_1.addDataType("*/*");
|
||||
filter_2.addDataType("*/*");
|
||||
filter_3.addDataType("*/*");
|
||||
} catch (MalformedMimeTypeException e) {
|
||||
throw new RuntimeException("fail", e);
|
||||
}
|
||||
|
||||
mFilters = new IntentFilter[]{filter_1, filter_2, filter_3};
|
||||
mTechList = new String[][]{new String[]{NfcF.class.getName()},
|
||||
new String[]{MifareClassic.class.getName()},
|
||||
new String[]{NfcA.class.getName()},
|
||||
new String[]{NfcB.class.getName()},
|
||||
new String[]{NfcV.class.getName()},
|
||||
new String[]{Ndef.class.getName()},
|
||||
new String[]{NdefFormatable.class.getName()},
|
||||
new String[]{MifareUltralight.class.getName()},
|
||||
new String[]{IsoDep.class.getName()}};
|
||||
}
|
||||
|
||||
public boolean checkNfcStatus() {
|
||||
return mNfcAdapter.isEnabled();
|
||||
}
|
||||
|
||||
public boolean changeNfcStatus(boolean enable) {
|
||||
|
||||
if (mNfcAdapter == null) return false;
|
||||
|
||||
boolean success = false;
|
||||
Class<?> nfcManagerClass = null;
|
||||
Method setNfcEnabled = null, setNfcDisabled = null;
|
||||
|
||||
if (enable) {
|
||||
try {
|
||||
nfcManagerClass = Class.forName(mNfcAdapter.getClass().getName());
|
||||
setNfcEnabled = nfcManagerClass.getDeclaredMethod("enable");
|
||||
setNfcEnabled.setAccessible(true);
|
||||
success = (Boolean) setNfcEnabled.invoke(mNfcAdapter);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
System.out.println(e.toString());
|
||||
}
|
||||
|
||||
} else {
|
||||
try {
|
||||
nfcManagerClass = Class.forName(mNfcAdapter.getClass().getName());
|
||||
setNfcDisabled = nfcManagerClass.getDeclaredMethod("disable");
|
||||
setNfcDisabled.setAccessible(true);
|
||||
success = (Boolean) setNfcDisabled.invoke(mNfcAdapter);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
public boolean enableForegroundDispatch() {
|
||||
if (mNfcAdapter != null) {
|
||||
mNfcAdapter.enableForegroundDispatch((Activity) mContext, mPendingIntent, mFilters, mTechList);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean disableForegroundDispatch() {
|
||||
|
||||
if (mNfcAdapter != null) {
|
||||
mNfcAdapter.disableForegroundDispatch((Activity) mContext);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean onNewIntent(Intent intent) {
|
||||
|
||||
mPassedIntent = intent;
|
||||
String action = mPassedIntent.getAction();
|
||||
|
||||
Toast.makeText(mContext, action, Toast.LENGTH_SHORT).show();
|
||||
|
||||
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action) ||
|
||||
NfcAdapter.ACTION_TECH_DISCOVERED.equals(action) ||
|
||||
NfcAdapter.ACTION_NDEF_DISCOVERED.equalsIgnoreCase(action))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public String processTag() {
|
||||
|
||||
if (mPassedIntent == null) return "NFC Tag is not discovered.";
|
||||
|
||||
Parcelable[] rawMsgs = mPassedIntent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
|
||||
|
||||
if (rawMsgs == null) {
|
||||
return "NDEF Message is null";
|
||||
}
|
||||
|
||||
mCurrentNdefString = "";
|
||||
|
||||
NdefMessage[] msgs = new NdefMessage[rawMsgs.length];
|
||||
|
||||
for (int i = 0; i < rawMsgs.length; i++) {
|
||||
msgs[i] = (NdefMessage) rawMsgs[i];
|
||||
mCurrentNdefString += ndefMessageToString(msgs[i]);
|
||||
}
|
||||
|
||||
return mCurrentNdefString;
|
||||
}
|
||||
|
||||
public String ndefMessageToString(NdefMessage message) {
|
||||
|
||||
String ndefString = "";
|
||||
NdefRecord[] ndef_records = message.getRecords();
|
||||
|
||||
ndefString += "**Num of NdefRecord : " + ndef_records.length + "\n";
|
||||
|
||||
for (int i = 0; i < ndef_records.length; i++) {
|
||||
String temp = "**Record No. " + i + "\n";
|
||||
byte[] type = ndef_records[i].getType();
|
||||
byte[] id = ndef_records[i].getId();
|
||||
byte[] pl = ndef_records[i].getPayload();
|
||||
byte[] arr = ndef_records[i].toByteArray();
|
||||
|
||||
temp = temp + "- TNF=" + ndef_records[i].getTnf() +
|
||||
"\n - TYPE=" + Util.getHexString(type, type.length) + " " + new String(type) +
|
||||
"\n - ID=" + Util.getHexString(id, id.length) + " " + new String(id) +
|
||||
"\n - PayLoad=" + Util.getHexString(pl, pl.length) + " " + new String(pl) +
|
||||
"\n - ByteArray=" + Util.getHexString(arr, arr.length) + " " + new String(arr) + "\n";
|
||||
|
||||
ndefString += temp;
|
||||
}
|
||||
|
||||
return ndefString;
|
||||
}
|
||||
|
||||
public byte[] getPayload() {
|
||||
|
||||
if (mPassedIntent == null)
|
||||
return null;
|
||||
|
||||
Parcelable[] rawMsgs = mPassedIntent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
|
||||
|
||||
if (rawMsgs == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
NdefMessage[] msgs = new NdefMessage[rawMsgs.length];
|
||||
|
||||
for (int i = 0; i < rawMsgs.length; i++) {
|
||||
msgs[i] = (NdefMessage) rawMsgs[i];
|
||||
}
|
||||
|
||||
NdefRecord[] records = msgs[0].getRecords();
|
||||
if (records.length > 0)
|
||||
return records[0].getPayload();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private NdefRecord createTextRecord(String text, Locale locale, boolean encodeInUtf8) {
|
||||
|
||||
final byte[] langBytes = locale.getLanguage().getBytes(Charset.forName("US-ASCII"));
|
||||
final Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset.forName("UTF-16");
|
||||
final byte[] textBytes = text.getBytes(utfEncoding);
|
||||
final int utfBit = encodeInUtf8 ? 0 : (1 << 7);
|
||||
final char status = (char) (utfBit + langBytes.length);
|
||||
final byte[] data = Util.concat(new byte[]{(byte) status}, langBytes, textBytes);
|
||||
|
||||
return new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], data);
|
||||
}
|
||||
|
||||
public boolean writeTextNdefMessage(String payload, boolean isAAR) {
|
||||
NdefRecord record = createTextRecord(payload, Locale.KOREAN, true);
|
||||
NdefMessage msg = null;
|
||||
if (isAAR)
|
||||
msg = new NdefMessage(new NdefRecord[]{record, NdefRecord.createApplicationRecord(mContext.getPackageName())});
|
||||
else
|
||||
msg = new NdefMessage(new NdefRecord[]{record});
|
||||
|
||||
return writeNdefMessage(msg);
|
||||
}
|
||||
|
||||
public boolean writeTextNdefMessage(byte[] payload, String AAR) {
|
||||
final byte[] langBytes = Locale.KOREAN.getLanguage().getBytes(Charset.forName("US-ASCII"));
|
||||
final Charset utfEncoding = Charset.forName("UTF-8");
|
||||
final int utfBit = 0;
|
||||
final char status = (char) (utfBit + langBytes.length);
|
||||
final byte[] data = Util.concat(new byte[]{(byte) status}, langBytes, payload);
|
||||
|
||||
NdefRecord record = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], data);
|
||||
NdefMessage msg = null;
|
||||
if (AAR != null)
|
||||
msg = new NdefMessage(new NdefRecord[]{record, NdefRecord.createApplicationRecord(AAR)});
|
||||
else
|
||||
msg = new NdefMessage(new NdefRecord[]{record});
|
||||
|
||||
return writeNdefMessage(msg);
|
||||
}
|
||||
|
||||
public boolean writeUriNdefMessage(String payload, String AAR) {
|
||||
|
||||
NdefRecord record = new NdefRecord(NdefRecord.TNF_ABSOLUTE_URI,
|
||||
NdefRecord.RTD_URI, new byte[0], payload.getBytes());
|
||||
NdefMessage msg = null;
|
||||
if (AAR != null)
|
||||
msg = new NdefMessage(new NdefRecord[]{record, NdefRecord.createApplicationRecord(AAR)});
|
||||
else
|
||||
msg = new NdefMessage(new NdefRecord[]{record});
|
||||
|
||||
return writeNdefMessage(msg);
|
||||
}
|
||||
|
||||
public boolean writeMimeNdefMessage(String payload, String AAR) {
|
||||
|
||||
NdefRecord record = new NdefRecord(NdefRecord.TNF_MIME_MEDIA,
|
||||
("application/" + mContext.getPackageName()).getBytes(), new byte[0], payload.getBytes());
|
||||
NdefMessage msg = null;
|
||||
if (AAR != null)
|
||||
msg = new NdefMessage(new NdefRecord[]{record, NdefRecord.createApplicationRecord(AAR)});
|
||||
else
|
||||
msg = new NdefMessage(new NdefRecord[]{record});
|
||||
|
||||
return writeNdefMessage(msg);
|
||||
}
|
||||
|
||||
// This needs API 16 and we will not use it by now, so commented
|
||||
// public boolean writeCustomNdefMessage(String payload, String AAR) {
|
||||
//
|
||||
// NdefRecord record = NdefRecord.createExternal("Yujin Robot", "Cafe demo", payload.getBytes());
|
||||
// NdefMessage msg = null ;
|
||||
// if (AAR != null)
|
||||
// msg = new NdefMessage(new NdefRecord[] {record, NdefRecord.createApplicationRecord(AAR)});
|
||||
// else
|
||||
// msg = new NdefMessage(new NdefRecord[] {record});
|
||||
//
|
||||
// return writeNdefMessage(msg);
|
||||
// }
|
||||
|
||||
public boolean writeNdefMessage(NdefMessage message) {
|
||||
|
||||
if (mPassedIntent == null) return false;
|
||||
|
||||
Tag tag = mPassedIntent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
|
||||
Ndef ndefTag = Ndef.get(tag);
|
||||
|
||||
try {
|
||||
ndefTag.connect();
|
||||
} catch (IOException e) {
|
||||
Log.e("NfcWriter", "Connect to tag failed. " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
ndefTag.writeNdefMessage(message);
|
||||
} catch (TagLostException e) {
|
||||
Log.e("NfcWriter", "The tag left the field. " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
} catch (IOException e) {
|
||||
Log.e("NfcWriter", "Message writing failure. " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
} catch (FormatException e) {
|
||||
Log.e("NfcWriter", "Malformed NDEF message. " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
ndefTag.close();
|
||||
} catch (IOException e) {
|
||||
Log.e("NfcWriter", "Close tag failed. " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="com.github.rosjava.android_remocons.common_tools"
|
||||
>
|
||||
</manifest>
|