代码片段

a_branch
luyao 2 years ago
parent d87240dcc6
commit 4dc12976a4

10
.gitignore vendored

@ -1,10 +0,0 @@
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/app/build
/captures
.externalNativeBuild

@ -1,7 +0,0 @@
111
555
444
333
222
666
777

@ -1,674 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. [http://fsf.org/]
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
{one line to give the program's name and a brief idea of what it does.}
Copyright (C) {year} {fullname}
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see [http://www.gnu.org/licenses/].
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
ship_gunner Copyright (C) 2018 rocket049
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
[http://www.gnu.org/licenses/].
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
[http://www.gnu.org/philosophy/why-not-lgpl.html].

@ -1,2 +0,0 @@
# git-test3

@ -0,0 +1,571 @@
package com.kuang.utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
// 在我们真实的分发中或者你们在公司一般都可以看到一个公司自己封装RedisUtil
@Component
public final class RedisUtil {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
// =============================common============================
/**
*
* @param key
* @param time ()
*/
public boolean expire(String key, long time) {
try {
if (time > 0) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* key
* @param key null
* @return () 0
*/
public long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
/**
* key
* @param key
* @return true false
*/
public boolean hasKey(String key) {
try {
return redisTemplate.hasKey(key);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
*
* @param key
*/
@SuppressWarnings("unchecked")
public void del(String... key) {
if (key != null && key.length > 0) {
if (key.length == 1) {
redisTemplate.delete(key[0]);
} else {
redisTemplate.delete(CollectionUtils.arrayToList(key));
}
}
}
// ============================String=============================
/**
*
* @param key
* @return
*/
public Object get(String key) {
return key == null ? null : redisTemplate.opsForValue().get(key);
}
/**
*
* @param key
* @param value
* @return true false
*/
public boolean set(String key, Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
*
* @param key
* @param value
* @param time () time0 time0
* @return true false
*/
public boolean set(String key, Object value, long time) {
try {
if (time > 0) {
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
} else {
set(key, value);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
*
* @param key
* @param delta (0)
*/
public long incr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递增因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, delta);
}
/**
*
* @param key
* @param delta (0)
*/
public long decr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递减因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, -delta);
}
// ================================Map=================================
/**
* HashGet
* @param key null
* @param item null
*/
public Object hget(String key, String item) {
return redisTemplate.opsForHash().get(key, item);
}
/**
* hashKey
* @param key
* @return
*/
public Map<Object, Object> hmget(String key) {
return redisTemplate.opsForHash().entries(key);
}
/**
* HashSet
* @param key
* @param map
*/
public boolean hmset(String key, Map<String, Object> map) {
try {
redisTemplate.opsForHash().putAll(key, map);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* HashSet
* @param key
* @param map
* @param time ()
* @return true false
*/
public boolean hmset(String key, Map<String, Object> map, long time) {
try {
redisTemplate.opsForHash().putAll(key, map);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* hash,
*
* @param key
* @param item
* @param value
* @return true false
*/
public boolean hset(String key, String item, Object value) {
try {
redisTemplate.opsForHash().put(key, item, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* hash,
*
* @param key
* @param item
* @param value
* @param time () :hash,
* @return true false
*/
public boolean hset(String key, String item, Object value, long time) {
try {
redisTemplate.opsForHash().put(key, item, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* hash
*
* @param key null
* @param item 使 null
*/
public void hdel(String key, Object... item) {
redisTemplate.opsForHash().delete(key, item);
}
/**
* hash
*
* @param key null
* @param item null
* @return true false
*/
public boolean hHasKey(String key, String item) {
return redisTemplate.opsForHash().hasKey(key, item);
}
/**
* hash ,
*
* @param key
* @param item
* @param by (0)
*/
public double hincr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, by);
}
/**
* hash
*
* @param key
* @param item
* @param by (0)
*/
public double hdecr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, -by);
}
// ============================set=============================
/**
* keySet
* @param key
*/
public Set<Object> sGet(String key) {
try {
return redisTemplate.opsForSet().members(key);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* valueset,
*
* @param key
* @param value
* @return true false
*/
public boolean sHasKey(String key, Object value) {
try {
return redisTemplate.opsForSet().isMember(key, value);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* set
*
* @param key
* @param values
* @return
*/
public long sSet(String key, Object... values) {
try {
return redisTemplate.opsForSet().add(key, values);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* set
*
* @param key
* @param time ()
* @param values
* @return
*/
public long sSetAndTime(String key, long time, Object... values) {
try {
Long count = redisTemplate.opsForSet().add(key, values);
if (time > 0)
expire(key, time);
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* set
*
* @param key
*/
public long sGetSetSize(String key) {
try {
return redisTemplate.opsForSet().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* value
*
* @param key
* @param values
* @return
*/
public long setRemove(String key, Object... values) {
try {
Long count = redisTemplate.opsForSet().remove(key, values);
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
// ===============================list=================================
/**
* list
*
* @param key
* @param start
* @param end 0 -1
*/
public List<Object> lGet(String key, long start, long end) {
try {
return redisTemplate.opsForList().range(key, start, end);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* list
*
* @param key
*/
public long lGetListSize(String key) {
try {
return redisTemplate.opsForList().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* list
*
* @param key
* @param index index>=0 0 1 index<0-1-2
*/
public Object lGetIndex(String key, long index) {
try {
return redisTemplate.opsForList().index(key, index);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* list
*
* @param key
* @param value
*/
public boolean lSet(String key, Object value) {
try {
redisTemplate.opsForList().rightPush(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* list
* @param key
* @param value
* @param time ()
*/
public boolean lSet(String key, Object value, long time) {
try {
redisTemplate.opsForList().rightPush(key, value);
if (time > 0)
expire(key, time);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* list
*
* @param key
* @param value
* @return
*/
public boolean lSet(String key, List<Object> value) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* list
*
* @param key
* @param value
* @param time ()
* @return
*/
public boolean lSet(String key, List<Object> value, long time) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
if (time > 0)
expire(key, time);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* list
*
* @param key
* @param index
* @param value
* @return
*/
public boolean lUpdateIndex(String key, long index, Object value) {
try {
redisTemplate.opsForList().set(key, index, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* Nvalue
*
* @param key
* @param count
* @param value
* @return
*/
public long lRemove(String key, long count, Object value) {
try {
Long remove = redisTemplate.opsForList().remove(key, count, value);
return remove;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
}

@ -0,0 +1,21 @@
#端口号配置
server:
port: 8080
#数据源配置
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/student?characterEncoding=UTF-8&serverTimezone=UTC
username: root
password: 123456
#mybatis相关配置
mybatis:
#配置MyBatis的xml配置文件路径
mapper-locations: classpath:com/uos/page/mapper/*.xml
#配置XML映射文件中指定的实体类别名路径
type-aliases-package: com.uos.page.domain
#开启驼峰命名
configuration:
map-underscore-to-camel-case: true

@ -1,63 +0,0 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
buildToolsVersion '28.0.2'
defaultConfig {
applicationId "org.xing.android"
minSdkVersion 15
targetSdkVersion 26
versionCode 20
versionName "1.4.2"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
}
buildTypes {
debug {
manifestPlaceholders = [bd_speech_appid : "9080060",
bd_speech_key : "TgEpVmjjELkIf3FKc1gj2jsj",
bd_speech_secret: "87c4d13cf12a83191e4b4ec23d98530e",
umeng_appkey : "none",
umeng_channel : "none"]
}
release {
minifyEnabled false
manifestPlaceholders = [bd_speech_appid : "9080060",
bd_speech_key : "TgEpVmjjELkIf3FKc1gj2jsj",
bd_speech_secret: "87c4d13cf12a83191e4b4ec23d98530e",
umeng_appkey : "586213d5ae1bf81811000768",
umeng_channel : "xing"]
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
//
applicationVariants.all { variant ->
variant.outputs.all {
outputFileName = rootProject.getName() +"-"+defaultConfig.versionName +"-"+defaultConfig.versionCode +".apk"
}
}
}
}
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile files('libs/antlr-runtime-4.6.jar')
compile files('libs/utdid4all-1.0.4.jar')
compile files('libs/umeng-analytics-v6.0.7.jar')
compile files('libs/Msc.jar')
compile 'com.zhy:okhttputils:2.4.1'
compile 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:1.0.2'
compile 'com.android.support:appcompat-v7:28.+'
compile 'com.android.support:support-v4:28.+'
compile 'com.android.support:support-vector-drawable:28.+'
testCompile 'junit:junit:4.12'
compile files('libs/open_sdk_r5785_lite.jar')
compile files('libs/bdasr_V3_20180320_9066860.jar')
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -1,17 +0,0 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in C:\Users\Administrator\AppData\Local\Android\Sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

@ -1,72 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.xing.android">
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<!-- 百度语音识别设置 -->
<meta-data
android:name="com.baidu.speech.APP_ID"
android:value="${bd_speech_appid}" />
<meta-data
android:name="com.baidu.speech.API_KEY"
android:value="${bd_speech_key}" />
<meta-data
android:name="com.baidu.speech.SECRET_KEY"
android:value="${bd_speech_secret}" />
<service
android:name="com.baidu.speech.VoiceRecognitionService"
android:exported="false" />
<!-- 友盟统计 -->
<meta-data
android:name="UMENG_APPKEY"
android:value="${umeng_appkey}" />
<meta-data
android:name="UMENG_CHANNEL"
android:value="${umeng_channel}" />
<!-- 橫屏切换不会导致Activity重新生成 -->
<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".SimpleHelpActivity"
android:configChanges="orientation|keyboardHidden|screenSize" />
<!--腾讯QQ分享 -->
<activity
android:name="com.tencent.tauth.AuthActivity"
android:noHistory="true"
android:launchMode="singleTask" >
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="tencent1105840771" />
</intent-filter>
</activity>
<activity android:name="com.tencent.connect.common.AssistActivity"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:configChanges="orientation|keyboardHidden|screenSize" />
</application>
</manifest>

@ -1,113 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name=”viewport” content=”width=device-width, initial-scale=1″ />
<link rel="stylesheet" href="./js/KaTeX/katex.min.css" />
<script src="./js/KaTeX/katex.min.js"></script>
<style>
*{
margin : 0;
padding : 0;
}
body {
color: #444444;
}
.list li {
word-break : break-all;
word-wrap: break-word;
box-sizing: border-box;
border-radius:5px;
margin: 5px 5px;
}
.base span {
float: left;
}
#history ul {
list-style:none;
-webkit-margin-before: -0.1em;
font-size : 175%;
}
.hide-block {
display : none;
}
</style>
</head>
<body>
<div id="history" class = "list history">
<ul id="list"></ul>
</div>
<script type="text/javascript">
disColort = "rgba(8,8,8,0.05)";
function replaceMultiply(expr) {
return expr.replace(new RegExp(/\/g), "×").replace(new RegExp(/>\/</g), ">÷<");
}
function clearHistory() {
var list = document.getElementById("list");
list.innerHTML = "";
}
function historyPop() {
var list = document.getElementById("list");
if(list.childNodes != null && list.childNodes.length > 0) {
list.removeChild(list.childNodes[0]);
}
}
function addItem(item) {
var li = document.createElement("li");
li.innerHTML = replaceMultiply(katex.renderToString(item));
//删除多余的标签,防止复制操作得到重复的数据
var span = li.childNodes[0];
span.removeChild(span.childNodes[0]);
var list = document.getElementById("list");
if(list.childNodes == null || list.childNodes.length == 0) {
list.appendChild(li);
} else {
if(list.childNodes.length % 2 == 1) {
li.style.backgroundColor = disColort;
}
list.insertBefore(li, list.childNodes[0]);
}
}
function setTextColor(color) {
var body = document.body;
body.style.color = color;
}
function setDistinguishColor(color) {
disColort = color;
var list = document.getElementById("list");
if(list.childNodes != null && list.childNodes.length != 0) {
for(var i=0;i<list.childNodes.length;i++) {
if(i % 2 == 1) {
var c = list.childNodes[i];
c.style.backgroundColor = disColort;
}
}
}
}
/*
//仅用于测试的代码
addItem("1 + 2 + 3 + 4 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = 55");
*/
</script>
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 372 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

@ -1,148 +0,0 @@
package org.xing.android;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.preference.PreferenceManager;
import android.text.TextUtils;
/**
* Created by Administrator on 2017/1/9 0009.
*/
public class AppConfig {
private static String packageName;
private static int versionCode;
private static String versionName;
private static String channel;
private static String themeId;
private static String preferedEngine;
private static int shareCount;
private static boolean isFirstStart;
private static boolean checkUpdate;
private static Context mContext;
private static SharedPreferences prefs;
private static SharedPreferences mConprefs;
public static void loadConfig(Context mContext) {
isFirstStart = false;
checkUpdate = false;
mContext = mContext;
packageName = mContext.getApplicationContext().getPackageName();
prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
try {
PackageInfo info = mContext.getPackageManager().getPackageInfo(packageName, 0);
versionCode = info.versionCode;
versionName = info.versionName;
int lastVersionCode = prefs.getInt("versionCode", 0);
if (versionCode > lastVersionCode) {
isFirstStart = true;
prefs.edit().putInt("versionCode", versionCode).commit();
//第一次启动,检查版本更新的字段重设
prefs.edit().putBoolean("checkUpdate", true).commit();
checkUpdate = true;
} else {
checkUpdate = prefs.getBoolean("checkUpdate", true);
}
channel = getAppMetaData(mContext, "UMENG_CHANNEL");
themeId = prefs.getString("themeId", "0");
preferedEngine = prefs.getString("preferedEngine", "baidu");
shareCount = prefs.getInt("shareCount", 0);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
public static String getPackageName() {
return packageName;
}
public static int getVersionCode() {
return versionCode;
}
public static String getVersionName() {
return versionName;
}
public static String getThemeId() {
return themeId;
}
public static void setThemeId(String themeId) {
AppConfig.themeId = themeId;
prefs.edit().putString("themeId", themeId).commit();
}
public static String getPreferedEngine() {
return preferedEngine;
}
public static void setPreferedEngine(String preferedEngine) {
AppConfig.preferedEngine = preferedEngine;
prefs.edit().putString("preferedEngine", preferedEngine).commit();
}
public static int getShareCount() {
return shareCount;
}
public static void setShareCount(int shareCount) {
AppConfig.shareCount = shareCount;
prefs.edit().putInt("shareCount", shareCount).commit();
}
public static void addShareCount() {
AppConfig.shareCount ++;
prefs.edit().putInt("shareCount", shareCount).commit();
}
public static boolean getIsFirstStart() {
return isFirstStart;
}
public static void setIsFirstStart(boolean b) {
isFirstStart = b;
}
public static boolean getCheckUpdate() {
return checkUpdate;
}
public static void setCheckUpdate(boolean b) {
checkUpdate = b;
prefs.edit().putBoolean("checkUpdate", b).commit();
}
/**
* applicationmeta-data
* @return ()
*/
public static String getAppMetaData(Context ctx, String key) {
if (ctx == null || TextUtils.isEmpty(key)) {
return null;
}
String resultData = null;
try {
PackageManager packageManager = ctx.getPackageManager();
if (packageManager != null) {
ApplicationInfo applicationInfo = packageManager.getApplicationInfo(ctx.getPackageName(), PackageManager.GET_META_DATA);
if (applicationInfo != null) {
if (applicationInfo.metaData != null) {
resultData = applicationInfo.metaData.getString(key);
}
}
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return resultData;
}
}

@ -1,752 +0,0 @@
package org.xing.android;
import android.Manifest;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings;
import android.speech.SpeechRecognizer;
import android.support.v7.app.AppCompatActivity;
import android.view.GestureDetector;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.umeng.analytics.MobclickAgent;
import org.xing.calc.Calculator;
import org.xing.calc.Tips;
import org.xing.calc.cmd.CmdParser;
import org.xing.calc.filter.ExprFilterChain;
import org.xing.calc.filter.PinyinExprFilter;
import org.xing.engine.BaiduSpeechEngine;
import org.xing.engine.IflySpeechEngine;
import org.xing.engine.SpeechEngine;
import org.xing.engine.SpeechListener;
import org.xing.logger.impl.EventLogger;
import org.xing.share.ShareManager;
import org.xing.theme.Theme;
import org.xing.theme.ThemeChangeListener;
import org.xing.theme.ThemeManager;
import org.xing.update.UpdateManager;
import org.xing.utils.DeviceUtil;
import org.xing.utils.NumberUtil;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
public class MainActivity extends AppCompatActivity implements SpeechListener, ThemeChangeListener {
private boolean hasAudioError;
private boolean isListening;
private SpeechEngine speechEngine;
private Calculator calculator;
private boolean newFeatureShowed;
private boolean shareTipsShowed;
public static EventLogger eventLogger;
private Tips tips;
private EditText inputText;
private TextView msgText;
private ProgressBar recordDynamic;
private Button stateButton;
private Button startButton;
private WebView historyList;
/*
*/
private Stack<Double> historyResult;
private ExprFilterChain cmdFilterChain;
private Map<String, Integer> cmdName;
private CmdParser cmdParser;
/*
*/
private Theme currentTheme;
private ThemeManager themeManager;
/*
*/
private LinearLayout shareLayout;
private ShareManager shareManager;
/*
maxNoInputCount
*/
private int noInputCount = 0;
private int maxNoInputCount = 5;
protected void showHelp() {
MobclickAgent.onEvent(this, "help");
eventLogger.onEvent("help");
Intent intent =new Intent(MainActivity.this, SimpleHelpActivity.class);
intent.putExtra("url", getString(R.string.helpUrl));
startActivity(intent);
}
/*
10s
*/
protected void showTips(int delaySecond) {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
//防止当前页面没有显示的时候显示对话框,从而导致程序崩溃
if(!isListening) return;
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("小技巧");
builder.setMessage(" 说'引擎',切换到讯飞识别引擎,计算速度更快。" +
"立即切换?");
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
stopListening();
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
changeSpeechEngine(null);
startListening(true);
}
}, 1000);
}
});
builder.setNegativeButton("知道", null);
builder.show();
}
}, delaySecond*1000);
}
private void initSpeechRecognizer() {
if(speechEngine != null) {
stopListening();
speechEngine.destroy();
}
hasAudioError = false;
isListening = false;
String preferedEngine = AppConfig.getPreferedEngine();
eventLogger.onEvent("engine-"+preferedEngine);
if(preferedEngine.equals("ifly")) {
//速度快,准确性差一点
speechEngine = new IflySpeechEngine(this);
} else {
//准确性高,速度稍慢
speechEngine = new BaiduSpeechEngine(this);
}
speechEngine.setSpeechListener(this);
}
private void changeSpeechEngine(String engine) {
eventLogger.onEvent("changeEngine");
String preferedEngine = AppConfig.getPreferedEngine();
if(preferedEngine.equals("ifly") && (engine == null || engine.equals("baidu"))){
AppConfig.setPreferedEngine("baidu");
Toast.makeText(this, "切换到百度语音引擎(更准确)\n" +
"说'引擎'或'讯飞'可以切换", Toast.LENGTH_LONG).show();
initSpeechRecognizer();
}else if(preferedEngine.equals("baidu") && (engine == null || engine.equals("ifly"))){
AppConfig.setPreferedEngine("ifly");
Toast.makeText(this, "切换到科大讯飞引擎(更快速)\n" +
"说'引擎'或'百度'可以切换", Toast.LENGTH_LONG).show();
initSpeechRecognizer();
} else {
if(preferedEngine.equals("baidu")) {
Toast.makeText(this, "已经是百度语音引擎,无需重新设置\n" +
"说'引擎'或'讯飞'可以切换", Toast.LENGTH_LONG).show();
}else {
Toast.makeText(this, "已经是科大讯飞引擎,无需重新设置\n" +
"说'引擎'或'百度'可以切换", Toast.LENGTH_LONG).show();
}
}
}
private void initUserView() {
stateButton = (Button) this.findViewById(R.id.stateButton);
stateButton = (Button) this.findViewById(R.id.stateButton);
stateButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MobclickAgent.onEvent(MainActivity.this, "statusClick");
eventLogger.onEvent("statusClick");
Toast toast = Toast.makeText(MainActivity.this,
"图标为绿色可以开始输入\n灰色表示已暂停或者正在识别。",
Toast.LENGTH_SHORT);
toast.setGravity(Gravity.TOP, 0, 0);
toast.show();
}
});
startButton = (Button) this.findViewById(R.id.ctrl_start);
startButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MobclickAgent.onEvent(MainActivity.this, "startClick");
eventLogger.onEvent("startClick");
if(isListening) {
stopListening();
startButton.setBackgroundResource(R.mipmap.start);
msgText.setText("已暂停");
if(AppConfig.getIsFirstStart() && (!shareTipsShowed)) {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this,
"小技巧每一次微信分享或QQ分享都可以减少广告分享三次即可彻底删除广告。",
Toast.LENGTH_LONG).show();
}
}, 10 * 1000);
shareTipsShowed = true;
}
} else {
//再次检查录音设备授权,部分用户误操作禁止了录音授权,这行代码可以让用户再次授权
if(hasAudioError) {
PermissionChecker.requestAudioPermission(MainActivity.this);
}
startListening(true);
startButton.setBackgroundResource(R.mipmap.stop);
msgText.setText("");
}
}
});
this.findViewById(R.id.help_mark).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showHelp();
}
});
inputText = (EditText) this.findViewById(R.id.input);
inputText.setKeyListener(null);
msgText = (TextView) this.findViewById(R.id.msg);
recordDynamic = (ProgressBar) this.findViewById(R.id.recordDynamic);
}
private void initCalculator(HashMap<Character, String> pinyin) {
newFeatureShowed = false;
calculator = Calculator.createDefault(pinyin);
historyList = (WebView) this.findViewById(R.id.historylist);
historyList.setBackgroundColor(0);
historyList.getSettings().setJavaScriptEnabled(true);
historyList.getSettings().setAppCacheEnabled(true);
historyList.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url)
{
super.onPageFinished(view, url);
if(currentTheme != null) {
String jsCode = "javascript:setTextColor('" + currentTheme.getStyle("historyColor") + "')";
historyList.loadUrl(jsCode);
}
}
});
//设置单击和双击触发事件
historyList.setOnTouchListener(new View.OnTouchListener() {
GestureDetector detector = null;
@Override
public boolean onTouch(View v, MotionEvent event) {
if(detector == null) {
detector = new GestureDetector(MainActivity.this,
new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onDoubleTap(MotionEvent e) {
themeManager.randomTheme();
return super.onDoubleTap(e);
}
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
startListening(true);
startButton.setBackgroundResource(R.mipmap.stop);
msgText.setText("");
return super.onSingleTapConfirmed(e);
}
}
);
}
detector.onTouchEvent(event);
return false;
}
});
historyList.loadUrl("javascript:var isFirstStart="+AppConfig.getIsFirstStart()+";");
historyList.loadUrl("file:///android_asset/history.html");
historyResult = new Stack<>();
}
private void initCommand(HashMap<Character, String> pinyin) {
cmdName = new HashMap<String, Integer>();
cmdName.put("清屏", 1);
cmdName.put("清空", 1);
cmdName.put("清除", 1);
cmdName.put("全部删除", 1);
cmdName.put("撤销", 2);
cmdName.put("取消", 2);
cmdName.put("倒退", 2);
cmdName.put("后退", 2);
cmdName.put("删除", 2);
cmdName.put("帮助", 3);
cmdName.put("示例", 3);
cmdName.put("说明", 3);
cmdName.put("升级", 4);
cmdName.put("版本", 4);
cmdName.put("主题", 5);
cmdName.put("背景", 5);
cmdName.put("风格", 5);
cmdName.put("引擎", 6);
cmdName.put("百度", 6);
cmdName.put("讯飞", 6);
cmdName.put("退出", 7);
cmdName.put("关闭", 7);
cmdName.put("暂停", 8);
StringBuilder allowedChars = new StringBuilder();
for(String key : cmdName.keySet()) {
allowedChars.append(key);
}
cmdFilterChain = new ExprFilterChain(allowedChars.toString(), pinyin);
cmdParser = new CmdParser();
}
private void initTheme() {
themeManager = new ThemeManager(this);
themeManager.addThemeChangeListener(this);
themeManager.applyTheme(AppConfig.getThemeId());
}
private void initShare() {
shareTipsShowed = false;
shareManager = new ShareManager(this);
shareLayout = (LinearLayout) findViewById(R.id.share_board);
this.findViewById(R.id.share_mark).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
shareLayout.setVisibility(View.VISIBLE);
}
});
this.findViewById(R.id.cancel_btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
shareLayout.setVisibility(View.GONE);
}
});
this.findViewById(R.id.share_weixin).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
shareManager.shareToWeixin(0);
}
});
this.findViewById(R.id.share_pengyouquan).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
shareManager.shareToWeixin(1);
}
});
this.findViewById(R.id.share_qq).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
shareManager.shareToQQ(0);
}
});
this.findViewById(R.id.share_kongjian).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
shareManager.shareToQQ(1);
}
});
}
private void initPermission() {
PermissionChecker.requestPermission(this, new String[] {
Manifest.permission.RECORD_AUDIO,
Manifest.permission.ACCESS_NETWORK_STATE,
Manifest.permission.INTERNET,
Manifest.permission.READ_PHONE_STATE
});
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AppConfig.loadConfig(this);
String uniqueId = DeviceUtil.getUniqueId(this);
eventLogger = new EventLogger(uniqueId, AppConfig.getVersionName(),
this.getString(R.string.recordUrl));
if(AppConfig.getIsFirstStart()) {
eventLogger.onEvent("new-start");
} else {
eventLogger.onEvent("start");
}
tips = Tips.createSimpleTips();
//10s后检查更新
UpdateManager.postUpdate(this, 10);
MobclickAgent.setScenarioType(this, MobclickAgent.EScenarioType.E_UM_NORMAL);
initPermission();
initUserView();
HashMap<Character, String> pinyin =
PinyinExprFilter.loadTokens(getResources().openRawResource(R.raw.token));
initCalculator(pinyin);
initCommand(pinyin);
initTheme();
initShare();
initSpeechRecognizer();
}
@Override
public void onResume() {
super.onResume();
startListening(true);
startButton.setBackgroundResource(R.mipmap.stop);
msgText.setText(tips.randomGet());
MobclickAgent.onResume(this);
}
@Override
public void onPause() {
super.onPause();
stopListening();
startButton.setBackgroundResource(R.mipmap.start);
MobclickAgent.onPause(this);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
public synchronized void startListening(boolean resetInputCount) {
if (isListening) return;
hasAudioError = false;
speechEngine.startListening();
isListening = true;
lastRmsdB = 0;
if (resetInputCount) {
noInputCount = 0;
}
}
public void stopListening() {
if(isListening) {
speechEngine.cancel();
}
listeningStopped();
}
public synchronized void listeningStopped() {
isListening = false;
stateButton.setBackgroundResource(R.mipmap.input_sleep);
}
public void onReadyForSpeech() {
stateButton.setBackgroundResource(R.mipmap.input_ready);
}
public void onBeginningOfSpeech() {
}
private float lastRmsdB=0;
public void onRmsChanged(float rmsdB) {
lastRmsdB = (rmsdB*3+lastRmsdB*7) /10;
recordDynamic.setProgress((int) lastRmsdB);
}
public void onEndOfSpeech() {
stateButton.setBackgroundResource(R.mipmap.input_sleep);
msgText.setText("正在识别...");
}
public void onError(int error) {
listeningStopped();
StringBuilder sb = new StringBuilder();
switch (error) {
case SpeechRecognizer.ERROR_AUDIO:
sb.append("请读出表达式");
startListening(true);
MobclickAgent.onEvent(this, "noAudio");
eventLogger.onEvent("noAudio");
break;
case SpeechRecognizer.ERROR_SPEECH_TIMEOUT:
noInputCount++;
if (noInputCount >= maxNoInputCount) {
sb.append("已暂停");
startButton.setBackgroundResource(R.mipmap.start);
} else {
startListening(false);
}
break;
case SpeechRecognizer.ERROR_CLIENT:
sb.append("客户端错误");
startButton.setBackgroundResource(R.mipmap.start);
eventLogger.onEvent("errorClient");
break;
case SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS:
sb.append("录音设备未授权");
startButton.setBackgroundResource(R.mipmap.start);
eventLogger.onEvent("errorPermissions");
hasAudioError = true;
break;
case SpeechRecognizer.ERROR_NETWORK:
sb.append("请检查网络连接");
MobclickAgent.onEvent(this, "errorNetwork");
eventLogger.onEvent("errorNetwork");
startButton.setBackgroundResource(R.mipmap.start);
break;
case SpeechRecognizer.ERROR_NO_MATCH:
sb.append("未识别");
MobclickAgent.onEvent(this, "failMatch");
eventLogger.onEvent("failMatch");
startListening(true);
break;
case SpeechRecognizer.ERROR_RECOGNIZER_BUSY:
sb.append("引擎忙");
MobclickAgent.onEvent(this, "busy");
eventLogger.onEvent("busy");
startButton.setBackgroundResource(R.mipmap.start);
break;
case SpeechRecognizer.ERROR_SERVER:
sb.append("未识别");
startListening(true);
MobclickAgent.onEvent(this, "failServer");
eventLogger.onEvent("failServer");
break;
case SpeechRecognizer.ERROR_NETWORK_TIMEOUT:
sb.append("网络连接连接超时");
MobclickAgent.onEvent(this, "errorNetworkTimeout");
eventLogger.onEvent("errorNetworkTimeout");
startButton.setBackgroundResource(R.mipmap.start);
break;
}
msgText.setText(sb.toString());
}
private String buildExpr(Bundle results) {
ArrayList<String> nbest = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
StringBuilder expr = new StringBuilder();
for (String w : nbest) {
expr.append(w);
}
return expr.toString();
}
private void showResult(String expr, Double evalResult, String readExpr) {
//界面上显示结果
if (!Double.isNaN(evalResult)) {
historyResult.push(evalResult);
String text = NumberUtil.format(evalResult, 8);
String item = readExpr + "=" + text;
historyList.loadUrl("javascript:addItem('" + item + "')");
inputText.setText(text);
msgText.setText("");
} else {
String errMsg = calculator.getErrMsg();
if(errMsg != null) {
msgText.setText("未识别,'"+errMsg+"'表达错误");
} else {
msgText.setText("未识别,'"+expr+"'表达错误");
}
}
}
public int handleCommand(String expr) {
String cmd = cmdFilterChain.call(expr);
int type = cmdParser.parse(cmd);
if(type > 0) {
this.eventLogger.onEvent("NaN", expr.toString(), "null", type);
switch (type) {
case 1:
historyResult.clear();
historyList.loadUrl("javascript:clearHistory()");
calculator.setLastResult(0);
inputText.setText("0");
break;
case 2:
if(historyResult.size() > 0) {
historyResult.pop();
historyList.loadUrl("javascript:historyPop()");
if(historyResult.size() > 0) {
Double lastResult = historyResult.peek();
calculator.setLastResult(lastResult);
inputText.setText(NumberUtil.format(lastResult, 8));
} else {
calculator.setLastResult(0);
inputText.setText("0");
}
}
break;
case 3:
showHelp();
break;
case 4:
UpdateManager.update(this, true);
break;
case 5:
themeManager.randomTheme();
break;
case 6:
if(cmd.contains("引擎")) {
changeSpeechEngine(null);
}else if(cmd.contains("百度")){
changeSpeechEngine("baidu");
}else {
changeSpeechEngine("ifly");
}
break;
case 7:
stopListening();
finish();
break;
case 8:
stopListening();
startButton.setBackgroundResource(R.mipmap.start);
msgText.setText("已暂停");
break;
default:
break;
}
if(type != 8) {
msgText.setText("");
}
}
return type;
}
public void onResults(String expr) {
int cmdType = handleCommand(expr);
if(expr != null &&expr.length()>0 &&
(!expr.equals("。")) && cmdType == 0) {
//结算结果
String readExpr = null;
Double evalResult = calculator.eval(expr.toString());
if (evalResult != null && (!evalResult.isNaN())) {
readExpr = calculator.getReadExpr();
}
this.eventLogger.onEvent(NumberUtil.format(evalResult, 8),
expr.toString(), readExpr, 0);
showResult(expr.toString(), evalResult, readExpr);
if(AppConfig.getIsFirstStart() && (!newFeatureShowed)) {
showTips(10);
newFeatureShowed = true;
}
}
//不是暂停命令的时候继续开启语音输入
if(cmdType != 8) {
isListening = false;
startListening(true);
}
}
public boolean isAlive() {
return !this.isFinishing();
}
public void onThemeChange(Theme theme) {
if(theme == null) return;
eventLogger.onEvent("theme-"+theme.getId());
try {
currentTheme = theme;
AppConfig.setThemeId(theme.getId());
int color;
List<String> backgroundImages = theme.getImagePaths();
LinearLayout layout = (LinearLayout) this.findViewById(R.id.backgroundLayout);
if(backgroundImages != null && backgroundImages.size() > 0) {
InputStream is = this.getAssets().open(backgroundImages.get(0));
Drawable background = Drawable.createFromStream(is, "theme");
layout.setBackgroundDrawable(background);
is.close();
} else {
layout.setBackgroundDrawable(null);
color = Color.parseColor(theme.getStyle("background"));
layout.setBackgroundColor(color);
}
String jsCode = "javascript:setTextColor('"+currentTheme.getStyle("historyColor")+"')";
historyList.loadUrl(jsCode);
color = Color.parseColor(theme.getStyle("resultColor"));
inputText.setTextColor(color);
color = Color.parseColor(theme.getStyle("msgColor"));
msgText.setTextColor(color);
}catch (Exception e) {
e.printStackTrace();
}
}
}

@ -1,83 +0,0 @@
package org.xing.android;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Handler;
import android.provider.Settings;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.widget.Toast;
import java.util.Vector;
/**
* Created by Administrator on 2017/3/18 0018.
*/
public class PermissionChecker {
public final static int REQUEST_CODE_ALL = 1;
public static void requestPermission(Activity activity, String[] permissions) {
Vector<String> lackedPermissions = new Vector<String>();
for(String per : permissions) {
if(ContextCompat.checkSelfPermission(activity, per) == PackageManager.PERMISSION_DENIED) {
lackedPermissions.add(per);
}
}
if(lackedPermissions.size() > 0) {
String[] tempPermissions = new String[lackedPermissions.size()];
for(int i=0;i<lackedPermissions.size();i++) {
tempPermissions[i] = lackedPermissions.get(i);
}
ActivityCompat.requestPermissions(activity, tempPermissions, REQUEST_CODE_ALL);
}
}
public static void requestAudioPermission(final Activity activity) {
final String per = Manifest.permission.RECORD_AUDIO;
int state = ContextCompat.checkSelfPermission(activity, per);
if(state != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.shouldShowRequestPermissionRationale(activity, per)) {
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setTitle("授权提醒");
builder.setMessage("计算器需要使用录音设备输入数字,请授权,否则无法使用。");
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(activity, new String[] {per}, REQUEST_CODE_ALL);
}
});
builder.show();
} else {
startSetting(activity , "\t计算器需要使用录音设备(麦克风)输入数字,请打开设置界面授权,否则无法使用。\n" +
"参考步骤:'权限设置'->'录音'->'星星声控计算器'->'允许'。");
}
}
public static void startSetting(final Activity activity, String msg) {
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setTitle("应用未授权");
builder.setMessage(msg);
builder.setPositiveButton("打开", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
try {
Intent intent = new Intent(Settings.ACTION_SETTINGS);
activity.startActivity(intent);
}catch (Exception ex) {
Toast.makeText(activity,
"抱歉,无法自动跳转到设置页面,请手动操作。",
Toast.LENGTH_SHORT).show();
}
}
});
builder.setNegativeButton("忽略", null);
builder.show();
}
}

