@ -0,0 +1,14 @@
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/caches
|
||||
/.idea/libraries
|
||||
/.idea/modules.xml
|
||||
/.idea/workspace.xml
|
||||
/.idea/navEditor.xml
|
||||
/.idea/assetWizardSettings.xml
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
.externalNativeBuild
|
||||
.cxx
|
@ -0,0 +1 @@
|
||||
luyin
|
@ -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,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<bytecodeTargetLevel target="1.8" />
|
||||
</component>
|
||||
</project>
|
@ -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="false" />
|
||||
<value-preview-pinned value="false" />
|
||||
</component>
|
||||
<component name="DBNavigator.Project.DataExportManager">
|
||||
<export-instructions>
|
||||
<create-header value="true" />
|
||||
<friendly-headers value="false" />
|
||||
<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.ExecutionManager">
|
||||
<retain-sticky-names value="false" />
|
||||
</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="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="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,23 @@
|
||||
<?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="disableWrapperSourceDistributionNotification" value="true" />
|
||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="gradleJvm" value="1.8" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
<option value="$PROJECT_DIR$/app" />
|
||||
</set>
|
||||
</option>
|
||||
<option name="resolveModulePerSourceSet" value="false" />
|
||||
<option name="useQualifiedModuleNames" value="true" />
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,35 @@
|
||||
<?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="maven2" />
|
||||
<option name="name" value="maven2" />
|
||||
<option name="url" value="https://raw.github.com/bmob/bmob-android-sdk/master" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="maven" />
|
||||
<option name="name" value="maven" />
|
||||
<option name="url" value="https://dl.bintray.com/chaozhouzhang/maven" />
|
||||
</remote-repository>
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" 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="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,56 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 30
|
||||
buildToolsVersion "30.0.3"
|
||||
|
||||
useLibrary 'org.apache.http.legacy'
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
defaultConfig {
|
||||
applicationId "com.example.luyin"
|
||||
minSdkVersion 23
|
||||
targetSdkVersion 30
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: "libs", include: ["*.jar"])
|
||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
|
||||
implementation files('src/main/jniLibs/Msc.jar')
|
||||
compileOnly files('src/main/jniLibs/Android_Map3D_SDK_V7.8.0_20201231.jar')
|
||||
compileOnly files('src/main/jniLibs/AMap_Location_V5.2.0_20200915.jar')
|
||||
implementation files('src/main/jniLibs/AMap_Search_V7.7.0_20201027.jar')
|
||||
compileOnly files('src/main/jniLibs/android-support-v4.jar')
|
||||
testImplementation 'junit:junit:4.12'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
|
||||
|
||||
implementation 'cn.bmob.android:bmob-sdk:3.7.8'
|
||||
implementation "io.reactivex.rxjava2:rxjava:2.2.8"
|
||||
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
|
||||
implementation 'com.squareup.okhttp3:okhttp:3.14.1'
|
||||
implementation 'com.squareup.okio:okio:2.2.2'
|
||||
implementation 'com.google.code.gson:gson:2.8.5'
|
||||
|
||||
implementation 'com.amap.api:location:latest.integration'
|
||||
|
||||
implementation 'com.yayandroid:LocationManager:2.0.4'
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# 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 *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
@ -0,0 +1,26 @@
|
||||
package com.example.luyin;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Instrumented 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() {
|
||||
// Context of the app under test.
|
||||
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
|
||||
assertEquals("com.example.luyin", appContext.getPackageName());
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 58 KiB |
@ -0,0 +1,54 @@
|
||||
package com.example.luyin.activities;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Toast;
|
||||
import com.example.luyin.services.EmergencyPeople;
|
||||
import com.example.luyin.R;
|
||||
import cn.bmob.v3.exception.BmobException;
|
||||
import cn.bmob.v3.listener.SaveListener;
|
||||
|
||||
public class Contact extends Activity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_contact);
|
||||
//Toast.makeText(Contact.this, "短信发送完成", Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
public void confirm(View view){
|
||||
EditText phoneNumber1=(EditText)findViewById(R.id.phonenumber);
|
||||
String phoneNumber2=phoneNumber1.getText().toString();
|
||||
EmergencyPeople people = new EmergencyPeople();
|
||||
people.setPhoneNumber(phoneNumber2);
|
||||
EditText name1=(EditText)findViewById(R.id.contact);
|
||||
String name2=name1.getText().toString();
|
||||
EmergencyPeople people1 = new EmergencyPeople();
|
||||
people1.setPhoneNumber(phoneNumber2);
|
||||
people1.setName(name2);
|
||||
Log.e("ss", "confirm: "+ people1.getName() );
|
||||
Log.e("bb", "confirm: "+people1.getPhoneNumber());
|
||||
people1.save(new SaveListener<String>() {
|
||||
@Override
|
||||
public void done(String s, BmobException e) {
|
||||
if(e==null){
|
||||
Toast.makeText(getApplicationContext(),"添加联系人成功",Toast.LENGTH_LONG).show();
|
||||
}else{
|
||||
Toast.makeText(getApplicationContext(),"添加失败",Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
});
|
||||
// Toast.makeText(Contact.this, "已添加紧急联系人",Toast.LENGTH_SHORT).show();
|
||||
|
||||
Intent intent = new Intent(Contact.this,MainActivity.class);
|
||||
startActivity(intent);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package com.example.luyin.activities;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Application;
|
||||
import android.os.Bundle;
|
||||
|
||||
|
||||
public class MyApplication extends Application {
|
||||
private int count = 0;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
|
||||
@Override
|
||||
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityStarted(Activity activity) {
|
||||
count ++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResumed(Activity activity) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityPaused(Activity activity) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityStopped(Activity activity) {
|
||||
if(count > 0) {
|
||||
count--;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityDestroyed(Activity activity) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断app是否在后台
|
||||
* @return
|
||||
*/
|
||||
public boolean isBackground(){
|
||||
if(count <= 0){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
package com.example.luyin.activities;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.telephony.SmsManager;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.example.luyin.R;
|
||||
|
||||
public class SMS extends Activity {
|
||||
|
||||
private EditText mNumberText;
|
||||
private EditText mContentText;
|
||||
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setTitle(getString(R.string.app_name));
|
||||
setContentView(R.layout.activity_sms);
|
||||
|
||||
mNumberText = (EditText)this.findViewById(R.id.number);//找到number
|
||||
mContentText = (EditText)this.findViewById(R.id.msg_content);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void SEND(View view) {
|
||||
|
||||
|
||||
//String content = mContentText.getText().toString();
|
||||
//String number = mNumberText.getText().toString();
|
||||
String content = "尼玛1111111111111111";
|
||||
String number = "18577348433";
|
||||
|
||||
if(TextUtils.isEmpty(number)){
|
||||
showToast("请输入手机号");
|
||||
return;
|
||||
}
|
||||
if(TextUtils.isEmpty(content)){
|
||||
showToast("请输入内容");
|
||||
return;
|
||||
}
|
||||
|
||||
ArrayList<String> messages = SmsManager.getDefault().divideMessage(content);
|
||||
for(String text : messages){
|
||||
SmsManager.getDefault().sendTextMessage(number, null, text, null, null);
|
||||
}
|
||||
showToast("success");
|
||||
}
|
||||
|
||||
private void showToast(String msg) {
|
||||
Toast.makeText(SMS.this, msg, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,155 @@
|
||||
package com.example.luyin.activities;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.ListView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.core.app.ActivityCompat;
|
||||
|
||||
import com.example.luyin.R;
|
||||
import com.example.luyin.activities.TtsDemo;
|
||||
import com.iflytek.cloud.SpeechConstant;
|
||||
import com.iflytek.cloud.SpeechUtility;
|
||||
|
||||
|
||||
public class VoiceActivity extends Activity implements OnClickListener{
|
||||
|
||||
private Toast mToast;
|
||||
@SuppressLint("ShowToast")
|
||||
public void onCreate(Bundle savedInstanceState){
|
||||
super.onCreate(savedInstanceState);
|
||||
// 设置标题栏(无标题)
|
||||
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
setContentView(R.layout.main);
|
||||
requestPermissions();
|
||||
mToast = Toast.makeText(this,"",Toast.LENGTH_SHORT);
|
||||
SimpleAdapter listitemAdapter = new SimpleAdapter();
|
||||
((ListView)findViewById(R.id.listview_main)).setAdapter(listitemAdapter);
|
||||
|
||||
StringBuffer param = new StringBuffer();
|
||||
param.append("appid="+getString(R.string.app_id));
|
||||
param.append(",");
|
||||
// 设置使用v5+
|
||||
param.append(SpeechConstant.ENGINE_MODE+"="+ SpeechConstant.MODE_MSC);
|
||||
SpeechUtility.createUtility(VoiceActivity.this, param.toString());
|
||||
}
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
int tag = Integer.parseInt(view.getTag().toString());
|
||||
Intent intent = null;
|
||||
switch (tag) {
|
||||
case 0:
|
||||
// 语音听写
|
||||
showTip("这个功能写不出来!");
|
||||
break;
|
||||
case 1:
|
||||
// 语法识别
|
||||
showTip("这个功能写不出来!");
|
||||
break;
|
||||
case 2:
|
||||
// 语义理解
|
||||
showTip("这个功能写不出来!");
|
||||
break;
|
||||
case 3 :
|
||||
case 4:
|
||||
// 合成(包括增强版)
|
||||
intent = new Intent(this, TtsDemo.class);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
// 唤醒
|
||||
showTip("这个功能写不出来!");
|
||||
break;
|
||||
case 6:
|
||||
// 声纹
|
||||
showTip("这个功能写不出来!");
|
||||
break;
|
||||
default:
|
||||
showTip("这个功能写不出来!");
|
||||
break;
|
||||
}
|
||||
if (intent != null) {
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Menu 列表
|
||||
String items[] = {"立刻体验语音听写","立刻体验语法识别","立刻体验语义理解","立刻体验语音合成","立即体验增强版语音合成","立刻体验语音唤醒","立刻体验声纹密码"};
|
||||
private class SimpleAdapter extends BaseAdapter{
|
||||
public View getView(int position, View convertView, ViewGroup parent)
|
||||
{
|
||||
if(null == convertView){
|
||||
LayoutInflater factory = LayoutInflater.from(VoiceActivity.this);
|
||||
View mView = factory.inflate(R.layout.list_items, null);
|
||||
convertView = mView;
|
||||
}
|
||||
Button btn = (Button)convertView.findViewById(R.id.btn);
|
||||
btn.setOnClickListener(VoiceActivity.this);
|
||||
btn.setTag(position);
|
||||
btn.setText(items[position]);
|
||||
return convertView;
|
||||
}
|
||||
@Override
|
||||
public int getCount() {
|
||||
return items.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getItem(int position) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
private void showTip(final String str)
|
||||
{
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mToast.setText(str);
|
||||
mToast.show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void requestPermissions(){
|
||||
try {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
int permission = ActivityCompat.checkSelfPermission(this,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
||||
if(permission!= PackageManager.PERMISSION_GRANTED) {
|
||||
ActivityCompat.requestPermissions(this,new String[] {
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||
Manifest.permission.LOCATION_HARDWARE,Manifest.permission.READ_PHONE_STATE,
|
||||
Manifest.permission.WRITE_SETTINGS,Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||
Manifest.permission.RECORD_AUDIO,Manifest.permission.READ_CONTACTS},0x0010);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
}
|
||||
}
|
@ -0,0 +1,426 @@
|
||||
package com.example.luyin.activities;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import android.accessibilityservice.AccessibilityService;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.os.Bundle;
|
||||
import android.os.Vibrator;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
import android.widget.Adapter;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.Switch;
|
||||
import android.widget.TextView;
|
||||
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.example.luyin.wechat.Constants;
|
||||
import com.example.luyin.R;
|
||||
import com.example.luyin.wechat.service.utils.SendMessage;
|
||||
import com.example.luyin.wechat.service.RedEnvelopeService;
|
||||
import com.example.luyin.wechat.utils.AccessibilityUtil;
|
||||
import com.example.luyin.wechat.utils.AppUtil;
|
||||
|
||||
import java.util.Calendar;
|
||||
|
||||
public class Wechat extends AppCompatActivity implements View.OnClickListener, AdapterView.OnItemSelectedListener, SensorEventListener {
|
||||
public static Context AppContext;
|
||||
public static Context WeChatContext;
|
||||
public static int Width;
|
||||
public static int Height;
|
||||
private static AccessibilityService CurrentService;
|
||||
public long lastTime = 0;
|
||||
public long timeDifference = 1000;
|
||||
|
||||
private Switch OpenService;
|
||||
private Switch AutoWeChat;
|
||||
private Switch AutoSendMsg;
|
||||
private LinearLayout SendMsgDetail;
|
||||
private TextView VersionView;
|
||||
|
||||
|
||||
private EditText ToWho;
|
||||
private EditText WhatMsg;
|
||||
private Button SendMsgBtn;
|
||||
|
||||
private Button InitFriend;
|
||||
//下拉列表
|
||||
private Spinner FriendList;
|
||||
//传感器
|
||||
private SensorManager sensorManager;
|
||||
//震动
|
||||
private Vibrator mVibrator;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.autowechat);
|
||||
init();
|
||||
initWeChatVersion();
|
||||
|
||||
// if(OpenService.isChecked()){
|
||||
// System.out.println("click");
|
||||
// SendMessage.NAME = ToWho.getText().toString();
|
||||
// SendMessage.CONTENT = WhatMsg.getText().toString();
|
||||
// Constants.CurrentTask = Constants.AutoSendMsgType;
|
||||
// gotoWeChat();
|
||||
// } else{
|
||||
// AppUtil.makeToast("请先打开辅助功能");
|
||||
// openAccessibility();
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
freshOpenServiceSwitch(RedEnvelopeService.class, OpenService);
|
||||
initList();
|
||||
}
|
||||
|
||||
private void initWeChatVersion(){
|
||||
Context weChat = AppUtil.getContext(this, Constants.WeChatInfo.WECHAT_PACKAGE);
|
||||
WeChatContext = weChat;
|
||||
if(weChat != null){
|
||||
String weChatVersion = AppUtil.getAppVersion(weChat);
|
||||
System.out.println(weChatVersion);
|
||||
Constants.setArgs(weChatVersion);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void init(){
|
||||
AppContext = this;
|
||||
initScreen();
|
||||
//initVersion();
|
||||
SendMsgDetail = findViewById(R.id.send_msg_detail);
|
||||
SendMsgDetail.clearAnimation();
|
||||
OpenService = findViewById(R.id.open_accessibility);
|
||||
setOpenServiceListener(RedEnvelopeService.class, OpenService);
|
||||
// AutoWeChat = findViewById(R.id.open_we_chat);
|
||||
// setSwitchListener(AutoWeChat);
|
||||
AutoSendMsg = findViewById(R.id.auto_send_msg);
|
||||
setSwitchListener(AutoSendMsg);
|
||||
//freshOpenServiceSwitch(RedEnvelopeService.class, OpenService);
|
||||
|
||||
ToWho = findViewById(R.id.send_name);
|
||||
WhatMsg = findViewById(R.id.send_msg);
|
||||
SendMsgBtn = findViewById(R.id.send_WeChat);
|
||||
SendMsgBtn.setOnClickListener(this);
|
||||
|
||||
InitFriend = findViewById(R.id.init_friend_btn);
|
||||
InitFriend.setOnClickListener(this);
|
||||
FriendList = findViewById(R.id.friend_list);
|
||||
|
||||
sensorManager=(SensorManager) getSystemService(SENSOR_SERVICE);
|
||||
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
|
||||
SensorManager.SENSOR_DELAY_UI);
|
||||
|
||||
mVibrator=(Vibrator) getSystemService(VIBRATOR_SERVICE);
|
||||
}
|
||||
@Override
|
||||
public void onSensorChanged(SensorEvent event) {
|
||||
|
||||
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
|
||||
if (Math.abs(event.values[0]) > 20|| Math.abs(event.values[1]) > 20 || Math.abs(event.values[2]) > 20) {
|
||||
long currentTime = Calendar.getInstance().getTimeInMillis();
|
||||
if (currentTime - lastTime > timeDifference) {
|
||||
lastTime = currentTime;
|
||||
//mVibrator.vibrate(100);
|
||||
//callPhone(phonenum);
|
||||
Toast.makeText(Wechat.this,"123",Toast.LENGTH_LONG).show();
|
||||
if(OpenService.isChecked()){
|
||||
System.out.println("click");
|
||||
SendMessage.NAME = ToWho.getText().toString();
|
||||
SendMessage.CONTENT = WhatMsg.getText().toString();
|
||||
Constants.CurrentTask = Constants.AutoSendMsgType;
|
||||
gotoWeChat();
|
||||
} else{
|
||||
AppUtil.makeToast("请先打开辅助功能");
|
||||
openAccessibility();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
switch (v.getId()){
|
||||
case R.id.send_WeChat:
|
||||
if(OpenService.isChecked()){
|
||||
System.out.println("click");
|
||||
SendMessage.NAME = ToWho.getText().toString();
|
||||
SendMessage.CONTENT = WhatMsg.getText().toString();
|
||||
Constants.CurrentTask = Constants.AutoSendMsgType;
|
||||
gotoWeChat();
|
||||
} else{
|
||||
AppUtil.makeToast("请先打开辅助功能");
|
||||
openAccessibility();
|
||||
}
|
||||
break;
|
||||
case R.id.init_friend_btn:
|
||||
if(OpenService.isChecked()){
|
||||
Constants.CurrentTask = Constants.InitFriendList;
|
||||
gotoWeChat();
|
||||
}else {
|
||||
AppUtil.makeToast("请先打开辅助功能");
|
||||
openAccessibility();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void gotoWeChat(){
|
||||
Intent intent = new Intent();
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
intent.setClassName(Constants.WeChatInfo.WECHAT_PACKAGE, Constants.WeChatInfo.WECHAT_LAUNCHER_UI);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
public static void performHome(AccessibilityService service) {
|
||||
if (service == null) {
|
||||
return;
|
||||
}
|
||||
service.performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);
|
||||
}
|
||||
|
||||
|
||||
private void initList(){
|
||||
if(Constants.FriendList == null) return;
|
||||
System.out.println(Constants.FriendList);
|
||||
FriendList.setAdapter(new ArrayAdapter<>(this, R.layout.spinner_item, Constants.FriendList));
|
||||
FriendList.setOnItemSelectedListener(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
System.out.println(Constants.FriendList.get(position));
|
||||
ToWho.setText(Constants.FriendList.get(position));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
|
||||
}
|
||||
|
||||
private void setOpenServiceListener(final Class clazz, Switch s){
|
||||
s.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
Log.i(Constants.TAG, "onCheckedChanged: " + isChecked);
|
||||
if(isChecked){
|
||||
if(!isAccessibilitySettingOn(clazz.getCanonicalName(), AppContext)){
|
||||
openAccessibility();
|
||||
}
|
||||
}else {
|
||||
if(isAccessibilitySettingOn(clazz.getCanonicalName(), AppContext)){
|
||||
openAccessibility();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setSwitchListener(final Switch s){
|
||||
s.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
if(isChecked){
|
||||
freshSwitch(s);
|
||||
}else {
|
||||
freshSwitch(s);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// private void initVersion(){
|
||||
// VersionView = findViewById(R.id.app_version);
|
||||
// String version = AppUtil.getAppVersion(this);
|
||||
// VersionView.setText(version);
|
||||
// }
|
||||
//重置服务按钮
|
||||
private void freshOpenServiceSwitch(Class clazz, Switch s){
|
||||
if(isAccessibilitySettingOn(clazz.getCanonicalName(), Wechat.this)){
|
||||
s.setChecked(true);
|
||||
switch (s.getId()){
|
||||
case R.id.open_accessibility:
|
||||
//freshSwitch(AutoWeChat);
|
||||
freshSwitch(AutoSendMsg);
|
||||
}
|
||||
}else {
|
||||
s.setChecked(false);
|
||||
switch (s.getId()){
|
||||
case R.id.open_accessibility:
|
||||
AutoSendMsg.setChecked(true);
|
||||
//AutoWeChat.setChecked(false);
|
||||
}
|
||||
}
|
||||
SendMsgDetail.setVisibility(View.VISIBLE);
|
||||
}
|
||||
//点击自动发送消息按钮,弹出详细发送界面,需要先点击开启辅助功能,否则打不开
|
||||
private void freshSwitch(Switch s){
|
||||
//if(OpenService.isChecked()) {
|
||||
if(Constants.CurrentTask == Constants.InitFriendList){
|
||||
Constants.CurrentTask = -1;
|
||||
}
|
||||
switch (s.getId()){
|
||||
// case R.id.open_we_chat:
|
||||
// if(s.isChecked()){
|
||||
// if(Constants.IsOver){
|
||||
// s.setChecked(false);
|
||||
// Constants.IsOver = false;
|
||||
// break;
|
||||
// }else if(AutoSendMsg.isChecked()){
|
||||
// AutoSendMsg.setChecked(false);
|
||||
// SendMsgDetail.setVisibility(View.GONE);
|
||||
// }
|
||||
// Constants.CurrentTask = Constants.RedEnvelopeType;
|
||||
// }else {
|
||||
// Constants.CurrentTask = -1;
|
||||
// }
|
||||
// break;
|
||||
case R.id.auto_send_msg:
|
||||
//if(OpenService.isChecked()) {
|
||||
if (s.isChecked()) {
|
||||
if (Constants.IsOver) {
|
||||
s.setChecked(false);
|
||||
Constants.IsOver = false;
|
||||
break;
|
||||
}
|
||||
//}else if(AutoWeChat.isChecked()){
|
||||
//AutoWeChat.setChecked(false);
|
||||
//}
|
||||
if (s.isChecked()) {
|
||||
SendMsgDetail.setVisibility(View.VISIBLE);
|
||||
}
|
||||
} else {
|
||||
SendMsgDetail.setVisibility(View.GONE);
|
||||
Constants.CurrentTask = -1;
|
||||
}
|
||||
// }
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// }else {
|
||||
// AppUtil.makeToast("请先打开辅助功能");
|
||||
// // s.setChecked(false);
|
||||
// }
|
||||
}
|
||||
|
||||
private boolean isAccessibilitySettingOn(String accessibilityServiceName, Context context){
|
||||
int enable = 0;
|
||||
String serviceName = context.getPackageName() + "/" + accessibilityServiceName;
|
||||
Log.i(Constants.TAG, "isAccessibilitySettingOn: " + serviceName);
|
||||
try {
|
||||
enable = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.ACCESSIBILITY_ENABLED, 0);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if(enable == 1){
|
||||
TextUtils.SimpleStringSplitter stringSplitter = new TextUtils.SimpleStringSplitter(':');
|
||||
String settingVal = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
|
||||
if(settingVal != null){
|
||||
stringSplitter.setString(settingVal);
|
||||
while(stringSplitter.hasNext()){
|
||||
String accessibilityService = stringSplitter.next();
|
||||
if(accessibilityService.equals(serviceName)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//打开系统设置
|
||||
private void openAccessibility(){
|
||||
DialogInterface.OnClickListener clickListener = new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
|
||||
startActivity(intent);
|
||||
}
|
||||
};
|
||||
DialogInterface.OnClickListener cancelListener = new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
freshOpenServiceSwitch(RedEnvelopeService.class, OpenService);
|
||||
}
|
||||
};
|
||||
DialogInterface.OnCancelListener cancel = new DialogInterface.OnCancelListener() {
|
||||
@Override
|
||||
public void onCancel(DialogInterface dialog) {
|
||||
freshOpenServiceSwitch(RedEnvelopeService.class, OpenService);
|
||||
}
|
||||
};
|
||||
AlertDialog dialog = new AlertDialog.Builder(this)
|
||||
.setMessage(R.string.tips)
|
||||
.setOnCancelListener(cancel)
|
||||
.setNegativeButton("取消", cancelListener)
|
||||
.setPositiveButton("确定", clickListener)
|
||||
.create();
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
private void initScreen(){
|
||||
WindowManager manager = this.getWindowManager();
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
manager.getDefaultDisplay().getMetrics(metrics);
|
||||
Width = metrics.widthPixels;
|
||||
Height = metrics.heightPixels;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
// if(keyCode == KeyEvent.KEYCODE_BACK){
|
||||
// moveTaskToBack(true);
|
||||
// return true;
|
||||
// }
|
||||
// return super.onKeyDown(keyCode, event);
|
||||
// }
|
||||
|
||||
// @Override
|
||||
// public void onBackPressed() {
|
||||
// moveTaskToBack(true);
|
||||
// }
|
||||
|
||||
@Override
|
||||
|
||||
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
||||
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,22 @@
|
||||
package com.example.luyin.services;
|
||||
|
||||
import cn.bmob.v3.BmobObject;
|
||||
|
||||
public class EmergencyPeople extends BmobObject {
|
||||
|
||||
private String name;
|
||||
private String phoneNumber;
|
||||
|
||||
public String getName(){
|
||||
return name;
|
||||
}
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
public String getPhoneNumber() {
|
||||
return phoneNumber;
|
||||
}
|
||||
public void setPhoneNumber(String phoneNumber) {
|
||||
this.phoneNumber=phoneNumber;
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.example.luyin.services;
|
||||
|
||||
import cn.bmob.v3.BmobObject;
|
||||
|
||||
public class Location extends BmobObject{
|
||||
private String name;
|
||||
private String address;
|
||||
|
||||
public String getName(){
|
||||
return name;
|
||||
}
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package com.example.luyin.speech.setting;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.preference.EditTextPreference;
|
||||
import android.preference.Preference;
|
||||
import android.preference.Preference.OnPreferenceChangeListener;
|
||||
import android.preference.PreferenceActivity;
|
||||
import android.view.Window;
|
||||
|
||||
import com.example.luyin.R;
|
||||
import com.example.luyin.speech.util.SettingTextWatcher;
|
||||
|
||||
/**
|
||||
* 听写设置界面
|
||||
*/
|
||||
public class IatSettings extends PreferenceActivity implements OnPreferenceChangeListener {
|
||||
|
||||
public static final String PREFER_NAME = "com.iflytek.setting";
|
||||
private EditTextPreference mVadbosPreference;
|
||||
private EditTextPreference mVadeosPreference;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
super.onCreate(savedInstanceState);
|
||||
getPreferenceManager().setSharedPreferencesName(PREFER_NAME);
|
||||
addPreferencesFromResource(R.xml.iat_setting);
|
||||
|
||||
mVadbosPreference = (EditTextPreference)findPreference("iat_vadbos_preference");
|
||||
mVadbosPreference.getEditText().addTextChangedListener(new SettingTextWatcher(IatSettings.this,mVadbosPreference,0,10000));
|
||||
|
||||
mVadeosPreference = (EditTextPreference)findPreference("iat_vadeos_preference");
|
||||
mVadeosPreference.getEditText().addTextChangedListener(new SettingTextWatcher(IatSettings.this,mVadeosPreference,0,10000));
|
||||
}
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package com.example.luyin.speech.setting;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.preference.EditTextPreference;
|
||||
import android.preference.Preference;
|
||||
import android.preference.Preference.OnPreferenceChangeListener;
|
||||
import android.preference.PreferenceActivity;
|
||||
import android.view.Window;
|
||||
|
||||
import com.example.luyin.R;
|
||||
import com.example.luyin.speech.util.SettingTextWatcher;
|
||||
|
||||
|
||||
/**
|
||||
* 合成设置界面
|
||||
*/
|
||||
public class TtsSettings extends PreferenceActivity implements OnPreferenceChangeListener {
|
||||
|
||||
public static final String PREFER_NAME = "com.iflytek.setting";
|
||||
private EditTextPreference mSpeedPreference;
|
||||
private EditTextPreference mPitchPreference;
|
||||
private EditTextPreference mVolumePreference;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
super.onCreate(savedInstanceState);
|
||||
// 指定保存文件名字
|
||||
getPreferenceManager().setSharedPreferencesName(PREFER_NAME);
|
||||
addPreferencesFromResource(R.xml.tts_setting);
|
||||
mSpeedPreference = (EditTextPreference)findPreference("speed_preference");
|
||||
mSpeedPreference.getEditText().addTextChangedListener(new SettingTextWatcher(TtsSettings.this,mSpeedPreference,0,200));
|
||||
|
||||
mPitchPreference = (EditTextPreference)findPreference("pitch_preference");
|
||||
mPitchPreference.getEditText().addTextChangedListener(new SettingTextWatcher(TtsSettings.this,mPitchPreference,0,100));
|
||||
|
||||
mVolumePreference = (EditTextPreference)findPreference("volume_preference");
|
||||
mVolumePreference.getEditText().addTextChangedListener(new SettingTextWatcher(TtsSettings.this,mVolumePreference,0,100));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package com.example.luyin.speech.util;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* 功能性函数扩展类
|
||||
*/
|
||||
public class FucUtil {
|
||||
/**
|
||||
* 读取asset目录下文件。
|
||||
* @return content
|
||||
*/
|
||||
public static String readFile(Context mContext,String file,String code)
|
||||
{
|
||||
int len = 0;
|
||||
byte []buf = null;
|
||||
String result = "";
|
||||
try {
|
||||
InputStream in = mContext.getAssets().open(file);
|
||||
len = in.available();
|
||||
buf = new byte[len];
|
||||
in.read(buf, 0, len);
|
||||
|
||||
result = new String(buf,code);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取asset目录下音频文件。
|
||||
*
|
||||
* @return 二进制文件数据
|
||||
*/
|
||||
public static byte[] readAudioFile(Context context, String filename) {
|
||||
try {
|
||||
InputStream ins = context.getAssets().open(filename);
|
||||
byte[] data = new byte[ins.available()];
|
||||
|
||||
ins.read(data);
|
||||
ins.close();
|
||||
|
||||
return data;
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,147 @@
|
||||
package com.example.luyin.speech.util;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import org.json.JSONTokener;
|
||||
|
||||
/**
|
||||
* Json结果解析类
|
||||
*/
|
||||
public class JsonParser {
|
||||
|
||||
public static String parseIatResult(String json) {
|
||||
StringBuffer ret = new StringBuffer();
|
||||
try {
|
||||
JSONTokener tokener = new JSONTokener(json);
|
||||
JSONObject joResult = new JSONObject(tokener);
|
||||
|
||||
JSONArray words = joResult.getJSONArray("ws");
|
||||
for (int i = 0; i < words.length(); i++) {
|
||||
// 转写结果词,默认使用第一个结果
|
||||
JSONArray items = words.getJSONObject(i).getJSONArray("cw");
|
||||
JSONObject obj = items.getJSONObject(0);
|
||||
ret.append(obj.getString("w"));
|
||||
// 如果需要多候选结果,解析数组其他字段
|
||||
// for(int j = 0; j < items.length(); j++)
|
||||
// {
|
||||
// JSONObject obj = items.getJSONObject(j);
|
||||
// ret.append(obj.getString("w"));
|
||||
// }
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
public static String parseGrammarResult(String json, String engType) {
|
||||
StringBuffer ret = new StringBuffer();
|
||||
try {
|
||||
JSONTokener tokener = new JSONTokener(json);
|
||||
JSONObject joResult = new JSONObject(tokener);
|
||||
|
||||
JSONArray words = joResult.getJSONArray("ws");
|
||||
// 云端和本地结果分情况解析
|
||||
if ("cloud".equals(engType)) {
|
||||
for (int i = 0; i < words.length(); i++) {
|
||||
JSONArray items = words.getJSONObject(i).getJSONArray("cw");
|
||||
for(int j = 0; j < items.length(); j++)
|
||||
{
|
||||
JSONObject obj = items.getJSONObject(j);
|
||||
if(obj.getString("w").contains("nomatch"))
|
||||
{
|
||||
ret.append("没有匹配结果.");
|
||||
return ret.toString();
|
||||
}
|
||||
ret.append("【结果】" + obj.getString("w"));
|
||||
ret.append("【置信度】" + obj.getInt("sc"));
|
||||
ret.append("\n");
|
||||
}
|
||||
}
|
||||
} else if ("local".equals(engType)) {
|
||||
ret.append("【结果】");
|
||||
for (int i = 0; i < words.length(); i++) {
|
||||
JSONObject wsItem = words.getJSONObject(i);
|
||||
JSONArray items = wsItem.getJSONArray("cw");
|
||||
if ("<contact>".equals(wsItem.getString("slot"))) {
|
||||
// 可能会有多个联系人供选择,用中括号括起来,这些候选项具有相同的置信度
|
||||
ret.append("【");
|
||||
for(int j = 0; j < items.length(); j++)
|
||||
{
|
||||
JSONObject obj = items.getJSONObject(j);
|
||||
if(obj.getString("w").contains("nomatch"))
|
||||
{
|
||||
ret.append("没有匹配结果.");
|
||||
return ret.toString();
|
||||
}
|
||||
ret.append(obj.getString("w")).append("|");
|
||||
}
|
||||
ret.setCharAt(ret.length() - 1, '】');
|
||||
} else {
|
||||
//本地多候选按照置信度高低排序,一般选取第一个结果即可
|
||||
JSONObject obj = items.getJSONObject(0);
|
||||
if(obj.getString("w").contains("nomatch"))
|
||||
{
|
||||
ret.append("没有匹配结果.");
|
||||
return ret.toString();
|
||||
}
|
||||
ret.append(obj.getString("w"));
|
||||
}
|
||||
}
|
||||
ret.append("【置信度】" + joResult.getInt("sc"));
|
||||
ret.append("\n");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
ret.append("没有匹配结果.");
|
||||
}
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
public static String parseGrammarResult(String json) {
|
||||
StringBuffer ret = new StringBuffer();
|
||||
try {
|
||||
JSONTokener tokener = new JSONTokener(json);
|
||||
JSONObject joResult = new JSONObject(tokener);
|
||||
|
||||
JSONArray words = joResult.getJSONArray("ws");
|
||||
for (int i = 0; i < words.length(); i++) {
|
||||
JSONArray items = words.getJSONObject(i).getJSONArray("cw");
|
||||
for(int j = 0; j < items.length(); j++)
|
||||
{
|
||||
JSONObject obj = items.getJSONObject(j);
|
||||
if(obj.getString("w").contains("nomatch"))
|
||||
{
|
||||
ret.append("没有匹配结果.");
|
||||
return ret.toString();
|
||||
}
|
||||
ret.append("【结果】" + obj.getString("w"));
|
||||
ret.append("【置信度】" + obj.getInt("sc"));
|
||||
ret.append("\n");
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
ret.append("没有匹配结果.");
|
||||
}
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
public static String parseTransResult(String json,String key) {
|
||||
StringBuffer ret = new StringBuffer();
|
||||
try {
|
||||
JSONTokener tokener = new JSONTokener(json);
|
||||
JSONObject joResult = new JSONObject(tokener);
|
||||
String errorCode = joResult.optString("ret");
|
||||
if(!errorCode.equals("0")) {
|
||||
return joResult.optString("errmsg");
|
||||
}
|
||||
JSONObject transResult = joResult.optJSONObject("trans_result");
|
||||
ret.append(transResult.optString(key));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return ret.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
package com.example.luyin.speech.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.preference.EditTextPreference;
|
||||
import android.text.Editable;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* 输入框输入范围控制
|
||||
*/
|
||||
public class SettingTextWatcher implements TextWatcher {
|
||||
private int editStart ;
|
||||
private int editCount ;
|
||||
private EditTextPreference mEditTextPreference;
|
||||
int minValue;//最小值
|
||||
int maxValue;//最大值
|
||||
private Context mContext;
|
||||
|
||||
public SettingTextWatcher(Context context,EditTextPreference e,int min, int max) {
|
||||
mContext = context;
|
||||
mEditTextPreference = e;
|
||||
minValue = min;
|
||||
maxValue = max;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
// Log.e("demo", "onTextChanged start:"+start+" count:"+count+" before:"+before);
|
||||
editStart = start;
|
||||
editCount = count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count,int after) {
|
||||
// Log.e("demo", "beforeTextChanged start:"+start+" count:"+count+" after:"+after);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
if (TextUtils.isEmpty(s)) {
|
||||
return;
|
||||
}
|
||||
String content = s.toString();
|
||||
// Log.e("demo", "content:"+content);
|
||||
if (isNumeric(content)) {
|
||||
int num = Integer.parseInt(content);
|
||||
if (num > maxValue || num < minValue) {
|
||||
s.delete(editStart, editStart+editCount);
|
||||
mEditTextPreference.getEditText().setText(s);
|
||||
Toast.makeText(mContext, "超出有效值范围", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}else {
|
||||
s.delete(editStart, editStart+editCount);
|
||||
mEditTextPreference.getEditText().setText(s);
|
||||
Toast.makeText(mContext, "只能输入数字哦", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 正则表达式-判断是否为数字
|
||||
*/
|
||||
public static boolean isNumeric(String str){
|
||||
Pattern pattern = Pattern.compile("[0-9]*");
|
||||
return pattern.matcher(str).matches();
|
||||
}
|
||||
|
||||
};
|
@ -0,0 +1,58 @@
|
||||
package com.example.luyin.speech.util;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
/**
|
||||
* Xml结果解析类
|
||||
*/
|
||||
public class XmlParser {
|
||||
|
||||
public static String parseNluResult(String xml)
|
||||
{
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
try
|
||||
{
|
||||
// DOM builder
|
||||
DocumentBuilder domBuilder = null;
|
||||
// DOM doc
|
||||
Document domDoc = null;
|
||||
|
||||
// init DOM
|
||||
DocumentBuilderFactory domFact = DocumentBuilderFactory.newInstance();
|
||||
domBuilder = domFact.newDocumentBuilder();
|
||||
InputStream is = new ByteArrayInputStream(xml.getBytes());
|
||||
domDoc = domBuilder.parse(is);
|
||||
|
||||
// 获取根节点
|
||||
Element root = (Element) domDoc.getDocumentElement();
|
||||
|
||||
Element raw = (Element)root.getElementsByTagName("rawtext").item(0);
|
||||
buffer.append("【识别结果】" + raw.getFirstChild().getNodeValue());
|
||||
buffer.append("\n");
|
||||
|
||||
Element e = (Element)root.getElementsByTagName("result").item(0);
|
||||
|
||||
Element focus = (Element)e.getElementsByTagName("focus").item(0);
|
||||
buffer.append("【FOCUS】" + focus.getFirstChild().getNodeValue());
|
||||
buffer.append("\n");
|
||||
|
||||
Element action = (Element)e.getElementsByTagName("action").item(0);
|
||||
Element operation = (Element)action.getElementsByTagName("operation").item(0);
|
||||
buffer.append("【ACTION】" + operation.getFirstChild().getNodeValue());
|
||||
buffer.append("\n");
|
||||
|
||||
|
||||
}catch(Exception e){
|
||||
e.printStackTrace();
|
||||
};
|
||||
buffer.append("【ALL】" + xml);
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
package com.example.luyin.wechat;
|
||||
|
||||
|
||||
import com.example.luyin.wechat.utils.AppUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Constants {
|
||||
public static String Version = "";
|
||||
public static boolean IsOver = false;
|
||||
public static int CurrentTask = -1;
|
||||
public static final int RedEnvelopeType = 1000;
|
||||
public static final int AutoSendMsgType = 1001;
|
||||
public static final int InitFriendList = 1002;
|
||||
public static List<String> FriendList;
|
||||
public static final String TAG = "Accessibility";
|
||||
|
||||
public static class WeChatInfo{
|
||||
public static final String WECHAT_PACKAGE = "com.tencent.mm";
|
||||
//首页
|
||||
public static final String WECHAT_LAUNCHER_UI = "com.tencent.mm.ui.LauncherUI";
|
||||
//红包界面
|
||||
public static final String LUCKY_MONEY_UI = "com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyNotHookReceiveUI";
|
||||
//聊天界面
|
||||
public static final String TALKING_UI = "com.tencent.mm.ui.chatting.ChattingUI";
|
||||
//微信联系人页面
|
||||
public static final String WECHAT_CLASS_CONTACT_INFO_UI = "com.tencent.mm.plugin.profile.ui.ContactInfoUI";
|
||||
|
||||
/**
|
||||
* 聊天界面
|
||||
*/
|
||||
//聊天框左上角名字id
|
||||
public static String ID_CHATTING_NAME;
|
||||
//聊天语音切换按钮id
|
||||
public static String ID_VOICE_BTN;
|
||||
//聊天界面输入框id
|
||||
public static String ID_EDIT_VIEW;
|
||||
//发送按钮
|
||||
public static String ID_SEND_BTN;
|
||||
|
||||
/**
|
||||
* 联系人界面
|
||||
*/
|
||||
//通讯录listViewId
|
||||
public static String ID_CONTACT_LIST;
|
||||
//联系人textViewID
|
||||
public static String ID_CONTACTOR_TEXT;
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static void setArgs(String version){
|
||||
switch (version){
|
||||
case "7.0.6":
|
||||
WeChatInfo.ID_CHATTING_NAME = "com.tencent.mm:id/l5";
|
||||
WeChatInfo.ID_VOICE_BTN = "com.tencent.mm:id/aok";
|
||||
WeChatInfo.ID_EDIT_VIEW = "com.tencent.mm:id/aom";
|
||||
WeChatInfo.ID_CONTACT_LIST = "com.tencent.mm:id/nn";
|
||||
WeChatInfo.ID_CONTACTOR_TEXT = "com.tencent.mm:id/ol";
|
||||
WeChatInfo.ID_SEND_BTN = "com.tencent.mm:id/aot";
|
||||
break;
|
||||
case "7.0.10":
|
||||
WeChatInfo.ID_CHATTING_NAME = "com.tencent.mm:id/lt";
|
||||
WeChatInfo.ID_VOICE_BTN = "com.tencent.mm:id/aqc";
|
||||
WeChatInfo.ID_EDIT_VIEW = "com.tencent.mm:id/aqe";
|
||||
WeChatInfo.ID_CONTACT_LIST = "com.tencent.mm:id/oc";
|
||||
WeChatInfo.ID_CONTACTOR_TEXT = "com.tencent.mm:id/pa";
|
||||
WeChatInfo.ID_SEND_BTN = "com.tencent.mm:id/aql";
|
||||
break;
|
||||
default:
|
||||
AppUtil.makeToast( "初始化版本失败");
|
||||
}
|
||||
}
|
||||
|
||||
public static void init(String version){
|
||||
switch (version){
|
||||
case "7.0.10":
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package com.example.luyin.wechat.service;
|
||||
|
||||
import android.accessibilityservice.AccessibilityService;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import com.example.luyin.wechat.Constants;
|
||||
import com.example.luyin.wechat.service.utils.AutoRedEnvelope;
|
||||
import com.example.luyin.wechat.service.utils.InitFriendList;
|
||||
import com.example.luyin.wechat.service.utils.SendMessage;
|
||||
import com.example.luyin.wechat.utils.AccessibilityUtil;
|
||||
import com.example.luyin.wechat.utils.AppUtil;
|
||||
|
||||
|
||||
|
||||
public class RedEnvelopeService extends AccessibilityService {
|
||||
|
||||
@Override
|
||||
protected void onServiceConnected() {
|
||||
AppUtil.makeToast("初始化成功");
|
||||
}
|
||||
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||
@Override
|
||||
public void onAccessibilityEvent(AccessibilityEvent event) {
|
||||
if(event == null || event.getPackageName() == null){
|
||||
return;
|
||||
}
|
||||
if(event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED || event.getEventType() == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED){
|
||||
switch (Constants.CurrentTask){
|
||||
case Constants.RedEnvelopeType:
|
||||
AutoRedEnvelope.getInstance(this).startEnvelope(event);
|
||||
break;
|
||||
case Constants.AutoSendMsgType:
|
||||
SendMessage.getInstance(this).startSedMessage(event);
|
||||
break;
|
||||
case Constants.InitFriendList:
|
||||
InitFriendList.getInstance(this).initList(event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInterrupt() {
|
||||
Log.i(Constants.TAG, "onInterrupt");
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
package com.example.luyin.wechat.service.utils;
|
||||
|
||||
import android.accessibilityservice.AccessibilityService;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
import com.example.luyin.wechat.Constants;
|
||||
import com.example.luyin.activities.Wechat;
|
||||
import com.example.luyin.wechat.utils.AccessibilityUtil;
|
||||
import com.example.luyin.wechat.utils.AppUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.example.luyin.wechat.utils.AppUtil.weakUpScreen;
|
||||
|
||||
public class AutoRedEnvelope {
|
||||
private static AutoRedEnvelope autoRedEnvelope;
|
||||
private static AccessibilityService Service;
|
||||
|
||||
private AutoRedEnvelope(AccessibilityService service){
|
||||
Service = service;
|
||||
}
|
||||
|
||||
public static AutoRedEnvelope getInstance(AccessibilityService service){
|
||||
if(autoRedEnvelope == null){
|
||||
synchronized (AutoRedEnvelope.class){
|
||||
if(autoRedEnvelope == null){
|
||||
autoRedEnvelope = new AutoRedEnvelope(service);
|
||||
}
|
||||
}
|
||||
}
|
||||
return autoRedEnvelope;
|
||||
}
|
||||
|
||||
public void startEnvelope(AccessibilityEvent event){
|
||||
switch (event.getEventType()){
|
||||
case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:
|
||||
Log.i(Constants.TAG, "CurrentPackage: " + event.getPackageName().toString());
|
||||
List<CharSequence> texts = event.getText();
|
||||
for(CharSequence ch : texts){
|
||||
Log.i(Constants.TAG, "NotificationContent: " + ch.toString());
|
||||
AppUtil.makeToast("Msg: " + ch.toString());
|
||||
if(ch.toString().contains("[微信红包]")){
|
||||
weakUpScreen();
|
||||
AccessibilityUtil.gotoApp(event);
|
||||
Log.i(Constants.TAG, "Get Red Envelope!");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED :
|
||||
String className = event.getClassName().toString();
|
||||
if(className.equals(Constants.WeChatInfo.WECHAT_LAUNCHER_UI)){
|
||||
AccessibilityNodeInfo nodeInfo = event.getSource();
|
||||
List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByText("微信红包");
|
||||
if(list != null && list.size() > 0){
|
||||
AccessibilityUtil.performClick(list.get(list.size() - 1));
|
||||
}
|
||||
|
||||
}else if(className.equals(Constants.WeChatInfo.LUCKY_MONEY_UI)){
|
||||
openRedEnvelope(event.getSource());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//开启红包
|
||||
private void openRedEnvelope(AccessibilityNodeInfo node){
|
||||
if(node == null) {
|
||||
Log.i(Constants.TAG, "node = null");
|
||||
}
|
||||
SystemClock.sleep(50);
|
||||
Log.i(Constants.TAG, "openRedEnvelope: fakeClick");
|
||||
float x = Wechat.Width / 2.0F;
|
||||
float y = Wechat.Height * 2 / 3.0F;
|
||||
for(int i = 0; i < 10; i++){
|
||||
SystemClock.sleep(17);
|
||||
AccessibilityUtil.performXYClick(Service, x, y);
|
||||
}
|
||||
SystemClock.sleep(500);
|
||||
AccessibilityUtil.globalGoHome(Service);
|
||||
}
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
package com.example.luyin.wechat.service.utils;
|
||||
|
||||
import android.accessibilityservice.AccessibilityService;
|
||||
import android.app.ActivityManager;
|
||||
import android.content.Context;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
import com.example.luyin.wechat.Constants;
|
||||
import com.example.luyin.wechat.utils.AccessibilityUtil;
|
||||
import com.example.luyin.wechat.utils.AppUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class InitFriendList {
|
||||
|
||||
private static AccessibilityService CurrentService;
|
||||
private static InitFriendList mInstance;
|
||||
|
||||
private InitFriendList(AccessibilityService service){
|
||||
CurrentService = service;
|
||||
}
|
||||
|
||||
public static InitFriendList getInstance(AccessibilityService service){
|
||||
if(mInstance == null){
|
||||
synchronized (InitFriendList.class){
|
||||
if(mInstance == null){
|
||||
mInstance = new InitFriendList(service);
|
||||
}
|
||||
}
|
||||
}
|
||||
return mInstance;
|
||||
}
|
||||
|
||||
public void initList(AccessibilityEvent event){
|
||||
String currentActivity = event.getClassName().toString();
|
||||
Log.i(Constants.TAG, "initList: " + currentActivity);
|
||||
switch (currentActivity){
|
||||
case Constants.WeChatInfo.WECHAT_LAUNCHER_UI:
|
||||
headToContactUI();
|
||||
break;
|
||||
default:
|
||||
AppUtil.makeToast("请回到主界面");
|
||||
}
|
||||
}
|
||||
//
|
||||
private void headToContactUI(){
|
||||
if(!AccessibilityUtil.findTextAndClick(CurrentService,"通讯录")) {
|
||||
AccessibilityUtil.globalGoBack(CurrentService);
|
||||
}
|
||||
freshContactUI();
|
||||
getList();
|
||||
resetApp();
|
||||
}
|
||||
//找到通讯录UI界面并点击
|
||||
private void freshContactUI(){
|
||||
AccessibilityUtil.findTextAndClick(CurrentService,"通讯录");
|
||||
SystemClock.sleep(500);
|
||||
AccessibilityUtil.findTextAndClick(CurrentService,"通讯录");
|
||||
}
|
||||
|
||||
private void getList(){
|
||||
AccessibilityNodeInfo nodeInfo = CurrentService.getRootInActiveWindow();
|
||||
List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByViewId(Constants.WeChatInfo.ID_CONTACT_LIST);
|
||||
if(list != null && !list.isEmpty()){
|
||||
List<String> userList = new ArrayList<>();
|
||||
while (true){
|
||||
List<AccessibilityNodeInfo> users = nodeInfo.findAccessibilityNodeInfosByViewId(Constants.WeChatInfo.ID_CONTACTOR_TEXT);
|
||||
if(users != null && !users.isEmpty()){
|
||||
for(int i = 0; i < users.size(); i++){
|
||||
AccessibilityNodeInfo node = users.get(i);
|
||||
String name = node.getText().toString();
|
||||
if(!userList.contains(name)){
|
||||
userList.add(name);
|
||||
}else{
|
||||
if(i == users.size() - 1){
|
||||
AppUtil.makeToast("扫描完毕");
|
||||
Constants.FriendList = userList;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
list.get(0).performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
|
||||
SystemClock.sleep(500);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void resetApp(){
|
||||
ActivityManager manager = (ActivityManager) CurrentService.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
List<ActivityManager.RunningTaskInfo> taskInfos = manager.getRunningTasks(3);
|
||||
for(ActivityManager.RunningTaskInfo info : taskInfos){
|
||||
if(CurrentService.getPackageName().equals(info.topActivity.getPackageName())){
|
||||
manager.moveTaskToFront(info.id, ActivityManager.MOVE_TASK_WITH_HOME);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,144 @@
|
||||
package com.example.luyin.wechat.service.utils;
|
||||
|
||||
import android.accessibilityservice.AccessibilityService;
|
||||
import android.app.ActivityManager;
|
||||
import android.content.Context;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
import com.example.luyin.wechat.Constants;
|
||||
import com.example.luyin.wechat.utils.AccessibilityUtil;
|
||||
import com.example.luyin.wechat.utils.AppUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SendMessage {
|
||||
public static String NAME;
|
||||
public static String CONTENT;
|
||||
private static AccessibilityService CurrentService;
|
||||
private static SendMessage mInstance;
|
||||
|
||||
private SendMessage(AccessibilityService service){
|
||||
CurrentService = service;
|
||||
}
|
||||
|
||||
public static SendMessage getInstance(AccessibilityService service){
|
||||
if(mInstance == null){
|
||||
synchronized (SendMessage.class){
|
||||
if(mInstance == null){
|
||||
mInstance = new SendMessage(service);
|
||||
}
|
||||
}
|
||||
}
|
||||
return mInstance;
|
||||
}
|
||||
|
||||
public void startSedMessage(AccessibilityEvent event){
|
||||
String currentActivity = event.getClassName().toString();
|
||||
Log.i(Constants.TAG, "startSedMessage: " + currentActivity);
|
||||
switch (currentActivity){
|
||||
case Constants.WeChatInfo.WECHAT_LAUNCHER_UI://首页
|
||||
headToContactUI();
|
||||
break;
|
||||
case "android.widget.LinearLayout":
|
||||
case Constants.WeChatInfo.TALKING_UI://聊天界面
|
||||
sendMsg();
|
||||
break;
|
||||
case Constants.WeChatInfo.WECHAT_CLASS_CONTACT_INFO_UI://联系人界面
|
||||
headToChattingUi();
|
||||
break;
|
||||
default:
|
||||
AppUtil.makeToast("请回到主界面");
|
||||
}
|
||||
}
|
||||
|
||||
private void headToContactUI(){
|
||||
if(!AccessibilityUtil.findTextAndClick(CurrentService,"通讯录")){
|
||||
String talker = AccessibilityUtil.findTextById(CurrentService, Constants.WeChatInfo.ID_CHATTING_NAME);
|
||||
if(talker.equals(NAME)){
|
||||
sendMsg();
|
||||
}else {
|
||||
AccessibilityUtil.globalGoBack(CurrentService);
|
||||
freshContactUI();
|
||||
}
|
||||
}else {
|
||||
freshContactUI();
|
||||
}
|
||||
}
|
||||
|
||||
private void freshContactUI(){
|
||||
AccessibilityUtil.findTextAndClick(CurrentService,"通讯录");
|
||||
SystemClock.sleep(300);
|
||||
AccessibilityUtil.findTextAndClick(CurrentService,"通讯录");
|
||||
SystemClock.sleep(300);
|
||||
AccessibilityNodeInfo node = findTalker();
|
||||
if(node != null){
|
||||
AccessibilityUtil.performClick(node);
|
||||
}
|
||||
}
|
||||
|
||||
private void headToChattingUi(){
|
||||
AccessibilityUtil.findTextAndClick(CurrentService, "发消息");
|
||||
}
|
||||
|
||||
private AccessibilityNodeInfo findTalker(){
|
||||
AccessibilityNodeInfo nodeInfo = CurrentService.getRootInActiveWindow();
|
||||
List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByViewId(Constants.WeChatInfo.ID_CONTACT_LIST);
|
||||
if(list != null && !list.isEmpty()){
|
||||
List<String> userList = new ArrayList<>();
|
||||
while (true){
|
||||
List<AccessibilityNodeInfo> users = nodeInfo.findAccessibilityNodeInfosByViewId(Constants.WeChatInfo.ID_CONTACTOR_TEXT);
|
||||
if(users != null && !users.isEmpty()){
|
||||
for(int i = 0; i < users.size(); i++){
|
||||
AccessibilityNodeInfo node = users.get(i);
|
||||
String name = node.getText().toString();
|
||||
if(name.equals(NAME)) return node;
|
||||
if(!userList.contains(name)){
|
||||
userList.add(name);
|
||||
}else{
|
||||
if(i == users.size() - 1){
|
||||
AppUtil.makeToast("未找到联系人");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
list.get(0).performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
|
||||
SystemClock.sleep(300);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void sendMsg(){
|
||||
String talker = AccessibilityUtil.findTextById(CurrentService, Constants.WeChatInfo.ID_CHATTING_NAME);
|
||||
if(talker != null && talker.equals(NAME)){
|
||||
if(!AccessibilityUtil.findIdAndWrite(CurrentService, Constants.WeChatInfo.ID_EDIT_VIEW, CONTENT)){
|
||||
AccessibilityUtil.findAndClickById(CurrentService, Constants.WeChatInfo.ID_VOICE_BTN);
|
||||
AccessibilityUtil.findIdAndWrite(CurrentService, Constants.WeChatInfo.ID_EDIT_VIEW, CONTENT);
|
||||
}
|
||||
AccessibilityUtil.findAndClickById(CurrentService, Constants.WeChatInfo.ID_SEND_BTN);
|
||||
resetApp();
|
||||
Constants.CurrentTask = -1;
|
||||
Constants.IsOver = true;
|
||||
}else {
|
||||
AccessibilityUtil.globalGoBack(CurrentService);
|
||||
freshContactUI();
|
||||
}
|
||||
}
|
||||
|
||||
public void resetApp(){
|
||||
ActivityManager manager = (ActivityManager) CurrentService.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
List<ActivityManager.RunningTaskInfo> taskInfos = manager.getRunningTasks(3);
|
||||
for(ActivityManager.RunningTaskInfo info : taskInfos){
|
||||
if(CurrentService.getPackageName().equals(info.topActivity.getPackageName())){
|
||||
manager.moveTaskToFront(info.id, ActivityManager.MOVE_TASK_WITH_HOME);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,136 @@
|
||||
package com.example.luyin.wechat.utils;
|
||||
|
||||
|
||||
import android.accessibilityservice.AccessibilityService;
|
||||
import android.accessibilityservice.GestureDescription;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Notification;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.graphics.Path;
|
||||
import android.os.Parcelable;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
import com.example.luyin.activities.Wechat;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static android.accessibilityservice.AccessibilityService.GLOBAL_ACTION_BACK;
|
||||
import static android.accessibilityservice.AccessibilityService.GLOBAL_ACTION_HOME;
|
||||
|
||||
public class AccessibilityUtil {
|
||||
|
||||
|
||||
//点击文字所属按钮事件
|
||||
public static boolean findTextAndClick(AccessibilityService service, String text){
|
||||
AccessibilityNodeInfo nodeInfo = service.getRootInActiveWindow();
|
||||
if(nodeInfo == null) return false;
|
||||
List<AccessibilityNodeInfo> nodeInfoList = nodeInfo.findAccessibilityNodeInfosByText(text);
|
||||
if(nodeInfoList != null && !nodeInfoList.isEmpty()){
|
||||
for(AccessibilityNodeInfo info : nodeInfoList){
|
||||
if(info != null && (text.equals(info.getText())) || text.equals(info.getContentDescription())){
|
||||
performClick(info);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//点击id所属按钮文字
|
||||
public static void findAndClickById(AccessibilityService service, String id){
|
||||
AccessibilityNodeInfo nodeInfo = service.getRootInActiveWindow();
|
||||
if(nodeInfo == null) return;
|
||||
List<AccessibilityNodeInfo> nodeInfoList = nodeInfo.findAccessibilityNodeInfosByViewId(id);
|
||||
if(nodeInfoList != null && nodeInfoList.size() > 0){
|
||||
performClick(nodeInfoList.get(0));
|
||||
}
|
||||
}
|
||||
|
||||
//获取id所属按钮文字
|
||||
public static String findTextById(AccessibilityService service, String id){
|
||||
AccessibilityNodeInfo nodeInfo = service.getRootInActiveWindow();
|
||||
if(nodeInfo == null) return null;
|
||||
List<AccessibilityNodeInfo> nodeInfoList = nodeInfo.findAccessibilityNodeInfosByViewId(id);
|
||||
if(nodeInfoList != null && nodeInfoList.size() > 0){
|
||||
return nodeInfoList.get(0).getText().toString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//编辑EditView
|
||||
public static boolean findIdAndWrite(AccessibilityService service, String id, String text){
|
||||
AccessibilityNodeInfo nodeInfo = service.getRootInActiveWindow();
|
||||
List<AccessibilityNodeInfo> edit = nodeInfo.findAccessibilityNodeInfosByViewId(id);
|
||||
if(edit != null && !edit.isEmpty()){
|
||||
AccessibilityNodeInfo node = edit.get(0);
|
||||
ClipboardManager clipboardManager = (ClipboardManager) Wechat.AppContext.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
ClipData clipData = ClipData.newPlainText("text", text);
|
||||
clipboardManager.setPrimaryClip(clipData);
|
||||
node.performAction(AccessibilityNodeInfo.ACTION_FOCUS);
|
||||
node.performAction(AccessibilityNodeInfo.ACTION_PASTE);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//输入x, y坐标模拟点击事件
|
||||
@TargetApi(android.os.Build.VERSION_CODES.N)
|
||||
public static void performXYClick(AccessibilityService service, float x, float y){
|
||||
Path path = new Path();
|
||||
path.moveTo(x, y);
|
||||
GestureDescription.Builder builder = new GestureDescription.Builder();
|
||||
builder.addStroke(new GestureDescription.StrokeDescription(path, 0, 1));
|
||||
GestureDescription gestureDescription = builder.build();
|
||||
service.dispatchGesture(gestureDescription, new AccessibilityService.GestureResultCallback() {
|
||||
@Override
|
||||
public void onCompleted(GestureDescription gestureDescription) {
|
||||
super.onCompleted(gestureDescription);
|
||||
//Log.i(Constants.TAG, "onCompleted: completed");
|
||||
}
|
||||
@Override
|
||||
public void onCancelled(GestureDescription gestureDescription) {
|
||||
super.onCancelled(gestureDescription);
|
||||
//Log.i(Constants.TAG, "onCancelled: cancelled");
|
||||
}
|
||||
}, null);
|
||||
}
|
||||
|
||||
//对某个节点进行点击
|
||||
public static void performClick(AccessibilityNodeInfo nodeInfo){
|
||||
if(nodeInfo == null) return;
|
||||
while (nodeInfo != null){
|
||||
if(nodeInfo.isClickable()){
|
||||
nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK);
|
||||
break;
|
||||
}
|
||||
nodeInfo = nodeInfo.getParent();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//通知栏事件进入应用
|
||||
public static void gotoApp(AccessibilityEvent event){
|
||||
Parcelable data = event.getParcelableData();
|
||||
if(data != null && data instanceof Notification){
|
||||
Notification notification = (Notification) data;
|
||||
PendingIntent intent = notification.contentIntent;
|
||||
try {
|
||||
intent.send();
|
||||
} catch (PendingIntent.CanceledException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
//模拟点击返回键
|
||||
public static void globalGoBack(AccessibilityService service){
|
||||
service.performGlobalAction(GLOBAL_ACTION_BACK);
|
||||
}
|
||||
//模拟点击Home键
|
||||
public static void globalGoHome(AccessibilityService service){
|
||||
service.performGlobalAction(GLOBAL_ACTION_HOME);
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package com.example.luyin.wechat.utils;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.KeyguardManager;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.PowerManager;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.example.luyin.activities.Wechat;
|
||||
|
||||
public class AppUtil {
|
||||
|
||||
|
||||
public static String getVersion(Context context, String packageName){
|
||||
try {
|
||||
return context.getPackageManager().getPackageInfo(packageName, 0).versionName;
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@SuppressLint("InvalidWakeLockTag")
|
||||
public static void weakUpScreen(){
|
||||
PowerManager pm = (PowerManager)Wechat.AppContext.getSystemService(Context.POWER_SERVICE);
|
||||
PowerManager.WakeLock wakeLock = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "WakeLock");
|
||||
wakeLock.acquire();
|
||||
wakeLock.release();
|
||||
|
||||
KeyguardManager km = (KeyguardManager) Wechat.AppContext.getSystemService(Context.KEYGUARD_SERVICE);
|
||||
KeyguardManager.KeyguardLock lock = km.newKeyguardLock("unlock");
|
||||
lock.disableKeyguard();
|
||||
}
|
||||
|
||||
public static void makeToast(String text){
|
||||
Toast.makeText(Wechat.AppContext, text, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
//获取版本号
|
||||
public static String getAppVersion(Context context){
|
||||
PackageManager packageManager = context.getPackageManager();
|
||||
PackageInfo info = null;
|
||||
try {
|
||||
info = packageManager.getPackageInfo(context.getPackageName(), 0);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return info.versionName;
|
||||
}
|
||||
|
||||
//创建context
|
||||
public static Context getContext(Context t, String packageName){
|
||||
Context context = null;
|
||||
try {
|
||||
context = t.createPackageContext(packageName, Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
}
|
After Width: | Height: | Size: 9.6 KiB |
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_pressed="true"
|
||||
android:drawable="@drawable/btn_left_p"/>
|
||||
<item android:state_focused="true"
|
||||
android:drawable="@drawable/btn_left_f"/>
|
||||
<item android:drawable="@drawable/btn_left_n" />
|
||||
</selector>
|
After Width: | Height: | Size: 702 B |
After Width: | Height: | Size: 945 B |
After Width: | Height: | Size: 1.0 KiB |
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_pressed="true"
|
||||
android:drawable="@drawable/btn_right_p"/>
|
||||
<item android:state_focused="true"
|
||||
android:drawable="@drawable/btn_right_f"/>
|
||||
<item android:drawable="@drawable/btn_right_n" />
|
||||
</selector>
|
After Width: | Height: | Size: 685 B |
After Width: | Height: | Size: 928 B |
After Width: | Height: | Size: 1.0 KiB |
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_pressed="true" android:drawable="@drawable/login_p" />
|
||||
<item android:state_enabled="false" android:drawable="@drawable/login" />
|
||||
<item android:drawable="@drawable/login" />
|
||||
</selector>
|
After Width: | Height: | Size: 125 B |
After Width: | Height: | Size: 125 B |
After Width: | Height: | Size: 527 B |
After Width: | Height: | Size: 660 B |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 4.5 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 6.1 KiB |
After Width: | Height: | Size: 7.4 KiB |
After Width: | Height: | Size: 8.3 KiB |
After Width: | Height: | Size: 9.4 KiB |
After Width: | Height: | Size: 634 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 122 B |
After Width: | Height: | Size: 126 B |
After Width: | Height: | Size: 122 B |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 33 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 4.1 KiB |