@ -1,254 +0,0 @@
package org.xing.android;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.umeng.analytics.MobclickAgent;
import java.io.ByteArrayInputStream;
public class SimpleHelpActivity extends AppCompatActivity {
private WebView helpWeb;
private View videoView;
private FrameLayout videoContainerView;
LinearLayout toolBar;
private ProgressBar progressBar;
private TextView titleText;
private WebChromeClient chromeClient;
/**
*
*/
private void setFullScreen() {
// 设置全屏的相关属性,获取当前的屏幕状态,然后设置全屏
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
// 全屏下的状态码1098974464
// 窗口下的状态吗1098973440
}
/**
* 退
*/
private void quitFullScreen() {
// 声明当前屏幕状态的参数并获取
final WindowManager.LayoutParams attrs = getWindow().getAttributes();
attrs.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().setAttributes(attrs);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_simple_help);
videoView = null;
videoContainerView = (FrameLayout) findViewById(R.id.video);
toolBar = (LinearLayout) findViewById(R.id.toolBar);
progressBar = (ProgressBar) findViewById(R.id.webProgress);
titleText = (TextView) findViewById(R.id.help_title);
Button closeButton = (Button) findViewById(R.id.help_close);
closeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
helpWeb = (WebView) this.findViewById(R.id.simple_help);
helpWeb.setBackgroundColor(0);
WebSettings settings = helpWeb.getSettings();
settings.setJavaScriptEnabled(true);
settings.setJavaScriptCanOpenWindowsAutomatically(true);
settings.setDatabaseEnabled(true);
settings.setAppCacheEnabled(true);
settings.setCacheMode(WebSettings.LOAD_DEFAULT);
settings.setPluginState(WebSettings.PluginState.ON);
settings.setAllowFileAccess(true);
settings.setLoadWithOverviewMode(false);
settings.setDomStorageEnabled(true);
chromeClient = new WebChromeClient() {
private CustomViewCallback callBack;
// 播放网络视频时全屏会被调用的方法
@Override
public void onShowCustomView(View view, CustomViewCallback callback) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
toolBar.setVisibility(View.INVISIBLE);
helpWeb.setVisibility(View.INVISIBLE);
// 如果一个视图已经存在,那么立刻终止并新建一个
if (videoView != null) {
callback.onCustomViewHidden();
return;
}
videoContainerView.addView(view);
videoView = view;
callBack = callback;
videoContainerView.setVisibility(View.VISIBLE);
setFullScreen();
}
// 视频播放退出全屏会被调用的
@Override
public void onHideCustomView() {
if (videoView == null)// 不是全屏播放状态
return;
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
videoView.setVisibility(View.GONE);
videoContainerView.removeView(videoView);
videoView = null;
videoContainerView.setVisibility(View.GONE);
callBack.onCustomViewHidden();
toolBar.setVisibility(View.VISIBLE);
helpWeb.setVisibility(View.VISIBLE);
quitFullScreen();
}
@Override
public void onProgressChanged(WebView view, int newProgress) {
if (newProgress == 100) {
progressBar.setVisibility(View.GONE);
} else {
if (View.INVISIBLE == progressBar.getVisibility()) {
progressBar.setVisibility(View.VISIBLE);
titleText.setText("页面加载中...");
}
progressBar.setProgress(newProgress);
}
super.onProgressChanged(view, newProgress);
}
};
helpWeb.setWebChromeClient(chromeClient);
helpWeb.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
WebView.HitTestResult hitTestResult = view.getHitTestResult();
if (!TextUtils.isEmpty(url) && hitTestResult == null) {
return;
}
titleText.setText(view.getTitle());
}
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
if (url.startsWith("http") || url.startsWith("https")
|| url.startsWith("javascript") || url.startsWith("file")) {
return super.shouldInterceptRequest(view, url);
} else {
String tips = "启动外部应用...";
try {
Intent in = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(in);
} catch (ActivityNotFoundException ex) {
tips = "启动外部应用失败,请安装最新版应用。";
}
return new WebResourceResponse("text/plain", "utf-8", new ByteArrayInputStream(tips.getBytes()));
}
}
});
helpWeb.setOnTouchListener(new View.OnTouchListener() {
private float x1 = 0;
private float x2 = 0;
private float y1 = 0;
private float y2 = 0;
@Override
public boolean onTouch(View v, MotionEvent event) {
//继承了Activity的onTouchEvent方法直接监听点击事件
if (event.getAction() == MotionEvent.ACTION_DOWN) {
//当手指按下的时候
x1 = event.getX();
y1 = event.getY();
}
if (event.getAction() == MotionEvent.ACTION_UP) {
//当手指离开的时候
x2 = event.getX();
y2 = event.getY();
if (y1 - y2 > 50) {
toolBar.setVisibility(View.GONE);
} else if (y2 - y1 > 50) {
toolBar.setVisibility(View.VISIBLE);
}
}
return false;
}
});
String url = getIntent().getStringExtra("url");
helpWeb.loadUrl(url);
}
@Override
public void onResume() {
super.onResume();
MobclickAgent.onResume(this);
helpWeb.onResume();
}
@Override
public void onPause() {
super.onPause();
MobclickAgent.onPause(this);
helpWeb.onPause();
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && helpWeb.canGoBack()) {
helpWeb.goBack();// 返回前一个页面
return true;
}
return super.onKeyDown(keyCode, event);
}
@Override
public void onBackPressed() {
if (videoView == null) {
super.onBackPressed();
} else {
chromeClient.onHideCustomView();
}
}
}

@ -1,282 +0,0 @@
package org.xing.calc;
import org.antlr.v4.runtime.ANTLRErrorListener;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.Parser;
import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.Recognizer;
import org.antlr.v4.runtime.atn.ATNConfigSet;
import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.tree.ParseTree;
import org.xing.calc.filter.CorrectionExprFilter;
import org.xing.calc.filter.ExprFilter;
import org.xing.calc.filter.PinyinExprFilter;
import org.xing.calc.parser.CalculatorEvalVisitor;
import org.xing.calc.parser.CalculatorLatexExprVisitor;
import org.xing.calc.parser.grammer.calculatorLexer;
import org.xing.calc.parser.grammer.calculatorParser;
import org.xing.utils.NumberUtil;
import java.io.InputStream;
import java.util.BitSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
/**
* @author Administrator
*
*/
public class Calculator implements ANTLRErrorListener{
/**
*
*/
private double lastResult;
/*
*
*/
private String lastReadExpr;
/*
*/
private String orgExpr;
/*
*/
private int errPos;
private String errMsg;
private String reason;
/**
*
*/
private List<ExprFilter> filters;
/*
*
*/
private Set<Character> continuousInputTag;
/*
*
*/
private Set<String> continuousFuncTag;
/*
*
*/
private Set<String> continuousPostFuncTag;
/*
*/
private Set<String> continuousPowTag;
public Calculator() {
setLastResult(0.0);
filters = new LinkedList<ExprFilter>();
String inputTags = "加+减-乘*×除/÷";
continuousInputTag = new HashSet<>();
for (int i = 0; i < inputTags.length(); i++) {
continuousInputTag.add(inputTags.charAt(i));
}
String[] funcTags = new String[]{"cos", "余弦", "sin",
"正弦", "tan", "正切", "acos", "反余弦", "asin", "反正弦",
"atan", "反正切", "ln", "log", "lg", "对数", "根号"};
continuousFuncTag = new HashSet<>();
for (int i = 0; i < funcTags.length; i++) {
continuousFuncTag.add(funcTags[i]);
}
String[] postFuncTags = new String[]{"开方", "开平方", "开立方", "平方根", "立方根"};
continuousPostFuncTag = new HashSet<>();
for (int i = 0; i < postFuncTags.length; i++) {
continuousPostFuncTag.add(postFuncTags[i]);
}
String[] powTags = new String[]{"平方", "立方"};
continuousPowTag = new HashSet<>();
for (int i = 0; i < powTags.length; i++) {
continuousPowTag.add(powTags[i]);
}
}
public void addFilter(ExprFilter filter) {
filters.add(filter);
}
public String execFilter(String expr) {
if(expr == null) return null;
for (ExprFilter filter : filters) {
expr = filter.call(expr);
}
return expr;
}
public double getLastResult() {
return lastResult;
}
public void setLastResult(double lastResult) {
this.lastResult = lastResult;
}
public String getErrMsg() {
return errMsg;
}
public String getReason() {
return reason;
}
public String getReadExpr() {
return lastReadExpr;
}
public void setErrorMsg(int pos, String r) {
int offset = 5;
if(errPos != -1) return;
if(orgExpr == null || pos < 0
|| pos >= orgExpr.length()) errMsg = null;
errPos = pos;
reason = r;
int start = pos > offset ? pos-offset:0;
int end = pos + offset < orgExpr.length() ? pos+offset:orgExpr.length();
errMsg = orgExpr.substring(start, end);
}
public Double innerEval(String expr) {
Double result = Double.NaN;
String readExpr = null;
ANTLRInputStream input = new ANTLRInputStream(expr);
calculatorLexer lexer = new calculatorLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
calculatorParser parser = new calculatorParser(tokens);
parser.addErrorListener(this);
ParseTree tree = parser.expression();
CalculatorEvalVisitor evalVisitor = new CalculatorEvalVisitor();
result = evalVisitor.visit(tree);
CalculatorLatexExprVisitor exprVisitor = new CalculatorLatexExprVisitor();
readExpr = exprVisitor.visit(tree);
if (result != null && !result.isNaN()) {
lastResult = result;
lastReadExpr = readExpr;
}
return result != null? result:Double.NaN;
}
public double eval(String expr) {
errMsg = null;
Double result = Double.NaN;
if(expr == null || expr.length() == 0) return result;
expr = expr.replace("再", "");
expr = expr.replace("等于", "");
expr = expr.replace("多少", "");
orgExpr = expr;
try {
for (ExprFilter filter : filters) {
expr = filter.call(expr);
}
//过滤的文字太多,视为无效表达式
if(orgExpr.length() - expr.length() > 4) {
return Double.NaN;
}
String currentExpr = null;
while(true) {
errPos = -1;
currentExpr = expr;
if(continuousInputTag.contains(expr.charAt(0))) {
expr = NumberUtil.format(this.lastResult, 8)+expr;
}else if(continuousFuncTag.contains(expr)) {
expr = expr + NumberUtil.format(this.lastResult, 8);
}else if(continuousPostFuncTag.contains(expr)) {
expr = NumberUtil.format(this.lastResult, 8)+ expr;
}else if(continuousPowTag.contains(expr)) {
expr = NumberUtil.format(this.lastResult, 8) + "的" + expr;
}
result = innerEval(expr);
if(errPos >= 0 && errPos <= currentExpr.length()) {
if(errPos < currentExpr.length() && currentExpr.charAt(errPos) == '点') {
char[] seq = currentExpr.toCharArray();
seq[errPos] = '减';
expr = String.valueOf(seq);
}else if(reason != null && reason.contains("次方")) {
//21的三九减四点六 中间的“的”改为“点”
char[] seq = currentExpr.toCharArray();
while(errPos >= 0) {
if(errPos < currentExpr.length() && seq[errPos] == '的') {
seq[errPos] = '点';
expr = String.valueOf(seq);
break;
}
errPos --;
}
if(errPos < 0) break;
} else {
break;
}
} else {
break;
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
return result;
}
public static Calculator createDefault(HashMap<Character, String> pinyin) {
String allowedChars =
"0123456789.零一二三四五六七八九点负个十百千万亿+-*/括号加上减去乘以除÷×根号开方的平方次方立方分之" +
"sincostanlglogln反正弦反余弦反正切对数()|^度°派π又";
Calculator calc = new Calculator();
calc.addFilter(new CorrectionExprFilter());
calc.addFilter(new PinyinExprFilter(allowedChars, pinyin));
return calc;
}
@Override
public void syntaxError(Recognizer<?, ?> recognizer, Object o, int i, int i1, String s, RecognitionException e) {
setErrorMsg(i1, s);
}
@Override
public void reportAmbiguity(Parser parser, DFA dfa, int i, int i1, boolean b, BitSet bitSet, ATNConfigSet atnConfigSet) {
setErrorMsg(i1, "");
}
@Override
public void reportAttemptingFullContext(Parser parser, DFA dfa, int i, int i1, BitSet bitSet, ATNConfigSet atnConfigSet) {
setErrorMsg(i1, "");
}
@Override
public void reportContextSensitivity(Parser parser, DFA dfa, int i, int i1, int i2, ATNConfigSet atnConfigSet) {
setErrorMsg(i1, "");
}
}

@ -1,65 +0,0 @@
package org.xing.calc;
import java.util.Random;
import java.util.Vector;
/**
* Created by Administrator on 2017/2/21 0021.
*/
public class Tips {
private Random random;
private Vector<String> tipsStr;
public Tips() {
random = new Random();
tipsStr = new Vector<>();
}
public void add(String tip) {
tipsStr.add(tip);
}
public String get(int index) {
if(index >= 0 && index < tipsStr.size())
return tipsStr.get(index);
else
return null;
}
public String randomGet() {
if(tipsStr.size() > 0) {
return tipsStr.get(
random.nextInt(tipsStr.size())
);
}
return null;
}
public static Tips createSimpleTips() {
Tips tips = new Tips();
tips.add("试一下:'帮助'");
tips.add("试一下:'升级'");
tips.add("试一下:'主题'");
tips.add("试一下:'三分之一'");
tips.add("试一下:'加一千'");
tips.add("试一下:'删除'");
tips.add("试一下:'对数三'");
tips.add("试一下:'三对数五'");
tips.add("试一下:'清空'");
tips.add("试一下:'二乘括号二加一括号'");
tips.add("试一下:'正弦零点二'");
tips.add("试一下:'正弦三分之派'");
tips.add("试一下:'正弦三十度'");
tips.add("试一下:'根号五'");
tips.add("试一下:'三根号五'");
tips.add("试一下:'三的平方'");
tips.add("试一下:'三的四次方'");
tips.add("试一下:'百度'");
tips.add("试一下:'讯飞'");
tips.add("试一下:'引擎'");
tips.add("试一下:'退出'");
tips.add("提示:分享三次可彻底删除广告");
return tips;
}
}

@ -1,28 +0,0 @@
package org.xing.calc.cmd;
import org.xing.calc.cmd.grammer.cmdBaseVisitor;
import org.xing.calc.cmd.grammer.cmdParser;
public class CmdDefaultVisitor extends cmdBaseVisitor<Integer>{
@Override public Integer visitCommand(cmdParser.CommandContext ctx) {
if(ctx.qingping() != null) {
return 1;
}else if(ctx.goback() != null) {
return 2;
}else if(ctx.help() != null) {
return 3;
}else if(ctx.update() != null) {
return 4;
}else if(ctx.theme() != null) {
return 5;
}else if(ctx.engine() != null) {
return 6;
}else if(ctx.close() != null) {
return 7;
}else if(ctx.stop() != null) {
return 8;
}
return 0;
}
}

@ -1,31 +0,0 @@
package org.xing.calc.cmd;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import org.xing.calc.cmd.grammer.cmdLexer;
import org.xing.calc.cmd.grammer.cmdParser;
public class CmdParser {
public CmdParser() {
}
public int parse(String expr) {
try {
ANTLRInputStream input = new ANTLRInputStream(expr);
cmdLexer lexer = new cmdLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
cmdParser parser = new cmdParser(tokens);
ParseTree tree = parser.command();
if(tree == null) return 0;
else {
CmdDefaultVisitor visitor = new CmdDefaultVisitor();
return visitor.visit(tree);
}
}catch (Exception ex) {
ex.printStackTrace();
}
return 0;
}
}

@ -1,77 +0,0 @@
// Generated from src/org/xing/calc/cmd/grammer/cmd.g4 by ANTLR 4.6
package org.xing.calc.cmd.grammer;
import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
/**
* This class provides an empty implementation of {@link cmdVisitor},
* which can be extended to create a visitor which only needs to handle a subset
* of the available methods.
*
* @param <T> The return type of the visit operation. Use {@link Void} for
* operations with no return type.
*/
public class cmdBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements cmdVisitor<T> {
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitCommand(cmdParser.CommandContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitQingping(cmdParser.QingpingContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitGoback(cmdParser.GobackContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitHelp(cmdParser.HelpContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitUpdate(cmdParser.UpdateContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitTheme(cmdParser.ThemeContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitEngine(cmdParser.EngineContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitClose(cmdParser.CloseContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitStop(cmdParser.StopContext ctx) { return visitChildren(ctx); }
}

@ -1,140 +0,0 @@
// Generated from src/org/xing/calc/cmd/grammer/cmd.g4 by ANTLR 4.6
package org.xing.calc.cmd.grammer;
import org.antlr.v4.runtime.Lexer;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.TokenStream;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.atn.*;
import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.misc.*;
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
public class cmdLexer extends Lexer {
static { RuntimeMetaData.checkVersion("4.6", RuntimeMetaData.VERSION); }
protected static final DFA[] _decisionToDFA;
protected static final PredictionContextCache _sharedContextCache =
new PredictionContextCache();
public static final int
T__0=1, T__1=2, T__2=3, T__3=4, T__4=5, T__5=6, T__6=7, T__7=8, T__8=9,
T__9=10, T__10=11, T__11=12, T__12=13, T__13=14, T__14=15, T__15=16, T__16=17,
T__17=18, T__18=19, T__19=20, T__20=21, T__21=22, T__22=23, WS=24;
public static String[] modeNames = {
"DEFAULT_MODE"
};
public static final String[] ruleNames = {
"T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", "T__7", "T__8",
"T__9", "T__10", "T__11", "T__12", "T__13", "T__14", "T__15", "T__16",
"T__17", "T__18", "T__19", "T__20", "T__21", "T__22", "WS"
};
private static final String[] _LITERAL_NAMES = {
null, "'清屏'", "'清空'", "'清除'", "'全部'", "'撤销'", "'取消'", "'倒退'", "'后退'",
"'删除'", "'帮助'", "'示例'", "'说明'", "'升级'", "'版本'", "'主题'", "'风格'", "'背景'",
"'引擎'", "'百度'", "'讯飞'", "'退出'", "'关闭'", "'暂停'"
};
private static final String[] _SYMBOLIC_NAMES = {
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null,
"WS"
};
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
/**
* @deprecated Use {@link #VOCABULARY} instead.
*/
@Deprecated
public static final String[] tokenNames;
static {
tokenNames = new String[_SYMBOLIC_NAMES.length];
for (int i = 0; i < tokenNames.length; i++) {
tokenNames[i] = VOCABULARY.getLiteralName(i);
if (tokenNames[i] == null) {
tokenNames[i] = VOCABULARY.getSymbolicName(i);
}
if (tokenNames[i] == null) {
tokenNames[i] = "<INVALID>";
}
}
}
@Override
@Deprecated
public String[] getTokenNames() {
return tokenNames;
}
@Override
public Vocabulary getVocabulary() {
return VOCABULARY;
}
public cmdLexer(CharStream input) {
super(input);
_interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
}
@Override
public String getGrammarFileName() { return "cmd.g4"; }
@Override
public String[] getRuleNames() { return ruleNames; }
@Override
public String getSerializedATN() { return _serializedATN; }
@Override
public String[] getModeNames() { return modeNames; }
@Override
public ATN getATN() { return _ATN; }
public static final String _serializedATN =
"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2\32\177\b\1\4\2\t"+
"\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+
"\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+
"\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+
"\3\2\3\2\3\2\3\3\3\3\3\3\3\4\3\4\3\4\3\5\3\5\3\5\3\6\3\6\3\6\3\7\3\7\3"+
"\7\3\b\3\b\3\b\3\t\3\t\3\t\3\n\3\n\3\n\3\13\3\13\3\13\3\f\3\f\3\f\3\r"+
"\3\r\3\r\3\16\3\16\3\16\3\17\3\17\3\17\3\20\3\20\3\20\3\21\3\21\3\21\3"+
"\22\3\22\3\22\3\23\3\23\3\23\3\24\3\24\3\24\3\25\3\25\3\25\3\26\3\26\3"+
"\26\3\27\3\27\3\27\3\30\3\30\3\30\3\31\6\31z\n\31\r\31\16\31{\3\31\3\31"+
"\2\2\32\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17"+
"\35\20\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\3\2\3\5\2\13\f\17"+
"\17\"\"\177\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2"+
"\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27"+
"\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2"+
"\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2\2\2+\3\2\2\2\2-\3\2\2\2"+
"\2/\3\2\2\2\2\61\3\2\2\2\3\63\3\2\2\2\5\66\3\2\2\2\79\3\2\2\2\t<\3\2\2"+
"\2\13?\3\2\2\2\rB\3\2\2\2\17E\3\2\2\2\21H\3\2\2\2\23K\3\2\2\2\25N\3\2"+
"\2\2\27Q\3\2\2\2\31T\3\2\2\2\33W\3\2\2\2\35Z\3\2\2\2\37]\3\2\2\2!`\3\2"+
"\2\2#c\3\2\2\2%f\3\2\2\2\'i\3\2\2\2)l\3\2\2\2+o\3\2\2\2-r\3\2\2\2/u\3"+
"\2\2\2\61y\3\2\2\2\63\64\7\u6e07\2\2\64\65\7\u5c51\2\2\65\4\3\2\2\2\66"+
"\67\7\u6e07\2\2\678\7\u7a7c\2\28\6\3\2\2\29:\7\u6e07\2\2:;\7\u9666\2\2"+
";\b\3\2\2\2<=\7\u516a\2\2=>\7\u90ea\2\2>\n\3\2\2\2?@\7\u64a6\2\2@A\7\u9502"+
"\2\2A\f\3\2\2\2BC\7\u53d8\2\2CD\7\u6d8a\2\2D\16\3\2\2\2EF\7\u5014\2\2"+
"FG\7\u9002\2\2G\20\3\2\2\2HI\7\u5410\2\2IJ\7\u9002\2\2J\22\3\2\2\2KL\7"+
"\u5222\2\2LM\7\u9666\2\2M\24\3\2\2\2NO\7\u5e30\2\2OP\7\u52ab\2\2P\26\3"+
"\2\2\2QR\7\u793c\2\2RS\7\u4f8d\2\2S\30\3\2\2\2TU\7\u8bf6\2\2UV\7\u6610"+
"\2\2V\32\3\2\2\2WX\7\u5349\2\2XY\7\u7ea9\2\2Y\34\3\2\2\2Z[\7\u724a\2\2"+
"[\\\7\u672e\2\2\\\36\3\2\2\2]^\7\u4e3d\2\2^_\7\u989a\2\2_ \3\2\2\2`a\7"+
"\u98d0\2\2ab\7\u683e\2\2b\"\3\2\2\2cd\7\u80ce\2\2de\7\u6671\2\2e$\3\2"+
"\2\2fg\7\u5f17\2\2gh\7\u64d0\2\2h&\3\2\2\2ij\7\u7680\2\2jk\7\u5ea8\2\2"+
"k(\3\2\2\2lm\7\u8bb1\2\2mn\7\u98e0\2\2n*\3\2\2\2op\7\u9002\2\2pq\7\u51fc"+
"\2\2q,\3\2\2\2rs\7\u5175\2\2st\7\u95ef\2\2t.\3\2\2\2uv\7\u6684\2\2vw\7"+
"\u505e\2\2w\60\3\2\2\2xz\t\2\2\2yx\3\2\2\2z{\3\2\2\2{y\3\2\2\2{|\3\2\2"+
"\2|}\3\2\2\2}~\b\31\2\2~\62\3\2\2\2\4\2{\3\2\3\2";
public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static {
_decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
_decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
}
}
}

@ -1,597 +0,0 @@
// Generated from src/org/xing/calc/cmd/grammer/cmd.g4 by ANTLR 4.6
package org.xing.calc.cmd.grammer;
import org.antlr.v4.runtime.atn.*;
import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.misc.*;
import org.antlr.v4.runtime.tree.*;
import java.util.List;
import java.util.Iterator;
import java.util.ArrayList;
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
public class cmdParser extends Parser {
static { RuntimeMetaData.checkVersion("4.6", RuntimeMetaData.VERSION); }
protected static final DFA[] _decisionToDFA;
protected static final PredictionContextCache _sharedContextCache =
new PredictionContextCache();
public static final int
T__0=1, T__1=2, T__2=3, T__3=4, T__4=5, T__5=6, T__6=7, T__7=8, T__8=9,
T__9=10, T__10=11, T__11=12, T__12=13, T__13=14, T__14=15, T__15=16, T__16=17,
T__17=18, T__18=19, T__19=20, T__20=21, T__21=22, T__22=23, WS=24;
public static final int
RULE_command = 0, RULE_qingping = 1, RULE_goback = 2, RULE_help = 3, RULE_update = 4,
RULE_theme = 5, RULE_engine = 6, RULE_close = 7, RULE_stop = 8;
public static final String[] ruleNames = {
"command", "qingping", "goback", "help", "update", "theme", "engine",
"close", "stop"
};
private static final String[] _LITERAL_NAMES = {
null, "'清屏'", "'清空'", "'清除'", "'全部'", "'撤销'", "'取消'", "'倒退'", "'后退'",
"'删除'", "'帮助'", "'示例'", "'说明'", "'升级'", "'版本'", "'主题'", "'风格'", "'背景'",
"'引擎'", "'百度'", "'讯飞'", "'退出'", "'关闭'", "'暂停'"
};
private static final String[] _SYMBOLIC_NAMES = {
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null,
"WS"
};
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
/**
* @deprecated Use {@link #VOCABULARY} instead.
*/
@Deprecated
public static final String[] tokenNames;
static {
tokenNames = new String[_SYMBOLIC_NAMES.length];
for (int i = 0; i < tokenNames.length; i++) {
tokenNames[i] = VOCABULARY.getLiteralName(i);
if (tokenNames[i] == null) {
tokenNames[i] = VOCABULARY.getSymbolicName(i);
}
if (tokenNames[i] == null) {
tokenNames[i] = "<INVALID>";
}
}
}
@Override
@Deprecated
public String[] getTokenNames() {
return tokenNames;
}
@Override
public Vocabulary getVocabulary() {
return VOCABULARY;
}
@Override
public String getGrammarFileName() { return "cmd.g4"; }
@Override
public String[] getRuleNames() { return ruleNames; }
@Override
public String getSerializedATN() { return _serializedATN; }
@Override
public ATN getATN() { return _ATN; }
public cmdParser(TokenStream input) {
super(input);
_interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
}
public static class CommandContext extends ParserRuleContext {
public QingpingContext qingping() {
return getRuleContext(QingpingContext.class,0);
}
public GobackContext goback() {
return getRuleContext(GobackContext.class,0);
}
public HelpContext help() {
return getRuleContext(HelpContext.class,0);
}
public UpdateContext update() {
return getRuleContext(UpdateContext.class,0);
}
public ThemeContext theme() {
return getRuleContext(ThemeContext.class,0);
}
public EngineContext engine() {
return getRuleContext(EngineContext.class,0);
}
public CloseContext close() {
return getRuleContext(CloseContext.class,0);
}
public StopContext stop() {
return getRuleContext(StopContext.class,0);
}
public CommandContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@Override public int getRuleIndex() { return RULE_command; }
@Override
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
if ( visitor instanceof cmdVisitor ) return ((cmdVisitor<? extends T>)visitor).visitCommand(this);
else return visitor.visitChildren(this);
}
}
public final CommandContext command() throws RecognitionException {
CommandContext _localctx = new CommandContext(_ctx, getState());
enterRule(_localctx, 0, RULE_command);
try {
setState(26);
_errHandler.sync(this);
switch (_input.LA(1)) {
case T__0:
case T__1:
case T__2:
case T__3:
enterOuterAlt(_localctx, 1);
{
setState(18);
qingping();
}
break;
case T__4:
case T__5:
case T__6:
case T__7:
case T__8:
enterOuterAlt(_localctx, 2);
{
setState(19);
goback();
}
break;
case T__9:
case T__10:
case T__11:
enterOuterAlt(_localctx, 3);
{
setState(20);
help();
}
break;
case T__12:
case T__13:
enterOuterAlt(_localctx, 4);
{
setState(21);
update();
}
break;
case T__14:
case T__15:
case T__16:
enterOuterAlt(_localctx, 5);
{
setState(22);
theme();
}
break;
case T__17:
case T__18:
case T__19:
enterOuterAlt(_localctx, 6);
{
setState(23);
engine();
}
break;
case T__20:
case T__21:
enterOuterAlt(_localctx, 7);
{
setState(24);
close();
}
break;
case T__22:
enterOuterAlt(_localctx, 8);
{
setState(25);
stop();
}
break;
default:
throw new NoViableAltException(this);
}
}
catch (RecognitionException re) {
_localctx.exception = re;
_errHandler.reportError(this, re);
_errHandler.recover(this, re);
}
finally {
exitRule();
}
return _localctx;
}
public static class QingpingContext extends ParserRuleContext {
public GobackContext goback() {
return getRuleContext(GobackContext.class,0);
}
public QingpingContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@Override public int getRuleIndex() { return RULE_qingping; }
@Override
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
if ( visitor instanceof cmdVisitor ) return ((cmdVisitor<? extends T>)visitor).visitQingping(this);
else return visitor.visitChildren(this);
}
}
public final QingpingContext qingping() throws RecognitionException {
QingpingContext _localctx = new QingpingContext(_ctx, getState());
enterRule(_localctx, 2, RULE_qingping);
try {
setState(33);
_errHandler.sync(this);
switch (_input.LA(1)) {
case T__0:
enterOuterAlt(_localctx, 1);
{
setState(28);
match(T__0);
}
break;
case T__1:
enterOuterAlt(_localctx, 2);
{
setState(29);
match(T__1);
}
break;
case T__2:
enterOuterAlt(_localctx, 3);
{
setState(30);
match(T__2);
}
break;
case T__3:
enterOuterAlt(_localctx, 4);
{
{
setState(31);
match(T__3);
setState(32);
goback();
}
}
break;
default:
throw new NoViableAltException(this);
}
}
catch (RecognitionException re) {
_localctx.exception = re;
_errHandler.reportError(this, re);
_errHandler.recover(this, re);
}
finally {
exitRule();
}
return _localctx;
}
public static class GobackContext extends ParserRuleContext {
public GobackContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@Override public int getRuleIndex() { return RULE_goback; }
@Override
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
if ( visitor instanceof cmdVisitor ) return ((cmdVisitor<? extends T>)visitor).visitGoback(this);
else return visitor.visitChildren(this);
}
}
public final GobackContext goback() throws RecognitionException {
GobackContext _localctx = new GobackContext(_ctx, getState());
enterRule(_localctx, 4, RULE_goback);
int _la;
try {
enterOuterAlt(_localctx, 1);
{
setState(35);
_la = _input.LA(1);
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__4) | (1L << T__5) | (1L << T__6) | (1L << T__7) | (1L << T__8))) != 0)) ) {
_errHandler.recoverInline(this);
}
else {
if ( _input.LA(1)==Token.EOF ) matchedEOF = true;
_errHandler.reportMatch(this);
consume();
}
}
}
catch (RecognitionException re) {
_localctx.exception = re;
_errHandler.reportError(this, re);
_errHandler.recover(this, re);
}
finally {
exitRule();
}
return _localctx;
}
public static class HelpContext extends ParserRuleContext {
public HelpContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@Override public int getRuleIndex() { return RULE_help; }
@Override
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
if ( visitor instanceof cmdVisitor ) return ((cmdVisitor<? extends T>)visitor).visitHelp(this);
else return visitor.visitChildren(this);
}
}
public final HelpContext help() throws RecognitionException {
HelpContext _localctx = new HelpContext(_ctx, getState());
enterRule(_localctx, 6, RULE_help);
int _la;
try {
enterOuterAlt(_localctx, 1);
{
setState(37);
_la = _input.LA(1);
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__9) | (1L << T__10) | (1L << T__11))) != 0)) ) {
_errHandler.recoverInline(this);
}
else {
if ( _input.LA(1)==Token.EOF ) matchedEOF = true;
_errHandler.reportMatch(this);
consume();
}
}
}
catch (RecognitionException re) {
_localctx.exception = re;
_errHandler.reportError(this, re);
_errHandler.recover(this, re);
}
finally {
exitRule();
}
return _localctx;
}
public static class UpdateContext extends ParserRuleContext {
public UpdateContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@Override public int getRuleIndex() { return RULE_update; }
@Override
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
if ( visitor instanceof cmdVisitor ) return ((cmdVisitor<? extends T>)visitor).visitUpdate(this);
else return visitor.visitChildren(this);
}
}
public final UpdateContext update() throws RecognitionException {
UpdateContext _localctx = new UpdateContext(_ctx, getState());
enterRule(_localctx, 8, RULE_update);
int _la;
try {
enterOuterAlt(_localctx, 1);
{
setState(39);
_la = _input.LA(1);
if ( !(_la==T__12 || _la==T__13) ) {
_errHandler.recoverInline(this);
}
else {
if ( _input.LA(1)==Token.EOF ) matchedEOF = true;
_errHandler.reportMatch(this);
consume();
}
}
}
catch (RecognitionException re) {
_localctx.exception = re;
_errHandler.reportError(this, re);
_errHandler.recover(this, re);
}
finally {
exitRule();
}
return _localctx;
}
public static class ThemeContext extends ParserRuleContext {
public ThemeContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@Override public int getRuleIndex() { return RULE_theme; }
@Override
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
if ( visitor instanceof cmdVisitor ) return ((cmdVisitor<? extends T>)visitor).visitTheme(this);
else return visitor.visitChildren(this);
}
}
public final ThemeContext theme() throws RecognitionException {
ThemeContext _localctx = new ThemeContext(_ctx, getState());
enterRule(_localctx, 10, RULE_theme);
int _la;
try {
enterOuterAlt(_localctx, 1);
{
setState(41);
_la = _input.LA(1);
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__14) | (1L << T__15) | (1L << T__16))) != 0)) ) {
_errHandler.recoverInline(this);
}
else {
if ( _input.LA(1)==Token.EOF ) matchedEOF = true;
_errHandler.reportMatch(this);
consume();
}
}
}
catch (RecognitionException re) {
_localctx.exception = re;
_errHandler.reportError(this, re);
_errHandler.recover(this, re);
}
finally {
exitRule();
}
return _localctx;
}
public static class EngineContext extends ParserRuleContext {
public EngineContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@Override public int getRuleIndex() { return RULE_engine; }
@Override
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
if ( visitor instanceof cmdVisitor ) return ((cmdVisitor<? extends T>)visitor).visitEngine(this);
else return visitor.visitChildren(this);
}
}
public final EngineContext engine() throws RecognitionException {
EngineContext _localctx = new EngineContext(_ctx, getState());
enterRule(_localctx, 12, RULE_engine);
int _la;
try {
enterOuterAlt(_localctx, 1);
{
setState(43);
_la = _input.LA(1);
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__17) | (1L << T__18) | (1L << T__19))) != 0)) ) {
_errHandler.recoverInline(this);
}
else {
if ( _input.LA(1)==Token.EOF ) matchedEOF = true;
_errHandler.reportMatch(this);
consume();
}
}
}
catch (RecognitionException re) {
_localctx.exception = re;
_errHandler.reportError(this, re);
_errHandler.recover(this, re);
}
finally {
exitRule();
}
return _localctx;
}
public static class CloseContext extends ParserRuleContext {
public CloseContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@Override public int getRuleIndex() { return RULE_close; }
@Override
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
if ( visitor instanceof cmdVisitor ) return ((cmdVisitor<? extends T>)visitor).visitClose(this);
else return visitor.visitChildren(this);
}
}
public final CloseContext close() throws RecognitionException {
CloseContext _localctx = new CloseContext(_ctx, getState());
enterRule(_localctx, 14, RULE_close);
int _la;
try {
enterOuterAlt(_localctx, 1);
{
setState(45);
_la = _input.LA(1);
if ( !(_la==T__20 || _la==T__21) ) {
_errHandler.recoverInline(this);
}
else {
if ( _input.LA(1)==Token.EOF ) matchedEOF = true;
_errHandler.reportMatch(this);
consume();
}
}
}
catch (RecognitionException re) {
_localctx.exception = re;
_errHandler.reportError(this, re);
_errHandler.recover(this, re);
}
finally {
exitRule();
}
return _localctx;
}
public static class StopContext extends ParserRuleContext {
public StopContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@Override public int getRuleIndex() { return RULE_stop; }
@Override
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
if ( visitor instanceof cmdVisitor ) return ((cmdVisitor<? extends T>)visitor).visitStop(this);
else return visitor.visitChildren(this);
}
}
public final StopContext stop() throws RecognitionException {
StopContext _localctx = new StopContext(_ctx, getState());
enterRule(_localctx, 16, RULE_stop);
try {
enterOuterAlt(_localctx, 1);
{
setState(47);
match(T__22);
}
}
catch (RecognitionException re) {
_localctx.exception = re;
_errHandler.reportError(this, re);
_errHandler.recover(this, re);
}
finally {
exitRule();
}
return _localctx;
}
public static final String _serializedATN =
"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3\32\64\4\2\t\2\4\3"+
"\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\3\2\3\2\3"+
"\2\3\2\3\2\3\2\3\2\3\2\5\2\35\n\2\3\3\3\3\3\3\3\3\3\3\5\3$\n\3\3\4\3\4"+
"\3\5\3\5\3\6\3\6\3\7\3\7\3\b\3\b\3\t\3\t\3\n\3\n\3\n\2\2\13\2\4\6\b\n"+
"\f\16\20\22\2\b\3\2\7\13\3\2\f\16\3\2\17\20\3\2\21\23\3\2\24\26\3\2\27"+
"\30\64\2\34\3\2\2\2\4#\3\2\2\2\6%\3\2\2\2\b\'\3\2\2\2\n)\3\2\2\2\f+\3"+
"\2\2\2\16-\3\2\2\2\20/\3\2\2\2\22\61\3\2\2\2\24\35\5\4\3\2\25\35\5\6\4"+
"\2\26\35\5\b\5\2\27\35\5\n\6\2\30\35\5\f\7\2\31\35\5\16\b\2\32\35\5\20"+
"\t\2\33\35\5\22\n\2\34\24\3\2\2\2\34\25\3\2\2\2\34\26\3\2\2\2\34\27\3"+
"\2\2\2\34\30\3\2\2\2\34\31\3\2\2\2\34\32\3\2\2\2\34\33\3\2\2\2\35\3\3"+
"\2\2\2\36$\7\3\2\2\37$\7\4\2\2 $\7\5\2\2!\"\7\6\2\2\"$\5\6\4\2#\36\3\2"+
"\2\2#\37\3\2\2\2# \3\2\2\2#!\3\2\2\2$\5\3\2\2\2%&\t\2\2\2&\7\3\2\2\2\'"+
"(\t\3\2\2(\t\3\2\2\2)*\t\4\2\2*\13\3\2\2\2+,\t\5\2\2,\r\3\2\2\2-.\t\6"+
"\2\2.\17\3\2\2\2/\60\t\7\2\2\60\21\3\2\2\2\61\62\7\31\2\2\62\23\3\2\2"+
"\2\4\34#";
public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static {
_decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
_decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
}
}
}

@ -1,67 +0,0 @@
// Generated from src/org/xing/calc/cmd/grammer/cmd.g4 by ANTLR 4.6
package org.xing.calc.cmd.grammer;
import org.antlr.v4.runtime.tree.ParseTreeVisitor;
/**
* This interface defines a complete generic visitor for a parse tree produced
* by {@link cmdParser}.
*
* @param <T> The return type of the visit operation. Use {@link Void} for
* operations with no return type.
*/
public interface cmdVisitor<T> extends ParseTreeVisitor<T> {
/**
* Visit a parse tree produced by {@link cmdParser#command}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitCommand(cmdParser.CommandContext ctx);
/**
* Visit a parse tree produced by {@link cmdParser#qingping}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitQingping(cmdParser.QingpingContext ctx);
/**
* Visit a parse tree produced by {@link cmdParser#goback}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitGoback(cmdParser.GobackContext ctx);
/**
* Visit a parse tree produced by {@link cmdParser#help}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitHelp(cmdParser.HelpContext ctx);
/**
* Visit a parse tree produced by {@link cmdParser#update}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitUpdate(cmdParser.UpdateContext ctx);
/**
* Visit a parse tree produced by {@link cmdParser#theme}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitTheme(cmdParser.ThemeContext ctx);
/**
* Visit a parse tree produced by {@link cmdParser#engine}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitEngine(cmdParser.EngineContext ctx);
/**
* Visit a parse tree produced by {@link cmdParser#close}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitClose(cmdParser.CloseContext ctx);
/**
* Visit a parse tree produced by {@link cmdParser#stop}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitStop(cmdParser.StopContext ctx);
}

@ -1,210 +0,0 @@
package org.xing.calc.filter;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class CorrectionExprFilter implements ExprFilter {
private StringBuilder regStr;
private Map<String, String> correctionStringMap;
public CorrectionExprFilter() {
regStr = new StringBuilder();
correctionStringMap = new HashMap<>();
addWord("佛", "负");
addWord("塑", "负");
addWord("僵", "加");
addWord("讲", "加");
addWord("将", "加");
addWord("奖", "加");
addWord("缉", "减");
addWord("倍", "乘");
addWord("澄", "乘");
addWord("橙", "乘");
addWord("盛", "乘");
addWord("重", "乘");
addWord("层", "乘");
addWord("曾", "乘");
addWord("城里", "乘以");
addWord("成语", "乘以");
addWord("初一", "除以");
addWord("乘与", "除以");
addWord("完了", "");
addWord("区", "除");
addWord("褚", "除");
addWord("括弧", "括号");
//一块二这种金额的表达方式
addWord("块", "点");
addWord(":", "点");
addWord("", "点");
addWord("幺", "一");
addWord("e", "一");
addWord("两", "二");
addWord("俩", "二");
addWord("山", "3");
addWord("善", "3");
addWord("潘", "3");
addWord("仨", "三");
addWord("是", "4");
addWord("事", "4");
addWord("士", "4");
addWord("式", "4");
addWord("氏", "4");
addWord("市", "4");
addWord("世", "4");
addWord("师", "4");
addWord("我", "5");
addWord("陆", "6");
addWord("料", "6");
addWord("乐", "6");
addWord("榴", "6");
addWord("亲", "7");
addWord("鸡", "7");
addWord("夕", "7");
addWord("欹", "7");
addWord("班", "8");
addWord("发", "8");
addWord("近", "9");
addWord("教", "9");
addWord("鱼线", "余弦");
addWord("预先", "余弦");
addWord("遇险", "余弦");
addWord("鱼鲜", "余弦");
addWord("玉仙", "余弦");
addWord("欲仙", "余弦");
addWord("预选", "余弦");
addWord("雨轩", "余弦");
addWord("宇轩", "余弦");
addWord("预选", "余弦");
addWord("玉轩", "余弦");
addWord("范玉献", "反余弦");
addWord("范瑜轩", "反余弦");
addWord("赣榆县", "反余弦");
addWord("争先", "正弦");
addWord("正线", "正弦");
addWord("争鲜", "正弦");
addWord("正选", "正弦");
addWord("郑玄", "正弦");
addWord("郑璇", "正弦");
addWord("反正选", "反正弦");
addWord("反正旋", "反正弦");
addWord("正确", "正切");
addWord("争取", "正切");
addWord("证券", "正切");
addWord("挣钱", "正切");
addWord("正气", "正切");
addWord("争气", "正切");
addWord("政权", "正切");
addWord("征求", "正切");
addWord("反正钱", "反正切");
addWord("反正去", "反正切");
addWord("括回", "括号");
addWord("货号", "括号");
addWord("对手", "对数");
addWord("开封", "开方");
addWord("次幂", "次方");
addWord("等于", "");
addWord("多少", "");
addWord("的差", "");
addWord("的和", "");
addWord("的积", "");
addWord("的商", "");
addWord("%", "/100");
addWord("", "/100");
addWord("以前", "一千");
addWord("^2", "的平方");
addWord("佳茵", "加一");
addWord("捡漏", "减六");
addWord("捡了", "减六");
addWord("图六", "除六");
addWord("除了", "除六");
addWord("成龙", "乘六");
addWord("成了", "乘六");
addWord("天气", "减七");
addWord("欹", "七");
addWord("成绩", "乘七");
addWord("长期", "乘七");
addWord("城西", "乘七");
addWord("晨曦", "乘七");
addWord("城邦", "乘八");
addWord("乘邦", "乘八");
addWord("主角", "除九");
addWord("图九", "除九");
addWord("圆周率", "派");
addWord("请您", "清零");
addWord("清平", "清屏");
addWord("青平", "清屏");
addWord("青萍", "清屏");
addWord("青苹", "清屏");
addWord("蜻蜓", "清屏");
addWord("金瓶", "清屏");
addWord("金平", "清屏");
addWord("亲萍", "清屏");
addWord("星空", "清空");
addWord("净空", "清空");
addWord("浙江", "撤销");
addWord("大腿", "倒退");
addWord("车享", "倒退");
addWord("阴茎", "引擎");
addWord("隐形", "引擎");
}
private void addWord(String tar, String with) {
if(regStr.length() > 0) {
regStr.append("|");
}
regStr.append("(");
String temp = tar;
temp = temp.replace("^", "\\^");
temp = temp.replace("%", "\\%");
regStr.append(temp);
regStr.append(")");
correctionStringMap.put(tar, with);
}
@Override
public String call(String expr) {
int start = 0;
StringBuilder str = new StringBuilder();
Pattern correctionPattern = Pattern.compile(regStr.toString());
Matcher mch = correctionPattern.matcher(expr);
while(mch.find()) {
if(mch.start() > start) {
str.append(expr.substring(start, mch.start()));
}
str.append(correctionStringMap.get(mch.group()));
start = mch.end();
}
if(start < expr.length()) {
str.append(expr.substring(start));
}
return str.toString();
}
}

@ -1,5 +0,0 @@
package org.xing.calc.filter;
public interface ExprFilter {
String call(String expr);
}

@ -1,33 +0,0 @@
package org.xing.calc.filter;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
/**
* Created by xing on 2017/5/10.
*/
public class ExprFilterChain implements ExprFilter {
private LinkedList<ExprFilter> filters;
public ExprFilterChain() {
filters = new LinkedList<>();
}
public ExprFilterChain(String allowedChars, HashMap<Character, String> pinyin) {
filters = new LinkedList<>();
filters.add(new CorrectionExprFilter());
filters.add(new PinyinExprFilter(allowedChars, pinyin));
}
public void addExprFilter(ExprFilter filter) {
filters.add(filter);
}
public String call(String expr) {
String temp = expr;
for(ExprFilter filter : filters) {
temp = filter.call(temp);
}
return temp;
}
}

@ -1,106 +0,0 @@
package org.xing.calc.filter;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class PinyinExprFilter implements ExprFilter{
private Set<Character> allowedChars;
private Map<String, Character> allowedCharsPinyin;
private HashMap<Character, String> pinyin;
public PinyinExprFilter(String legalChars, HashMap<Character, String> pinyin) {
this.pinyin = (HashMap<Character, String> )pinyin.clone();
allowedChars = new HashSet<Character>();
allowedCharsPinyin = new HashMap<String, Character>();
for(int i=0;i<legalChars.length();i++) {
Character c = legalChars.charAt(i);
allowedChars.add(c);
if(pinyin!= null && pinyin.containsKey(c)) {
if(allowedCharsPinyin.containsKey(pinyin.get(c))) {
System.err.println("严重错误,有拼音相同的字:"+c);
}else {
allowedCharsPinyin.put(pinyin.get(c), c);
}
}
}
//通过拼音来加入纠正一批由于用户读音不准确导致的识别错误
allowedCharsPinyin.put("qu", '除');
allowedCharsPinyin.put("ceng", '乘');
allowedCharsPinyin.put("xuan", '弦');
allowedCharsPinyin.put("yao", '一');
}
public static HashMap<Character, String> loadTokens(InputStream input) {
HashMap<Character, String> pinyin = new HashMap<Character, String>();
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(input, "utf-8"));
String line = null;
while((line = reader.readLine()) != null) {
if(line.length() > 0) {
String[] fields = line.split("\\s+");
String charPinyin = fields[1];
String chars = fields[2];
for(int i=0;i<chars.length();i++) {
pinyin.put(chars.charAt(i), charPinyin);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return pinyin;
}
@Override
public String call(String expr) {
StringBuilder str = new StringBuilder();
for(int i=0;i<expr.length();i++) {
Character c = expr.charAt(i);
if(allowedChars.contains(c)) {
str.append(c);
}else if(pinyin!= null && pinyin.containsKey(c)){
String py = pinyin.get(c);
if(allowedCharsPinyin.containsKey(py)) {
str.append(allowedCharsPinyin.get(py));
}else {
//很多人前后鼻音不分
py = py+"g";
if(allowedCharsPinyin.containsKey(py)) {
str.append(allowedCharsPinyin.get(py));
}
}
}
}
/*
*/
String result = str.toString();
if(result.endsWith("加") || result.endsWith("减")
|| result.endsWith("乘") || result.endsWith("点")
|| result.endsWith("+") || result.endsWith("-")
|| result.endsWith("×") || result.endsWith("/") ) {
result = result.substring(0, result.length()-1);
} else if(result.endsWith("加上") || result.endsWith("减去")
|| result.endsWith("乘以") || result.endsWith("除以")) {
result = result.substring(0, result.length()-2);
} else if(result.startsWith("-")){
/*讯飞语音直接将‘负’改成了‘-’号,导致错误的识别为连续计算*/
result = "负" + result.substring(1, result.length());
}
return result;
}
}

@ -1,223 +0,0 @@
package org.xing.calc.parser;
import org.antlr.v4.runtime.tree.TerminalNode;
import org.xing.calc.parser.grammer.calculatorBaseVisitor;
import org.xing.calc.parser.grammer.calculatorParser;
import org.xing.calc.parser.grammer.calculatorParser.FuncnameContext;
import org.xing.calc.parser.grammer.calculatorParser.FuncnameExContext;
import org.xing.calc.parser.grammer.calculatorParser.FunctionContext;
import org.xing.calc.parser.grammer.calculatorParser.PostFuncnameContext;
public class CalculatorEvalVisitor extends calculatorBaseVisitor<Double> {
private NumberParser numParser;
public CalculatorEvalVisitor() {
numParser = new NumberParser();
}
@Override
public Double visitExpression(calculatorParser.ExpressionContext ctx) {
Double result = visit(ctx.getChild(0));
if(ctx.getChildCount() > 2) {
for(int i=1;i<ctx.getChildCount();i+=2) {
TerminalNode oper = (TerminalNode)ctx.getChild(i);
Double exprValue = visit(ctx.getChild(i+1));
if(oper.getSymbol().getType() == calculatorParser.PLUS) {
result = result + exprValue;
} else {
result = result - exprValue;
}
}
}
return result;
}
@Override
public Double visitMultiplyingExpression(
calculatorParser.MultiplyingExpressionContext ctx) {
Double result = visit(ctx.getChild(0));
if(ctx.getChildCount() > 2) {
for(int i=1;i<ctx.getChildCount();i+=2) {
TerminalNode oper = (TerminalNode)ctx.getChild(i);
Double exprValue = visit(ctx.getChild(i+1));
if(oper.getSymbol().getType() == calculatorParser.DIV) {
result = result / exprValue;
} else {
result = result * exprValue;
}
}
}
return result;
}
@Override
public Double visitPowExpression(calculatorParser.PowExpressionContext ctx) {
Double result = Double.NaN;
int index = 0;
result = visit(ctx.getChild(index++));
while (index < ctx.getChildCount()) {
TerminalNode node = (TerminalNode) ctx.getChild(index);
if(node.getSymbol().getType() == calculatorParser.DE) {
if (ctx.getChild(index + 1) instanceof TerminalNode) {
int type = ((TerminalNode) ctx.getChild(index + 1)).getSymbol()
.getType();
if (type == calculatorParser.PINGFANG) {
result = Math.pow(result, 2);
} else if (type == calculatorParser.LIFANG) {
result = Math.pow(result, 3);
} else {
System.err.println("未处理的终端节点:visitChinaPowExpression");
}
index += 2;
} else {
Double pow = visit(ctx.getChild(index + 1));
result = Math.pow(result, pow);
index += 3;
}
} else {
Double pow = visit(ctx.getChild(index + 1));
result = Math.pow(result, pow);
index += 2;
}
}
return result;
}
@Override
public Double visitAtom(calculatorParser.AtomContext ctx) {
if(ctx.MINUS() != null) {
return -visit(ctx.getChild(1));
}else if(ctx.PLUS() != null) {
return visit(ctx.getChild(1));
}if(ctx.getChildCount() == 3) {
if(ctx.FRAC() != null) {
if(ctx.FRAC().getText().equals("分之")) {
return visit(ctx.getChild(2)) / visit(ctx.getChild(0));
}else {
//分数用'/'表示,这是语音识别的结果导致的,它偶尔自动把分数转化成了'/'
return visit(ctx.getChild(0)) / visit(ctx.getChild(2));
}
}else {
return visit(ctx.expression());
}
}else if(ctx.getChildCount() == 5) {
Double firstNumber = visit(ctx.getChild(0));
Double secondNumber = visit(ctx.getChild(2));
Double thirdNumber = visit(ctx.getChild(4));
//三又2/3 这种被语音识别引擎处理过的表达方式
if(ctx.getChild(3).getText().equals("/")) {
secondNumber = visit(ctx.getChild(4));
thirdNumber = visit(ctx.getChild(2));
}
if(firstNumber < 0) {
return (firstNumber * secondNumber - thirdNumber) / secondNumber;
} else {
return (firstNumber * secondNumber + thirdNumber) / secondNumber;
}
}else {
Double result = visit(ctx.getChild(0));
return result == null? Double.NaN:result;
}
}
@Override
public Double visitFunction(FunctionContext ctx) {
Double result = Double.NaN;
if(ctx.funcnameEx() != null) {
FuncnameExContext func = ctx.funcnameEx();
Double firstNum = visit(ctx.getChild(0));
Double secondNum = visit(ctx.getChild(2));
if(func.DUISHU() != null) {
result = Math.log(secondNum) / Math.log(firstNum);
}else if(func.GENHAO() != null) {
result = Math.pow(secondNum, 1/firstNum);
}
} else if(ctx.funcname() != null){
FuncnameContext func = ctx.funcname();
Double exprValue = visit(ctx.getChild(1));
if(exprValue.isNaN()) return result;
if(func.SIN() != null) {
result = Math.sin(exprValue);
}else if(func.COS() != null) {
result = Math.cos(exprValue);
}else if(func.TAN() != null) {
result = Math.tan(exprValue);
}else if(func.ASIN() != null) {
result = Math.asin(exprValue);
}else if(func.ACOS() != null) {
result = Math.acos(exprValue);
}else if(func.ATAN() != null) {
result = Math.atan(exprValue);
}else if(func.LG() != null) {
result = Math.log10(exprValue);
}else if(func.LOG() != null) {
result = Math.log(exprValue) / Math.log(2);
}else if(func.LN() != null) {
result = Math.log(exprValue);
}else if(func.GENHAO() != null) {
result = Math.pow(exprValue, 0.5);
}else if(func.DUISHU() != null) {
result = Math.log(exprValue);
}else{
System.err.println("Not supported function '"+ctx.funcname()+"'");
}
}else if(ctx.postFuncname() != null) {
PostFuncnameContext postFuncname = ctx.postFuncname();
Double exprValue = visit(ctx.getChild(0));
if(postFuncname.KAIFANG() != null
|| postFuncname.KAIPINGFANG() != null) {
result = Math.pow(exprValue, 0.5);
}else if(postFuncname.PINGFANG() != null){
if(postFuncname.GEN() != null) {
result = Math.pow(exprValue, 0.5);
}else {
result = Math.pow(exprValue, 2);
}
}else if(postFuncname.KAILIFANG() != null) {
result = Math.pow(exprValue, 1.0/3);
}else if(postFuncname.LIFANG() != null) {
if(postFuncname.GEN() != null) {
result = Math.pow(exprValue, 1.0/3);
}else {
result = Math.pow(exprValue, 3);
}
}
}
return result;
}
@Override
public Double visitNumber(calculatorParser.NumberContext ctx) {
try{
String expr = ctx.getText();
if(ctx.PAI() != null || ctx.DU() != null) {
if(ctx.DIGIT().isEmpty()) {
return Math.PI;
}
numParser.parse(expr.substring(0, expr.length()-1));
Double result = Double.parseDouble(numParser.getEvalExpr());
if(ctx.PAI() != null) {
return result * Math.PI;
}else {
return result * Math.PI / 180;
}
} else {
numParser.parse(expr);
return Double.parseDouble(numParser.getEvalExpr());
}
}catch(Exception ex) {
return Double.NaN;
}
}
}

@ -1,335 +0,0 @@
package org.xing.calc.parser;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.TerminalNode;
import org.xing.calc.parser.grammer.calculatorBaseVisitor;
import org.xing.calc.parser.grammer.calculatorParser;
import java.util.Stack;
/**
* Created by xing on 2017/1/1.
*/
public class CalculatorLatexExprVisitor extends calculatorBaseVisitor<String> {
protected NumberParser numParser;
public CalculatorLatexExprVisitor() {
numParser = new NumberParser();
}
public enum AtomType{
None, PosNumber, NegNumber, Sqrt, Frac, Log, Brack, Pow, Mixed
}
private boolean bracketsLeggal(String expr) {
Stack<Character> brackets = new Stack<>();
for(int i=0;i<expr.length();i++) {
Character c = expr.charAt(i);
if(c == '(') {
brackets.add(c);
} else if(c== ')') {
if((!brackets.empty()) && brackets.peek() == '(') {
brackets.pop();
}else {
return false;
}
}
}
if(brackets.empty()) return true;
return false;
}
protected String trimBrackets(String expr) {
if(expr == null) return null;
if(expr.startsWith("(") && expr.endsWith(")")) {
String substr = expr.substring(1, expr.length()-1);
if(bracketsLeggal(substr)) return substr;
}
return expr;
}
public static AtomType getAtomType(String expr) {
if(expr == null) return AtomType.None;
if(expr.startsWith("-")) {
return AtomType.NegNumber;
}else if(expr.startsWith("\\\\sqrt")) {
return AtomType.Sqrt;
}else if(expr.startsWith("\\\\frac")) {
return AtomType.Frac;
}else if(expr.startsWith("log")) {
return AtomType.Log;
}else if(expr.startsWith("(") && expr.endsWith(")")) {
return AtomType.Brack;
}else if(expr.contains("^")) {
return AtomType.Pow;
}else if(expr.contains("\\\\frac")) {
return AtomType.Frac;
}else if(expr.contains("+") || expr.contains("-")
|| expr.contains("÷") || expr.contains("×") ) {
return AtomType.Mixed;
}
return AtomType.PosNumber;
}
public String[] getBrackExpr(String expr) {
String brackResult = expr;
String nonbrackResult = expr;
AtomType atomType = getAtomType(expr);
if(atomType == AtomType.NegNumber || atomType == AtomType.Frac
|| atomType == AtomType.Pow || atomType == AtomType.Log
|| atomType == AtomType.Sqrt || atomType == AtomType.Mixed) {
brackResult = "("+expr + ")";
}else if(atomType == AtomType.Brack) {
nonbrackResult = trimBrackets(expr);
}
return new String[] {brackResult, nonbrackResult};
}
@Override
public String visitExpression(calculatorParser.ExpressionContext ctx) {
StringBuilder result = new StringBuilder();
for(int i=0;i<ctx.getChildCount();i++) {
ParseTree child = ctx.getChild(i);
if(child instanceof TerminalNode) {
int type = ((TerminalNode) child).getSymbol().getType();
if(type == calculatorParser.PLUS) {
result.append("+");
} else {
result.append("-");
}
}else {
String expr = visit(child);
AtomType atomType = getAtomType(expr);
if(atomType == AtomType.NegNumber && result.length() > 0) {
result.append("("+expr+")");
}else {
result.append(expr);
}
}
}
return result.toString();
}
@Override
public String visitMultiplyingExpression(
calculatorParser.MultiplyingExpressionContext ctx) {
StringBuilder result = new StringBuilder();
for(int i=0;i<ctx.getChildCount();i++) {
ParseTree child = ctx.getChild(i);
if(child instanceof TerminalNode) {
int type = ((TerminalNode) child).getSymbol().getType();
if(type == calculatorParser.DIV) {
result.append("/");
} else {
result.append("*");
}
}else {
String expr = visit(child);
AtomType atomType = getAtomType(expr);
if(atomType == AtomType.NegNumber && result.length() > 0) {
result.append("("+expr+")");
}else {
result.append(expr);
}
}
}
return result.toString();
}
@Override
public String visitPowExpression(calculatorParser.PowExpressionContext ctx) {
int index = 0;
String result = visit(ctx.getChild(index++));
while (index < ctx.getChildCount()) {
String[] brackExpr = getBrackExpr(result);
TerminalNode node = (TerminalNode) ctx.getChild(index);
if(node.getSymbol().getType() == calculatorParser.DE) {
if (ctx.getChild(index + 1) instanceof TerminalNode) {
int type = ((TerminalNode) ctx.getChild(index + 1)).getSymbol()
.getType();
if (type == calculatorParser.PINGFANG) {
result = "{" + brackExpr[0] + "}^2";
} else if (type == calculatorParser.LIFANG) {
result = "{" + brackExpr[0] + "}^3";
} else if (type == calculatorParser.KAIFANG) {
result = "\\\\sqrt{" + brackExpr[1] + "}";
} else {
System.err.println("未处理的终端节点:visitChinaPowExpression");
}
index += 2;
} else {
String pow = visit(ctx.getChild(index + 1));
result = "{" + brackExpr[0] + "}^{" + pow + "}";
index += 3;
}
} else {
String pow = visit(ctx.getChild(index + 1));
result = "{" + brackExpr[0] + "}^{" + pow + "}";
index += 2;
}
}
return result;
}
@Override
public String visitAtom(calculatorParser.AtomContext ctx) {
if(ctx.MINUS() != null) {
return "-" + visit(ctx.getChild(1));
}else if(ctx.PLUS() != null) {
return visit(ctx.getChild(1));
}if(ctx.getChildCount() == 3) {
if(ctx.FRAC() != null) {
String expr0 = visit(ctx.getChild(0));
String expr2 = visit(ctx.getChild(2));
//对于负的分数特殊处理
String negTag = "";
boolean neg0 = expr0.startsWith("-");
boolean neg2 = expr2.startsWith("-");
if(neg0 != neg2) {
if(neg0) {
expr0 = expr0.substring(1);
}else {
expr2 = expr2.substring(1);
}
negTag = "-";
}
String[] brackExpr0 = getBrackExpr(expr0);
String[] brackExpr2 = getBrackExpr(expr2);
if(ctx.FRAC().getText().equals("分之")) {
return negTag+"\\\\frac{"+brackExpr2[1]+"}{"+brackExpr0[1]+"}";
}else {
return negTag+"\\\\frac{"+brackExpr0[1]+"}{"+brackExpr2[1]+"}";
}
}else {
String[] brackExpr = getBrackExpr(visit(ctx.expression()));
return "("+brackExpr[1]+")";
}
}else if(ctx.getChildCount() == 5) {
String expr0 = visit(ctx.getChild(0));
String expr2 = visit(ctx.getChild(2));
String expr4 = visit(ctx.getChild(4));
//三又2/3 这种被语音识别引擎处理过的表达方式
if(ctx.getChild(3).getText().equals("/")) {
expr2 = visit(ctx.getChild(4));
expr4 = visit(ctx.getChild(2));
}
return expr0+"\\\\frac{"+expr4+"}{"+expr2+"}";
}else {
return visit(ctx.getChild(0));
}
}
@Override
public String visitFunction(calculatorParser.FunctionContext ctx) {
if(ctx.funcnameEx() != null) {
calculatorParser.FuncnameExContext func = ctx.funcnameEx();
String firstNum = visit(ctx.getChild(0));
String secondNum = visit(ctx.getChild(2));
if(firstNum == null || secondNum == null) return null;
String[] brackFirstNum = getBrackExpr(firstNum);
String[] brackSecondNum = getBrackExpr(secondNum);
if(func.DUISHU() != null) {
return "log_{"+brackFirstNum[0]+"}"+brackSecondNum[0];
}else if(func.GENHAO() != null) {
return "\\\\sqrt["+brackFirstNum[0]+"]{"+brackSecondNum[1]+"}";
}
} else if(ctx.funcname() != null){
String expr = visit(ctx.getChild(1));
calculatorParser.FuncnameContext func = ctx.funcname();
if(expr == null) return null;
String[] brackExpr = getBrackExpr(expr);
if(func.SIN() != null) {
return "sin("+brackExpr[1]+")";
}else if(func.COS() != null) {
return "cos("+brackExpr[1]+")";
}else if(func.TAN() != null) {
return "tan("+brackExpr[1]+")";
}else if(func.ASIN() != null) {
return "asin("+brackExpr[1]+")";
}else if(func.ACOS() != null) {
return "acos("+brackExpr[1]+")";
}else if(func.ATAN() != null) {
return "atan("+brackExpr[1]+")";
}else if(func.LG() != null) {
return "lg("+brackExpr[1]+")";
}else if(func.LOG() != null) {
return "log("+brackExpr[1]+")";
}else if(func.LN() != null) {
return "ln("+brackExpr[1]+")";
}else if(func.GENHAO() != null) {
return "\\\\sqrt{"+brackExpr[1]+"}";
}else if(func.DUISHU() != null) {
return "ln("+brackExpr[1]+")";
}else{
System.err.println("Not supported function '"+ctx.funcname()+"'");
}
}else if(ctx.postFuncname() != null) {
calculatorParser.PostFuncnameContext postFuncname = ctx.postFuncname();
String expr = visit(ctx.getChild(0));
String[] brackExpr = getBrackExpr(expr);
if(postFuncname.KAIFANG() != null
|| postFuncname.KAIPINGFANG() != null) {
return "\\\\sqrt{"+brackExpr[1]+"}";
}else if(postFuncname.PINGFANG() != null) {
if(postFuncname.GEN() != null) {
return "\\\\sqrt{"+brackExpr[1]+"}";
}else {
return expr+"^2";
}
}else if(postFuncname.KAILIFANG() != null) {
return "\\\\sqrt[3]{"+brackExpr[1]+"}";
}else if(postFuncname.LIFANG() != null) {
if(postFuncname.GEN() != null) {
return "\\\\sqrt[3]{"+brackExpr[1]+"}";
}else {
return expr+"^3";
}
}
}
return null;
}
@Override
public String visitNumber(calculatorParser.NumberContext ctx) {
try{
String expr = ctx.getText();
StringBuilder result = new StringBuilder();
if(ctx.PAI() != null || ctx.DU() != null) {
if (ctx.DIGIT().isEmpty()) {
result.append("\\\\pi");
}else {
numParser.parse(expr.substring(0, expr.length() - 1));
result.append(numParser.getReadExpr());
if (ctx.PAI() != null) {
result.append("\\\\pi");
} else {
result.append("\\\\degree");
}
}
} else {
numParser.parse(ctx.getText());
result.append(numParser.getReadExpr());
}
return result.toString();
}catch(Exception ex) {
return null;
}
}
}

@ -1,170 +0,0 @@
package org.xing.calc.parser;
import java.util.HashMap;
import java.util.Map;
public class NumberParser extends Parser {
private Map<Character, String> chineseToMathMap;
private Map<Character, Integer> numberDigitsMap;
public NumberParser() {
chineseToMathMap = new HashMap<Character, String>();
chineseToMathMap.put('零', "0");
chineseToMathMap.put('一', "1");
chineseToMathMap.put('二', "2");
chineseToMathMap.put('三', "3");
chineseToMathMap.put('四', "4");
chineseToMathMap.put('五', "5");
chineseToMathMap.put('六', "6");
chineseToMathMap.put('七', "7");
chineseToMathMap.put('八', "8");
chineseToMathMap.put('九', "9");
numberDigitsMap = new HashMap<Character, Integer>();
numberDigitsMap.put('个', 0);
numberDigitsMap.put('十', 1);
numberDigitsMap.put('百', 2);
numberDigitsMap.put('千', 3);
numberDigitsMap.put('万', 4);
numberDigitsMap.put('亿', 8);
}
private boolean isNumber(char c) {
if(c >= '0' && c <= '9') return true;
if(chineseToMathMap.containsKey(c)) return true;
return false;
}
public void parse(String inputNumber) {
StringBuilder str = new StringBuilder();
StringBuilder reversedInputNumber = new StringBuilder(inputNumber).reverse();
int numDigits = 0; //整数位的位数
int maxNumZero = 0; //专门处理类似于三百万这种连续两个单位的数字
int secondaryMaxNumZero = 0; //二级最大值
int index = 0;
while(index < reversedInputNumber.length()) {
char c = reversedInputNumber.charAt(index);
if(isNumber(c)) {
if(chineseToMathMap.containsKey(c)) {
str.append(chineseToMathMap.get(c));
} else {
str.append(c);
}
numDigits ++;
} else if (c == '-' || c == '负'){
str.append('-');
} else if(c == '.' || c == '点') {
str.append('.');
numDigits = 0;
} else if(numberDigitsMap.containsKey(c)){
int numZero = numberDigitsMap.get(c);
if(numZero <= maxNumZero) {
if(numZero <= secondaryMaxNumZero) {
numZero += secondaryMaxNumZero;
} else {
secondaryMaxNumZero = numZero;
}
numZero += maxNumZero;
} else {
maxNumZero = numZero;
secondaryMaxNumZero = 0;
}
if(index == 1
&& (!numberDigitsMap.containsKey(reversedInputNumber.charAt(0)))
) {
//处理‘一万二’、‘三千四’这种简略说法
int headFilledNumZero = numberDigitsMap.get(c) - numDigits;
for(int i=0;i<headFilledNumZero;i++) {
str.insert(0, '0');
numDigits ++;
}
} else {
//处理通用说法
int filledNumZero = numZero - numDigits;
for(int i=0;i<filledNumZero;i++) {
str.append('0');
numDigits ++;
}
}
//处理'十四',‘十’,'百''千''万''一千零十四'这种简略说法
if(numberDigitsMap.get(c) <= 4) {
if(index == reversedInputNumber.length() - 1 ||
reversedInputNumber.charAt(index+1) == '零' ||
reversedInputNumber.charAt(index+1) == '负') {
str.append('1');
numDigits ++;
}
}
} else {
//System.err.println("错误的符号:'"+c+"'");
}
index ++;
}
this.evalExpr = this.readExpr = str.reverse().toString();
}
//测试代码
public static void testParseNumber(String[] argv) {
Map<String, String> chnMap = new HashMap<String, String>();
chnMap.put("一", "1");
chnMap.put("一十五", "15");
chnMap.put("零点三五", "0.35");
chnMap.put("负十五", "-15");
chnMap.put("十五", "15");
chnMap.put("二十", "20");
chnMap.put("二十三", "23");
chnMap.put("一百", "100");
chnMap.put("一百一", "110");
chnMap.put("一百零一", "101");
chnMap.put("一百一十", "110");
chnMap.put("一百一十一", "111");
chnMap.put("一千", "1000");
chnMap.put("一千一", "1100");
chnMap.put("一千零一", "1001");
chnMap.put("一千零一十", "1010");
chnMap.put("一千零三十一", "1031");
chnMap.put("一万零一", "10001");
chnMap.put("一万一", "11000");
chnMap.put("一万零一百", "10100");
chnMap.put("一万零二十一", "10021");
chnMap.put("一万零三百二十一.三五", "10321.35");
chnMap.put("一万一千三百二十一", "11321");
chnMap.put("三千零十五万点二零", "30150000.20");
chnMap.put("三千零一十五万", "30150000");
chnMap.put("三千五百六十八万零一百零一", "35680101");
chnMap.put("五十亿三千零七十五万零六百二十二", "5030750622");
chnMap.put("十三亿三千零十五万零三百一十二", "1330150312");
chnMap.put("负三千零七十八亿三千零十五万零三百一十二", "-307830150312");
chnMap.put("一千二百五十八亿", "125800000000");
chnMap.put("一千二百五十8万亿零三千三百二十一点124", "1258000000003321.124");
int correctNum = 0;
int wrongNum = 0;
NumberParser parser = new NumberParser();
for(String num : chnMap.keySet()) {
String value = chnMap.get(num);
parser.parse(num);
String result = parser.getEvalExpr();
if(!result.equals(value)) {
System.err.println("错误:"+num+", "+value+", 错误结果:"+result);
wrongNum ++;
} else {
correctNum ++;
}
}
System.out.println("总计:\n\t正确 "+correctNum+", 错误 "+wrongNum);
}
public static void main(String[] argv) {
testParseNumber(argv);
}
}

@ -1,41 +0,0 @@
package org.xing.calc.parser;
public abstract class Parser {
//用于计算的表达式
protected String evalExpr;
//易于阅读的表达式
protected String readExpr;
//用于语音朗读的表达式
protected String speechExpr;
public String getEvalExpr() {
return evalExpr;
}
public void setEvalExpr(String evalExpr) {
this.evalExpr = evalExpr;
}
public String getReadExpr() {
return readExpr;
}
public void setReadExpr(String readExpr) {
this.readExpr = readExpr;
}
public String getSpeechExpr() {
return speechExpr;
}
public void setSpeechExpr(String speechExpr) {
this.speechExpr = speechExpr;
}
public void parse(String expr) {
}
}

@ -1,77 +0,0 @@
// Generated from src/org/xing/calc/parser/grammer/calculator.g4 by ANTLR 4.6
package org.xing.calc.parser.grammer;
import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
/**
* This class provides an empty implementation of {@link calculatorVisitor},
* which can be extended to create a visitor which only needs to handle a subset
* of the available methods.
*
* @param <T> The return type of the visit operation. Use {@link Void} for
* operations with no return type.
*/
public class calculatorBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements calculatorVisitor<T> {
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitExpression(calculatorParser.ExpressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitMultiplyingExpression(calculatorParser.MultiplyingExpressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitPowExpression(calculatorParser.PowExpressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitAtom(calculatorParser.AtomContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitFunction(calculatorParser.FunctionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitFuncname(calculatorParser.FuncnameContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitFuncnameEx(calculatorParser.FuncnameExContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitPostFuncname(calculatorParser.PostFuncnameContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitNumber(calculatorParser.NumberContext ctx) { return visitChildren(ctx); }
}

@ -1,193 +0,0 @@
// Generated from src/org/xing/calc/parser/grammer/calculator.g4 by ANTLR 4.6
package org.xing.calc.parser.grammer;
import org.antlr.v4.runtime.Lexer;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.TokenStream;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.atn.*;
import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.misc.*;
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
public class calculatorLexer extends Lexer {
static { RuntimeMetaData.checkVersion("4.6", RuntimeMetaData.VERSION); }
protected static final DFA[] _decisionToDFA;
protected static final PredictionContextCache _sharedContextCache =
new PredictionContextCache();
public static final int
COS=1, SIN=2, TAN=3, ACOS=4, ASIN=5, ATAN=6, LN=7, LOG=8, LG=9, DUISHU=10,
GENHAO=11, KUOHAO=12, LPAREN=13, RPAREN=14, PLUS=15, MINUS=16, TIMES=17,
DIV=18, FRAC=19, YOU=20, PINGFANG=21, LIFANG=22, CIFANG=23, KAIFANG=24,
KAIPINGFANG=25, KAILIFANG=26, DE=27, GEN=28, DU=29, PAI=30, POINT=31,
E=32, POW=33, LETTER=34, DIGIT=35, WS=36;
public static String[] modeNames = {
"DEFAULT_MODE"
};
public static final String[] ruleNames = {
"COS", "SIN", "TAN", "ACOS", "ASIN", "ATAN", "LN", "LOG", "LG", "DUISHU",
"GENHAO", "KUOHAO", "LPAREN", "RPAREN", "PLUS", "MINUS", "TIMES", "DIV",
"FRAC", "YOU", "PINGFANG", "LIFANG", "CIFANG", "KAIFANG", "KAIPINGFANG",
"KAILIFANG", "DE", "GEN", "DU", "PAI", "POINT", "E", "POW", "LETTER",
"DIGIT", "WS"
};
private static final String[] _LITERAL_NAMES = {
null, null, null, null, null, null, null, "'ln'", "'log'", "'lg'", "'对数'",
"'根号'", null, "'('", "')'", null, null, null, null, null, "'又'", "'平方'",
"'立方'", "'次方'", "'开方'", "'开平方'", "'开立方'", "'的'", "'根'", null, null, null,
null, "'^'"
};
private static final String[] _SYMBOLIC_NAMES = {
null, "COS", "SIN", "TAN", "ACOS", "ASIN", "ATAN", "LN", "LOG", "LG",
"DUISHU", "GENHAO", "KUOHAO", "LPAREN", "RPAREN", "PLUS", "MINUS", "TIMES",
"DIV", "FRAC", "YOU", "PINGFANG", "LIFANG", "CIFANG", "KAIFANG", "KAIPINGFANG",
"KAILIFANG", "DE", "GEN", "DU", "PAI", "POINT", "E", "POW", "LETTER",
"DIGIT", "WS"
};
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
/**
* @deprecated Use {@link #VOCABULARY} instead.
*/
@Deprecated
public static final String[] tokenNames;
static {
tokenNames = new String[_SYMBOLIC_NAMES.length];
for (int i = 0; i < tokenNames.length; i++) {
tokenNames[i] = VOCABULARY.getLiteralName(i);
if (tokenNames[i] == null) {
tokenNames[i] = VOCABULARY.getSymbolicName(i);
}
if (tokenNames[i] == null) {
tokenNames[i] = "<INVALID>";
}
}
}
@Override
@Deprecated
public String[] getTokenNames() {
return tokenNames;
}
@Override
public Vocabulary getVocabulary() {
return VOCABULARY;
}
public calculatorLexer(CharStream input) {
super(input);
_interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
}
@Override
public String getGrammarFileName() { return "calculator.g4"; }
@Override
public String[] getRuleNames() { return ruleNames; }
@Override
public String getSerializedATN() { return _serializedATN; }
@Override
public String[] getModeNames() { return modeNames; }
@Override
public ATN getATN() { return _ATN; }
public static final String _serializedATN =
"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2&\u00e6\b\1\4\2\t"+
"\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+
"\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+
"\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+
"\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t \4!"+
"\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\3\2\3\2\3\2\3\2\3\2\5\2Q\n\2\3\3\3\3\3\3"+
"\3\3\3\3\5\3X\n\3\3\4\3\4\3\4\3\4\3\4\5\4_\n\4\3\5\3\5\3\5\3\5\3\5\3\5"+
"\3\5\5\5h\n\5\3\6\3\6\3\6\3\6\3\6\3\6\3\6\5\6q\n\6\3\7\3\7\3\7\3\7\3\7"+
"\3\7\3\7\5\7z\n\7\3\b\3\b\3\b\3\t\3\t\3\t\3\t\3\n\3\n\3\n\3\13\3\13\3"+
"\13\3\f\3\f\3\f\3\r\3\r\3\r\5\r\u008f\n\r\3\16\3\16\3\17\3\17\3\20\3\20"+
"\3\20\5\20\u0098\n\20\5\20\u009a\n\20\3\21\3\21\3\21\5\21\u009f\n\21\5"+
"\21\u00a1\n\21\3\22\3\22\3\22\5\22\u00a6\n\22\5\22\u00a8\n\22\3\23\3\23"+
"\3\23\5\23\u00ad\n\23\5\23\u00af\n\23\3\24\3\24\3\24\5\24\u00b4\n\24\3"+
"\25\3\25\3\26\3\26\3\26\3\27\3\27\3\27\3\30\3\30\3\30\3\31\3\31\3\31\3"+
"\32\3\32\3\32\3\32\3\33\3\33\3\33\3\33\3\34\3\34\3\35\3\35\3\36\3\36\3"+
"\37\3\37\3 \3 \3!\3!\3\"\3\"\3#\5#\u00db\n#\3$\5$\u00de\n$\3%\6%\u00e1"+
"\n%\r%\16%\u00e2\3%\3%\2\2&\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25"+
"\f\27\r\31\16\33\17\35\20\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32"+
"\63\33\65\34\67\359\36;\37= ?!A\"C#E$G%I&\3\2\13\4\2//\u8d21\u8d21\4\2"+
",,\u00d9\u00d9\4\2\u00b2\u00b2\u5ea8\u5ea8\4\2\u03c2\u03c2\u6d40\u6d40"+
"\4\2\60\60\u70bb\u70bb\4\2GGgg\4\2C\\c|\22\2\62;\u4e02\u4e02\u4e05\u4e05"+
"\u4e09\u4e09\u4e0b\u4e0b\u4e5f\u4e5f\u4e8e\u4e8e\u4e96\u4e96\u4ec1\u4ec1"+
"\u516d\u516d\u516f\u516f\u5343\u5343\u5345\u5345\u56dd\u56dd\u7680\u7680"+
"\u96f8\u96f8\5\2\13\f\17\17\"\"\u00f6\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2"+
"\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2"+
"\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3"+
"\2\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3"+
"\2\2\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3\2\2\2\2\65"+
"\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2A\3"+
"\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\3P\3\2\2\2\5W\3\2\2"+
"\2\7^\3\2\2\2\tg\3\2\2\2\13p\3\2\2\2\ry\3\2\2\2\17{\3\2\2\2\21~\3\2\2"+
"\2\23\u0082\3\2\2\2\25\u0085\3\2\2\2\27\u0088\3\2\2\2\31\u008e\3\2\2\2"+
"\33\u0090\3\2\2\2\35\u0092\3\2\2\2\37\u0099\3\2\2\2!\u00a0\3\2\2\2#\u00a7"+
"\3\2\2\2%\u00ae\3\2\2\2\'\u00b3\3\2\2\2)\u00b5\3\2\2\2+\u00b7\3\2\2\2"+
"-\u00ba\3\2\2\2/\u00bd\3\2\2\2\61\u00c0\3\2\2\2\63\u00c3\3\2\2\2\65\u00c7"+
"\3\2\2\2\67\u00cb\3\2\2\29\u00cd\3\2\2\2;\u00cf\3\2\2\2=\u00d1\3\2\2\2"+
"?\u00d3\3\2\2\2A\u00d5\3\2\2\2C\u00d7\3\2\2\2E\u00da\3\2\2\2G\u00dd\3"+
"\2\2\2I\u00e0\3\2\2\2KL\7e\2\2LM\7q\2\2MQ\7u\2\2NO\7\u4f5b\2\2OQ\7\u5f28"+
"\2\2PK\3\2\2\2PN\3\2\2\2Q\4\3\2\2\2RS\7u\2\2ST\7k\2\2TX\7p\2\2UV\7\u6b65"+
"\2\2VX\7\u5f28\2\2WR\3\2\2\2WU\3\2\2\2X\6\3\2\2\2YZ\7v\2\2Z[\7c\2\2[_"+
"\7p\2\2\\]\7\u6b65\2\2]_\7\u5209\2\2^Y\3\2\2\2^\\\3\2\2\2_\b\3\2\2\2`"+
"a\7c\2\2ab\7e\2\2bc\7q\2\2ch\7u\2\2de\7\u53cf\2\2ef\7\u4f5b\2\2fh\7\u5f28"+
"\2\2g`\3\2\2\2gd\3\2\2\2h\n\3\2\2\2ij\7c\2\2jk\7u\2\2kl\7k\2\2lq\7p\2"+
"\2mn\7\u53cf\2\2no\7\u6b65\2\2oq\7\u5f28\2\2pi\3\2\2\2pm\3\2\2\2q\f\3"+
"\2\2\2rs\7c\2\2st\7v\2\2tu\7c\2\2uz\7p\2\2vw\7\u53cf\2\2wx\7\u6b65\2\2"+
"xz\7\u5209\2\2yr\3\2\2\2yv\3\2\2\2z\16\3\2\2\2{|\7n\2\2|}\7p\2\2}\20\3"+
"\2\2\2~\177\7n\2\2\177\u0080\7q\2\2\u0080\u0081\7i\2\2\u0081\22\3\2\2"+
"\2\u0082\u0083\7n\2\2\u0083\u0084\7i\2\2\u0084\24\3\2\2\2\u0085\u0086"+
"\7\u5bfb\2\2\u0086\u0087\7\u6572\2\2\u0087\26\3\2\2\2\u0088\u0089\7\u683b"+
"\2\2\u0089\u008a\7\u53f9\2\2\u008a\30\3\2\2\2\u008b\u008f\7~\2\2\u008c"+
"\u008d\7\u62ee\2\2\u008d\u008f\7\u53f9\2\2\u008e\u008b\3\2\2\2\u008e\u008c"+
"\3\2\2\2\u008f\32\3\2\2\2\u0090\u0091\7*\2\2\u0091\34\3\2\2\2\u0092\u0093"+
"\7+\2\2\u0093\36\3\2\2\2\u0094\u009a\7-\2\2\u0095\u0097\7\u52a2\2\2\u0096"+
"\u0098\7\u4e0c\2\2\u0097\u0096\3\2\2\2\u0097\u0098\3\2\2\2\u0098\u009a"+
"\3\2\2\2\u0099\u0094\3\2\2\2\u0099\u0095\3\2\2\2\u009a \3\2\2\2\u009b"+
"\u00a1\t\2\2\2\u009c\u009e\7\u51d1\2\2\u009d\u009f\7\u53bd\2\2\u009e\u009d"+
"\3\2\2\2\u009e\u009f\3\2\2\2\u009f\u00a1\3\2\2\2\u00a0\u009b\3\2\2\2\u00a0"+
"\u009c\3\2\2\2\u00a1\"\3\2\2\2\u00a2\u00a8\t\3\2\2\u00a3\u00a5\7\u4e5a"+
"\2\2\u00a4\u00a6\7\u4ee7\2\2\u00a5\u00a4\3\2\2\2\u00a5\u00a6\3\2\2\2\u00a6"+
"\u00a8\3\2\2\2\u00a7\u00a2\3\2\2\2\u00a7\u00a3\3\2\2\2\u00a8$\3\2\2\2"+
"\u00a9\u00af\7\u00f9\2\2\u00aa\u00ac\7\u9666\2\2\u00ab\u00ad\7\u4ee7\2"+
"\2\u00ac\u00ab\3\2\2\2\u00ac\u00ad\3\2\2\2\u00ad\u00af\3\2\2\2\u00ae\u00a9"+
"\3\2\2\2\u00ae\u00aa\3\2\2\2\u00af&\3\2\2\2\u00b0\u00b4\7\61\2\2\u00b1"+
"\u00b2\7\u5208\2\2\u00b2\u00b4\7\u4e4d\2\2\u00b3\u00b0\3\2\2\2\u00b3\u00b1"+
"\3\2\2\2\u00b4(\3\2\2\2\u00b5\u00b6\7\u53ca\2\2\u00b6*\3\2\2\2\u00b7\u00b8"+
"\7\u5e75\2\2\u00b8\u00b9\7\u65bb\2\2\u00b9,\3\2\2\2\u00ba\u00bb\7\u7acd"+
"\2\2\u00bb\u00bc\7\u65bb\2\2\u00bc.\3\2\2\2\u00bd\u00be\7\u6b23\2\2\u00be"+
"\u00bf\7\u65bb\2\2\u00bf\60\3\2\2\2\u00c0\u00c1\7\u5f02\2\2\u00c1\u00c2"+
"\7\u65bb\2\2\u00c2\62\3\2\2\2\u00c3\u00c4\7\u5f02\2\2\u00c4\u00c5\7\u5e75"+
"\2\2\u00c5\u00c6\7\u65bb\2\2\u00c6\64\3\2\2\2\u00c7\u00c8\7\u5f02\2\2"+
"\u00c8\u00c9\7\u7acd\2\2\u00c9\u00ca\7\u65bb\2\2\u00ca\66\3\2\2\2\u00cb"+
"\u00cc\7\u7686\2\2\u00cc8\3\2\2\2\u00cd\u00ce\7\u683b\2\2\u00ce:\3\2\2"+
"\2\u00cf\u00d0\t\4\2\2\u00d0<\3\2\2\2\u00d1\u00d2\t\5\2\2\u00d2>\3\2\2"+
"\2\u00d3\u00d4\t\6\2\2\u00d4@\3\2\2\2\u00d5\u00d6\t\7\2\2\u00d6B\3\2\2"+
"\2\u00d7\u00d8\7`\2\2\u00d8D\3\2\2\2\u00d9\u00db\t\b\2\2\u00da\u00d9\3"+
"\2\2\2\u00dbF\3\2\2\2\u00dc\u00de\t\t\2\2\u00dd\u00dc\3\2\2\2\u00deH\3"+
"\2\2\2\u00df\u00e1\t\n\2\2\u00e0\u00df\3\2\2\2\u00e1\u00e2\3\2\2\2\u00e2"+
"\u00e0\3\2\2\2\u00e2\u00e3\3\2\2\2\u00e3\u00e4\3\2\2\2\u00e4\u00e5\b%"+
"\2\2\u00e5J\3\2\2\2\26\2PW^gpy\u008e\u0097\u0099\u009e\u00a0\u00a5\u00a7"+
"\u00ac\u00ae\u00b3\u00da\u00dd\u00e2\3\2\3\2";
public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static {
_decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
_decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
}
}
}

@ -1,67 +0,0 @@
// Generated from src/org/xing/calc/parser/grammer/calculator.g4 by ANTLR 4.6
package org.xing.calc.parser.grammer;
import org.antlr.v4.runtime.tree.ParseTreeVisitor;
/**
* This interface defines a complete generic visitor for a parse tree produced
* by {@link calculatorParser}.
*
* @param <T> The return type of the visit operation. Use {@link Void} for
* operations with no return type.
*/
public interface calculatorVisitor<T> extends ParseTreeVisitor<T> {
/**
* Visit a parse tree produced by {@link calculatorParser#expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitExpression(calculatorParser.ExpressionContext ctx);
/**
* Visit a parse tree produced by {@link calculatorParser#multiplyingExpression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitMultiplyingExpression(calculatorParser.MultiplyingExpressionContext ctx);
/**
* Visit a parse tree produced by {@link calculatorParser#powExpression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitPowExpression(calculatorParser.PowExpressionContext ctx);
/**
* Visit a parse tree produced by {@link calculatorParser#atom}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitAtom(calculatorParser.AtomContext ctx);
/**
* Visit a parse tree produced by {@link calculatorParser#function}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitFunction(calculatorParser.FunctionContext ctx);
/**
* Visit a parse tree produced by {@link calculatorParser#funcname}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitFuncname(calculatorParser.FuncnameContext ctx);
/**
* Visit a parse tree produced by {@link calculatorParser#funcnameEx}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitFuncnameEx(calculatorParser.FuncnameExContext ctx);
/**
* Visit a parse tree produced by {@link calculatorParser#postFuncname}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitPostFuncname(calculatorParser.PostFuncnameContext ctx);
/**
* Visit a parse tree produced by {@link calculatorParser#number}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitNumber(calculatorParser.NumberContext ctx);
}

@ -1,105 +0,0 @@
package org.xing.engine;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.speech.RecognitionListener;
import android.speech.SpeechRecognizer;
import com.baidu.speech.VoiceRecognitionService;
import org.xing.utils.Logger;
import java.util.ArrayList;
/**
* Created by Administrator on 2017/3/8 0008.
*/
public class BaiduSpeechEngine implements SpeechEngine{
private Context ctx;
private SpeechListener listener;
private SpeechRecognizer speechRecognizer;
private InternalRecognitionListener _listener;
public BaiduSpeechEngine(Context ctx) {
this.ctx = ctx;
speechRecognizer = SpeechRecognizer.createSpeechRecognizer(
ctx, new ComponentName(ctx, VoiceRecognitionService.class));
}
public void setSpeechListener(SpeechListener listener){
this.listener = listener;
this._listener = new InternalRecognitionListener(listener);
speechRecognizer.setRecognitionListener(_listener);
}
public void startListening() {
speechRecognizer.startListening(new Intent());
}
public void stopListening() {
speechRecognizer.stopListening();
}
public void cancel() {
speechRecognizer.cancel();
}
public void destroy() {
speechRecognizer.destroy();
}
private static class InternalRecognitionListener implements RecognitionListener {
private SpeechListener listener;
public InternalRecognitionListener(SpeechListener listener) {
this.listener = listener;
}
public void onResults(Bundle results) {
ArrayList<String> nbest = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
StringBuilder expr = new StringBuilder();
for (String w : nbest) {
expr.append(w);
}
listener.onResults(expr.toString());
}
public void onReadyForSpeech(Bundle bundle) {
listener.onReadyForSpeech();
}
//会话发生错误回调接口
public void onError(int error) {
listener.onError(error);
}
//开始录音
public void onBeginningOfSpeech() {
listener.onBeginningOfSpeech();
}
//音量值
public void onRmsChanged(float rms){
listener.onRmsChanged(rms/20);
}
//结束录音
public void onEndOfSpeech() {
listener.onEndOfSpeech();
}
public void onPartialResults(Bundle partialResults) {
}
public void onEvent(int eventType, Bundle params) {
Logger.info("xing", String.valueOf(eventType)+": "+params.toString());
}
public void onBufferReceived(byte[] buffer) {
}
};
}

@ -1,132 +0,0 @@
package org.xing.engine;
import android.content.Context;
import android.os.Bundle;
import com.iflytek.cloud.RecognizerListener;
import com.iflytek.cloud.RecognizerResult;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechRecognizer;
import com.iflytek.cloud.SpeechUtility;
import org.xing.android.MainActivity;
import org.xing.logger.impl.EventLogger;
import org.xing.utils.JsonParser;
import static com.iflytek.cloud.ErrorCode.ERROR_AUDIO_RECORD;
import static com.iflytek.cloud.ErrorCode.ERROR_ENGINE_BUSY;
import static com.iflytek.cloud.ErrorCode.ERROR_NETWORK_TIMEOUT;
import static com.iflytek.cloud.ErrorCode.ERROR_NO_MATCH;
import static com.iflytek.cloud.ErrorCode.ERROR_NO_NETWORK;
import static com.iflytek.cloud.ErrorCode.ERROR_PERMISSION_DENIED;
import static com.iflytek.cloud.ErrorCode.MSP_ERROR_NO_DATA;
/**
* Created by Administrator on 2017/3/8 0008.
*/
public class IflySpeechEngine implements SpeechEngine{
private Context ctx;
private SpeechListener listener;
private SpeechRecognizer speechRecognizer;
private InternalRecognizerListener _listener;
private static EventLogger eventLogger;
public IflySpeechEngine(Context ctx) {
this.ctx = ctx;
SpeechUtility.createUtility(ctx, SpeechConstant.APPID +"=585290e7");
speechRecognizer= SpeechRecognizer.createRecognizer(ctx, null);
speechRecognizer.setParameter(SpeechConstant.DOMAIN, "iat"); //{短信和日常用语iat (默认) 视频video 地图poi 音乐music
speechRecognizer.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
speechRecognizer.setParameter(SpeechConstant.ACCENT, "mandarin");
speechRecognizer.setParameter(SpeechConstant.VAD_BOS, "10000"); //十秒超时
speechRecognizer.setParameter(SpeechConstant.ASR_PTT, "0"); //不带标点
eventLogger = MainActivity.eventLogger;
}
public void setSpeechListener(SpeechListener listener){
this.listener = listener;
_listener = new InternalRecognizerListener(listener);
}
public void startListening() {
speechRecognizer.startListening(_listener);
listener.onReadyForSpeech();
}
public void stopListening() {
speechRecognizer.stopListening();
}
public void cancel() {
speechRecognizer.cancel();
}
public void destroy() {
speechRecognizer.destroy();
}
private static class InternalRecognizerListener implements RecognizerListener{
private SpeechListener listener;
public InternalRecognizerListener(SpeechListener listener) {
this.listener = listener;
}
public void onResult(RecognizerResult results, boolean isLast) {
String expr = JsonParser.parseIatResult(results.getResultString());
listener.onResults(expr);
}
//会话发生错误回调接口
public void onError(SpeechError error) {
switch (error.getErrorCode()) {
case ERROR_AUDIO_RECORD:
listener.onError(android.speech.SpeechRecognizer.ERROR_AUDIO);
break;
case ERROR_ENGINE_BUSY:
listener.onError(android.speech.SpeechRecognizer.ERROR_RECOGNIZER_BUSY);
break;
case ERROR_PERMISSION_DENIED:
listener.onError(android.speech.SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS);
break;
case ERROR_NO_NETWORK:
listener.onError(android.speech.SpeechRecognizer.ERROR_NETWORK);
break;
case ERROR_NETWORK_TIMEOUT:
listener.onError(android.speech.SpeechRecognizer.ERROR_NETWORK_TIMEOUT);
break;
case ERROR_NO_MATCH:
listener.onError(android.speech.SpeechRecognizer.ERROR_NO_MATCH);
break;
case MSP_ERROR_NO_DATA:
listener.onError(android.speech.SpeechRecognizer.ERROR_SPEECH_TIMEOUT);
break;
default:
eventLogger.onEvent("ifly-error-"+error.getErrorCode()+": "+error.getErrorDescription());
listener.onError(android.speech.SpeechRecognizer.ERROR_CLIENT);
break;
}
}
//开始录音
public void onBeginOfSpeech() {
listener.onBeginningOfSpeech();
}
//音量值0~30
public void onVolumeChanged(int volume, byte[] data){
listener.onRmsChanged((float)volume * 10);
}
//结束录音
public void onEndOfSpeech() {
listener.onEndOfSpeech();
}
//扩展用接口
public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {
}
};
}

@ -1,13 +0,0 @@
package org.xing.engine;
/**
* Created by Administrator on 2017/3/8 0008.
*/
public interface SpeechEngine {
void setSpeechListener(SpeechListener listener);
void startListening();
void stopListening();
void cancel();
void destroy();
}

@ -1,20 +0,0 @@
package org.xing.engine;
/**
* Created by Administrator on 2017/3/8 0008.
*/
public interface SpeechListener{
void onReadyForSpeech();
void onBeginningOfSpeech();
void onRmsChanged(float rmsdB);
void onEndOfSpeech();
void onError(int error);
void onResults(String expr);
}

@ -1,35 +0,0 @@
package org.xing.logger;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Created by Administrator on 2016/12/29 0029.
*/
public class AsyncLog implements Log {
private Log syncLog;
private ExecutorService executorService;
public AsyncLog(Log log) {
this.syncLog = log;
executorService = Executors.newSingleThreadExecutor();
}
@Override
public boolean log(final Map<String, Object> params) {
executorService.submit(new Runnable() {
@Override
public void run() {
syncLog.log(params);
}
});
return true;
}
public static AsyncLog createAsyncHttpLog(String url) {
return new AsyncLog(new HttpLog(url));
}
}

@ -1,24 +0,0 @@
package org.xing.logger;
import org.xing.utils.HttpUtil;
import java.util.Map;
/**
* Created by Administrator on 2016/12/29 0029.
*/
public class HttpLog implements Log {
private String url;
public HttpLog(String url) {
this.url = url;
}
@Override
public boolean log(Map<String, Object> params) {
HttpUtil.doPost(this.url, params, "utf-8");
return true;
}
}

@ -1,11 +0,0 @@
package org.xing.logger;
import java.util.Map;
/**
* Created by Administrator on 2016/12/29 0029.
*/
public interface Log {
boolean log(Map<String, Object> params);
}

@ -1,53 +0,0 @@
package org.xing.logger.impl;
import android.os.Build;
import org.xing.logger.AsyncLog;
import org.xing.logger.Log;
import java.util.HashMap;
import java.util.Map;
/**
* Created by Administrator on 2017/2/21 0021.
*/
public class EventLogger {
private String userId;
private String version;
private Log eventLogger;
public EventLogger(String userId, String version, String url) {
this.userId = userId;
this.version = version;
eventLogger = AsyncLog.createAsyncHttpLog(url);
}
/*
*/
public void onEvent(String event) {
Map<String, Object> params = new HashMap<>();
params.put("_eventType", 1);
params.put("version", version);
params.put("userId", userId);
params.put("model", Build.VERSION.SDK_INT + " " + Build.BRAND + " " + Build.MODEL);
params.put("event", event);
eventLogger.log(params);
}
/*
*/
public void onEvent(String result, String inputExpr, String readExpr, int type) {
Map<String, Object> params = new HashMap<>();
params.put("_eventType", 2);
params.put("userId", userId);
params.put("version", version);
params.put("result", result);
params.put("inputExpr", inputExpr);
params.put("readExpr", readExpr == null ? "null" : readExpr);
params.put("type", type);
eventLogger.log(params);
}
}

@ -1,114 +0,0 @@
package org.xing.share;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import com.tencent.connect.share.QQShare;
import com.tencent.connect.share.QzoneShare;
import com.tencent.mm.opensdk.modelmsg.SendMessageToWX;
import com.tencent.mm.opensdk.modelmsg.WXMediaMessage;
import com.tencent.mm.opensdk.modelmsg.WXWebpageObject;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import com.tencent.tauth.IUiListener;
import com.tencent.tauth.Tencent;
import com.tencent.tauth.UiError;
import org.xing.android.MainActivity;
import org.xing.android.R;
import org.xing.logger.impl.EventLogger;
import java.util.ArrayList;
/**
* Created by Administrator on 2017/3/19 0019.
*/
public class ShareManager {
private Activity activity;
/*
*/
private String weixinAppid;
private IWXAPI iwxapi;
/*
QQ
*/
private String qqAppid;
private Tencent mTencent;
private EventLogger eventLogger;
public ShareManager(Activity activity) {
eventLogger = MainActivity.eventLogger;
this.activity = activity;
weixinAppid = "wxf3bb46c3047a46dd";
iwxapi = WXAPIFactory.createWXAPI(activity, weixinAppid, true);
iwxapi.registerApp(weixinAppid);
qqAppid = "1105840771";
mTencent = Tencent.createInstance(qqAppid, activity.getApplicationContext());
}
public void shareToWeixin(int flag) {
WXWebpageObject webpage = new WXWebpageObject();
webpage.webpageUrl = activity.getString(R.string.shareUrl);
WXMediaMessage msg = new WXMediaMessage(webpage);
msg.title = activity.getString(R.string.shareTitle);
msg.description = activity.getString(R.string.shareDesc);
//这里替换一张自己工程里的图片资源
Bitmap thumb = BitmapFactory.decodeResource(activity.getResources(), R.mipmap.share_icon);
msg.setThumbImage(thumb);
SendMessageToWX.Req req = new SendMessageToWX.Req();
req.transaction = String.valueOf(System.currentTimeMillis());
req.message = msg;
req.scene = flag == 0? SendMessageToWX.Req.WXSceneSession:SendMessageToWX.Req.WXSceneTimeline;
eventLogger.onEvent(flag == 0? "weixinShare":"pengyouquanShare");
iwxapi.sendReq(req);
}
public void shareToQQ(int flag) {
final Bundle params = new Bundle();
if(flag == 0) {
params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_DEFAULT);
params.putString(QQShare.SHARE_TO_QQ_TITLE, activity.getString(R.string.shareTitle));
params.putString(QQShare.SHARE_TO_QQ_SUMMARY, activity.getString(R.string.shareDesc));
params.putString(QQShare.SHARE_TO_QQ_TARGET_URL, activity.getString(R.string.shareUrl));
params.putString(QQShare.SHARE_TO_QQ_IMAGE_URL, activity.getString(R.string.shareImage));
params.putString(QQShare.SHARE_TO_QQ_APP_NAME, activity.getString(R.string.app_name));
} else {
params.putInt(QzoneShare.SHARE_TO_QZONE_KEY_TYPE, QzoneShare.SHARE_TO_QZONE_TYPE_IMAGE_TEXT );
params.putString(QzoneShare.SHARE_TO_QQ_TITLE, activity.getString(R.string.shareTitle));
params.putString(QzoneShare.SHARE_TO_QQ_SUMMARY, activity.getString(R.string.shareDesc));
params.putString(QzoneShare.SHARE_TO_QQ_TARGET_URL, activity.getString(R.string.shareUrl));
ArrayList<String> imageList = new ArrayList<>();
imageList.add(activity.getString(R.string.shareImage));
params.putStringArrayList(QzoneShare.SHARE_TO_QQ_IMAGE_URL, imageList);
}
IUiListener defaultUiListener = new IUiListener() {
public void onComplete(Object var1){}
public void onError(UiError var1){}
public void onCancel() {}
};
if(flag == 0) {
eventLogger.onEvent("qqShare");
mTencent.shareToQQ(activity, params, defaultUiListener);
} else {
eventLogger.onEvent("qzoneShare");
mTencent.shareToQzone(activity, params, defaultUiListener);
}
}
}

@ -1,104 +0,0 @@
package org.xing.theme;
import org.json.JSONObject;
import java.util.LinkedList;
import java.util.List;
/**
* Created by Administrator on 2017/3/1 0001.
*/
public class Theme {
private String id;
private String name;
private JSONObject style;
private List<String> imagePaths;
public Theme () {
//默认全白色背景,黑色字体
id = "0";
name = "默认主题";
style = null;
imagePaths = new LinkedList<>();
}
public Theme (String id, String name, String style, String imagePathStr) {
this.id = id;
this.name = name;
try {
this.style = new JSONObject(style);
}catch (Exception e) { }
imagePaths = new LinkedList<>();
if(imagePathStr != null) {
String[] fields = imagePathStr.split(";");
for(String path : fields) {
if(path.length() > 0) {
imagePaths.add(path);
}
}
}
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getStyle() {
return style.toString();
}
public String getStyle(String name) {
try {
return style.getString(name);
}catch (Exception e) { }
return null;
}
public void setStyle(String style) {
try {
this.style = new JSONObject(style);
}catch (Exception e) { }
imagePaths = new LinkedList<>();
}
public List<String> getImagePaths() {
return imagePaths;
}
public String getImagePathsStr() {
StringBuilder str= new StringBuilder();
for(String path : imagePaths) {
if(str.length() > 0) {
str.append(";");
}
str.append(path);
}
return str.toString();
}
public void setBackgroundImage(String imagePathStr) {
imagePaths.clear();
if(imagePathStr != null) {
String[] fields = imagePathStr.split(";");
for(String path : fields) {
if(path.length() > 0) {
imagePaths.add(path);
}
}
}
}
}

@ -1,10 +0,0 @@
package org.xing.theme;
/**
* Created by Administrator on 2017/3/1 0001.
*/
public interface ThemeChangeListener {
boolean isAlive();
void onThemeChange(Theme theme);
}

@ -1,173 +0,0 @@
package org.xing.theme;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import org.xing.android.AppConfig;
import org.xing.android.MainActivity;
import org.xing.logger.impl.EventLogger;
import java.util.LinkedList;
import java.util.List;
/**
* Created by Administrator on 2017/3/1 0001.
*/
public class ThemeManager {
private int nextTheme;
private SQLiteDatabase database;
private LinkedList<ThemeChangeListener> listeners;
private EventLogger eventLogger;
public ThemeManager(Context ctx) {
nextTheme = 0;
listeners = new LinkedList<>();
eventLogger = MainActivity.eventLogger;
try {
String databasePath = ctx.getFilesDir().getAbsolutePath() + "/theme.db";
database = SQLiteDatabase.openOrCreateDatabase(databasePath, null);
if(AppConfig.getIsFirstStart()) {
database.execSQL("drop table if exists themes");
String createTableSql = "create table if not exists themes (" +
"id CHAR(32) PRIMARY KEY, " +
"name CHAR(32), " +
"style VARCHAR, " +
"img_paths VARCHAR" +
")";
database.execSQL(createTableSql);
}else {
database.delete("themes", null, null);
}
addTheme(new Theme("0", "白色", "{'resultColor':'#000000', 'historyColor':'#444444', 'msgColor':'#555555', 'background':'#ffffff'}", null));
addTheme(new Theme("1", "大鱼", "{'resultColor':'#FF3300', 'historyColor':'#ee3300', 'msgColor':'#aa3300'}", "theme/01.jpg"));
addTheme(new Theme("2", "银河", "{'resultColor':'#ffffff', 'historyColor':'#f0f0f0', 'msgColor':'#aaaaaa'}", "theme/02.jpg"));
addTheme(new Theme("3", "萌宠", "{'resultColor':'#ffa000', 'historyColor':'#ee9000', 'msgColor':'#cc7000'}", "theme/03.jpg"));
addTheme(new Theme("4", "雪景", "{'resultColor':'#3eb3ed', 'historyColor':'#2ea3dd', 'msgColor':'#ffa066'}", "theme/04.jpg"));
addTheme(new Theme("5", "银色", "{'resultColor':'#333333', 'historyColor':'#444444', 'msgColor':'#555555'}", "theme/05.jpg"));
}catch (Exception e) {
e.printStackTrace();
database = null;
}
}
public boolean addTheme(Theme theme) {
if(database == null) return false;
ContentValues values = new ContentValues();
values.put("id", theme.getId());
values.put("name", theme.getName());
values.put("style", theme.getStyle());
values.put("img_paths", theme.getImagePathsStr());
try {
long result = database.insert("themes", null, values);
if (result > 0) return true;
}catch (Exception e) {
e.printStackTrace();
}
return false;
}
public boolean deleteTheme(String id) {
if(database == null || id == null) return false;
String whereClause = "id=?";
String[] whereArgs = {id};
try {
long result = database.delete("themes", whereClause, whereArgs);
if (result > 0) return true;
}catch (Exception e) {
e.printStackTrace();
}
return false;
}
public boolean deleteTheme(Theme theme) {
return deleteTheme(theme.getId());
}
public Theme getTheme(String id) {
try {
Cursor cursor = database.rawQuery("select id, name, style, img_paths from themes where id='"+id+"'", null);
if(cursor.moveToFirst()) {
Theme theme = new Theme(cursor.getString(0), cursor.getString(1),
cursor.getString(2), cursor.getString(3));
return theme;
}
}catch (Exception e) {
e.printStackTrace();
}
return null;
}
public List<Theme> getAllTheme() {
List<Theme> themes = new LinkedList<>();
try {
Cursor cursor = database.rawQuery("select id, name, style, img_paths from themes", null);
if(cursor.moveToFirst()) {
do {
Theme theme = new Theme(cursor.getString(0), cursor.getString(1),
cursor.getString(2), cursor.getString(3));
themes.add(theme);
}while(cursor.moveToNext());
}
}catch (Exception e) {
e.printStackTrace();
}
return themes;
}
public void addThemeChangeListener(ThemeChangeListener listener) {
listeners.add(listener);
}
public void applyTheme(String id) {
if(id == null) return;
List<Theme> themes = getAllTheme();
nextTheme = 0;
for(Theme theme : themes) {
nextTheme ++;
if(theme.getId().equals(id)) {
break;
}
}
applyTheme(getTheme(id));
}
public void applyTheme(Theme theme) {
if(theme == null) return;
for(ThemeChangeListener listener : listeners) {
if(listener.isAlive()) {
listener.onThemeChange(theme);
}
}
}
public void randomTheme() {
eventLogger.onEvent("changeTheme");
List<Theme> themes = getAllTheme();
if(themes.size() > 0) {
if(nextTheme >= themes.size()) {
nextTheme %= themes.size();
}
applyTheme(
themes.get(nextTheme++)
);
}
}
}

@ -1,38 +0,0 @@
package org.xing.update;
import org.json.JSONException;
import org.json.JSONObject;
import java.math.BigInteger;
/**
* Created by sangbo on 16-5-19.
*/
public class UpdateEntity {
public int versionCode = 0;
public int isForceUpdate = 0;
public int preBaselineCode = 0;
public String versionName = "";
public String downUrl = "";
public String updateLog = "";
public BigInteger md5 = null;
public int fileSize = 0;
public UpdateEntity(String json) throws JSONException {
JSONObject jsonObject = new JSONObject(json);
this.versionCode = jsonObject.getInt("versionCode");
this.versionName = jsonObject.getString("versionName");
this.isForceUpdate = jsonObject.getInt("isForceUpdate");
this.downUrl = jsonObject.getString("downUrl");
this.preBaselineCode = jsonObject.getInt("preBaselineCode");
this.updateLog = jsonObject.getString("updateLog");
String md5String = jsonObject.getString("md5");
if(md5String != null) {
this.md5 = new BigInteger(md5String, 16);
}
this.fileSize = jsonObject.getInt("fileSize");
}
}

@ -1,295 +0,0 @@
package org.xing.update;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
import com.umeng.analytics.MobclickAgent;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.callback.FileCallBack;
import com.zhy.http.okhttp.callback.StringCallback;
import org.json.JSONException;
import org.xing.android.AppConfig;
import org.xing.android.MainActivity;
import org.xing.android.R;
import org.xing.logger.impl.EventLogger;
import org.xing.utils.NumberUtil;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.security.MessageDigest;
import okhttp3.Call;
/**
* app
* Created by sangbo on 16-5-19.
*/
public class UpdateManager {
private static int mAppVersionCode = 0;
private static Context mContext;
private static ProgressDialog mAlertDialog;
private static boolean mIsEnforceCheck = false;
private static EventLogger eventLogger = null;
public static String checkUrl = "";
public static UpdateEntity mUpdateEntity;
public static void postUpdate(final Context context, int delaySecond) {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
if(AppConfig.getCheckUpdate()) {
mIsEnforceCheck = false;
update(context);
}
}
}, delaySecond*1000);
}
public static void update(Context context){
update(context,mIsEnforceCheck);
}
public static void update(Context context, final boolean isEnforceCheck){
mContext = context;
mIsEnforceCheck = isEnforceCheck;
mAppVersionCode = AppConfig.getVersionCode();
if(eventLogger == null) {
eventLogger = MainActivity.eventLogger;
}
checkUrl = mContext.getString(R.string.updateCheckUrl);
if(TextUtils.isEmpty(checkUrl)){
Toast.makeText(mContext, "url不能为空请设置url", Toast.LENGTH_SHORT).show();
return;
}
OkHttpUtils.get().url(checkUrl).build().execute(new StringCallback() {
@Override
public void onError(Call call, Exception e) {
if(mIsEnforceCheck)
Toast.makeText(mContext, "更新失败,请检查网络", Toast.LENGTH_SHORT).show();
}
@Override
public void onResponse(String response) {
loadOnlineData(response);
}
});
}
private static void loadOnlineData(String json) {
try {
UpdateEntity updateEntity = new UpdateEntity(json);
if(updateEntity == null){
if(mIsEnforceCheck)
Toast.makeText(mContext, "网络信息获取失败,请重试", Toast.LENGTH_SHORT).show();
return;
}
mUpdateEntity = updateEntity;
if(mAppVersionCode < mUpdateEntity.versionCode){
//启动更新
AlertUpdate();
} else if(mIsEnforceCheck){
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setTitle("更新");
builder.setMessage("已是最新版本:"+AppConfig.getVersionName());
builder.setPositiveButton("确定", null);
builder.show();
}
} catch (JSONException e) {
MobclickAgent.reportError(mContext, e);
}
}
private static void AlertUpdate(){
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setTitle("发现新版本");
builder.setMessage("当前版本:" + AppConfig.getVersionName() + "\n"
+ "新版本:" + mUpdateEntity.versionName + "\n"
+ "大小:" + NumberUtil.getPrintSize(mUpdateEntity.fileSize) + "\n"
+ mUpdateEntity.updateLog + "\n");
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
eventLogger.onEvent("updateConfirm");
updateApp();
}
});
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
eventLogger.onEvent("updateCancel");
//选择取消之后,不再检查更新
AppConfig.setCheckUpdate(false);
}
});
builder.show();
}
private static void updateApp() {
updateApp(false);
}
private static void updateApp(boolean isEnforceDown) {
String filePath = Environment.getExternalStorageDirectory().getAbsolutePath();
String fileName = AppConfig.getPackageName() + mUpdateEntity.versionName +".apk";
if(!isEnforceDown){
File file = new File(filePath+"/"+fileName);
if(file.exists()){
install(file);
return;
}
}
mAlertDialog = new ProgressDialog(mContext);
mAlertDialog.setTitle("更新("+mUpdateEntity.versionName+")");
mAlertDialog.setMessage("正在下载最新版本...");
mAlertDialog.setCancelable(false);
mAlertDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mAlertDialog.setProgress(0);
mAlertDialog.setMax(100);
mAlertDialog.setIndeterminate(false);
mAlertDialog.setProgressNumberFormat("");
mAlertDialog.show();
OkHttpUtils.get().url(mUpdateEntity.downUrl).build().execute(
new FileCallBack(
filePath,
fileName) {
@Override
public void inProgress(float progress, long total) {
int downloadSize = (int)(progress * total);
if(downloadSize > mAlertDialog.getProgress() + 100 * 1024) {
mAlertDialog.setProgress((int)(100*progress));
mAlertDialog.setProgressNumberFormat(
String.format("%s/%s",
NumberUtil.getPrintSize(downloadSize),
NumberUtil.getPrintSize(total))
);
}
}
@Override
public void onError(Call call, Exception e) {
//下载失败,是否重试
resterAlert();
eventLogger.onEvent("updateError-"+e.getMessage());
}
@Override
public void onResponse(File file) {
//下载成功,开始安装
install(file);
}
@Override
public void onAfter() {
mAlertDialog.dismiss();
}
});
}
public static void install(File file) {
if(!checkMD5(file)){
md5Alert();
return;
}
eventLogger.onEvent("install");
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
}
private static void md5Alert() {
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setTitle("提示");
builder.setMessage("\n安装文件不完整是否重新下载\n");
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
updateApp(true);
}
});
builder.setNegativeButton("取消", null);
builder.show();
}
private static void resterAlert() {
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setTitle("提示");
builder.setMessage("\n文件下载失败是否重试\n");
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
updateApp();
}
});
builder.setNegativeButton("取消", null);
builder.show();
}
private static boolean checkMD5(File file) {
BigInteger md5Value = null;
try {
md5Value = getMd5ByFile(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Log.d("md5:",md5Value.toString(16));
return md5Value != null && mUpdateEntity.md5 != null && md5Value.equals(mUpdateEntity.md5);
}
public static BigInteger getMd5ByFile(File file) throws FileNotFoundException {
BigInteger value = null;
FileInputStream in = new FileInputStream(file);
try {
MappedByteBuffer byteBuffer = in.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, file.length());
MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update(byteBuffer);
value = new BigInteger(1, md5.digest());
} catch (Exception e) {
e.printStackTrace();
} finally {
if(null != in) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return value;
}
}

@ -1,39 +0,0 @@
package org.xing.utils;
import android.app.Activity;
import android.content.Context;
import android.os.Build;
import android.telephony.TelephonyManager;
import java.util.UUID;
/**
* Created by Administrator on 2016/12/29 0029.
*/
public class DeviceUtil {
public static String getUniqueId(Activity act) {
TelephonyManager tm = (TelephonyManager) act.getBaseContext().getSystemService(Context.TELEPHONY_SERVICE);
String tmDevice, tmSerial, tmPhone, androidId;
tmDevice = Build.BRAND;
tmSerial = Build.SERIAL;
androidId = Build.MODEL;
try {
//部分机型这里会抛出异常
tmDevice += tm.getDeviceId();
tmSerial += tm.getSimSerialNumber();
androidId += android.provider.Settings.Secure.getString(
act.getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);
}catch (Exception ex) {
ex.printStackTrace();
}
UUID deviceUuid = new UUID(androidId.hashCode(), ((long)tmDevice.hashCode() << 32) | tmSerial.hashCode());
String uniqueId = deviceUuid.toString();
return uniqueId;
}
}

@ -1,104 +0,0 @@
package org.xing.utils;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Collections;
import java.util.Map;
import java.util.Vector;
/**
* Created by Administrator on 2016/12/29 0029.
*/
public class HttpUtil {
public static String bytes2HexString(byte[] b) {
String ret = "";
for (int i = 0; i < b.length; i++) {
String hex = Integer.toHexString(b[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
ret += hex.toUpperCase();
}
return ret;
}
public static String md5Encode(String str)
throws NoSuchAlgorithmException, UnsupportedEncodingException{
MessageDigest md5=MessageDigest.getInstance("MD5");
String newstr=bytes2HexString(md5.digest(str.getBytes("utf-8")));
return newstr;
}
public static String formPostParams(Map<String, Object> params, String charset, String secret)
throws UnsupportedEncodingException {
StringBuilder str = new StringBuilder();
Vector<String> fields = new Vector<>();
for(Map.Entry<String, Object> en : params.entrySet()) {
fields.add(URLEncoder.encode(en.getKey(), charset)+
"="+URLEncoder.encode(en.getValue().toString(), charset));
}
Collections.sort(fields);
for(String field : fields) {
if(str.length() > 0) {
str.append("&");
}
str.append(field);
}
try {
String sign = md5Encode(str.toString()+secret);
str.append("&sign="+sign);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
//System.out.println(str.toString());
return str.toString();
}
public static String doPost(String urlString, Map<String, Object> params, String charset) {
StringBuilder result = new StringBuilder();
String secret = "862369397363725329";
try{
String bodyData = formPostParams(params, charset, secret);
URL url = new URL(urlString);
HttpURLConnection urlConn=(HttpURLConnection)url.openConnection();
urlConn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
urlConn.setDoOutput(true);
urlConn.setDoInput(true);
urlConn.setRequestMethod("POST");
urlConn.setUseCaches(false);
urlConn.connect();
DataOutputStream out = new DataOutputStream(urlConn.getOutputStream());
out.writeBytes(bodyData);
String line = null;
BufferedReader reader = new BufferedReader(
new InputStreamReader(urlConn.getInputStream(), "utf-8"));
while((line = reader.readLine()) != null) {
result.append(line);
}
//System.out.println(result.toString());
out.flush();
out.close();
}catch(Exception e){
e.printStackTrace();
}
return result.toString();
}
}

@ -1,95 +0,0 @@
package org.xing.utils;
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) {
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 parseLocalGrammarResult(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("\n");
}
}
ret.append("【置信度】" + joResult.optInt("sc"));
} catch (Exception e) {
e.printStackTrace();
ret.append("没有匹配结果.");
}
return ret.toString();
}
}

@ -1,63 +0,0 @@
package org.xing.utils;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
/**
* Created by fujiayi on 2017/5/17.
*/
public class Logger {
private static final String TAG = "Logger";
private static final String INFO = "INFO";
private static final String ERROR = "ERROR";
private static boolean ENABLE = true;
private static Handler handler;
public static void info(String message) {
info(TAG, message);
}
public static void info(String tag, String message) {
log(INFO, tag, message);
}
public static void error(String message) {
error(TAG, message);
}
public static void error(String tag, String message) {
log(ERROR, tag, message);
}
public static void setHandler(Handler handler) {
Logger.handler = handler;
}
private static void log(String level, String tag, String message) {
if (!ENABLE) {
return;
}
if (level.equals(INFO)) {
Log.i(tag, message);
} else if (level.equals(ERROR)) {
Log.e(tag, message);
}
if (handler != null) {
Message msg = Message.obtain();
msg.obj = "[" + level + "]" + message + "\n";
handler.sendMessage(msg);
}
}
public static void setEnable(boolean isEnable) {
ENABLE = isEnable;
}
}

@ -1,27 +0,0 @@
package org.xing.utils;
/**
* Created by Administrator on 2016/12/30 0030.
*/
public class NumberUtil {
public static String format(double num, int maxFloat) {
String text = String.format("%."+maxFloat+"f", num);
text = text.replaceAll("(\\.)?0*$", "");
return text;
}
public static String getPrintSize(long size) {
float printSize = (float)size / 1024/ 1024;
return String.format("%.1fMB", printSize);
}
public static String toFraction(Double number) {
if(number == null || number.isNaN() || number.isInfinite()) {
return null;
}
StringBuilder frac = new StringBuilder();
return frac.toString();
}
}

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<solid android:color="@color/colorBackground" />
<stroke android:width="1dip" android:color="@color/colorBackground"/>
<corners android:topLeftRadius="3dp"
android:topRightRadius="3dp"
android:bottomRightRadius="3dp"
android:bottomLeftRadius="3dp"/>
</shape>

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<solid android:color="@color/colorFront" />
<stroke android:width="1dip" android:color="@color/colorFront"/>
<corners android:topLeftRadius="3dp"
android:topRightRadius="3dp"
android:bottomRightRadius="3dp"
android:bottomLeftRadius="3dp"/>
</shape>

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@mipmap/btn_close_click" android:state_pressed="true"/>
<item android:drawable="@mipmap/btn_close" android:state_focused="false" android:state_pressed="false"/>
</selector>

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<solid android:color="#32A091" />
<stroke android:width="1dip" android:color="#32A091"/>
<corners android:topLeftRadius="10dp"
android:topRightRadius="10dp"
android:bottomRightRadius="10dp"
android:bottomLeftRadius="10dp"/>
</shape>

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/colorGrey" android:state_pressed="true"/>
<item android:drawable="@color/colorBackground" android:state_focused="false" android:state_pressed="false"/>
</selector>

@ -1,54 +0,0 @@
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@android:id/background">
<shape>
<corners android:radius="5dip" />
<gradient
android:angle="0"
android:centerColor="#aaaaaa"
android:centerY="0.75"
android:endColor="#aaaaaa"
android:startColor="#9d9e9d" />
</shape>
</item>
<item android:id="@android:id/secondaryProgress">
<clip>
<shape>
<corners android:radius="5dip" />
<gradient
android:angle="0"
android:centerColor="#80ffb600"
android:centerY="0.75"
android:endColor="#a0ffcb00"
android:startColor="#80ffd300" />
</shape>
</clip>
</item>
<item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="5dip" />
<gradient
android:angle="0"
android:startColor="#00ff00"
android:endColor="#00aa00"
/>
</shape>
</clip>
</item>
</layer-list>

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<solid android:color="@color/colorBackground" />
<stroke android:width="1dip" android:color="#cccccc"/>
</shape>

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@mipmap/help_mark_click" android:state_pressed="true"/>
<item android:drawable="@mipmap/help_mark" android:state_focused="false" android:state_pressed="false"/>
</selector>

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@mipmap/share_mark_click" android:state_pressed="true"/>
<item android:drawable="@mipmap/share_mark" android:state_focused="false" android:state_pressed="false"/>
</selector>

@ -1,247 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:auto="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="org.xing.android.MainActivity" >
<LinearLayout
android:id="@+id/backgroundLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:background="@color/colorBackground" >
<!-- 计算结果显示区 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="@android:color/transparent"
android:orientation="horizontal" >
<EditText
android:id="@+id/input"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="5dp"
android:background="@android:color/transparent"
android:inputType="textPersonName"
android:textIsSelectable="true"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:textColor="@color/colorText"
android:typeface="serif"
android:text="0"
android:textSize="45dp"
android:duplicateParentState="false" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_gravity="right"
android:gravity="center"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
>
<Button
android:id="@+id/stateButton"
android:layout_height="30dp"
android:layout_width="30dp"
android:background="@mipmap/input_sleep"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignBottom="@+id/input" />
</LinearLayout>
</FrameLayout>
<ProgressBar
style="@android:style/Widget.ProgressBar.Horizontal"
android:id="@+id/recordDynamic"
android:max="100"
android:progress="0"
android:visibility="visible"
android:alpha="50"
android:layout_height="2dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:indeterminate="false"
android:layout_width="match_parent"
android:paddingLeft="2dp"
android:paddingRight="2dp"
android:progressDrawable="@drawable/record_progress" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_weight="90"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:background="@android:color/transparent"
>
<!-- 计算历史显示区 -->
<WebView
android:id="@+id/historylist"
android:layout_width="match_parent"
android:background="@android:color/transparent"
android:layout_height="0dp"
android:layout_weight="97"
android:layout_margin="5dp"
android:layout_gravity="center"
android:layerType="software" />
<!-- 控制和状态显示区 -->
<FrameLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_alignParentTop="true" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="3dip"
android:orientation="horizontal"
android:layout_gravity="bottom"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:background="@android:color/transparent" >
<TextView
android:id = "@+id/msg"
android:layout_width="0dp"
android:layout_weight="45"
android:layout_height="wrap_content"
android:textColor="#777777"
android:textSize="12dp"
android:padding="1dip"
android:gravity="bottom"
android:background="@android:color/transparent"
android:layout_gravity="bottom" />
<Button
android:id = "@+id/ctrl_start"
android:layout_width="60dp"
android:layout_height="60dp"
android:clickable="true"
android:background="@mipmap/start"
android:gravity="center"
android:layout_gravity="center_horizontal" />
<LinearLayout
android:layout_width="0dp"
android:layout_weight="45"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="bottom"
android:gravity="right"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:background="@android:color/transparent" >
<Button
android:id = "@+id/share_mark"
android:layout_width="25dp"
android:layout_height="25dp"
android:textColor="#777777"
android:clickable="true"
android:layout_marginRight="5dp"
android:background="@drawable/textview_share_selector"
android:gravity="center" />
<Button
android:id = "@+id/help_mark"
android:layout_width="25dp"
android:layout_height="25dp"
android:textColor="#777777"
android:clickable="true"
android:background="@drawable/textview_help_selector"
android:gravity="center" />
</LinearLayout>
</LinearLayout>
<!-- 分享操作区 -->
<LinearLayout
android:id="@+id/share_board"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/share_boder"
android:visibility="gone"
android:orientation="vertical" >
<TextView
android:id = "@+id/share_title"
android:layout_width="match_parent"
android:layout_height="25dp"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp"
android:textColor="#777777"
android:textSize="15dp"
android:text="分享到" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<ImageView
android:id="@+id/share_weixin"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@drawable/image_selector"
android:src = "@mipmap/socialize_wechat" />
<ImageView
android:id="@+id/share_pengyouquan"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@drawable/image_selector"
android:src = "@mipmap/socialize_wxcircle" />
<ImageView
android:id="@+id/share_qq"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@drawable/image_selector"
android:src = "@mipmap/socialize_qq" />
<ImageView
android:id="@+id/share_kongjian"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@drawable/image_selector"
android:src = "@mipmap/socialize_qzone" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="@+id/cancel_btn"
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="#eeeeee"
android:textSize="16dp"
android:text="取消" />
</LinearLayout>
</LinearLayout>
</FrameLayout>
</LinearLayout>
</LinearLayout>
</RelativeLayout>

@ -1,91 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_simple_help"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorBackground"
tools:context="org.xing.android.SimpleHelpActivity">
<FrameLayout
android:id="@+id/video"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="invisible"
android:background="@android:color/transparent"
android:orientation="horizontal" >
</FrameLayout>
<LinearLayout
android:id="@+id/web"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true">
<LinearLayout
android:id="@+id/toolBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="center"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:background="@color/colorBackground"
>
<Button
android:id="@+id/help_close"
android:layout_height="40dp"
android:layout_width="40dp"
android:background="@drawable/btn_close_selector"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<TextView
android:id = "@+id/help_title"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:textColor="#333333"
android:maxLines="1"
android:textSize="20dp"
android:gravity="center"
android:layout_gravity="center_vertical" />
<Button
android:id="@+id/help_blank"
android:layout_height="40dp"
android:layout_width="40dp"
android:background="@color/colorBackground"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
</LinearLayout>
<ProgressBar
style="@android:style/Widget.ProgressBar.Horizontal"
android:id="@+id/webProgress"
android:max="100"
android:progress="0"
android:visibility="invisible"
android:alpha="50"
android:layout_height="2dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:indeterminate="false"
android:layout_width="match_parent"
android:paddingLeft="2dp"
android:paddingRight="2dp"
android:progressDrawable="@drawable/record_progress" />
<WebView
android:id="@+id/simple_help"
android:background="@color/colorBackground"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layerType="hardware" />
</LinearLayout>
</RelativeLayout>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save